Imported Upstream version 66.0.0 upstream/66.0.0
authorJinWang An <jinwang.an@samsung.com>
Mon, 27 Mar 2023 08:02:58 +0000 (17:02 +0900)
committerJinWang An <jinwang.an@samsung.com>
Mon, 27 Mar 2023 08:02:58 +0000 (17:02 +0900)
132 files changed:
.bumpversion.cfg
CHANGES.rst
docs/userguide/ext_modules.rst
pkg_resources/__init__.py
pkg_resources/_vendor/appdirs-1.4.3.dist-info/DESCRIPTION.rst [deleted file]
pkg_resources/_vendor/appdirs-1.4.3.dist-info/INSTALLER [deleted file]
pkg_resources/_vendor/appdirs-1.4.3.dist-info/METADATA [deleted file]
pkg_resources/_vendor/appdirs-1.4.3.dist-info/RECORD [deleted file]
pkg_resources/_vendor/appdirs-1.4.3.dist-info/REQUESTED [deleted file]
pkg_resources/_vendor/appdirs-1.4.3.dist-info/WHEEL [deleted file]
pkg_resources/_vendor/appdirs-1.4.3.dist-info/metadata.json [deleted file]
pkg_resources/_vendor/appdirs-1.4.3.dist-info/top_level.txt [deleted file]
pkg_resources/_vendor/appdirs.py [deleted file]
pkg_resources/_vendor/importlib_resources-5.4.0.dist-info/RECORD
pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/INSTALLER [deleted file]
pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/LICENSE [deleted file]
pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/METADATA [deleted file]
pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/RECORD [deleted file]
pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/WHEEL [deleted file]
pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/top_level.txt [deleted file]
pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/INSTALLER [new file with mode: 0644]
pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/LICENSE [new file with mode: 0644]
pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/METADATA [new file with mode: 0644]
pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/RECORD [new file with mode: 0644]
pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/WHEEL [new file with mode: 0644]
pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/top_level.txt [new file with mode: 0644]
pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/INSTALLER [deleted file]
pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/LICENSE [deleted file]
pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/METADATA [deleted file]
pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/RECORD [deleted file]
pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/WHEEL [deleted file]
pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/top_level.txt [deleted file]
pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/INSTALLER [new file with mode: 0644]
pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/LICENSE [new file with mode: 0644]
pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/METADATA [new file with mode: 0644]
pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/RECORD [new file with mode: 0644]
pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/WHEEL [new file with mode: 0644]
pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/top_level.txt [new file with mode: 0644]
pkg_resources/_vendor/jaraco.text-3.7.0.dist-info/RECORD
pkg_resources/_vendor/jaraco/context.py
pkg_resources/_vendor/more_itertools-8.12.0.dist-info/INSTALLER [deleted file]
pkg_resources/_vendor/more_itertools-8.12.0.dist-info/LICENSE [deleted file]
pkg_resources/_vendor/more_itertools-8.12.0.dist-info/METADATA [deleted file]
pkg_resources/_vendor/more_itertools-8.12.0.dist-info/RECORD [deleted file]
pkg_resources/_vendor/more_itertools-8.12.0.dist-info/WHEEL [deleted file]
pkg_resources/_vendor/more_itertools-8.12.0.dist-info/top_level.txt [deleted file]
pkg_resources/_vendor/more_itertools-9.0.0.dist-info/INSTALLER [new file with mode: 0644]
pkg_resources/_vendor/more_itertools-9.0.0.dist-info/LICENSE [new file with mode: 0644]
pkg_resources/_vendor/more_itertools-9.0.0.dist-info/METADATA [new file with mode: 0644]
pkg_resources/_vendor/more_itertools-9.0.0.dist-info/RECORD [new file with mode: 0644]
pkg_resources/_vendor/more_itertools-9.0.0.dist-info/WHEEL [new file with mode: 0644]
pkg_resources/_vendor/more_itertools/__init__.py
pkg_resources/_vendor/more_itertools/more.py [changed mode: 0644->0755]
pkg_resources/_vendor/more_itertools/more.pyi
pkg_resources/_vendor/more_itertools/recipes.py
pkg_resources/_vendor/more_itertools/recipes.pyi
pkg_resources/_vendor/packaging-21.3.dist-info/RECORD
pkg_resources/_vendor/platformdirs-2.6.2.dist-info/INSTALLER [new file with mode: 0644]
pkg_resources/_vendor/platformdirs-2.6.2.dist-info/METADATA [new file with mode: 0644]
pkg_resources/_vendor/platformdirs-2.6.2.dist-info/RECORD [new file with mode: 0644]
pkg_resources/_vendor/platformdirs-2.6.2.dist-info/REQUESTED [new file with mode: 0644]
pkg_resources/_vendor/platformdirs-2.6.2.dist-info/WHEEL [new file with mode: 0644]
pkg_resources/_vendor/platformdirs-2.6.2.dist-info/licenses/LICENSE [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/__init__.py [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/__main__.py [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/android.py [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/api.py [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/macos.py [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/py.typed [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/unix.py [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/version.py [new file with mode: 0644]
pkg_resources/_vendor/platformdirs/windows.py [new file with mode: 0644]
pkg_resources/_vendor/pyparsing-3.0.8.dist-info/INSTALLER [deleted file]
pkg_resources/_vendor/pyparsing-3.0.8.dist-info/LICENSE [deleted file]
pkg_resources/_vendor/pyparsing-3.0.8.dist-info/METADATA [deleted file]
pkg_resources/_vendor/pyparsing-3.0.8.dist-info/RECORD [deleted file]
pkg_resources/_vendor/pyparsing-3.0.8.dist-info/REQUESTED [deleted file]
pkg_resources/_vendor/pyparsing-3.0.8.dist-info/WHEEL [deleted file]
pkg_resources/_vendor/pyparsing-3.0.9.dist-info/RECORD
pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/INSTALLER [new file with mode: 0644]
pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/LICENSE [new file with mode: 0644]
pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/METADATA [new file with mode: 0644]
pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/RECORD [new file with mode: 0644]
pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/REQUESTED [new file with mode: 0644]
pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/WHEEL [new file with mode: 0644]
pkg_resources/_vendor/typing_extensions.py [new file with mode: 0644]
pkg_resources/_vendor/vendored.txt
pkg_resources/_vendor/zipp-3.7.0.dist-info/RECORD
pkg_resources/extern/__init__.py
setup.cfg
setuptools/_vendor/importlib_metadata-4.11.1.dist-info/RECORD
setuptools/_vendor/importlib_resources-5.4.0.dist-info/RECORD
setuptools/_vendor/jaraco.context-4.1.1.dist-info/INSTALLER [deleted file]
setuptools/_vendor/jaraco.context-4.1.1.dist-info/LICENSE [deleted file]
setuptools/_vendor/jaraco.context-4.1.1.dist-info/METADATA [deleted file]
setuptools/_vendor/jaraco.context-4.1.1.dist-info/RECORD [deleted file]
setuptools/_vendor/jaraco.context-4.1.1.dist-info/WHEEL [deleted file]
setuptools/_vendor/jaraco.context-4.1.1.dist-info/top_level.txt [deleted file]
setuptools/_vendor/jaraco.context-4.2.0.dist-info/INSTALLER [new file with mode: 0644]
setuptools/_vendor/jaraco.context-4.2.0.dist-info/LICENSE [new file with mode: 0644]
setuptools/_vendor/jaraco.context-4.2.0.dist-info/METADATA [new file with mode: 0644]
setuptools/_vendor/jaraco.context-4.2.0.dist-info/RECORD [new file with mode: 0644]
setuptools/_vendor/jaraco.context-4.2.0.dist-info/WHEEL [new file with mode: 0644]
setuptools/_vendor/jaraco.context-4.2.0.dist-info/top_level.txt [new file with mode: 0644]
setuptools/_vendor/jaraco.functools-3.5.0.dist-info/INSTALLER [deleted file]
setuptools/_vendor/jaraco.functools-3.5.0.dist-info/LICENSE [deleted file]
setuptools/_vendor/jaraco.functools-3.5.0.dist-info/METADATA [deleted file]
setuptools/_vendor/jaraco.functools-3.5.0.dist-info/RECORD [deleted file]
setuptools/_vendor/jaraco.functools-3.5.0.dist-info/WHEEL [deleted file]
setuptools/_vendor/jaraco.functools-3.5.0.dist-info/top_level.txt [deleted file]
setuptools/_vendor/jaraco.functools-3.5.2.dist-info/INSTALLER [new file with mode: 0644]
setuptools/_vendor/jaraco.functools-3.5.2.dist-info/LICENSE [new file with mode: 0644]
setuptools/_vendor/jaraco.functools-3.5.2.dist-info/METADATA [new file with mode: 0644]
setuptools/_vendor/jaraco.functools-3.5.2.dist-info/RECORD [new file with mode: 0644]
setuptools/_vendor/jaraco.functools-3.5.2.dist-info/WHEEL [new file with mode: 0644]
setuptools/_vendor/jaraco.functools-3.5.2.dist-info/top_level.txt [new file with mode: 0644]
setuptools/_vendor/jaraco.text-3.7.0.dist-info/RECORD
setuptools/_vendor/jaraco/context.py
setuptools/_vendor/more_itertools-8.8.0.dist-info/RECORD
setuptools/_vendor/ordered_set-3.1.1.dist-info/METADATA
setuptools/_vendor/ordered_set-3.1.1.dist-info/RECORD
setuptools/_vendor/ordered_set-3.1.1.dist-info/WHEEL
setuptools/_vendor/packaging-21.3.dist-info/RECORD
setuptools/_vendor/pyparsing-3.0.9.dist-info/RECORD
setuptools/_vendor/tomli-2.0.1.dist-info/RECORD
setuptools/_vendor/typing_extensions-4.0.1.dist-info/RECORD
setuptools/_vendor/zipp-3.7.0.dist-info/RECORD
setuptools/command/egg_info.py
setuptools/package_index.py
setuptools/tests/test_dist_info.py
setuptools/tests/test_packageindex.py
tools/vendored.py

index 3428c6fef5b459ae261421f5423c1ad65047d369..a7f4e5095cbadcfa13eeab5dcd085ae6811f7676 100644 (file)
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 65.7.0
+current_version = 66.0.0
 commit = True
 tag = True
 
index 495d8aa6e23fd6976570d6d60d5aa3f9aff7f670..a5d7a4a0b23ddee93f1f6b36e4d9603fab72e02c 100644 (file)
@@ -1,3 +1,16 @@
+v66.0.0
+-------
+
+
+Breaking Changes
+^^^^^^^^^^^^^^^^
+* #2497: Support for PEP 440 non-conforming versions has been removed. Environments containing packages with non-conforming versions may fail or the packages may not be recognized.
+
+Changes
+^^^^^^^
+* #3769: Replace 'appdirs' with 'platformdirs'.
+
+
 v65.7.0
 -------
 
index 9119830ca20684c0250b60672bfe4e4a7d0f3273..a59599b2756b7394d376f9375d5257f57770a14b 100644 (file)
@@ -76,8 +76,8 @@ compiler and linker options from various sources:
 * the ``sysconfig`` variables ``CC``, ``CXX``, ``CCSHARED``,
   ``LDSHARED``, and ``CFLAGS``,
 * the environment variables ``CC``, ``CPP``,
-  ``CXX``, ``LDSHARED`` and ``LDFLAGS``,
-  ``CFLAGS``, ``CPPFLAGS``, ``LDFLAGS``,
+  ``CXX``, ``LDSHARED`` and ``CFLAGS``,
+  ``CPPFLAGS``, ``LDFLAGS``,
 * the ``Extension`` attributes ``include_dirs``,
   ``library_dirs``, ``extra_compile_args``, ``extra_link_args``,
   ``runtime_library_dirs``.
index d59226af9d7fe1b5279e99ff6e333032d1cec274..bba775b9087dcbf3cd0e1795bc8e71cd0971ece4 100644 (file)
@@ -34,7 +34,6 @@ import email.parser
 import errno
 import tempfile
 import textwrap
-import itertools
 import inspect
 import ntpath
 import posixpath
@@ -54,8 +53,10 @@ except NameError:
 
 # capture these to bypass sandboxing
 from os import utime
+
 try:
     from os import mkdir, rename, unlink
+
     WRITE_SUPPORT = True
 except ImportError:
     # no write support, probably under GAE
@@ -66,6 +67,7 @@ from os.path import isdir, split
 
 try:
     import importlib.machinery as importlib_machinery
+
     # access attribute to force import under delayed import mechanisms.
     importlib_machinery.__name__
 except ImportError:
@@ -77,8 +79,9 @@ from pkg_resources.extern.jaraco.text import (
     join_continuation,
 )
 
-from pkg_resources.extern import appdirs
+from pkg_resources.extern import platformdirs
 from pkg_resources.extern import packaging
+
 __import__('pkg_resources.extern.packaging.version')
 __import__('pkg_resources.extern.packaging.specifiers')
 __import__('pkg_resources.extern.packaging.requirements')
@@ -116,16 +119,7 @@ class PEP440Warning(RuntimeWarning):
     """
 
 
-def parse_version(v):
-    try:
-        return packaging.version.Version(v)
-    except packaging.version.InvalidVersion:
-        warnings.warn(
-            f"{v} is an invalid version and will not be supported in "
-            "a future release",
-            PkgResourcesDeprecationWarning,
-        )
-        return packaging.version.LegacyVersion(v)
+parse_version = packaging.version.Version
 
 
 _state_vars = {}
@@ -197,51 +191,87 @@ def get_supported_platform():
 
 __all__ = [
     # Basic resource access and distribution/entry point discovery
-    'require', 'run_script', 'get_provider', 'get_distribution',
-    'load_entry_point', 'get_entry_map', 'get_entry_info',
+    'require',
+    'run_script',
+    'get_provider',
+    'get_distribution',
+    'load_entry_point',
+    'get_entry_map',
+    'get_entry_info',
     'iter_entry_points',
-    'resource_string', 'resource_stream', 'resource_filename',
-    'resource_listdir', 'resource_exists', 'resource_isdir',
-
+    'resource_string',
+    'resource_stream',
+    'resource_filename',
+    'resource_listdir',
+    'resource_exists',
+    'resource_isdir',
     # Environmental control
-    'declare_namespace', 'working_set', 'add_activation_listener',
-    'find_distributions', 'set_extraction_path', 'cleanup_resources',
+    'declare_namespace',
+    'working_set',
+    'add_activation_listener',
+    'find_distributions',
+    'set_extraction_path',
+    'cleanup_resources',
     'get_default_cache',
-
     # Primary implementation classes
-    'Environment', 'WorkingSet', 'ResourceManager',
-    'Distribution', 'Requirement', 'EntryPoint',
-
+    'Environment',
+    'WorkingSet',
+    'ResourceManager',
+    'Distribution',
+    'Requirement',
+    'EntryPoint',
     # Exceptions
-    'ResolutionError', 'VersionConflict', 'DistributionNotFound',
-    'UnknownExtra', 'ExtractionError',
-
+    'ResolutionError',
+    'VersionConflict',
+    'DistributionNotFound',
+    'UnknownExtra',
+    'ExtractionError',
     # Warnings
     'PEP440Warning',
-
     # Parsing functions and string utilities
-    'parse_requirements', 'parse_version', 'safe_name', 'safe_version',
-    'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections',
-    'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker',
-
+    'parse_requirements',
+    'parse_version',
+    'safe_name',
+    'safe_version',
+    'get_platform',
+    'compatible_platforms',
+    'yield_lines',
+    'split_sections',
+    'safe_extra',
+    'to_filename',
+    'invalid_marker',
+    'evaluate_marker',
     # filesystem utilities
-    'ensure_directory', 'normalize_path',
-
+    'ensure_directory',
+    'normalize_path',
     # Distribution "precedence" constants
-    'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST',
-
+    'EGG_DIST',
+    'BINARY_DIST',
+    'SOURCE_DIST',
+    'CHECKOUT_DIST',
+    'DEVELOP_DIST',
     # "Provider" interfaces, implementations, and registration/lookup APIs
-    'IMetadataProvider', 'IResourceProvider', 'FileMetadata',
-    'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider',
-    'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider',
-    'register_finder', 'register_namespace_handler', 'register_loader_type',
-    'fixup_namespace_packages', 'get_importer',
-
+    'IMetadataProvider',
+    'IResourceProvider',
+    'FileMetadata',
+    'PathMetadata',
+    'EggMetadata',
+    'EmptyProvider',
+    'empty_provider',
+    'NullProvider',
+    'EggProvider',
+    'DefaultProvider',
+    'ZipProvider',
+    'register_finder',
+    'register_namespace_handler',
+    'register_loader_type',
+    'fixup_namespace_packages',
+    'get_importer',
     # Warnings
     'PkgResourcesDeprecationWarning',
-
     # Deprecated/backward compatibility only
-    'run_main', 'AvailableDistributions',
+    'run_main',
+    'AvailableDistributions',
 ]
 
 
@@ -300,8 +330,10 @@ class ContextualVersionConflict(VersionConflict):
 class DistributionNotFound(ResolutionError):
     """A requested distribution was not found"""
 
-    _template = ("The '{self.req}' distribution was not found "
-                 "and is required by {self.requirers_str}")
+    _template = (
+        "The '{self.req}' distribution was not found "
+        "and is required by {self.requirers_str}"
+    )
 
     @property
     def req(self):
@@ -395,7 +427,8 @@ def get_build_platform():
             version = _macos_vers()
             machine = os.uname()[4].replace(" ", "_")
             return "macosx-%d.%d-%s" % (
-                int(version[0]), int(version[1]),
+                int(version[0]),
+                int(version[1]),
                 _macos_arch(machine),
             )
         except ValueError:
@@ -436,15 +469,18 @@ def compatible_platforms(provided, required):
             if provDarwin:
                 dversion = int(provDarwin.group(1))
                 macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2))
-                if dversion == 7 and macosversion >= "10.3" or \
-                        dversion == 8 and macosversion >= "10.4":
+                if (
+                    dversion == 7
+                    and macosversion >= "10.3"
+                    or dversion == 8
+                    and macosversion >= "10.4"
+                ):
                     return True
             # egg isn't macOS or legacy darwin
             return False
 
         # are they the same major version and machine type?
-        if provMac.group(1) != reqMac.group(1) or \
-                provMac.group(3) != reqMac.group(3):
+        if provMac.group(1) != reqMac.group(1) or provMac.group(3) != reqMac.group(3):
             return False
 
         # is the required OS major update >= the provided one?
@@ -506,8 +542,8 @@ class IMetadataProvider:
     def get_metadata_lines(name):
         """Yield named metadata resource as list of non-blank non-comment lines
 
-       Leading and trailing whitespace is stripped from each line, and lines
-       with ``#`` as the first non-blank character are omitted."""
+        Leading and trailing whitespace is stripped from each line, and lines
+        with ``#`` as the first non-blank character are omitted."""
 
     def metadata_isdir(name):
         """Is the named metadata a directory?  (like ``os.path.isdir()``)"""
@@ -720,9 +756,14 @@ class WorkingSet:
             keys2.append(dist.key)
         self._added_new(dist)
 
-    # FIXME: 'WorkingSet.resolve' is too complex (11)
-    def resolve(self, requirements, env=None, installer=None,  # noqa: C901
-                replace_conflicting=False, extras=None):
+    def resolve(
+        self,
+        requirements,
+        env=None,
+        installer=None,
+        replace_conflicting=False,
+        extras=None,
+    ):
         """List all distributions needed to (recursively) meet `requirements`
 
         `requirements` must be a sequence of ``Requirement`` objects.  `env`,
@@ -771,33 +812,9 @@ class WorkingSet:
             if not req_extras.markers_pass(req, extras):
                 continue
 
-            dist = best.get(req.key)
-            if dist is None:
-                # Find the best distribution and add it to the map
-                dist = self.by_key.get(req.key)
-                if dist is None or (dist not in req and replace_conflicting):
-                    ws = self
-                    if env is None:
-                        if dist is None:
-                            env = Environment(self.entries)
-                        else:
-                            # Use an empty environment and workingset to avoid
-                            # any further conflicts with the conflicting
-                            # distribution
-                            env = Environment([])
-                            ws = WorkingSet([])
-                    dist = best[req.key] = env.best_match(
-                        req, ws, installer,
-                        replace_conflicting=replace_conflicting
-                    )
-                    if dist is None:
-                        requirers = required_by.get(req, None)
-                        raise DistributionNotFound(req, requirers)
-                to_activate.append(dist)
-            if dist not in req:
-                # Oops, the "best" so far conflicts with a dependency
-                dependent_req = required_by[req]
-                raise VersionConflict(dist, req).with_context(dependent_req)
+            dist = self._resolve_dist(
+                req, best, replace_conflicting, env, installer, required_by, to_activate
+            )
 
             # push the new requirements onto the stack
             new_requirements = dist.requires(req.extras)[::-1]
@@ -813,8 +830,38 @@ class WorkingSet:
         # return list of distros to activate
         return to_activate
 
-    def find_plugins(
-            self, plugin_env, full_env=None, installer=None, fallback=True):
+    def _resolve_dist(
+        self, req, best, replace_conflicting, env, installer, required_by, to_activate
+    ):
+        dist = best.get(req.key)
+        if dist is None:
+            # Find the best distribution and add it to the map
+            dist = self.by_key.get(req.key)
+            if dist is None or (dist not in req and replace_conflicting):
+                ws = self
+                if env is None:
+                    if dist is None:
+                        env = Environment(self.entries)
+                    else:
+                        # Use an empty environment and workingset to avoid
+                        # any further conflicts with the conflicting
+                        # distribution
+                        env = Environment([])
+                        ws = WorkingSet([])
+                dist = best[req.key] = env.best_match(
+                    req, ws, installer, replace_conflicting=replace_conflicting
+                )
+                if dist is None:
+                    requirers = required_by.get(req, None)
+                    raise DistributionNotFound(req, requirers)
+            to_activate.append(dist)
+        if dist not in req:
+            # Oops, the "best" so far conflicts with a dependency
+            dependent_req = required_by[req]
+            raise VersionConflict(dist, req).with_context(dependent_req)
+        return dist
+
+    def find_plugins(self, plugin_env, full_env=None, installer=None, fallback=True):
         """Find all activatable distributions in `plugin_env`
 
         Example usage::
@@ -933,8 +980,11 @@ class WorkingSet:
 
     def __getstate__(self):
         return (
-            self.entries[:], self.entry_keys.copy(), self.by_key.copy(),
-            self.normalized_to_canonical_keys.copy(), self.callbacks[:]
+            self.entries[:],
+            self.entry_keys.copy(),
+            self.by_key.copy(),
+            self.normalized_to_canonical_keys.copy(),
+            self.callbacks[:],
         )
 
     def __setstate__(self, e_k_b_n_c):
@@ -970,8 +1020,8 @@ class Environment:
     """Searchable snapshot of distributions on a search path"""
 
     def __init__(
-            self, search_path=None, platform=get_supported_platform(),
-            python=PY_MAJOR):
+        self, search_path=None, platform=get_supported_platform(), python=PY_MAJOR
+    ):
         """Snapshot distributions available on a search path
 
         Any distributions found on `search_path` are added to the environment.
@@ -1038,16 +1088,14 @@ class Environment:
         return self._distmap.get(distribution_key, [])
 
     def add(self, dist):
-        """Add `dist` if we ``can_add()`` it and it has not already been added
-        """
+        """Add `dist` if we ``can_add()`` it and it has not already been added"""
         if self.can_add(dist) and dist.has_version():
             dists = self._distmap.setdefault(dist.key, [])
             if dist not in dists:
                 dists.append(dist)
                 dists.sort(key=operator.attrgetter('hashcmp'), reverse=True)
 
-    def best_match(
-            self, req, working_set, installer=None, replace_conflicting=False):
+    def best_match(self, req, working_set, installer=None, replace_conflicting=False):
         """Find distribution best matching `req` and usable on `working_set`
 
         This calls the ``find(req)`` method of the `working_set` to see if a
@@ -1134,6 +1182,7 @@ class ExtractionError(RuntimeError):
 
 class ResourceManager:
     """Manage resource extraction and packages"""
+
     extraction_path = None
 
     def __init__(self):
@@ -1145,9 +1194,7 @@ class ResourceManager:
 
     def resource_isdir(self, package_or_requirement, resource_name):
         """Is the named resource an existing directory?"""
-        return get_provider(package_or_requirement).resource_isdir(
-            resource_name
-        )
+        return get_provider(package_or_requirement).resource_isdir(resource_name)
 
     def resource_filename(self, package_or_requirement, resource_name):
         """Return a true filesystem path for specified resource"""
@@ -1169,9 +1216,7 @@ class ResourceManager:
 
     def resource_listdir(self, package_or_requirement, resource_name):
         """List the contents of the named resource directory"""
-        return get_provider(package_or_requirement).resource_listdir(
-            resource_name
-        )
+        return get_provider(package_or_requirement).resource_listdir(resource_name)
 
     def extraction_error(self):
         """Give an error message for problems extracting file(s)"""
@@ -1179,7 +1224,8 @@ class ResourceManager:
         old_exc = sys.exc_info()[1]
         cache_path = self.extraction_path or get_default_cache()
 
-        tmpl = textwrap.dedent("""
+        tmpl = textwrap.dedent(
+            """
             Can't extract file(s) to egg cache
 
             The following error occurred while trying to extract file(s)
@@ -1194,7 +1240,8 @@ class ResourceManager:
             Perhaps your account does not have write access to this directory?
             You can change the cache directory by setting the PYTHON_EGG_CACHE
             environment variable to point to an accessible directory.
-            """).lstrip()
+            """
+        ).lstrip()
         err = ExtractionError(tmpl.format(**locals()))
         err.manager = self
         err.cache_path = cache_path
@@ -1293,9 +1340,7 @@ class ResourceManager:
         ``cleanup_resources()``.)
         """
         if self.cached_files:
-            raise ValueError(
-                "Can't change extraction path, files already extracted"
-            )
+            raise ValueError("Can't change extraction path, files already extracted")
 
         self.extraction_path = path
 
@@ -1319,9 +1364,8 @@ def get_default_cache():
     or a platform-relevant user cache dir for an app
     named "Python-Eggs".
     """
-    return (
-        os.environ.get('PYTHON_EGG_CACHE')
-        or appdirs.user_cache_dir(appname='Python-Eggs')
+    return os.environ.get('PYTHON_EGG_CACHE') or platformdirs.user_cache_dir(
+        appname='Python-Eggs'
     )
 
 
@@ -1458,8 +1502,9 @@ class NullProvider:
         script = 'scripts/' + script_name
         if not self.has_metadata(script):
             raise ResolutionError(
-                "Script {script!r} not found in metadata at {self.egg_info!r}"
-                .format(**locals()),
+                "Script {script!r} not found in metadata at {self.egg_info!r}".format(
+                    **locals()
+                ),
             )
         script_text = self.get_metadata(script).replace('\r\n', '\n')
         script_text = script_text.replace('\r', '\n')
@@ -1472,8 +1517,12 @@ class NullProvider:
             exec(code, namespace, namespace)
         else:
             from linecache import cache
+
             cache[script_filename] = (
-                len(script_text), 0, script_text.split('\n'), script_filename
+                len(script_text),
+                0,
+                script_text.split('\n'),
+                script_filename,
             )
             script_code = compile(script_text, script_filename, 'exec')
             exec(script_code, namespace, namespace)
@@ -1553,9 +1602,9 @@ is not allowed.
         AttributeError: ...
         """
         invalid = (
-            os.path.pardir in path.split(posixpath.sep) or
-            posixpath.isabs(path) or
-            ntpath.isabs(path)
+            os.path.pardir in path.split(posixpath.sep)
+            or posixpath.isabs(path)
+            or ntpath.isabs(path)
         )
         if not invalid:
             return
@@ -1637,7 +1686,10 @@ class DefaultProvider(EggProvider):
 
     @classmethod
     def _register(cls):
-        loader_names = 'SourceFileLoader', 'SourcelessFileLoader',
+        loader_names = (
+            'SourceFileLoader',
+            'SourcelessFileLoader',
+        )
         for name in loader_names:
             loader_cls = getattr(importlib_machinery, name, type(None))
             register_loader_type(loader_cls, cls)
@@ -1697,6 +1749,7 @@ class MemoizedZipManifests(ZipManifests):
     """
     Memoized zipfile manifests.
     """
+
     manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime')
 
     def load(self, path):
@@ -1730,20 +1783,16 @@ class ZipProvider(EggProvider):
         if fspath == self.loader.archive:
             return ''
         if fspath.startswith(self.zip_pre):
-            return fspath[len(self.zip_pre):]
-        raise AssertionError(
-            "%s is not a subpath of %s" % (fspath, self.zip_pre)
-        )
+            return fspath[len(self.zip_pre) :]
+        raise AssertionError("%s is not a subpath of %s" % (fspath, self.zip_pre))
 
     def _parts(self, zip_path):
         # Convert a zipfile subpath into an egg-relative path part list.
         # pseudo-fs path
         fspath = self.zip_pre + zip_path
         if fspath.startswith(self.egg_root + os.sep):
-            return fspath[len(self.egg_root) + 1:].split(os.sep)
-        raise AssertionError(
-            "%s is not a subpath of %s" % (fspath, self.egg_root)
-        )
+            return fspath[len(self.egg_root) + 1 :].split(os.sep)
+        raise AssertionError("%s is not a subpath of %s" % (fspath, self.egg_root))
 
     @property
     def zipinfo(self):
@@ -1776,22 +1825,19 @@ class ZipProvider(EggProvider):
 
         if zip_path in self._index():
             for name in self._index()[zip_path]:
-                last = self._extract_resource(
-                    manager, os.path.join(zip_path, name)
-                )
+                last = self._extract_resource(manager, os.path.join(zip_path, name))
             # return the extracted directory name
             return os.path.dirname(last)
 
         timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
 
         if not WRITE_SUPPORT:
-            raise IOError('"os.rename" and "os.unlink" are not supported '
-                          'on this platform')
+            raise IOError(
+                '"os.rename" and "os.unlink" are not supported ' 'on this platform'
+            )
         try:
 
-            real_path = manager.get_cache_path(
-                self.egg_name, self._parts(zip_path)
-            )
+            real_path = manager.get_cache_path(self.egg_name, self._parts(zip_path))
 
             if self._is_current(real_path, zip_path):
                 return real_path
@@ -2027,70 +2073,21 @@ def find_nothing(importer, path_item, only=False):
 register_finder(object, find_nothing)
 
 
-def _by_version_descending(names):
-    """
-    Given a list of filenames, return them in descending order
-    by version number.
-
-    >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg'
-    >>> _by_version_descending(names)
-    ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'bar', 'foo']
-    >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg'
-    >>> _by_version_descending(names)
-    ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg']
-    >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg'
-    >>> _by_version_descending(names)
-    ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg']
-    """
-    def try_parse(name):
-        """
-        Attempt to parse as a version or return a null version.
-        """
-        try:
-            return packaging.version.Version(name)
-        except Exception:
-            return packaging.version.Version('0')
-
-    def _by_version(name):
-        """
-        Parse each component of the filename
-        """
-        name, ext = os.path.splitext(name)
-        parts = itertools.chain(name.split('-'), [ext])
-        return [try_parse(part) for part in parts]
-
-    return sorted(names, key=_by_version, reverse=True)
-
-
 def find_on_path(importer, path_item, only=False):
     """Yield distributions accessible on a sys.path directory"""
     path_item = _normalize_cached(path_item)
 
     if _is_unpacked_egg(path_item):
         yield Distribution.from_filename(
-            path_item, metadata=PathMetadata(
-                path_item, os.path.join(path_item, 'EGG-INFO')
-            )
+            path_item,
+            metadata=PathMetadata(path_item, os.path.join(path_item, 'EGG-INFO')),
         )
         return
 
-    entries = (
-        os.path.join(path_item, child)
-        for child in safe_listdir(path_item)
-    )
-
-    # for performance, before sorting by version,
-    # screen entries for only those that will yield
-    # distributions
-    filtered = (
-        entry
-        for entry in entries
-        if dist_factory(path_item, entry, only)
-    )
+    entries = (os.path.join(path_item, child) for child in safe_listdir(path_item))
 
     # scan for .egg and .egg-info in directory
-    path_item_entries = _by_version_descending(filtered)
-    for entry in path_item_entries:
+    for entry in sorted(entries):
         fullpath = os.path.join(path_item, entry)
         factory = dist_factory(path_item, entry, only)
         for dist in factory(fullpath):
@@ -2101,19 +2098,18 @@ def dist_factory(path_item, entry, only):
     """Return a dist_factory for the given entry."""
     lower = entry.lower()
     is_egg_info = lower.endswith('.egg-info')
-    is_dist_info = (
-        lower.endswith('.dist-info') and
-        os.path.isdir(os.path.join(path_item, entry))
+    is_dist_info = lower.endswith('.dist-info') and os.path.isdir(
+        os.path.join(path_item, entry)
     )
     is_meta = is_egg_info or is_dist_info
     return (
         distributions_from_metadata
-        if is_meta else
-        find_distributions
-        if not only and _is_egg_path(entry) else
-        resolve_egg_link
-        if not only and lower.endswith('.egg-link') else
-        NoDists()
+        if is_meta
+        else find_distributions
+        if not only and _is_egg_path(entry)
+        else resolve_egg_link
+        if not only and lower.endswith('.egg-link')
+        else NoDists()
     )
 
 
@@ -2125,6 +2121,7 @@ class NoDists:
     >>> list(NoDists()('anything'))
     []
     """
+
     def __bool__(self):
         return False
 
@@ -2159,7 +2156,10 @@ def distributions_from_metadata(path):
         metadata = FileMetadata(path)
     entry = os.path.basename(path)
     yield Distribution.from_location(
-        root, entry, metadata, precedence=DEVELOP_DIST,
+        root,
+        entry,
+        metadata,
+        precedence=DEVELOP_DIST,
     )
 
 
@@ -2181,8 +2181,7 @@ def resolve_egg_link(path):
     """
     referenced_paths = non_empty_lines(path)
     resolved_paths = (
-        os.path.join(os.path.dirname(path), ref)
-        for ref in referenced_paths
+        os.path.join(os.path.dirname(path), ref) for ref in referenced_paths
     )
     dist_groups = map(find_distributions, resolved_paths)
     return next(dist_groups, ())
@@ -2361,8 +2360,7 @@ register_namespace_handler(object, null_ns_handler)
 
 def normalize_path(filename):
     """Normalize a file/dir name for comparison purposes"""
-    return os.path.normcase(os.path.realpath(os.path.normpath(
-        _cygwin_patch(filename))))
+    return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename))))
 
 
 def _cygwin_patch(filename):  # pragma: nocover
@@ -2393,9 +2391,9 @@ def _is_egg_path(path):
 
 def _is_zip_egg(path):
     return (
-        path.lower().endswith('.egg') and
-        os.path.isfile(path) and
-        zipfile.is_zipfile(path)
+        path.lower().endswith('.egg')
+        and os.path.isfile(path)
+        and zipfile.is_zipfile(path)
     )
 
 
@@ -2403,9 +2401,8 @@ def _is_unpacked_egg(path):
     """
     Determine if given path appears to be an unpacked egg.
     """
-    return (
-        path.lower().endswith('.egg') and
-        os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO'))
+    return path.lower().endswith('.egg') and os.path.isfile(
+        os.path.join(path, 'EGG-INFO', 'PKG-INFO')
     )
 
 
@@ -2569,8 +2566,10 @@ def _version_from_file(lines):
     Given an iterable of lines from a Metadata file, return
     the value of the Version field, if present, or None otherwise.
     """
+
     def is_version_line(line):
         return line.lower().startswith('version:')
+
     version_lines = filter(is_version_line, lines)
     line = next(iter(version_lines), '')
     _, _, value = line.partition(':')
@@ -2579,12 +2578,19 @@ def _version_from_file(lines):
 
 class Distribution:
     """Wrap an actual or potential sys.path entry w/metadata"""
+
     PKG_INFO = 'PKG-INFO'
 
     def __init__(
-            self, location=None, metadata=None, project_name=None,
-            version=None, py_version=PY_MAJOR, platform=None,
-            precedence=EGG_DIST):
+        self,
+        location=None,
+        metadata=None,
+        project_name=None,
+        version=None,
+        py_version=PY_MAJOR,
+        platform=None,
+        precedence=EGG_DIST,
+    ):
         self.project_name = safe_name(project_name or 'Unknown')
         if version is not None:
             self._version = safe_version(version)
@@ -2607,8 +2613,13 @@ class Distribution:
                     'name', 'ver', 'pyver', 'plat'
                 )
         return cls(
-            location, metadata, project_name=project_name, version=version,
-            py_version=py_version, platform=platform, **kw
+            location,
+            metadata,
+            project_name=project_name,
+            version=version,
+            py_version=py_version,
+            platform=platform,
+            **kw,
         )._reload_version()
 
     def _reload_version(self):
@@ -2668,32 +2679,6 @@ class Distribution:
 
         return self._parsed_version
 
-    def _warn_legacy_version(self):
-        LV = packaging.version.LegacyVersion
-        is_legacy = isinstance(self._parsed_version, LV)
-        if not is_legacy:
-            return
-
-        # While an empty version is technically a legacy version and
-        # is not a valid PEP 440 version, it's also unlikely to
-        # actually come from someone and instead it is more likely that
-        # it comes from setuptools attempting to parse a filename and
-        # including it in the list. So for that we'll gate this warning
-        # on if the version is anything at all or not.
-        if not self.version:
-            return
-
-        tmpl = textwrap.dedent("""
-            '{project_name} ({version})' is being parsed as a legacy,
-            non PEP 440,
-            version. You may find odd behavior and sort order.
-            In particular it will be sorted as less than 0.0. It
-            is recommended to migrate to PEP 440 compatible
-            versions.
-            """).strip().replace('\n', ' ')
-
-        warnings.warn(tmpl.format(**vars(self)), PEP440Warning)
-
     @property
     def version(self):
         try:
@@ -2702,9 +2687,9 @@ class Distribution:
             version = self._get_version()
             if version is None:
                 path = self._get_metadata_path_for_display(self.PKG_INFO)
-                msg = (
-                    "Missing 'Version:' header and/or {} file at path: {}"
-                ).format(self.PKG_INFO, path)
+                msg = ("Missing 'Version:' header and/or {} file at path: {}").format(
+                    self.PKG_INFO, path
+                )
                 raise ValueError(msg, self) from e
 
             return version
@@ -2733,8 +2718,7 @@ class Distribution:
             reqs = dm.pop(extra)
             new_extra, _, marker = extra.partition(':')
             fails_marker = marker and (
-                invalid_marker(marker)
-                or not evaluate_marker(marker)
+                invalid_marker(marker) or not evaluate_marker(marker)
             )
             if fails_marker:
                 reqs = []
@@ -2806,8 +2790,9 @@ class Distribution:
     def egg_name(self):
         """Return what this distribution's standard .egg filename should be"""
         filename = "%s-%s-py%s" % (
-            to_filename(self.project_name), to_filename(self.version),
-            self.py_version or PY_MAJOR
+            to_filename(self.project_name),
+            to_filename(self.version),
+            self.py_version or PY_MAJOR,
         )
 
         if self.platform:
@@ -2837,17 +2822,13 @@ class Distribution:
     def __dir__(self):
         return list(
             set(super(Distribution, self).__dir__())
-            | set(
-                attr for attr in self._provider.__dir__()
-                if not attr.startswith('_')
-            )
+            | set(attr for attr in self._provider.__dir__() if not attr.startswith('_'))
         )
 
     @classmethod
     def from_filename(cls, filename, metadata=None, **kw):
         return cls.from_location(
-            _normalize_cached(filename), os.path.basename(filename), metadata,
-            **kw
+            _normalize_cached(filename), os.path.basename(filename), metadata, **kw
         )
 
     def as_requirement(self):
@@ -2959,14 +2940,18 @@ class Distribution:
         nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt'))
         loc = normalize_path(self.location)
         for modname in self._get_metadata('top_level.txt'):
-            if (modname not in sys.modules or modname in nsp
-                    or modname in _namespace_packages):
+            if (
+                modname not in sys.modules
+                or modname in nsp
+                or modname in _namespace_packages
+            ):
                 continue
             if modname in ('pkg_resources', 'setuptools', 'site'):
                 continue
             fn = getattr(sys.modules[modname], '__file__', None)
-            if fn and (normalize_path(fn).startswith(loc) or
-                       fn.startswith(self.location)):
+            if fn and (
+                normalize_path(fn).startswith(loc) or fn.startswith(self.location)
+            ):
                 continue
             issue_warning(
                 "Module %s was already imported from %s, but %s is being added"
@@ -3018,6 +3003,7 @@ class DistInfoDistribution(Distribution):
     Wrap an actual or potential sys.path entry
     w/metadata, .dist-info style.
     """
+
     PKG_INFO = 'METADATA'
     EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])")
 
@@ -3103,8 +3089,7 @@ class Requirement(packaging.requirements.Requirement):
         self.unsafe_name = self.name
         project_name = safe_name(self.name)
         self.project_name, self.key = project_name, project_name.lower()
-        self.specs = [
-            (spec.operator, spec.version) for spec in self.specifier]
+        self.specs = [(spec.operator, spec.version) for spec in self.specifier]
         self.extras = tuple(map(safe_extra, self.extras))
         self.hashCmp = (
             self.key,
@@ -3116,10 +3101,7 @@ class Requirement(packaging.requirements.Requirement):
         self.__hash = hash(self.hashCmp)
 
     def __eq__(self, other):
-        return (
-            isinstance(other, Requirement) and
-            self.hashCmp == other.hashCmp
-        )
+        return isinstance(other, Requirement) and self.hashCmp == other.hashCmp
 
     def __ne__(self, other):
         return not self == other
@@ -3144,7 +3126,7 @@ class Requirement(packaging.requirements.Requirement):
 
     @staticmethod
     def parse(s):
-        req, = parse_requirements(s)
+        (req,) = parse_requirements(s)
         return req
 
 
@@ -3282,10 +3264,7 @@ def _initialize_master_working_set():
     # ensure that all distributions added to the working set in the future
     # (e.g. by calling ``require()``) will get activated as well,
     # with higher priority (replace=True).
-    tuple(
-        dist.activate(replace=False)
-        for dist in working_set
-    )
+    tuple(dist.activate(replace=False) for dist in working_set)
     add_activation_listener(
         lambda dist: dist.activate(replace=True),
         existing=False,
diff --git a/pkg_resources/_vendor/appdirs-1.4.3.dist-info/DESCRIPTION.rst b/pkg_resources/_vendor/appdirs-1.4.3.dist-info/DESCRIPTION.rst
deleted file mode 100644 (file)
index c605ec2..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-
-.. image:: https://secure.travis-ci.org/ActiveState/appdirs.png
-    :target: http://travis-ci.org/ActiveState/appdirs
-
-the problem
-===========
-
-What directory should your app use for storing user data? If running on Mac OS X, you
-should use::
-
-    ~/Library/Application Support/<AppName>
-
-If on Windows (at least English Win XP) that should be::
-
-    C:\Documents and Settings\<User>\Application Data\Local Settings\<AppAuthor>\<AppName>
-
-or possibly::
-
-    C:\Documents and Settings\<User>\Application Data\<AppAuthor>\<AppName>
-
-for `roaming profiles <http://bit.ly/9yl3b6>`_ but that is another story.
-
-On Linux (and other Unices) the dir, according to the `XDG
-spec <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_, is::
-
-    ~/.local/share/<AppName>
-
-
-``appdirs`` to the rescue
-=========================
-
-This kind of thing is what the ``appdirs`` module is for. ``appdirs`` will
-help you choose an appropriate:
-
-- user data dir (``user_data_dir``)
-- user config dir (``user_config_dir``)
-- user cache dir (``user_cache_dir``)
-- site data dir (``site_data_dir``)
-- site config dir (``site_config_dir``)
-- user log dir (``user_log_dir``)
-
-and also:
-
-- is a single module so other Python packages can include their own private copy
-- is slightly opinionated on the directory names used. Look for "OPINION" in
-  documentation and code for when an opinion is being applied.
-
-
-some example output
-===================
-
-On Mac OS X::
-
-    >>> from appdirs import *
-    >>> appname = "SuperApp"
-    >>> appauthor = "Acme"
-    >>> user_data_dir(appname, appauthor)
-    '/Users/trentm/Library/Application Support/SuperApp'
-    >>> site_data_dir(appname, appauthor)
-    '/Library/Application Support/SuperApp'
-    >>> user_cache_dir(appname, appauthor)
-    '/Users/trentm/Library/Caches/SuperApp'
-    >>> user_log_dir(appname, appauthor)
-    '/Users/trentm/Library/Logs/SuperApp'
-
-On Windows 7::
-
-    >>> from appdirs import *
-    >>> appname = "SuperApp"
-    >>> appauthor = "Acme"
-    >>> user_data_dir(appname, appauthor)
-    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp'
-    >>> user_data_dir(appname, appauthor, roaming=True)
-    'C:\\Users\\trentm\\AppData\\Roaming\\Acme\\SuperApp'
-    >>> user_cache_dir(appname, appauthor)
-    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Cache'
-    >>> user_log_dir(appname, appauthor)
-    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Logs'
-
-On Linux::
-
-    >>> from appdirs import *
-    >>> appname = "SuperApp"
-    >>> appauthor = "Acme"
-    >>> user_data_dir(appname, appauthor)
-    '/home/trentm/.local/share/SuperApp
-    >>> site_data_dir(appname, appauthor)
-    '/usr/local/share/SuperApp'
-    >>> site_data_dir(appname, appauthor, multipath=True)
-    '/usr/local/share/SuperApp:/usr/share/SuperApp'
-    >>> user_cache_dir(appname, appauthor)
-    '/home/trentm/.cache/SuperApp'
-    >>> user_log_dir(appname, appauthor)
-    '/home/trentm/.cache/SuperApp/log'
-    >>> user_config_dir(appname)
-    '/home/trentm/.config/SuperApp'
-    >>> site_config_dir(appname)
-    '/etc/xdg/SuperApp'
-    >>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc'
-    >>> site_config_dir(appname, multipath=True)
-    '/etc/SuperApp:/usr/local/etc/SuperApp'
-
-
-``AppDirs`` for convenience
-===========================
-
-::
-
-    >>> from appdirs import AppDirs
-    >>> dirs = AppDirs("SuperApp", "Acme")
-    >>> dirs.user_data_dir
-    '/Users/trentm/Library/Application Support/SuperApp'
-    >>> dirs.site_data_dir
-    '/Library/Application Support/SuperApp'
-    >>> dirs.user_cache_dir
-    '/Users/trentm/Library/Caches/SuperApp'
-    >>> dirs.user_log_dir
-    '/Users/trentm/Library/Logs/SuperApp'
-
-
-
-Per-version isolation
-=====================
-
-If you have multiple versions of your app in use that you want to be
-able to run side-by-side, then you may want version-isolation for these
-dirs::
-
-    >>> from appdirs import AppDirs
-    >>> dirs = AppDirs("SuperApp", "Acme", version="1.0")
-    >>> dirs.user_data_dir
-    '/Users/trentm/Library/Application Support/SuperApp/1.0'
-    >>> dirs.site_data_dir
-    '/Library/Application Support/SuperApp/1.0'
-    >>> dirs.user_cache_dir
-    '/Users/trentm/Library/Caches/SuperApp/1.0'
-    >>> dirs.user_log_dir
-    '/Users/trentm/Library/Logs/SuperApp/1.0'
-
-
-
-appdirs Changelog
-=================
-
-appdirs 1.4.3
--------------
-- [PR #76] Python 3.6 invalid escape sequence deprecation fixes
-- Fix for Python 3.6 support
-
-appdirs 1.4.2
--------------
-- [PR #84] Allow installing without setuptools
-- [PR #86] Fix string delimiters in setup.py description
-- Add Python 3.6 support
-
-appdirs 1.4.1
--------------
-- [issue #38] Fix _winreg import on Windows Py3
-- [issue #55] Make appname optional
-
-appdirs 1.4.0
--------------
-- [PR #42] AppAuthor is now optional on Windows
-- [issue 41] Support Jython on Windows, Mac, and Unix-like platforms. Windows
-  support requires `JNA <https://github.com/twall/jna>`_.
-- [PR #44] Fix incorrect behaviour of the site_config_dir method
-
-appdirs 1.3.0
--------------
-- [Unix, issue 16] Conform to XDG standard, instead of breaking it for
-  everybody
-- [Unix] Removes gratuitous case mangling of the case, since \*nix-es are
-  usually case sensitive, so mangling is not wise
-- [Unix] Fixes the utterly wrong behaviour in ``site_data_dir``, return result
-  based on XDG_DATA_DIRS and make room for respecting the standard which
-  specifies XDG_DATA_DIRS is a multiple-value variable
-- [Issue 6] Add ``*_config_dir`` which are distinct on nix-es, according to
-  XDG specs; on Windows and Mac return the corresponding ``*_data_dir``
-
-appdirs 1.2.0
--------------
-
-- [Unix] Put ``user_log_dir`` under the *cache* dir on Unix. Seems to be more
-  typical.
-- [issue 9] Make ``unicode`` work on py3k.
-
-appdirs 1.1.0
--------------
-
-- [issue 4] Add ``AppDirs.user_log_dir``.
-- [Unix, issue 2, issue 7] appdirs now conforms to `XDG base directory spec
-  <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
-- [Mac, issue 5] Fix ``site_data_dir()`` on Mac.
-- [Mac] Drop use of 'Carbon' module in favour of hardcoded paths; supports
-  Python3 now.
-- [Windows] Append "Cache" to ``user_cache_dir`` on Windows by default. Use
-  ``opinion=False`` option to disable this.
-- Add ``appdirs.AppDirs`` convenience class. Usage:
-
-        >>> dirs = AppDirs("SuperApp", "Acme", version="1.0")
-        >>> dirs.user_data_dir
-        '/Users/trentm/Library/Application Support/SuperApp/1.0'
-
-- [Windows] Cherry-pick Komodo's change to downgrade paths to the Windows short
-  paths if there are high bit chars.
-- [Linux] Change default ``user_cache_dir()`` on Linux to be singular, e.g.
-  "~/.superapp/cache".
-- [Windows] Add ``roaming`` option to ``user_data_dir()`` (for use on Windows only)
-  and change the default ``user_data_dir`` behaviour to use a *non*-roaming
-  profile dir (``CSIDL_LOCAL_APPDATA`` instead of ``CSIDL_APPDATA``). Why? Because
-  a large roaming profile can cause login speed issues. The "only syncs on
-  logout" behaviour can cause surprises in appdata info.
-
-
-appdirs 1.0.1 (never released)
-------------------------------
-
-Started this changelog 27 July 2010. Before that this module originated in the
-`Komodo <http://www.activestate.com/komodo>`_ product as ``applib.py`` and then
-as `applib/location.py
-<http://github.com/ActiveState/applib/blob/master/applib/location.py>`_ (used by
-`PyPM <http://code.activestate.com/pypm/>`_ in `ActivePython
-<http://www.activestate.com/activepython>`_). This is basically a fork of
-applib.py 1.0.1 and applib/location.py 1.0.1.
-
-
-
diff --git a/pkg_resources/_vendor/appdirs-1.4.3.dist-info/INSTALLER b/pkg_resources/_vendor/appdirs-1.4.3.dist-info/INSTALLER
deleted file mode 100644 (file)
index a1b589e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pip
diff --git a/pkg_resources/_vendor/appdirs-1.4.3.dist-info/METADATA b/pkg_resources/_vendor/appdirs-1.4.3.dist-info/METADATA
deleted file mode 100644 (file)
index 69ddf93..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-Metadata-Version: 2.0
-Name: appdirs
-Version: 1.4.3
-Summary: A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".
-Home-page: http://github.com/ActiveState/appdirs
-Author: Trent Mick; Sridhar Ratnakumar; Jeff Rouse
-Author-email: trentm@gmail.com; github@srid.name; jr@its.to
-License: MIT
-Keywords: application directory log cache user
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.2
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: Implementation :: PyPy
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-
-
-.. image:: https://secure.travis-ci.org/ActiveState/appdirs.png
-    :target: http://travis-ci.org/ActiveState/appdirs
-
-the problem
-===========
-
-What directory should your app use for storing user data? If running on Mac OS X, you
-should use::
-
-    ~/Library/Application Support/<AppName>
-
-If on Windows (at least English Win XP) that should be::
-
-    C:\Documents and Settings\<User>\Application Data\Local Settings\<AppAuthor>\<AppName>
-
-or possibly::
-
-    C:\Documents and Settings\<User>\Application Data\<AppAuthor>\<AppName>
-
-for `roaming profiles <http://bit.ly/9yl3b6>`_ but that is another story.
-
-On Linux (and other Unices) the dir, according to the `XDG
-spec <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_, is::
-
-    ~/.local/share/<AppName>
-
-
-``appdirs`` to the rescue
-=========================
-
-This kind of thing is what the ``appdirs`` module is for. ``appdirs`` will
-help you choose an appropriate:
-
-- user data dir (``user_data_dir``)
-- user config dir (``user_config_dir``)
-- user cache dir (``user_cache_dir``)
-- site data dir (``site_data_dir``)
-- site config dir (``site_config_dir``)
-- user log dir (``user_log_dir``)
-
-and also:
-
-- is a single module so other Python packages can include their own private copy
-- is slightly opinionated on the directory names used. Look for "OPINION" in
-  documentation and code for when an opinion is being applied.
-
-
-some example output
-===================
-
-On Mac OS X::
-
-    >>> from appdirs import *
-    >>> appname = "SuperApp"
-    >>> appauthor = "Acme"
-    >>> user_data_dir(appname, appauthor)
-    '/Users/trentm/Library/Application Support/SuperApp'
-    >>> site_data_dir(appname, appauthor)
-    '/Library/Application Support/SuperApp'
-    >>> user_cache_dir(appname, appauthor)
-    '/Users/trentm/Library/Caches/SuperApp'
-    >>> user_log_dir(appname, appauthor)
-    '/Users/trentm/Library/Logs/SuperApp'
-
-On Windows 7::
-
-    >>> from appdirs import *
-    >>> appname = "SuperApp"
-    >>> appauthor = "Acme"
-    >>> user_data_dir(appname, appauthor)
-    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp'
-    >>> user_data_dir(appname, appauthor, roaming=True)
-    'C:\\Users\\trentm\\AppData\\Roaming\\Acme\\SuperApp'
-    >>> user_cache_dir(appname, appauthor)
-    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Cache'
-    >>> user_log_dir(appname, appauthor)
-    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Logs'
-
-On Linux::
-
-    >>> from appdirs import *
-    >>> appname = "SuperApp"
-    >>> appauthor = "Acme"
-    >>> user_data_dir(appname, appauthor)
-    '/home/trentm/.local/share/SuperApp
-    >>> site_data_dir(appname, appauthor)
-    '/usr/local/share/SuperApp'
-    >>> site_data_dir(appname, appauthor, multipath=True)
-    '/usr/local/share/SuperApp:/usr/share/SuperApp'
-    >>> user_cache_dir(appname, appauthor)
-    '/home/trentm/.cache/SuperApp'
-    >>> user_log_dir(appname, appauthor)
-    '/home/trentm/.cache/SuperApp/log'
-    >>> user_config_dir(appname)
-    '/home/trentm/.config/SuperApp'
-    >>> site_config_dir(appname)
-    '/etc/xdg/SuperApp'
-    >>> os.environ['XDG_CONFIG_DIRS'] = '/etc:/usr/local/etc'
-    >>> site_config_dir(appname, multipath=True)
-    '/etc/SuperApp:/usr/local/etc/SuperApp'
-
-
-``AppDirs`` for convenience
-===========================
-
-::
-
-    >>> from appdirs import AppDirs
-    >>> dirs = AppDirs("SuperApp", "Acme")
-    >>> dirs.user_data_dir
-    '/Users/trentm/Library/Application Support/SuperApp'
-    >>> dirs.site_data_dir
-    '/Library/Application Support/SuperApp'
-    >>> dirs.user_cache_dir
-    '/Users/trentm/Library/Caches/SuperApp'
-    >>> dirs.user_log_dir
-    '/Users/trentm/Library/Logs/SuperApp'
-
-
-
-Per-version isolation
-=====================
-
-If you have multiple versions of your app in use that you want to be
-able to run side-by-side, then you may want version-isolation for these
-dirs::
-
-    >>> from appdirs import AppDirs
-    >>> dirs = AppDirs("SuperApp", "Acme", version="1.0")
-    >>> dirs.user_data_dir
-    '/Users/trentm/Library/Application Support/SuperApp/1.0'
-    >>> dirs.site_data_dir
-    '/Library/Application Support/SuperApp/1.0'
-    >>> dirs.user_cache_dir
-    '/Users/trentm/Library/Caches/SuperApp/1.0'
-    >>> dirs.user_log_dir
-    '/Users/trentm/Library/Logs/SuperApp/1.0'
-
-
-
-appdirs Changelog
-=================
-
-appdirs 1.4.3
--------------
-- [PR #76] Python 3.6 invalid escape sequence deprecation fixes
-- Fix for Python 3.6 support
-
-appdirs 1.4.2
--------------
-- [PR #84] Allow installing without setuptools
-- [PR #86] Fix string delimiters in setup.py description
-- Add Python 3.6 support
-
-appdirs 1.4.1
--------------
-- [issue #38] Fix _winreg import on Windows Py3
-- [issue #55] Make appname optional
-
-appdirs 1.4.0
--------------
-- [PR #42] AppAuthor is now optional on Windows
-- [issue 41] Support Jython on Windows, Mac, and Unix-like platforms. Windows
-  support requires `JNA <https://github.com/twall/jna>`_.
-- [PR #44] Fix incorrect behaviour of the site_config_dir method
-
-appdirs 1.3.0
--------------
-- [Unix, issue 16] Conform to XDG standard, instead of breaking it for
-  everybody
-- [Unix] Removes gratuitous case mangling of the case, since \*nix-es are
-  usually case sensitive, so mangling is not wise
-- [Unix] Fixes the utterly wrong behaviour in ``site_data_dir``, return result
-  based on XDG_DATA_DIRS and make room for respecting the standard which
-  specifies XDG_DATA_DIRS is a multiple-value variable
-- [Issue 6] Add ``*_config_dir`` which are distinct on nix-es, according to
-  XDG specs; on Windows and Mac return the corresponding ``*_data_dir``
-
-appdirs 1.2.0
--------------
-
-- [Unix] Put ``user_log_dir`` under the *cache* dir on Unix. Seems to be more
-  typical.
-- [issue 9] Make ``unicode`` work on py3k.
-
-appdirs 1.1.0
--------------
-
-- [issue 4] Add ``AppDirs.user_log_dir``.
-- [Unix, issue 2, issue 7] appdirs now conforms to `XDG base directory spec
-  <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
-- [Mac, issue 5] Fix ``site_data_dir()`` on Mac.
-- [Mac] Drop use of 'Carbon' module in favour of hardcoded paths; supports
-  Python3 now.
-- [Windows] Append "Cache" to ``user_cache_dir`` on Windows by default. Use
-  ``opinion=False`` option to disable this.
-- Add ``appdirs.AppDirs`` convenience class. Usage:
-
-        >>> dirs = AppDirs("SuperApp", "Acme", version="1.0")
-        >>> dirs.user_data_dir
-        '/Users/trentm/Library/Application Support/SuperApp/1.0'
-
-- [Windows] Cherry-pick Komodo's change to downgrade paths to the Windows short
-  paths if there are high bit chars.
-- [Linux] Change default ``user_cache_dir()`` on Linux to be singular, e.g.
-  "~/.superapp/cache".
-- [Windows] Add ``roaming`` option to ``user_data_dir()`` (for use on Windows only)
-  and change the default ``user_data_dir`` behaviour to use a *non*-roaming
-  profile dir (``CSIDL_LOCAL_APPDATA`` instead of ``CSIDL_APPDATA``). Why? Because
-  a large roaming profile can cause login speed issues. The "only syncs on
-  logout" behaviour can cause surprises in appdata info.
-
-
-appdirs 1.0.1 (never released)
-------------------------------
-
-Started this changelog 27 July 2010. Before that this module originated in the
-`Komodo <http://www.activestate.com/komodo>`_ product as ``applib.py`` and then
-as `applib/location.py
-<http://github.com/ActiveState/applib/blob/master/applib/location.py>`_ (used by
-`PyPM <http://code.activestate.com/pypm/>`_ in `ActivePython
-<http://www.activestate.com/activepython>`_). This is basically a fork of
-applib.py 1.0.1 and applib/location.py 1.0.1.
-
-
-
diff --git a/pkg_resources/_vendor/appdirs-1.4.3.dist-info/RECORD b/pkg_resources/_vendor/appdirs-1.4.3.dist-info/RECORD
deleted file mode 100644 (file)
index 3f45ff5..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-__pycache__/appdirs.cpython-310.pyc,,\r
-appdirs-1.4.3.dist-info/DESCRIPTION.rst,sha256=77Fe8OIOLSjDSNdLiL5xywMKO-AGE42rdXkqKo4Ee-k,7531\r
-appdirs-1.4.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
-appdirs-1.4.3.dist-info/METADATA,sha256=3IFw6jTfImdOqsCb2GYvVR157tL7KEzfRAszn382csk,8773\r
-appdirs-1.4.3.dist-info/RECORD,,\r
-appdirs-1.4.3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-appdirs-1.4.3.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110\r
-appdirs-1.4.3.dist-info/metadata.json,sha256=fL_Q-GuFJu3PJxMrwU7SdsI8RGqjIfi2AvouCSF5DSA,1359\r
-appdirs-1.4.3.dist-info/top_level.txt,sha256=nKncE8CUqZERJ6VuQWL4_bkunSPDNfn7KZqb4Tr5YEM,8\r
-appdirs.py,sha256=MievUEuv3l_mQISH5SF0shDk_BNhHHzYiAPrT3ITN4I,24701\r
diff --git a/pkg_resources/_vendor/appdirs-1.4.3.dist-info/REQUESTED b/pkg_resources/_vendor/appdirs-1.4.3.dist-info/REQUESTED
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/pkg_resources/_vendor/appdirs-1.4.3.dist-info/WHEEL b/pkg_resources/_vendor/appdirs-1.4.3.dist-info/WHEEL
deleted file mode 100644 (file)
index 8b6dd1b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.29.0)
-Root-Is-Purelib: true
-Tag: py2-none-any
-Tag: py3-none-any
-
diff --git a/pkg_resources/_vendor/appdirs-1.4.3.dist-info/metadata.json b/pkg_resources/_vendor/appdirs-1.4.3.dist-info/metadata.json
deleted file mode 100644 (file)
index da1e5f3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules"], "extensions": {"python.details": {"contacts": [{"email": "trentm@gmail.com; github@srid.name; jr@its.to", "name": "Trent Mick; Sridhar Ratnakumar; Jeff Rouse", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "http://github.com/ActiveState/appdirs"}}}, "generator": "bdist_wheel (0.29.0)", "keywords": ["application", "directory", "log", "cache", "user"], "license": "MIT", "metadata_version": "2.0", "name": "appdirs", "summary": "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\".", "test_requires": [{"requires": []}], "version": "1.4.3"}
\ No newline at end of file
diff --git a/pkg_resources/_vendor/appdirs-1.4.3.dist-info/top_level.txt b/pkg_resources/_vendor/appdirs-1.4.3.dist-info/top_level.txt
deleted file mode 100644 (file)
index d64bc32..0000000
+++ /dev/null
@@ -1 +0,0 @@
-appdirs
diff --git a/pkg_resources/_vendor/appdirs.py b/pkg_resources/_vendor/appdirs.py
deleted file mode 100644 (file)
index ae67001..0000000
+++ /dev/null
@@ -1,608 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-# Copyright (c) 2005-2010 ActiveState Software Inc.
-# Copyright (c) 2013 Eddy Petrișor
-
-"""Utilities for determining application-specific dirs.
-
-See <http://github.com/ActiveState/appdirs> for details and usage.
-"""
-# Dev Notes:
-# - MSDN on where to store app data files:
-#   http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120
-# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html
-# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
-
-__version_info__ = (1, 4, 3)
-__version__ = '.'.join(map(str, __version_info__))
-
-
-import sys
-import os
-
-PY3 = sys.version_info[0] == 3
-
-if PY3:
-    unicode = str
-
-if sys.platform.startswith('java'):
-    import platform
-    os_name = platform.java_ver()[3][0]
-    if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc.
-        system = 'win32'
-    elif os_name.startswith('Mac'): # "Mac OS X", etc.
-        system = 'darwin'
-    else: # "Linux", "SunOS", "FreeBSD", etc.
-        # Setting this to "linux2" is not ideal, but only Windows or Mac
-        # are actually checked for and the rest of the module expects
-        # *sys.platform* style strings.
-        system = 'linux2'
-else:
-    system = sys.platform
-
-
-
-def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
-    r"""Return full path to the user-specific data dir for this application.
-
-        "appname" is the name of application.
-            If None, just the system directory is returned.
-        "appauthor" (only used on Windows) is the name of the
-            appauthor or distributing body for this application. Typically
-            it is the owning company name. This falls back to appname. You may
-            pass False to disable it.
-        "version" is 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 "<major>.<minor>".
-            Only applied when appname is present.
-        "roaming" (boolean, default False) can be set True to use the Windows
-            roaming appdata directory. That means that for users on a Windows
-            network setup for roaming profiles, this user data will be
-            sync'd on login. See
-            <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
-            for a discussion of issues.
-
-    Typical user data directories are:
-        Mac OS X:               ~/Library/Application Support/<AppName>
-        Unix:                   ~/.local/share/<AppName>    # or in $XDG_DATA_HOME, if defined
-        Win XP (not roaming):   C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName>
-        Win XP (roaming):       C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>
-        Win 7  (not roaming):   C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>
-        Win 7  (roaming):       C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName>
-
-    For Unix, we follow the XDG spec and support $XDG_DATA_HOME.
-    That means, by default "~/.local/share/<AppName>".
-    """
-    if system == "win32":
-        if appauthor is None:
-            appauthor = appname
-        const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA"
-        path = os.path.normpath(_get_win_folder(const))
-        if appname:
-            if appauthor is not False:
-                path = os.path.join(path, appauthor, appname)
-            else:
-                path = os.path.join(path, appname)
-    elif system == 'darwin':
-        path = os.path.expanduser('~/Library/Application Support/')
-        if appname:
-            path = os.path.join(path, appname)
-    else:
-        path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share"))
-        if appname:
-            path = os.path.join(path, appname)
-    if appname and version:
-        path = os.path.join(path, version)
-    return path
-
-
-def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
-    r"""Return full path to the user-shared data dir for this application.
-
-        "appname" is the name of application.
-            If None, just the system directory is returned.
-        "appauthor" (only used on Windows) is the name of the
-            appauthor or distributing body for this application. Typically
-            it is the owning company name. This falls back to appname. You may
-            pass False to disable it.
-        "version" is 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 "<major>.<minor>".
-            Only applied when appname is present.
-        "multipath" is an optional parameter only applicable to *nix
-            which indicates that the entire list of data dirs should be
-            returned. By default, the first item from XDG_DATA_DIRS is
-            returned, or '/usr/local/share/<AppName>',
-            if XDG_DATA_DIRS is not set
-
-    Typical site data directories are:
-        Mac OS X:   /Library/Application Support/<AppName>
-        Unix:       /usr/local/share/<AppName> or /usr/share/<AppName>
-        Win XP:     C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName>
-        Vista:      (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.)
-        Win 7:      C:\ProgramData\<AppAuthor>\<AppName>   # Hidden, but writeable on Win 7.
-
-    For Unix, this is using the $XDG_DATA_DIRS[0] default.
-
-    WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
-    """
-    if system == "win32":
-        if appauthor is None:
-            appauthor = appname
-        path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA"))
-        if appname:
-            if appauthor is not False:
-                path = os.path.join(path, appauthor, appname)
-            else:
-                path = os.path.join(path, appname)
-    elif system == 'darwin':
-        path = os.path.expanduser('/Library/Application Support')
-        if appname:
-            path = os.path.join(path, appname)
-    else:
-        # XDG default for $XDG_DATA_DIRS
-        # only first, if multipath is False
-        path = os.getenv('XDG_DATA_DIRS',
-                         os.pathsep.join(['/usr/local/share', '/usr/share']))
-        pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
-        if appname:
-            if version:
-                appname = os.path.join(appname, version)
-            pathlist = [os.sep.join([x, appname]) for x in pathlist]
-
-        if multipath:
-            path = os.pathsep.join(pathlist)
-        else:
-            path = pathlist[0]
-        return path
-
-    if appname and version:
-        path = os.path.join(path, version)
-    return path
-
-
-def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
-    r"""Return full path to the user-specific config dir for this application.
-
-        "appname" is the name of application.
-            If None, just the system directory is returned.
-        "appauthor" (only used on Windows) is the name of the
-            appauthor or distributing body for this application. Typically
-            it is the owning company name. This falls back to appname. You may
-            pass False to disable it.
-        "version" is 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 "<major>.<minor>".
-            Only applied when appname is present.
-        "roaming" (boolean, default False) can be set True to use the Windows
-            roaming appdata directory. That means that for users on a Windows
-            network setup for roaming profiles, this user data will be
-            sync'd on login. See
-            <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
-            for a discussion of issues.
-
-    Typical user config directories are:
-        Mac OS X:               same as user_data_dir
-        Unix:                   ~/.config/<AppName>     # or in $XDG_CONFIG_HOME, if defined
-        Win *:                  same as user_data_dir
-
-    For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME.
-    That means, by default "~/.config/<AppName>".
-    """
-    if system in ["win32", "darwin"]:
-        path = user_data_dir(appname, appauthor, None, roaming)
-    else:
-        path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config"))
-        if appname:
-            path = os.path.join(path, appname)
-    if appname and version:
-        path = os.path.join(path, version)
-    return path
-
-
-def site_config_dir(appname=None, appauthor=None, version=None, multipath=False):
-    r"""Return full path to the user-shared data dir for this application.
-
-        "appname" is the name of application.
-            If None, just the system directory is returned.
-        "appauthor" (only used on Windows) is the name of the
-            appauthor or distributing body for this application. Typically
-            it is the owning company name. This falls back to appname. You may
-            pass False to disable it.
-        "version" is 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 "<major>.<minor>".
-            Only applied when appname is present.
-        "multipath" is an optional parameter only applicable to *nix
-            which indicates that the entire list of config dirs should be
-            returned. By default, the first item from XDG_CONFIG_DIRS is
-            returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set
-
-    Typical site config directories are:
-        Mac OS X:   same as site_data_dir
-        Unix:       /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in
-                    $XDG_CONFIG_DIRS
-        Win *:      same as site_data_dir
-        Vista:      (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.)
-
-    For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False
-
-    WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
-    """
-    if system in ["win32", "darwin"]:
-        path = site_data_dir(appname, appauthor)
-        if appname and version:
-            path = os.path.join(path, version)
-    else:
-        # XDG default for $XDG_CONFIG_DIRS
-        # only first, if multipath is False
-        path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg')
-        pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
-        if appname:
-            if version:
-                appname = os.path.join(appname, version)
-            pathlist = [os.sep.join([x, appname]) for x in pathlist]
-
-        if multipath:
-            path = os.pathsep.join(pathlist)
-        else:
-            path = pathlist[0]
-    return path
-
-
-def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
-    r"""Return full path to the user-specific cache dir for this application.
-
-        "appname" is the name of application.
-            If None, just the system directory is returned.
-        "appauthor" (only used on Windows) is the name of the
-            appauthor or distributing body for this application. Typically
-            it is the owning company name. This falls back to appname. You may
-            pass False to disable it.
-        "version" is 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 "<major>.<minor>".
-            Only applied when appname is present.
-        "opinion" (boolean) can be False to disable the appending of
-            "Cache" to the base app data dir for Windows. See
-            discussion below.
-
-    Typical user cache directories are:
-        Mac OS X:   ~/Library/Caches/<AppName>
-        Unix:       ~/.cache/<AppName> (XDG default)
-        Win XP:     C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache
-        Vista:      C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache
-
-    On Windows the only suggestion in the MSDN docs is that local settings go in
-    the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming
-    app data dir (the default returned by `user_data_dir` above). Apps typically
-    put cache data somewhere *under* the given dir here. Some examples:
-        ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache
-        ...\Acme\SuperApp\Cache\1.0
-    OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value.
-    This can be disabled with the `opinion=False` option.
-    """
-    if system == "win32":
-        if appauthor is None:
-            appauthor = appname
-        path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA"))
-        if appname:
-            if appauthor is not False:
-                path = os.path.join(path, appauthor, appname)
-            else:
-                path = os.path.join(path, appname)
-            if opinion:
-                path = os.path.join(path, "Cache")
-    elif system == 'darwin':
-        path = os.path.expanduser('~/Library/Caches')
-        if appname:
-            path = os.path.join(path, appname)
-    else:
-        path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
-        if appname:
-            path = os.path.join(path, appname)
-    if appname and version:
-        path = os.path.join(path, version)
-    return path
-
-
-def user_state_dir(appname=None, appauthor=None, version=None, roaming=False):
-    r"""Return full path to the user-specific state dir for this application.
-
-        "appname" is the name of application.
-            If None, just the system directory is returned.
-        "appauthor" (only used on Windows) is the name of the
-            appauthor or distributing body for this application. Typically
-            it is the owning company name. This falls back to appname. You may
-            pass False to disable it.
-        "version" is 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 "<major>.<minor>".
-            Only applied when appname is present.
-        "roaming" (boolean, default False) can be set True to use the Windows
-            roaming appdata directory. That means that for users on a Windows
-            network setup for roaming profiles, this user data will be
-            sync'd on login. See
-            <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
-            for a discussion of issues.
-
-    Typical user state directories are:
-        Mac OS X:  same as user_data_dir
-        Unix:      ~/.local/state/<AppName>   # or in $XDG_STATE_HOME, if defined
-        Win *:     same as user_data_dir
-
-    For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state>
-    to extend the XDG spec and support $XDG_STATE_HOME.
-
-    That means, by default "~/.local/state/<AppName>".
-    """
-    if system in ["win32", "darwin"]:
-        path = user_data_dir(appname, appauthor, None, roaming)
-    else:
-        path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state"))
-        if appname:
-            path = os.path.join(path, appname)
-    if appname and version:
-        path = os.path.join(path, version)
-    return path
-
-
-def user_log_dir(appname=None, appauthor=None, version=None, opinion=True):
-    r"""Return full path to the user-specific log dir for this application.
-
-        "appname" is the name of application.
-            If None, just the system directory is returned.
-        "appauthor" (only used on Windows) is the name of the
-            appauthor or distributing body for this application. Typically
-            it is the owning company name. This falls back to appname. You may
-            pass False to disable it.
-        "version" is 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 "<major>.<minor>".
-            Only applied when appname is present.
-        "opinion" (boolean) can be False to disable the appending of
-            "Logs" to the base app data dir for Windows, and "log" to the
-            base cache dir for Unix. See discussion below.
-
-    Typical user log directories are:
-        Mac OS X:   ~/Library/Logs/<AppName>
-        Unix:       ~/.cache/<AppName>/log  # or under $XDG_CACHE_HOME if defined
-        Win XP:     C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs
-        Vista:      C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs
-
-    On Windows the only suggestion in the MSDN docs is that local settings
-    go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in
-    examples of what some windows apps use for a logs dir.)
-
-    OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA`
-    value for Windows and appends "log" to the user cache dir for Unix.
-    This can be disabled with the `opinion=False` option.
-    """
-    if system == "darwin":
-        path = os.path.join(
-            os.path.expanduser('~/Library/Logs'),
-            appname)
-    elif system == "win32":
-        path = user_data_dir(appname, appauthor, version)
-        version = False
-        if opinion:
-            path = os.path.join(path, "Logs")
-    else:
-        path = user_cache_dir(appname, appauthor, version)
-        version = False
-        if opinion:
-            path = os.path.join(path, "log")
-    if appname and version:
-        path = os.path.join(path, version)
-    return path
-
-
-class AppDirs(object):
-    """Convenience wrapper for getting application dirs."""
-    def __init__(self, appname=None, appauthor=None, version=None,
-            roaming=False, multipath=False):
-        self.appname = appname
-        self.appauthor = appauthor
-        self.version = version
-        self.roaming = roaming
-        self.multipath = multipath
-
-    @property
-    def user_data_dir(self):
-        return user_data_dir(self.appname, self.appauthor,
-                             version=self.version, roaming=self.roaming)
-
-    @property
-    def site_data_dir(self):
-        return site_data_dir(self.appname, self.appauthor,
-                             version=self.version, multipath=self.multipath)
-
-    @property
-    def user_config_dir(self):
-        return user_config_dir(self.appname, self.appauthor,
-                               version=self.version, roaming=self.roaming)
-
-    @property
-    def site_config_dir(self):
-        return site_config_dir(self.appname, self.appauthor,
-                             version=self.version, multipath=self.multipath)
-
-    @property
-    def user_cache_dir(self):
-        return user_cache_dir(self.appname, self.appauthor,
-                              version=self.version)
-
-    @property
-    def user_state_dir(self):
-        return user_state_dir(self.appname, self.appauthor,
-                              version=self.version)
-
-    @property
-    def user_log_dir(self):
-        return user_log_dir(self.appname, self.appauthor,
-                            version=self.version)
-
-
-#---- internal support stuff
-
-def _get_win_folder_from_registry(csidl_name):
-    """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.
-    """
-    if PY3:
-      import winreg as _winreg
-    else:
-      import _winreg
-
-    shell_folder_name = {
-        "CSIDL_APPDATA": "AppData",
-        "CSIDL_COMMON_APPDATA": "Common AppData",
-        "CSIDL_LOCAL_APPDATA": "Local AppData",
-    }[csidl_name]
-
-    key = _winreg.OpenKey(
-        _winreg.HKEY_CURRENT_USER,
-        r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
-    )
-    dir, type = _winreg.QueryValueEx(key, shell_folder_name)
-    return dir
-
-
-def _get_win_folder_with_pywin32(csidl_name):
-    from win32com.shell import shellcon, shell
-    dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0)
-    # Try to make this a unicode path because SHGetFolderPath does
-    # not return unicode strings when there is unicode data in the
-    # path.
-    try:
-        dir = unicode(dir)
-
-        # Downgrade to short path name if have highbit chars. See
-        # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
-        has_high_char = False
-        for c in dir:
-            if ord(c) > 255:
-                has_high_char = True
-                break
-        if has_high_char:
-            try:
-                import win32api
-                dir = win32api.GetShortPathName(dir)
-            except ImportError:
-                pass
-    except UnicodeError:
-        pass
-    return dir
-
-
-def _get_win_folder_with_ctypes(csidl_name):
-    import ctypes
-
-    csidl_const = {
-        "CSIDL_APPDATA": 26,
-        "CSIDL_COMMON_APPDATA": 35,
-        "CSIDL_LOCAL_APPDATA": 28,
-    }[csidl_name]
-
-    buf = ctypes.create_unicode_buffer(1024)
-    ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
-
-    # Downgrade to short path name if have highbit chars. See
-    # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
-    has_high_char = False
-    for c in buf:
-        if ord(c) > 255:
-            has_high_char = True
-            break
-    if has_high_char:
-        buf2 = ctypes.create_unicode_buffer(1024)
-        if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024):
-            buf = buf2
-
-    return buf.value
-
-def _get_win_folder_with_jna(csidl_name):
-    import array
-    from com.sun import jna
-    from com.sun.jna.platform import win32
-
-    buf_size = win32.WinDef.MAX_PATH * 2
-    buf = array.zeros('c', buf_size)
-    shell = win32.Shell32.INSTANCE
-    shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf)
-    dir = jna.Native.toString(buf.tostring()).rstrip("\0")
-
-    # Downgrade to short path name if have highbit chars. See
-    # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
-    has_high_char = False
-    for c in dir:
-        if ord(c) > 255:
-            has_high_char = True
-            break
-    if has_high_char:
-        buf = array.zeros('c', buf_size)
-        kernel = win32.Kernel32.INSTANCE
-        if kernel.GetShortPathName(dir, buf, buf_size):
-            dir = jna.Native.toString(buf.tostring()).rstrip("\0")
-
-    return dir
-
-if system == "win32":
-    try:
-        import win32com.shell
-        _get_win_folder = _get_win_folder_with_pywin32
-    except ImportError:
-        try:
-            from ctypes import windll
-            _get_win_folder = _get_win_folder_with_ctypes
-        except ImportError:
-            try:
-                import com.sun.jna
-                _get_win_folder = _get_win_folder_with_jna
-            except ImportError:
-                _get_win_folder = _get_win_folder_from_registry
-
-
-#---- self test code
-
-if __name__ == "__main__":
-    appname = "MyApp"
-    appauthor = "MyCompany"
-
-    props = ("user_data_dir",
-             "user_config_dir",
-             "user_cache_dir",
-             "user_state_dir",
-             "user_log_dir",
-             "site_data_dir",
-             "site_config_dir")
-
-    print("-- app dirs %s --" % __version__)
-
-    print("-- app dirs (with optional 'version')")
-    dirs = AppDirs(appname, appauthor, version="1.0")
-    for prop in props:
-        print("%s: %s" % (prop, getattr(dirs, prop)))
-
-    print("\n-- app dirs (without optional 'version')")
-    dirs = AppDirs(appname, appauthor)
-    for prop in props:
-        print("%s: %s" % (prop, getattr(dirs, prop)))
-
-    print("\n-- app dirs (without optional 'appauthor')")
-    dirs = AppDirs(appname)
-    for prop in props:
-        print("%s: %s" % (prop, getattr(dirs, prop)))
-
-    print("\n-- app dirs (with disabled 'appauthor')")
-    dirs = AppDirs(appname, appauthor=False)
-    for prop in props:
-        print("%s: %s" % (prop, getattr(dirs, prop)))
index 7a68a2f26c1dbd4d6aa8b2863731e4264f9be145..7f579ddb1c103d245584f0eb2ed927da1987303c 100644 (file)
@@ -6,15 +6,15 @@ importlib_resources-5.4.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
 importlib_resources-5.4.0.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92\r
 importlib_resources-5.4.0.dist-info/top_level.txt,sha256=fHIjHU1GZwAjvcydpmUnUrTnbvdiWjG4OEVZK8by0TQ,20\r
 importlib_resources/__init__.py,sha256=zuA0lbRgtVVCcAztM0z5LuBiOCV9L_3qtI6mW2p5xAg,525\r
-importlib_resources/__pycache__/__init__.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_adapters.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_common.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_compat.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_itertools.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_legacy.cpython-310.pyc,,\r
-importlib_resources/__pycache__/abc.cpython-310.pyc,,\r
-importlib_resources/__pycache__/readers.cpython-310.pyc,,\r
-importlib_resources/__pycache__/simple.cpython-310.pyc,,\r
+importlib_resources/__pycache__/__init__.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_adapters.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_common.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_compat.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_itertools.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_legacy.cpython-311.pyc,,\r
+importlib_resources/__pycache__/abc.cpython-311.pyc,,\r
+importlib_resources/__pycache__/readers.cpython-311.pyc,,\r
+importlib_resources/__pycache__/simple.cpython-311.pyc,,\r
 importlib_resources/_adapters.py,sha256=o51tP2hpVtohP33gSYyAkGNpLfYDBqxxYsadyiRZi1E,4504\r
 importlib_resources/_common.py,sha256=iIxAaQhotSh6TLLUEfL_ynU2fzEeyHMz9JcL46mUhLg,2741\r
 importlib_resources/_compat.py,sha256=3LpkIfeN9x4oXjRea5TxZP5VYhPlzuVRhGe-hEv-S0s,2704\r
@@ -25,34 +25,34 @@ importlib_resources/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
 importlib_resources/readers.py,sha256=_9QLGQ5AzrED3PY8S2Zf8V6yLR0-nqqYqtQmgleDJzY,3566\r
 importlib_resources/simple.py,sha256=xt0qhXbwt3bZ86zuaaKbTiE9A0mDbwu0saRjUq_pcY0,2836\r
 importlib_resources/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/__pycache__/__init__.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/_compat.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_contents.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_files.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_open.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_path.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_read.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_reader.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_resource.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/update-zips.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/util.cpython-310.pyc,,\r
+importlib_resources/tests/__pycache__/__init__.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/_compat.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_contents.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_files.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_open.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_path.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_read.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_reader.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_resource.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/update-zips.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/util.cpython-311.pyc,,\r
 importlib_resources/tests/_compat.py,sha256=QGI_4p0DXybypoYvw0kr3jfQqvls3p8u4wy4Wvf0Z_o,435\r
 importlib_resources/tests/data01/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data01/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data01/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data01/binary.file,sha256=BU7ewdAhH2JP7Qy8qdT5QAsOSRxDdCryxbCr6_DJkNg,4\r
 importlib_resources/tests/data01/subdirectory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data01/subdirectory/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data01/subdirectory/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data01/subdirectory/binary.file,sha256=BU7ewdAhH2JP7Qy8qdT5QAsOSRxDdCryxbCr6_DJkNg,4\r
 importlib_resources/tests/data01/utf-16.file,sha256=t5q9qhxX0rYqItBOM8D3ylwG-RHrnOYteTLtQr6sF7g,44\r
 importlib_resources/tests/data01/utf-8.file,sha256=kwWgYG4yQ-ZF2X_WA66EjYPmxJRn-w8aSOiS9e8tKYY,20\r
 importlib_resources/tests/data02/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data02/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data02/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data02/one/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data02/one/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data02/one/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data02/one/resource1.txt,sha256=10flKac7c-XXFzJ3t-AB5MJjlBy__dSZvPE_dOm2q6U,13\r
 importlib_resources/tests/data02/two/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data02/two/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data02/two/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data02/two/resource2.txt,sha256=lt2jbN3TMn9QiFKM832X39bU_62UptDdUkoYzkvEbl0,13\r
 importlib_resources/tests/namespacedata01/binary.file,sha256=BU7ewdAhH2JP7Qy8qdT5QAsOSRxDdCryxbCr6_DJkNg,4\r
 importlib_resources/tests/namespacedata01/utf-16.file,sha256=t5q9qhxX0rYqItBOM8D3ylwG-RHrnOYteTLtQr6sF7g,44\r
@@ -68,8 +68,8 @@ importlib_resources/tests/test_resource.py,sha256=DqfLNc9kaN5obqxU8kn0sRUWMf9Myg
 importlib_resources/tests/update-zips.py,sha256=x3iJVqWnMM5qp4Oob2Pl3o6Yi03sUjEv_5Wf-UCg3ps,1415\r
 importlib_resources/tests/util.py,sha256=X1j-0C96pu3_tmtJuLhzfBfcfMenOphDLkxtCt5j7t4,5309\r
 importlib_resources/tests/zipdata01/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/zipdata01/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/zipdata01/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/zipdata01/ziptestdata.zip,sha256=z5Of4dsv3T0t-46B0MsVhxlhsPGMz28aUhJDWpj3_oY,876\r
 importlib_resources/tests/zipdata02/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/zipdata02/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/zipdata02/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/zipdata02/ziptestdata.zip,sha256=ydI-_j-xgQ7tDxqBp9cjOqXBGxUp6ZBbwVJu6Xj-nrY,698\r
diff --git a/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/INSTALLER b/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/INSTALLER
deleted file mode 100644 (file)
index a1b589e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pip
diff --git a/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/LICENSE b/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/LICENSE
deleted file mode 100644 (file)
index 353924b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright Jason R. Coombs
-
-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.
diff --git a/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/METADATA b/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/METADATA
deleted file mode 100644 (file)
index 908711b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-Metadata-Version: 2.1
-Name: jaraco.context
-Version: 4.1.1
-Summary: Context managers by jaraco
-Home-page: https://github.com/jaraco/jaraco.context
-Author: Jason R. Coombs
-Author-email: jaraco@jaraco.com
-License: UNKNOWN
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3 :: Only
-Requires-Python: >=3.6
-License-File: LICENSE
-Provides-Extra: docs
-Requires-Dist: sphinx ; extra == 'docs'
-Requires-Dist: jaraco.packaging (>=8.2) ; extra == 'docs'
-Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
-Provides-Extra: testing
-Requires-Dist: pytest (>=6) ; extra == 'testing'
-Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
-Requires-Dist: pytest-flake8 ; extra == 'testing'
-Requires-Dist: pytest-cov ; extra == 'testing'
-Requires-Dist: pytest-enabler (>=1.0.1) ; extra == 'testing'
-Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
-Requires-Dist: pytest-mypy ; (platform_python_implementation != "PyPy") and extra == 'testing'
-
-.. image:: https://img.shields.io/pypi/v/jaraco.context.svg
-   :target: `PyPI link`_
-
-.. image:: https://img.shields.io/pypi/pyversions/jaraco.context.svg
-   :target: `PyPI link`_
-
-.. _PyPI link: https://pypi.org/project/jaraco.context
-
-.. image:: https://github.com/jaraco/jaraco.context/workflows/tests/badge.svg
-   :target: https://github.com/jaraco/jaraco.context/actions?query=workflow%3A%22tests%22
-   :alt: tests
-
-.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
-   :target: https://github.com/psf/black
-   :alt: Code style: Black
-
-.. image:: https://readthedocs.org/projects/jaracocontext/badge/?version=latest
-   :target: https://jaracocontext.readthedocs.io/en/latest/?badge=latest
-
-.. image:: https://img.shields.io/badge/skeleton-2021-informational
-   :target: https://blog.jaraco.com/skeleton
-
-
diff --git a/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/RECORD b/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/RECORD
deleted file mode 100644 (file)
index f40d48c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-jaraco.context-4.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
-jaraco.context-4.1.1.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
-jaraco.context-4.1.1.dist-info/METADATA,sha256=bvqDGCk6Z7TkohUqr5XZm19SbF9mVxrtXjN6uF_BAMQ,2031\r
-jaraco.context-4.1.1.dist-info/RECORD,,\r
-jaraco.context-4.1.1.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92\r
-jaraco.context-4.1.1.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
-jaraco/__pycache__/context.cpython-310.pyc,,\r
-jaraco/context.py,sha256=7X1tpCLc5EN45iWGzGcsH0Unx62REIkvtRvglj0SiUA,5420\r
diff --git a/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/WHEEL b/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/WHEEL
deleted file mode 100644 (file)
index 5bad85f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.0)
-Root-Is-Purelib: true
-Tag: py3-none-any
-
diff --git a/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/top_level.txt b/pkg_resources/_vendor/jaraco.context-4.1.1.dist-info/top_level.txt
deleted file mode 100644 (file)
index f6205a5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-jaraco
diff --git a/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/INSTALLER b/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/INSTALLER
new file mode 100644 (file)
index 0000000..a1b589e
--- /dev/null
@@ -0,0 +1 @@
+pip
diff --git a/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/LICENSE b/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/LICENSE
new file mode 100644 (file)
index 0000000..353924b
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright Jason R. Coombs
+
+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.
diff --git a/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/METADATA b/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/METADATA
new file mode 100644 (file)
index 0000000..34d372e
--- /dev/null
@@ -0,0 +1,67 @@
+Metadata-Version: 2.1
+Name: jaraco.context
+Version: 4.2.0
+Summary: Context managers by jaraco
+Home-page: https://github.com/jaraco/jaraco.context
+Author: Jason R. Coombs
+Author-email: jaraco@jaraco.com
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Requires-Python: >=3.7
+License-File: LICENSE
+Provides-Extra: docs
+Requires-Dist: sphinx (>=3.5) ; extra == 'docs'
+Requires-Dist: jaraco.packaging (>=9) ; extra == 'docs'
+Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
+Requires-Dist: furo ; extra == 'docs'
+Requires-Dist: jaraco.tidelift (>=1.4) ; extra == 'docs'
+Provides-Extra: testing
+Requires-Dist: pytest (>=6) ; extra == 'testing'
+Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
+Requires-Dist: pytest-flake8 ; extra == 'testing'
+Requires-Dist: flake8 (<5) ; extra == 'testing'
+Requires-Dist: pytest-cov ; extra == 'testing'
+Requires-Dist: pytest-enabler (>=1.3) ; extra == 'testing'
+Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
+Requires-Dist: pytest-mypy (>=0.9.1) ; (platform_python_implementation != "PyPy") and extra == 'testing'
+
+.. image:: https://img.shields.io/pypi/v/jaraco.context.svg
+   :target: https://pypi.org/project/jaraco.context
+
+.. image:: https://img.shields.io/pypi/pyversions/jaraco.context.svg
+
+.. image:: https://github.com/jaraco/jaraco.context/workflows/tests/badge.svg
+   :target: https://github.com/jaraco/jaraco.context/actions?query=workflow%3A%22tests%22
+   :alt: tests
+
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
+   :target: https://github.com/psf/black
+   :alt: Code style: Black
+
+.. image:: https://readthedocs.org/projects/jaracocontext/badge/?version=latest
+   :target: https://jaracocontext.readthedocs.io/en/latest/?badge=latest
+
+.. image:: https://img.shields.io/badge/skeleton-2022-informational
+   :target: https://blog.jaraco.com/skeleton
+
+.. image:: https://tidelift.com/badges/package/pypi/jaraco.context
+   :target: https://tidelift.com/subscription/pkg/pypi-jaraco.context?utm_source=pypi-jaraco.context&utm_medium=readme
+
+For Enterprise
+==============
+
+Available as part of the Tidelift Subscription.
+
+This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.
+
+`Learn more <https://tidelift.com/subscription/pkg/pypi-jaraco.context?utm_source=pypi-jaraco.context&utm_medium=referral&utm_campaign=github>`_.
+
+Security Contact
+================
+
+To report a security vulnerability, please use the
+`Tidelift security contact <https://tidelift.com/security>`_.
+Tidelift will coordinate the fix and disclosure.
diff --git a/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/RECORD b/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/RECORD
new file mode 100644 (file)
index 0000000..a34ec80
--- /dev/null
@@ -0,0 +1,8 @@
+jaraco.context-4.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+jaraco.context-4.2.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
+jaraco.context-4.2.0.dist-info/METADATA,sha256=6gWxpGoBWTzl4e8J1HisvNsL79YB4t1DG7ziQj-0k9Y,2883\r
+jaraco.context-4.2.0.dist-info/RECORD,,\r
+jaraco.context-4.2.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92\r
+jaraco.context-4.2.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
+jaraco/__pycache__/context.cpython-311.pyc,,\r
+jaraco/context.py,sha256=NvdB7ArVCDrhtexOnOwSv4ScDuueGbf9LRiOSCqPn6Y,6488\r
diff --git a/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/WHEEL b/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/WHEEL
new file mode 100644 (file)
index 0000000..57e3d84
--- /dev/null
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.38.4)
+Root-Is-Purelib: true
+Tag: py3-none-any
+
diff --git a/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/top_level.txt b/pkg_resources/_vendor/jaraco.context-4.2.0.dist-info/top_level.txt
new file mode 100644 (file)
index 0000000..f6205a5
--- /dev/null
@@ -0,0 +1 @@
+jaraco
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/INSTALLER b/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/INSTALLER
deleted file mode 100644 (file)
index a1b589e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pip
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/LICENSE b/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/LICENSE
deleted file mode 100644 (file)
index 353924b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright Jason R. Coombs
-
-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.
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/METADATA b/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/METADATA
deleted file mode 100644 (file)
index 12dfbdd..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-Metadata-Version: 2.1
-Name: jaraco.functools
-Version: 3.5.0
-Summary: Functools like those found in stdlib
-Home-page: https://github.com/jaraco/jaraco.functools
-Author: Jason R. Coombs
-Author-email: jaraco@jaraco.com
-License: UNKNOWN
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3 :: Only
-Requires-Python: >=3.7
-License-File: LICENSE
-Requires-Dist: more-itertools
-Provides-Extra: docs
-Requires-Dist: sphinx ; extra == 'docs'
-Requires-Dist: jaraco.packaging (>=8.2) ; extra == 'docs'
-Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
-Provides-Extra: testing
-Requires-Dist: pytest (>=6) ; extra == 'testing'
-Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
-Requires-Dist: pytest-flake8 ; extra == 'testing'
-Requires-Dist: pytest-cov ; extra == 'testing'
-Requires-Dist: pytest-enabler (>=1.0.1) ; extra == 'testing'
-Requires-Dist: jaraco.classes ; extra == 'testing'
-Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
-Requires-Dist: pytest-mypy ; (platform_python_implementation != "PyPy") and extra == 'testing'
-
-.. image:: https://img.shields.io/pypi/v/jaraco.functools.svg
-   :target: `PyPI link`_
-
-.. image:: https://img.shields.io/pypi/pyversions/jaraco.functools.svg
-
-.. image:: https://img.shields.io/travis/jaraco/jaraco.functools/master.svg
-   :target: `PyPI link`_
-
-.. _PyPI link: https://pypi.org/project/jaraco.functools
-
-.. image:: https://github.com/jaraco/jaraco.functools/workflows/tests/badge.svg
-   :target: https://github.com/jaraco/jaraco.functools/actions?query=workflow%3A%22tests%22
-   :alt: tests
-
-.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
-   :target: https://github.com/psf/black
-   :alt: Code style: Black
-
-.. image:: https://readthedocs.org/projects/jaracofunctools/badge/?version=latest
-   :target: https://jaracofunctools.readthedocs.io/en/latest/?badge=latest
-
-.. image:: https://img.shields.io/badge/skeleton-2021-informational
-   :target: https://blog.jaraco.com/skeleton
-
-Additional functools in the spirit of stdlib's functools.
-
-
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/RECORD b/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/RECORD
deleted file mode 100644 (file)
index fbda3d1..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-jaraco.functools-3.5.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
-jaraco.functools-3.5.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
-jaraco.functools-3.5.0.dist-info/METADATA,sha256=cE9C7u9bo_GjLAuw4nML67a25kUaPDiHn4j03lG4jd0,2276\r
-jaraco.functools-3.5.0.dist-info/RECORD,,\r
-jaraco.functools-3.5.0.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92\r
-jaraco.functools-3.5.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
-jaraco/__pycache__/functools.cpython-310.pyc,,\r
-jaraco/functools.py,sha256=PtEHbXZstgVJrwje4GvJOsz5pEbgslOcgEn2EJNpr2c,13494\r
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/WHEEL b/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/WHEEL
deleted file mode 100644 (file)
index 5bad85f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.0)
-Root-Is-Purelib: true
-Tag: py3-none-any
-
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/top_level.txt b/pkg_resources/_vendor/jaraco.functools-3.5.0.dist-info/top_level.txt
deleted file mode 100644 (file)
index f6205a5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-jaraco
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/INSTALLER b/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/INSTALLER
new file mode 100644 (file)
index 0000000..a1b589e
--- /dev/null
@@ -0,0 +1 @@
+pip
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/LICENSE b/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/LICENSE
new file mode 100644 (file)
index 0000000..353924b
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright Jason R. Coombs
+
+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.
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/METADATA b/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/METADATA
new file mode 100644 (file)
index 0000000..fa8f021
--- /dev/null
@@ -0,0 +1,75 @@
+Metadata-Version: 2.1
+Name: jaraco.functools
+Version: 3.5.2
+Summary: Functools like those found in stdlib
+Home-page: https://github.com/jaraco/jaraco.functools
+Author: Jason R. Coombs
+Author-email: jaraco@jaraco.com
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Requires-Python: >=3.7
+License-File: LICENSE
+Requires-Dist: more-itertools
+Provides-Extra: docs
+Requires-Dist: sphinx (>=3.5) ; extra == 'docs'
+Requires-Dist: jaraco.packaging (>=9) ; extra == 'docs'
+Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
+Requires-Dist: jaraco.tidelift (>=1.4) ; extra == 'docs'
+Provides-Extra: testing
+Requires-Dist: pytest (>=6) ; extra == 'testing'
+Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
+Requires-Dist: pytest-flake8 ; extra == 'testing'
+Requires-Dist: flake8 (<5) ; extra == 'testing'
+Requires-Dist: pytest-cov ; extra == 'testing'
+Requires-Dist: pytest-enabler (>=1.3) ; extra == 'testing'
+Requires-Dist: jaraco.classes ; extra == 'testing'
+Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
+Requires-Dist: pytest-mypy (>=0.9.1) ; (platform_python_implementation != "PyPy") and extra == 'testing'
+
+.. image:: https://img.shields.io/pypi/v/jaraco.functools.svg
+   :target: `PyPI link`_
+
+.. image:: https://img.shields.io/pypi/pyversions/jaraco.functools.svg
+
+.. image:: https://img.shields.io/travis/jaraco/jaraco.functools/master.svg
+   :target: `PyPI link`_
+
+.. _PyPI link: https://pypi.org/project/jaraco.functools
+
+.. image:: https://github.com/jaraco/jaraco.functools/workflows/tests/badge.svg
+   :target: https://github.com/jaraco/jaraco.functools/actions?query=workflow%3A%22tests%22
+   :alt: tests
+
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
+   :target: https://github.com/psf/black
+   :alt: Code style: Black
+
+.. image:: https://readthedocs.org/projects/jaracofunctools/badge/?version=latest
+   :target: https://jaracofunctools.readthedocs.io/en/latest/?badge=latest
+
+.. image:: https://img.shields.io/badge/skeleton-2022-informational
+   :target: https://blog.jaraco.com/skeleton
+
+.. image:: https://tidelift.com/badges/package/pypi/jaraco.functools
+   :target: https://tidelift.com/subscription/pkg/pypi-jaraco.functools?utm_source=pypi-jaraco.functools&utm_medium=readme
+
+Additional functools in the spirit of stdlib's functools.
+
+For Enterprise
+==============
+
+Available as part of the Tidelift Subscription.
+
+This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.
+
+`Learn more <https://tidelift.com/subscription/pkg/pypi-jaraco.functools?utm_source=pypi-jaraco.functools&utm_medium=referral&utm_campaign=github>`_.
+
+Security Contact
+================
+
+To report a security vulnerability, please use the
+`Tidelift security contact <https://tidelift.com/security>`_.
+Tidelift will coordinate the fix and disclosure.
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/RECORD b/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/RECORD
new file mode 100644 (file)
index 0000000..127b826
--- /dev/null
@@ -0,0 +1,8 @@
+jaraco.functools-3.5.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+jaraco.functools-3.5.2.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
+jaraco.functools-3.5.2.dist-info/METADATA,sha256=ZIViwS4ZOmaWwA5ArwZ_xXQGR9WDnUSzx-0MO5kGPi8,3154\r
+jaraco.functools-3.5.2.dist-info/RECORD,,\r
+jaraco.functools-3.5.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92\r
+jaraco.functools-3.5.2.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
+jaraco/__pycache__/functools.cpython-311.pyc,,\r
+jaraco/functools.py,sha256=PtEHbXZstgVJrwje4GvJOsz5pEbgslOcgEn2EJNpr2c,13494\r
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/WHEEL b/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/WHEEL
new file mode 100644 (file)
index 0000000..becc9a6
--- /dev/null
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.37.1)
+Root-Is-Purelib: true
+Tag: py3-none-any
+
diff --git a/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/top_level.txt b/pkg_resources/_vendor/jaraco.functools-3.5.2.dist-info/top_level.txt
new file mode 100644 (file)
index 0000000..f6205a5
--- /dev/null
@@ -0,0 +1 @@
+jaraco
index 916ad7d3f81087cea1a463df4b315b27a4089138..dd471b070829ecac87c98a302c5eb71337c44d1c 100644 (file)
@@ -7,4 +7,4 @@ jaraco.text-3.7.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FG
 jaraco.text-3.7.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
 jaraco/text/Lorem ipsum.txt,sha256=N_7c_79zxOufBY9HZ3yzMgOkNv-TkOTTio4BydrSjgs,1335\r
 jaraco/text/__init__.py,sha256=I56MW2ZFwPrYXIxzqxMBe2A1t-T4uZBgEgAKe9-JoqM,15538\r
-jaraco/text/__pycache__/__init__.cpython-310.pyc,,\r
+jaraco/text/__pycache__/__init__.cpython-311.pyc,,\r
index 87a4e3dca299c4201ac50f6ef589dc73f1c45576..818f16f364c1a529985df5fbf81155eae4c24a45 100644 (file)
@@ -211,3 +211,43 @@ class suppress(contextlib.suppress, contextlib.ContextDecorator):
     ...     {}['']
     >>> key_error()
     """
+
+
+class on_interrupt(contextlib.ContextDecorator):
+    """
+    Replace a KeyboardInterrupt with SystemExit(1)
+
+    >>> def do_interrupt():
+    ...     raise KeyboardInterrupt()
+    >>> on_interrupt('error')(do_interrupt)()
+    Traceback (most recent call last):
+    ...
+    SystemExit: 1
+    >>> on_interrupt('error', code=255)(do_interrupt)()
+    Traceback (most recent call last):
+    ...
+    SystemExit: 255
+    >>> on_interrupt('suppress')(do_interrupt)()
+    >>> with __import__('pytest').raises(KeyboardInterrupt):
+    ...     on_interrupt('ignore')(do_interrupt)()
+    """
+
+    def __init__(
+        self,
+        action='error',
+        # py3.7 compat
+        # /,
+        code=1,
+    ):
+        self.action = action
+        self.code = code
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exctype, excinst, exctb):
+        if exctype is not KeyboardInterrupt or self.action == 'ignore':
+            return
+        elif self.action == 'error':
+            raise SystemExit(self.code) from excinst
+        return self.action == 'suppress'
diff --git a/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/INSTALLER b/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/INSTALLER
deleted file mode 100644 (file)
index a1b589e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pip
diff --git a/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/LICENSE b/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/LICENSE
deleted file mode 100644 (file)
index 0a523be..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2012 Erik Rose
-
-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.
diff --git a/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/METADATA b/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/METADATA
deleted file mode 100644 (file)
index 9efacdd..0000000
+++ /dev/null
@@ -1,521 +0,0 @@
-Metadata-Version: 2.1
-Name: more-itertools
-Version: 8.12.0
-Summary: More routines for operating on iterables, beyond itertools
-Home-page: https://github.com/more-itertools/more-itertools
-Author: Erik Rose
-Author-email: erikrose@grinchcentral.com
-License: MIT
-Keywords: itertools,iterator,iteration,filter,peek,peekable,collate,chunk,chunked
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Natural Language :: English
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 3
-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 :: Only
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
-Classifier: Topic :: Software Development :: Libraries
-Requires-Python: >=3.5
-Description-Content-Type: text/x-rst
-License-File: LICENSE
-
-==============
-More Itertools
-==============
-
-.. image:: https://readthedocs.org/projects/more-itertools/badge/?version=latest
-  :target: https://more-itertools.readthedocs.io/en/stable/
-
-Python's ``itertools`` library is a gem - you can compose elegant solutions
-for a variety of problems with the functions it provides. In ``more-itertools``
-we collect additional building blocks, recipes, and routines for working with
-Python iterables.
-
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Grouping               | `chunked <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.chunked>`_,                                                                               |
-|                        | `ichunked <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ichunked>`_,                                                                             |
-|                        | `sliced <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sliced>`_,                                                                                 |
-|                        | `distribute <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distribute>`_,                                                                         |
-|                        | `divide <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.divide>`_,                                                                                 |
-|                        | `split_at <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_at>`_,                                                                             |
-|                        | `split_before <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_before>`_,                                                                     |
-|                        | `split_after <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_after>`_,                                                                       |
-|                        | `split_into <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_into>`_,                                                                         |
-|                        | `split_when <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_when>`_,                                                                         |
-|                        | `bucket <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.bucket>`_,                                                                                 |
-|                        | `unzip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unzip>`_,                                                                                   |
-|                        | `grouper <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.grouper>`_,                                                                               |
-|                        | `partition <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.partition>`_                                                                            |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Lookahead and lookback | `spy <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.spy>`_,                                                                                       |
-|                        | `peekable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.peekable>`_,                                                                             |
-|                        | `seekable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.seekable>`_                                                                              |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Windowing              | `windowed <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.windowed>`_,                                                                             |
-|                        | `substrings <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.substrings>`_,                                                                         |
-|                        | `substrings_indexes <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.substrings_indexes>`_,                                                         |
-|                        | `stagger <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.stagger>`_,                                                                               |
-|                        | `windowed_complete <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.windowed_complete>`_,                                                           |
-|                        | `pairwise <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.pairwise>`_,                                                                             |
-|                        | `triplewise <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.triplewise>`_,                                                                         |
-|                        | `sliding_window <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sliding_window>`_                                                                  |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Augmenting             | `count_cycle <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.count_cycle>`_,                                                                       |
-|                        | `intersperse <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.intersperse>`_,                                                                       |
-|                        | `padded <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.padded>`_,                                                                                 |
-|                        | `mark_ends <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.mark_ends>`_,                                                                           |
-|                        | `repeat_last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.repeat_last>`_,                                                                       |
-|                        | `adjacent <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.adjacent>`_,                                                                             |
-|                        | `groupby_transform <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.groupby_transform>`_,                                                           |
-|                        | `pad_none <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.pad_none>`_,                                                                             |
-|                        | `ncycles <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ncycles>`_                                                                                |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Combining              | `collapse <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.collapse>`_,                                                                             |
-|                        | `sort_together <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sort_together>`_,                                                                   |
-|                        | `interleave <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave>`_,                                                                         |
-|                        | `interleave_longest <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave_longest>`_,                                                         |
-|                        | `interleave_evenly <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave_evenly>`_,                                                           |
-|                        | `zip_offset <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_offset>`_,                                                                         |
-|                        | `zip_equal <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_equal>`_,                                                                           |
-|                        | `zip_broadcast <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_broadcast>`_,                                                                   |
-|                        | `dotproduct <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.dotproduct>`_,                                                                         |
-|                        | `convolve <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.convolve>`_,                                                                             |
-|                        | `flatten <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.flatten>`_,                                                                               |
-|                        | `roundrobin <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.roundrobin>`_,                                                                         |
-|                        | `prepend <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.prepend>`_,                                                                               |
-|                        | `value_chain <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.value_chain>`_                                                                        |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Summarizing            | `ilen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ilen>`_,                                                                                     |
-|                        | `unique_to_each <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_to_each>`_,                                                                 |
-|                        | `sample <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sample>`_,                                                                                 |
-|                        | `consecutive_groups <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consecutive_groups>`_,                                                         |
-|                        | `run_length <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.run_length>`_,                                                                         |
-|                        | `map_reduce <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_reduce>`_,                                                                         |
-|                        | `exactly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.exactly_n>`_,                                                                           |
-|                        | `is_sorted <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.is_sorted>`_,                                                                           |
-|                        | `all_equal <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.all_equal>`_,                                                                           |
-|                        | `all_unique <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.all_unique>`_,                                                                         |
-|                        | `minmax <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.minmax>`_,                                                                                 |
-|                        | `first_true <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first_true>`_,                                                                         |
-|                        | `quantify <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.quantify>`_                                                                              |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Selecting              | `islice_extended <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.islice_extended>`_,                                                               |
-|                        | `first <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first>`_,                                                                                   |
-|                        | `last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.last>`_,                                                                                     |
-|                        | `one <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.one>`_,                                                                                       |
-|                        | `only <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.only>`_,                                                                                     |
-|                        | `strictly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.strictly_n>`_,                                                                         |
-|                        | `strip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.strip>`_,                                                                                   |
-|                        | `lstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.lstrip>`_,                                                                                 |
-|                        | `rstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rstrip>`_,                                                                                 |
-|                        | `filter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.filter_except>`_,                                                                   |
-|                        | `map_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_except>`_,                                                                         |
-|                        | `nth_or_last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_or_last>`_,                                                                       |
-|                        | `unique_in_window <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_in_window>`_,                                                             |
-|                        | `before_and_after <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.before_and_after>`_,                                                             |
-|                        | `nth <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth>`_,                                                                                       |
-|                        | `take <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.take>`_,                                                                                     |
-|                        | `tail <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.tail>`_,                                                                                     |
-|                        | `unique_everseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertoo ls.unique_everseen>`_,                                                              |
-|                        | `unique_justseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_justseen>`_,                                                               |
-|                        | `duplicates_everseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.duplicates_everseen>`_,                                                       |
-|                        | `duplicates_justseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.duplicates_justseen>`_                                                        |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Combinatorics          | `distinct_permutations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_permutations>`_,                                                   |
-|                        | `distinct_combinations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_combinations>`_,                                                   |
-|                        | `circular_shifts <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.circular_shifts>`_,                                                               |
-|                        | `partitions <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.partitions>`_,                                                                         |
-|                        | `set_partitions <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.set_partitions>`_,                                                                 |
-|                        | `product_index <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.product_index>`_,                                                                   |
-|                        | `combination_index <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.combination_index>`_,                                                           |
-|                        | `permutation_index <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.permutation_index>`_,                                                           |
-|                        | `powerset <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.powerset>`_,                                                                             |
-|                        | `random_product <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.random_product>`_,                                                                 |
-|                        | `random_permutation <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.random_permutation>`_,                                                         |
-|                        | `random_combination <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.random_combination>`_,                                                         |
-|                        | `random_combination_with_replacement <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.random_combination_with_replacement>`_,                       |
-|                        | `nth_product <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_product>`_,                                                                       |
-|                        | `nth_permutation <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_permutation>`_,                                                               |
-|                        | `nth_combination <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_combination>`_                                                                |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Wrapping               | `always_iterable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable>`_,                                                               |
-|                        | `always_reversible <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_reversible>`_,                                                           |
-|                        | `countable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.countable>`_,                                                                           |
-|                        | `consumer <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consumer>`_,                                                                             |
-|                        | `with_iter <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.with_iter>`_,                                                                           |
-|                        | `iter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iter_except>`_                                                                        |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Others                 | `locate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.locate>`_,                                                                                 |
-|                        | `rlocate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate>`_,                                                                               |
-|                        | `replace <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.replace>`_,                                                                               |
-|                        | `numeric_range <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.numeric_range>`_,                                                                   |
-|                        | `side_effect <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.side_effect>`_,                                                                       |
-|                        | `iterate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iterate>`_,                                                                               |
-|                        | `difference <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.difference>`_,                                                                         |
-|                        | `make_decorator <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.make_decorator>`_,                                                                 |
-|                        | `SequenceView <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.SequenceView>`_,                                                                     |
-|                        | `time_limited <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.time_limited>`_,                                                                     |
-|                        | `consume <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consume>`_,                                                                               |
-|                        | `tabulate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.tabulate>`_,                                                                             |
-|                        | `repeatfunc <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.repeatfunc>`_                                                                          |
-+------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-
-
-Getting started
-===============
-
-To get started, install the library with `pip <https://pip.pypa.io/en/stable/>`_:
-
-.. code-block:: shell
-
-    pip install more-itertools
-
-The recipes from the `itertools docs <https://docs.python.org/3/library/itertools.html#itertools-recipes>`_
-are included in the top-level package:
-
-.. code-block:: python
-
-    >>> from more_itertools import flatten
-    >>> iterable = [(0, 1), (2, 3)]
-    >>> list(flatten(iterable))
-    [0, 1, 2, 3]
-
-Several new recipes are available as well:
-
-.. code-block:: python
-
-    >>> from more_itertools import chunked
-    >>> iterable = [0, 1, 2, 3, 4, 5, 6, 7, 8]
-    >>> list(chunked(iterable, 3))
-    [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
-
-    >>> from more_itertools import spy
-    >>> iterable = (x * x for x in range(1, 6))
-    >>> head, iterable = spy(iterable, n=3)
-    >>> list(head)
-    [1, 4, 9]
-    >>> list(iterable)
-    [1, 4, 9, 16, 25]
-
-
-
-For the full listing of functions, see the `API documentation <https://more-itertools.readthedocs.io/en/stable/api.html>`_.
-
-
-Links elsewhere
-===============
-
-Blog posts about ``more-itertools``:
-
-* `Yo, I heard you like decorators <https://www.bbayles.com/index/decorator_factory>`__
-* `Tour of Python Itertools <https://martinheinz.dev/blog/16>`__ (`Alternate <https://dev.to/martinheinz/tour-of-python-itertools-4122>`__)
-* `Real-World Python More Itertools <https://www.gidware.com/real-world-more-itertools/>`_
-
-
-Development
-===========
-
-``more-itertools`` is maintained by `@erikrose <https://github.com/erikrose>`_
-and `@bbayles <https://github.com/bbayles>`_, with help from `many others <https://github.com/more-itertools/more-itertools/graphs/contributors>`_.
-If you have a problem or suggestion, please file a bug or pull request in this
-repository. Thanks for contributing!
-
-
-Version History
-===============
-
-
-   :noindex:
-
-8.12.0
-------
-
-* Bug fixes
-    * Some documentation issues were fixed (thanks to Masynchin, spookylukey, astrojuanlu, and stephengmatthews)
-    * Python 3.5 support was temporarily restored (thanks to mattbonnell)
-
-8.11.0
-------
-
-* New functions
-    * The before_and_after, sliding_window, and triplewise recipes from the Python 3.10 docs were added
-    * duplicates_everseen and duplicates_justseen (thanks to OrBin and DavidPratt512)
-    * minmax (thanks to Ricocotam, MSeifert04, and ruancomelli)
-    * strictly_n (thanks to hwalinga and NotWearingPants)
-    * unique_in_window
-
-* Changes to existing functions
-    * groupby_transform had its type stub improved (thanks to mjk4 and ruancomelli)
-    * is_sorted now accepts a ``strict`` parameter (thanks to Dutcho and ruancomelli)
-    * zip_broadcast was updated to fix a bug (thanks to kalekundert)
-
-8.10.0
-------
-
-* Changes to existing functions
-    * The type stub for iter_except was improved (thanks to  MarcinKonowalczyk)
-
-* Other changes:
-    *  Type stubs now ship with the source release (thanks to saaketp)
-    *  The Sphinx docs were improved (thanks to MarcinKonowalczyk)
-
-8.9.0
------
-
-* New functions
-    * interleave_evenly (thanks to mbugert)
-    * repeat_each (thanks to FinalSh4re)
-    * chunked_even (thanks to valtron)
-    * map_if (thanks to sassbalint)
-    * zip_broadcast (thanks to kalekundert)
-
-* Changes to existing functions
-    * The type stub for chunked was improved (thanks to  PhilMacKay)
-    * The type stubs for zip_equal and `zip_offset` were improved (thanks to maffoo)
-    * Building Sphinx docs locally was improved (thanks to MarcinKonowalczyk)
-
-8.8.0
------
-
-* New functions
-    * countable (thanks to krzysieq)
-
-* Changes to existing functions
-    * split_before was updated to handle empy collections (thanks to TiunovNN)
-    * unique_everseen got a performance boost (thanks to Numerlor)
-    * The type hint for value_chain was corrected (thanks to vr2262)
-
-8.7.0
------
-
-* New functions
-    * convolve (from the Python itertools docs)
-    * product_index, combination_index, and permutation_index (thanks to N8Brooks)
-    * value_chain (thanks to jenstroeger)
-
-* Changes to existing functions
-    * distinct_combinations now uses a non-recursive algorithm (thanks to  knutdrand)
-    * pad_none is now the preferred name for padnone, though the latter remains available.
-    * pairwise will now use the Python standard library implementation on Python 3.10+
-    * sort_together now accepts a ``key`` argument (thanks to brianmaissy)
-    * seekable now has a ``peek`` method, and can indicate whether the iterator it's wrapping is exhausted (thanks to gsakkis)
-    * time_limited can now indicate whether its iterator has expired (thanks to roysmith)
-    * The implementation of unique_everseen was improved (thanks to plammens)
-
-* Other changes:
-    * Various documentation updates (thanks to cthoyt, Evantm, and cyphase)
-
-8.6.0
------
-
-* New itertools
-    * all_unique (thanks to brianmaissy)
-    * nth_product and nth_permutation (thanks to N8Brooks)
-
-* Changes to existing itertools
-    * chunked and sliced now accept a ``strict`` parameter (thanks to shlomif and jtwool)
-
-* Other changes
-    * Python 3.5 has reached its end of life and is no longer supported.
-    * Python 3.9 is officially supported.
-    * Various documentation fixes (thanks to timgates42)
-
-8.5.0
------
-
-* New itertools
-    * windowed_complete (thanks to MarcinKonowalczyk)
-
-* Changes to existing itertools:
-    * The is_sorted implementation was improved (thanks to cool-RR)
-    * The groupby_transform now accepts a ``reducefunc`` parameter.
-    * The last implementation was improved (thanks to brianmaissy)
-
-* Other changes
-    * Various documentation fixes (thanks to craigrosie, samuelstjean, PiCT0)
-    * The tests for distinct_combinations were improved (thanks to Minabsapi)
-    * Automated tests now run on GitHub Actions. All commits now check:
-        * That unit tests pass
-        * That the examples in docstrings work
-        * That test coverage remains high (using `coverage`)
-        * For linting errors (using `flake8`)
-        * For consistent style (using `black`)
-        * That the type stubs work (using `mypy`)
-        * That the docs build correctly (using `sphinx`)
-        * That packages build correctly (using `twine`)
-
-8.4.0
------
-
-* New itertools
-    * mark_ends (thanks to kalekundert)
-    * is_sorted
-
-* Changes to existing itertools:
-    * islice_extended can now be used with real slices (thanks to cool-RR)
-    * The implementations for filter_except and map_except were improved (thanks to SergBobrovsky)
-
-* Other changes
-    * Automated tests now enforce code style (using `black <https://github.com/psf/black>`__)
-    * The various signatures of islice_extended and numeric_range now appear in the docs (thanks to dsfulf)
-    * The test configuration for mypy was updated (thanks to blueyed)
-
-
-8.3.0
------
-
-* New itertools
-    * zip_equal (thanks to frankier and alexmojaki)
-
-* Changes to existing itertools:
-    * split_at, split_before, split_after, and split_when all got a ``maxsplit`` paramter (thanks to jferard and ilai-deutel)
-    * split_at now accepts a ``keep_separator`` parameter (thanks to jferard)
-    * distinct_permutations can now generate ``r``-length permutations (thanks to SergBobrovsky and ilai-deutel)
-    * The windowed implementation was improved  (thanks to SergBobrovsky)
-    * The spy implementation was improved (thanks to has2k1)
-
-* Other changes
-    * Type stubs are now tested with ``stubtest`` (thanks to ilai-deutel)
-    * Tests now run with ``python -m unittest`` instead of ``python setup.py test`` (thanks to jdufresne)
-
-8.2.0
------
-
-* Bug fixes
-    * The .pyi files for typing were updated. (thanks to blueyed and ilai-deutel)
-
-* Changes to existing itertools:
-    * numeric_range now behaves more like the built-in range. (thanks to jferard)
-    * bucket now allows for enumerating keys. (thanks to alexchandel)
-    * sliced now should now work for numpy arrays. (thanks to sswingle)
-    * seekable now has a ``maxlen`` parameter.
-
-8.1.0
------
-
-* Bug fixes
-    * partition works with ``pred=None`` again. (thanks to MSeifert04)
-
-* New itertools
-    * sample (thanks to tommyod)
-    * nth_or_last (thanks to d-ryzhikov)
-
-* Changes to existing itertools:
-    * The implementation for divide was improved. (thanks to jferard)
-
-8.0.2
------
-
-* Bug fixes
-    * The type stub files are now part of the wheel distribution (thanks to keisheiled)
-
-8.0.1
------
-
-* Bug fixes
-    * The type stub files now work for functions imported from the
-      root package (thanks to keisheiled)
-
-8.0.0
------
-
-* New itertools and other additions
-    * This library now ships type hints for use with mypy.
-      (thanks to ilai-deutel for the implementation, and to gabbard and fmagin for assistance)
-    * split_when (thanks to jferard)
-    * repeat_last (thanks to d-ryzhikov)
-
-* Changes to existing itertools:
-    * The implementation for set_partitions was improved. (thanks to jferard)
-    * partition was optimized for expensive predicates. (thanks to stevecj)
-    * unique_everseen and groupby_transform were re-factored. (thanks to SergBobrovsky)
-    * The implementation for difference was improved. (thanks to Jabbey92)
-
-* Other changes
-    * Python 3.4 has reached its end of life and is no longer supported.
-    * Python 3.8 is officially supported. (thanks to jdufresne)
-    * The ``collate`` function has been deprecated.
-      It raises a ``DeprecationWarning`` if used, and will be removed in a future release.
-    * one and only now provide more informative error messages. (thanks to gabbard)
-    * Unit tests were moved outside of the main package (thanks to jdufresne)
-    * Various documentation fixes (thanks to kriomant, gabbard, jdufresne)
-
-
-7.2.0
------
-
-* New itertools
-    * distinct_combinations
-    * set_partitions (thanks to kbarrett)
-    * filter_except
-    * map_except
-
-7.1.0
------
-
-* New itertools
-    * ichunked (thanks davebelais and youtux)
-    * only (thanks jaraco)
-
-* Changes to existing itertools:
-    * numeric_range now supports ranges specified by
-      ``datetime.datetime`` and ``datetime.timedelta`` objects (thanks to MSeifert04 for tests).
-    * difference now supports an *initial* keyword argument.
-
-
-* Other changes
-    * Various documentation fixes (thanks raimon49, pylang)
-
-7.0.0
------
-
-* New itertools:
-    * time_limited
-    * partitions (thanks to rominf and Saluev)
-    * substrings_indexes (thanks to rominf)
-
-* Changes to existing itertools:
-    * collapse now treats ``bytes`` objects the same as ``str`` objects. (thanks to Sweenpet)
-
-The major version update is due to the change in the default behavior of
-collapse. It now treats ``bytes`` objects the same as ``str`` objects.
-This aligns its behavior with always_iterable.
-
-.. code-block:: python
-
-    >>> from more_itertools import collapse
-    >>> iterable = [[1, 2], b'345', [6]]
-    >>> print(list(collapse(iterable)))
-    [1, 2, b'345', 6]
-
-6.0.0
------
-
-* Major changes:
-    * Python 2.7 is no longer supported. The 5.0.0 release will be the last
-      version targeting Python 2.7.
-    * All future releases will target the active versions of Python 3.
-      As of 2019, those are Python 3.4 and above.
-    * The ``six`` library is no longer a dependency.
-    * The accumulate function is no longer part of this library. You
-      may import a better version from the standard ``itertools`` module.
-
-* Changes to existing itertools:
-    * The order of the parameters in grouper have changed to match
-      the latest recipe in the itertools documentation. Use of the old order
-      will be supported in this release, but emit a  ``DeprecationWarning``.
-      The legacy behavior will be dropped in a future release. (thanks to jaraco)
-    * distinct_permutations was improved (thanks to jferard - see also `permutations with unique values <https://stackoverflow.com/questions/6284396/permutations-with-unique-values>`_ at StackOverflow.)
-    * An unused parameter was removed from substrings. (thanks to pylang)
-
-* Other changes:
-    * The docs for unique_everseen were improved. (thanks to jferard and MSeifert04)
-    * Several Python 2-isms were removed. (thanks to jaraco, MSeifert04, and hugovk)
-
-
diff --git a/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/RECORD b/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/RECORD
deleted file mode 100644 (file)
index 4484729..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-more_itertools-8.12.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
-more_itertools-8.12.0.dist-info/LICENSE,sha256=CfHIyelBrz5YTVlkHqm4fYPAyw_QB-te85Gn4mQ8GkY,1053\r
-more_itertools-8.12.0.dist-info/METADATA,sha256=QCCEcisEPr7iSfBIKCukhP-FbG9ehMK8tDIliZ3FBDc,39405\r
-more_itertools-8.12.0.dist-info/RECORD,,\r
-more_itertools-8.12.0.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92\r
-more_itertools-8.12.0.dist-info/top_level.txt,sha256=fAuqRXu9LPhxdB9ujJowcFOu1rZ8wzSpOW9_jlKis6M,15\r
-more_itertools/__init__.py,sha256=ZQYu_9H6stSG7viUgT32TFqslqcZwq82kWRZooKiI8Y,83\r
-more_itertools/__init__.pyi,sha256=5B3eTzON1BBuOLob1vCflyEb2lSd6usXQQ-Cv-hXkeA,43\r
-more_itertools/__pycache__/__init__.cpython-310.pyc,,\r
-more_itertools/__pycache__/more.cpython-310.pyc,,\r
-more_itertools/__pycache__/recipes.cpython-310.pyc,,\r
-more_itertools/more.py,sha256=jSrvV9BK-XKa4x7MPPp9yWYRDtRgR5h7yryEqHMU4mg,132578\r
-more_itertools/more.pyi,sha256=kWOkRKx0V8ZwC1D2j0c0DUfy56dazzpmRcm5ZuY_aqo,20006\r
-more_itertools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-more_itertools/recipes.py,sha256=N6aCDwoIPvE-aiqpGU-nbFwqiM3X8MKRcxBM84naW88,18410\r
-more_itertools/recipes.pyi,sha256=Lx3vb0p_vY7rF8MQuguvOcVaS9qd1WRL8JO_qVo7hiY,3925\r
diff --git a/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/WHEEL b/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/WHEEL
deleted file mode 100644 (file)
index 5bad85f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.0)
-Root-Is-Purelib: true
-Tag: py3-none-any
-
diff --git a/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/top_level.txt b/pkg_resources/_vendor/more_itertools-8.12.0.dist-info/top_level.txt
deleted file mode 100644 (file)
index a5035be..0000000
+++ /dev/null
@@ -1 +0,0 @@
-more_itertools
diff --git a/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/INSTALLER b/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/INSTALLER
new file mode 100644 (file)
index 0000000..a1b589e
--- /dev/null
@@ -0,0 +1 @@
+pip
diff --git a/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/LICENSE b/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/LICENSE
new file mode 100644 (file)
index 0000000..0a523be
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Erik Rose
+
+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.
diff --git a/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/METADATA b/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/METADATA
new file mode 100644 (file)
index 0000000..bd98892
--- /dev/null
@@ -0,0 +1,241 @@
+Metadata-Version: 2.1
+Name: more-itertools
+Version: 9.0.0
+Summary: More routines for operating on iterables, beyond itertools
+Keywords: itertools,iterator,iteration,filter,peek,peekable,chunk,chunked
+Author-email: Erik Rose <erikrose@grinchcentral.com>
+Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Natural Language :: English
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 3
+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 :: 3.11
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Software Development :: Libraries
+Project-URL: Homepage, https://github.com/more-itertools/more-itertools
+
+==============
+More Itertools
+==============
+
+.. image:: https://readthedocs.org/projects/more-itertools/badge/?version=latest
+  :target: https://more-itertools.readthedocs.io/en/stable/
+
+Python's ``itertools`` library is a gem - you can compose elegant solutions
+for a variety of problems with the functions it provides. In ``more-itertools``
+we collect additional building blocks, recipes, and routines for working with
+Python iterables.
+
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Grouping               | `chunked <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.chunked>`_,                                                                               |
+|                        | `ichunked <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ichunked>`_,                                                                             |
+|                        | `chunked_even <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.chunked_even>`_,                                                                     |
+|                        | `sliced <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sliced>`_,                                                                                 |
+|                        | `constrained_batches <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.constrained_batches>`_,                                                       |
+|                        | `distribute <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distribute>`_,                                                                         |
+|                        | `divide <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.divide>`_,                                                                                 |
+|                        | `split_at <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_at>`_,                                                                             |
+|                        | `split_before <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_before>`_,                                                                     |
+|                        | `split_after <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_after>`_,                                                                       |
+|                        | `split_into <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_into>`_,                                                                         |
+|                        | `split_when <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_when>`_,                                                                         |
+|                        | `bucket <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.bucket>`_,                                                                                 |
+|                        | `unzip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unzip>`_,                                                                                   |
+|                        | `batched <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.batched>`_,                                                                               |
+|                        | `grouper <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.grouper>`_,                                                                               |
+|                        | `partition <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.partition>`_                                                                            |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Lookahead and lookback | `spy <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.spy>`_,                                                                                       |
+|                        | `peekable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.peekable>`_,                                                                             |
+|                        | `seekable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.seekable>`_                                                                              |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Windowing              | `windowed <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.windowed>`_,                                                                             |
+|                        | `substrings <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.substrings>`_,                                                                         |
+|                        | `substrings_indexes <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.substrings_indexes>`_,                                                         |
+|                        | `stagger <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.stagger>`_,                                                                               |
+|                        | `windowed_complete <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.windowed_complete>`_,                                                           |
+|                        | `pairwise <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.pairwise>`_,                                                                             |
+|                        | `triplewise <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.triplewise>`_,                                                                         |
+|                        | `sliding_window <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sliding_window>`_,                                                                 |
+|                        | `subslices <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.subslices>`_                                                                            |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Augmenting             | `count_cycle <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.count_cycle>`_,                                                                       |
+|                        | `intersperse <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.intersperse>`_,                                                                       |
+|                        | `padded <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.padded>`_,                                                                                 |
+|                        | `repeat_each <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.repeat_each>`_,                                                                       |
+|                        | `mark_ends <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.mark_ends>`_,                                                                           |
+|                        | `repeat_last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.repeat_last>`_,                                                                       |
+|                        | `adjacent <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.adjacent>`_,                                                                             |
+|                        | `groupby_transform <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.groupby_transform>`_,                                                           |
+|                        | `pad_none <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.pad_none>`_,                                                                             |
+|                        | `ncycles <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ncycles>`_                                                                                |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Combining              | `collapse <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.collapse>`_,                                                                             |
+|                        | `sort_together <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sort_together>`_,                                                                   |
+|                        | `interleave <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave>`_,                                                                         |
+|                        | `interleave_longest <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave_longest>`_,                                                         |
+|                        | `interleave_evenly <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.interleave_evenly>`_,                                                           |
+|                        | `zip_offset <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_offset>`_,                                                                         |
+|                        | `zip_equal <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_equal>`_,                                                                           |
+|                        | `zip_broadcast <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.zip_broadcast>`_,                                                                   |
+|                        | `dotproduct <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.dotproduct>`_,                                                                         |
+|                        | `convolve <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.convolve>`_,                                                                             |
+|                        | `flatten <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.flatten>`_,                                                                               |
+|                        | `roundrobin <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.roundrobin>`_,                                                                         |
+|                        | `prepend <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.prepend>`_,                                                                               |
+|                        | `value_chain <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.value_chain>`_                                                                        |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Summarizing            | `ilen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.ilen>`_,                                                                                     |
+|                        | `unique_to_each <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_to_each>`_,                                                                 |
+|                        | `sample <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sample>`_,                                                                                 |
+|                        | `consecutive_groups <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consecutive_groups>`_,                                                         |
+|                        | `run_length <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.run_length>`_,                                                                         |
+|                        | `map_reduce <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_reduce>`_,                                                                         |
+|                        | `exactly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.exactly_n>`_,                                                                           |
+|                        | `is_sorted <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.is_sorted>`_,                                                                           |
+|                        | `all_equal <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.all_equal>`_,                                                                           |
+|                        | `all_unique <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.all_unique>`_,                                                                         |
+|                        | `minmax <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.minmax>`_,                                                                                 |
+|                        | `first_true <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first_true>`_,                                                                         |
+|                        | `quantify <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.quantify>`_,                                                                             |
+|                        | `iequals <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iequals>`_                                                                                |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Selecting              | `islice_extended <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.islice_extended>`_,                                                               |
+|                        | `first <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.first>`_,                                                                                   |
+|                        | `last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.last>`_,                                                                                     |
+|                        | `one <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.one>`_,                                                                                       |
+|                        | `only <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.only>`_,                                                                                     |
+|                        | `strictly_n <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.strictly_n>`_,                                                                         |
+|                        | `strip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.strip>`_,                                                                                   |
+|                        | `lstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.lstrip>`_,                                                                                 |
+|                        | `rstrip <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rstrip>`_,                                                                                 |
+|                        | `filter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.filter_except>`_,                                                                   |
+|                        | `map_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_except>`_,                                                                         |
+|                        | `nth_or_last <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_or_last>`_,                                                                       |
+|                        | `unique_in_window <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_in_window>`_,                                                             |
+|                        | `before_and_after <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.before_and_after>`_,                                                             |
+|                        | `nth <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth>`_,                                                                                       |
+|                        | `take <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.take>`_,                                                                                     |
+|                        | `tail <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.tail>`_,                                                                                     |
+|                        | `unique_everseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertoo ls.unique_everseen>`_,                                                              |
+|                        | `unique_justseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.unique_justseen>`_,                                                               |
+|                        | `duplicates_everseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.duplicates_everseen>`_,                                                       |
+|                        | `duplicates_justseen <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.duplicates_justseen>`_,                                                       |
+|                        | `longest_common_prefix <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.longest_common_prefix>`_                                                    |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Combinatorics          | `distinct_permutations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_permutations>`_,                                                   |
+|                        | `distinct_combinations <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.distinct_combinations>`_,                                                   |
+|                        | `circular_shifts <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.circular_shifts>`_,                                                               |
+|                        | `partitions <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.partitions>`_,                                                                         |
+|                        | `set_partitions <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.set_partitions>`_,                                                                 |
+|                        | `product_index <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.product_index>`_,                                                                   |
+|                        | `combination_index <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.combination_index>`_,                                                           |
+|                        | `permutation_index <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.permutation_index>`_,                                                           |
+|                        | `powerset <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.powerset>`_,                                                                             |
+|                        | `random_product <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.random_product>`_,                                                                 |
+|                        | `random_permutation <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.random_permutation>`_,                                                         |
+|                        | `random_combination <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.random_combination>`_,                                                         |
+|                        | `random_combination_with_replacement <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.random_combination_with_replacement>`_,                       |
+|                        | `nth_product <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_product>`_,                                                                       |
+|                        | `nth_permutation <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_permutation>`_,                                                               |
+|                        | `nth_combination <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.nth_combination>`_                                                                |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Wrapping               | `always_iterable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable>`_,                                                               |
+|                        | `always_reversible <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_reversible>`_,                                                           |
+|                        | `countable <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.countable>`_,                                                                           |
+|                        | `consumer <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consumer>`_,                                                                             |
+|                        | `with_iter <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.with_iter>`_,                                                                           |
+|                        | `iter_except <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iter_except>`_                                                                        |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Others                 | `locate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.locate>`_,                                                                                 |
+|                        | `rlocate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate>`_,                                                                               |
+|                        | `replace <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.replace>`_,                                                                               |
+|                        | `numeric_range <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.numeric_range>`_,                                                                   |
+|                        | `side_effect <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.side_effect>`_,                                                                       |
+|                        | `iterate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iterate>`_,                                                                               |
+|                        | `difference <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.difference>`_,                                                                         |
+|                        | `make_decorator <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.make_decorator>`_,                                                                 |
+|                        | `SequenceView <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.SequenceView>`_,                                                                     |
+|                        | `time_limited <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.time_limited>`_,                                                                     |
+|                        | `map_if <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.map_if>`_,                                                                                 |
+|                        | `consume <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.consume>`_,                                                                               |
+|                        | `tabulate <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.tabulate>`_,                                                                             |
+|                        | `repeatfunc <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.repeatfunc>`_                                                                          |
+|                        | `polynomial_from_roots <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.polynomial_from_roots>`_                                                    |
+|                        | `sieve <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.sieve>`_                                                                                    |
++------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+
+Getting started
+===============
+
+To get started, install the library with `pip <https://pip.pypa.io/en/stable/>`_:
+
+.. code-block:: shell
+
+    pip install more-itertools
+
+The recipes from the `itertools docs <https://docs.python.org/3/library/itertools.html#itertools-recipes>`_
+are included in the top-level package:
+
+.. code-block:: python
+
+    >>> from more_itertools import flatten
+    >>> iterable = [(0, 1), (2, 3)]
+    >>> list(flatten(iterable))
+    [0, 1, 2, 3]
+
+Several new recipes are available as well:
+
+.. code-block:: python
+
+    >>> from more_itertools import chunked
+    >>> iterable = [0, 1, 2, 3, 4, 5, 6, 7, 8]
+    >>> list(chunked(iterable, 3))
+    [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
+
+    >>> from more_itertools import spy
+    >>> iterable = (x * x for x in range(1, 6))
+    >>> head, iterable = spy(iterable, n=3)
+    >>> list(head)
+    [1, 4, 9]
+    >>> list(iterable)
+    [1, 4, 9, 16, 25]
+
+
+
+For the full listing of functions, see the `API documentation <https://more-itertools.readthedocs.io/en/stable/api.html>`_.
+
+
+Links elsewhere
+===============
+
+Blog posts about ``more-itertools``:
+
+* `Yo, I heard you like decorators <https://www.bbayles.com/index/decorator_factory>`__
+* `Tour of Python Itertools <https://martinheinz.dev/blog/16>`__ (`Alternate <https://dev.to/martinheinz/tour-of-python-itertools-4122>`__)
+* `Real-World Python More Itertools <https://www.gidware.com/real-world-more-itertools/>`_
+
+
+Development
+===========
+
+``more-itertools`` is maintained by `@erikrose <https://github.com/erikrose>`_
+and `@bbayles <https://github.com/bbayles>`_, with help from `many others <https://github.com/more-itertools/more-itertools/graphs/contributors>`_.
+If you have a problem or suggestion, please file a bug or pull request in this
+repository. Thanks for contributing!
+
+
+Version History
+===============
+
+The version history can be found in `documentation <https://more-itertools.readthedocs.io/en/stable/versions.html>`_.
+
diff --git a/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/RECORD b/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/RECORD
new file mode 100644 (file)
index 0000000..4ae7d82
--- /dev/null
@@ -0,0 +1,15 @@
+more_itertools-9.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+more_itertools-9.0.0.dist-info/LICENSE,sha256=CfHIyelBrz5YTVlkHqm4fYPAyw_QB-te85Gn4mQ8GkY,1053\r
+more_itertools-9.0.0.dist-info/METADATA,sha256=o71Ks93mbZ7709yvfFg09Vxgj-8t2ZZaYIyUprS8GHw,31266\r
+more_itertools-9.0.0.dist-info/RECORD,,\r
+more_itertools-9.0.0.dist-info/WHEEL,sha256=4TfKIB_xu-04bc2iKz6_zFt-gEFEEDU_31HGhqzOCE8,81\r
+more_itertools/__init__.py,sha256=5PNQMpy400s5GB3jcWwzje0RCw8k0bvU9W_C49V0fd0,148\r
+more_itertools/__init__.pyi,sha256=5B3eTzON1BBuOLob1vCflyEb2lSd6usXQQ-Cv-hXkeA,43\r
+more_itertools/__pycache__/__init__.cpython-311.pyc,,\r
+more_itertools/__pycache__/more.cpython-311.pyc,,\r
+more_itertools/__pycache__/recipes.cpython-311.pyc,,\r
+more_itertools/more.py,sha256=FmmtkT-j69qILkxEELk5ZRoZK8St1Vg_fOGW0sTFd7g,133336\r
+more_itertools/more.pyi,sha256=hbf2oqg56wctXwf6yM1B0QLWqsNyDrqtX2znvQRAe3Q,20297\r
+more_itertools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+more_itertools/recipes.py,sha256=ZX4-2IfbZKlPIVaDITH2buX_fPuMDe1EVc6e2XSsCz8,22975\r
+more_itertools/recipes.pyi,sha256=NA6qqcKMbQ2fly9hCyCzMcx46Tn9TLl-9mFnZsRytZM,3851\r
diff --git a/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/WHEEL b/pkg_resources/_vendor/more_itertools-9.0.0.dist-info/WHEEL
new file mode 100644 (file)
index 0000000..668ba4d
--- /dev/null
@@ -0,0 +1,4 @@
+Wheel-Version: 1.0
+Generator: flit 3.7.1
+Root-Is-Purelib: true
+Tag: py3-none-any
index ea38bef1f661e62d577b3c2207386d901d851c72..557bfc206fd5f36c56d9abedc72b3f786d2e1cb2 100644 (file)
@@ -1,4 +1,6 @@
+"""More routines for operating on iterables, beyond itertools"""
+
 from .more import *  # noqa
 from .recipes import *  # noqa
 
-__version__ = '8.12.0'
+__version__ = '9.0.0'
old mode 100644 (file)
new mode 100755 (executable)
index 6b6a5ca..0b29fca
@@ -3,7 +3,7 @@ import warnings
 from collections import Counter, defaultdict, deque, abc
 from collections.abc import Sequence
 from functools import partial, reduce, wraps
-from heapq import merge, heapify, heapreplace, heappop
+from heapq import heapify, heapreplace, heappop
 from itertools import (
     chain,
     compress,
@@ -26,12 +26,16 @@ from sys import hexversion, maxsize
 from time import monotonic
 
 from .recipes import (
+    _marker,
+    _zip_equal,
+    UnequalIterablesError,
     consume,
     flatten,
     pairwise,
     powerset,
     take,
     unique_everseen,
+    all_equal,
 )
 
 __all__ = [
@@ -48,9 +52,9 @@ __all__ = [
     'chunked_even',
     'circular_shifts',
     'collapse',
-    'collate',
     'combination_index',
     'consecutive_groups',
+    'constrained_batches',
     'consumer',
     'count_cycle',
     'countable',
@@ -66,6 +70,7 @@ __all__ = [
     'first',
     'groupby_transform',
     'ichunked',
+    'iequals',
     'ilen',
     'interleave',
     'interleave_evenly',
@@ -76,6 +81,7 @@ __all__ = [
     'iterate',
     'last',
     'locate',
+    'longest_common_prefix',
     'lstrip',
     'make_decorator',
     'map_except',
@@ -132,9 +138,6 @@ __all__ = [
 ]
 
 
-_marker = object()
-
-
 def chunked(iterable, n, strict=False):
     """Break *iterable* into lists of length *n*:
 
@@ -409,44 +412,6 @@ class peekable:
         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
@@ -872,7 +837,9 @@ def windowed(seq, n, fillvalue=None, step=1):
             yield tuple(window)
 
     size = len(window)
-    if size < n:
+    if size == 0:
+        return
+    elif size < n:
         yield tuple(chain(window, repeat(fillvalue, n - size)))
     elif 0 < i < min(step, n):
         window += (fillvalue,) * i
@@ -1645,45 +1612,6 @@ def stagger(iterable, offsets=(-1, 0, 1), longest=False, fillvalue=None):
     )
 
 
-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):
-    # 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_equal(*iterables):
     """``zip`` the input *iterables* together, but raise
     ``UnequalIterablesError`` if they aren't all the same length.
@@ -1825,7 +1753,7 @@ def unzip(iterable):
     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
+    of the zipped iterable. The first element is used to determine the
     length of the remaining elements.
 
         >>> iterable = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
@@ -2375,6 +2303,16 @@ def locate(iterable, pred=bool, window_size=None):
     return compress(count(), starmap(pred, it))
 
 
+def longest_common_prefix(iterables):
+    """Yield elements of the longest common prefix amongst given *iterables*.
+
+    >>> ''.join(longest_common_prefix(['abcd', 'abc', 'abf']))
+    'ab'
+
+    """
+    return (c[0] for c in takewhile(all_equal, zip(*iterables)))
+
+
 def lstrip(iterable, pred):
     """Yield the items from *iterable*, but strip any from the beginning
     for which *pred* returns ``True``.
@@ -2683,7 +2621,7 @@ def difference(iterable, func=sub, *, initial=None):
     if initial is not None:
         first = []
 
-    return chain(first, starmap(func, zip(b, a)))
+    return chain(first, map(func, b, a))
 
 
 class SequenceView(Sequence):
@@ -3326,6 +3264,27 @@ def only(iterable, default=None, too_long=None):
     return first_value
 
 
+class _IChunk:
+    def __init__(self, iterable, n):
+        self._it = islice(iterable, n)
+        self._cache = deque()
+
+    def fill_cache(self):
+        self._cache.extend(self._it)
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        try:
+            return next(self._it)
+        except StopIteration:
+            if self._cache:
+                return self._cache.popleft()
+            else:
+                raise
+
+
 def ichunked(iterable, n):
     """Break *iterable* into sub-iterables with *n* elements each.
     :func:`ichunked` is like :func:`chunked`, but it yields iterables
@@ -3347,20 +3306,39 @@ def ichunked(iterable, n):
     [8, 9, 10, 11]
 
     """
-    source = iter(iterable)
-
+    source = peekable(iter(iterable))
+    ichunk_marker = object()
     while True:
         # Check to see whether we're at the end of the source iterable
-        item = next(source, _marker)
-        if item is _marker:
+        item = source.peek(ichunk_marker)
+        if item is ichunk_marker:
             return
 
-        # Clone the source and yield an n-length slice
-        source, it = tee(chain([item], source))
-        yield islice(it, n)
+        chunk = _IChunk(source, n)
+        yield chunk
+
+        # Advance the source iterable and fill previous chunk's cache
+        chunk.fill_cache()
+
+
+def iequals(*iterables):
+    """Return ``True`` if all given *iterables* are equal to each other,
+    which means that they contain the same elements in the same order.
 
-        # Advance the source iterable
-        consume(source, n)
+    The function is useful for comparing iterables of different data types
+    or iterables that do not support equality checks.
+
+    >>> iequals("abc", ['a', 'b', 'c'], ('a', 'b', 'c'), iter("abc"))
+    True
+
+    >>> iequals("abc", "acb")
+    False
+
+    Not to be confused with :func:`all_equals`, which checks whether all
+    elements of iterable are equal to each other.
+
+    """
+    return all(map(all_equal, zip_longest(*iterables, fillvalue=object())))
 
 
 def distinct_combinations(iterable, r):
@@ -3655,7 +3633,9 @@ class callback_iter:
         self._aborted = False
         self._future = None
         self._wait_seconds = wait_seconds
-        self._executor = __import__("concurrent.futures").futures.ThreadPoolExecutor(max_workers=1)
+        # Lazily import concurrent.future
+        self._executor = __import__(
+        ).futures.__import__("concurrent.futures").futures.ThreadPoolExecutor(max_workers=1)
         self._iterator = self._reader()
 
     def __enter__(self):
@@ -3960,7 +3940,7 @@ def combination_index(element, iterable):
 
     n, _ = last(pool, default=(n, None))
 
-    # Python versiosn below 3.8 don't have math.comb
+    # Python versions below 3.8 don't have math.comb
     index = 1
     for i, j in enumerate(reversed(indexes), start=1):
         j = n - j
@@ -4113,7 +4093,7 @@ def zip_broadcast(*objects, scalar_types=(str, bytes), strict=False):
 
     If the *strict* keyword argument is ``True``, then
     ``UnequalIterablesError`` will be raised if any of the iterables have
-    different lengthss.
+    different lengths.
     """
 
     def is_scalar(obj):
@@ -4314,3 +4294,53 @@ def minmax(iterable_or_value, *others, key=None, default=_marker):
                 hi, hi_key = y, y_key
 
     return lo, hi
+
+
+def constrained_batches(
+    iterable, max_size, max_count=None, get_len=len, strict=True
+):
+    """Yield batches of items from *iterable* with a combined size limited by
+    *max_size*.
+
+    >>> iterable = [b'12345', b'123', b'12345678', b'1', b'1', b'12', b'1']
+    >>> list(constrained_batches(iterable, 10))
+    [(b'12345', b'123'), (b'12345678', b'1', b'1'), (b'12', b'1')]
+
+    If a *max_count* is supplied, the number of items per batch is also
+    limited:
+
+    >>> iterable = [b'12345', b'123', b'12345678', b'1', b'1', b'12', b'1']
+    >>> list(constrained_batches(iterable, 10, max_count = 2))
+    [(b'12345', b'123'), (b'12345678', b'1'), (b'1', b'12'), (b'1',)]
+
+    If a *get_len* function is supplied, use that instead of :func:`len` to
+    determine item size.
+
+    If *strict* is ``True``, raise ``ValueError`` if any single item is bigger
+    than *max_size*. Otherwise, allow single items to exceed *max_size*.
+    """
+    if max_size <= 0:
+        raise ValueError('maximum size must be greater than zero')
+
+    batch = []
+    batch_size = 0
+    batch_count = 0
+    for item in iterable:
+        item_len = get_len(item)
+        if strict and item_len > max_size:
+            raise ValueError('item size exceeds maximum size')
+
+        reached_count = batch_count == max_count
+        reached_size = item_len + batch_size > max_size
+        if batch_count and (reached_size or reached_count):
+            yield tuple(batch)
+            batch.clear()
+            batch_size = 0
+            batch_count = 0
+
+        batch.append(item)
+        batch_size += item_len
+        batch_count += 1
+
+    if batch:
+        yield tuple(batch)
index fe7d4bdd7a822c713142dca8a3f4289cca89ee07..1413fae72f51a9262374909d983ac586ee2e66e5 100644 (file)
@@ -72,7 +72,6 @@ class peekable(Generic[_T], Iterator[_T]):
     @overload
     def __getitem__(self, index: slice) -> List[_T]: ...
 
-def collate(*iterables: Iterable[_T], **kwargs: Any) -> Iterable[_T]: ...
 def consumer(func: _GenFn) -> _GenFn: ...
 def ilen(iterable: Iterable[object]) -> int: ...
 def iterate(func: Callable[[_T], _T], start: _T) -> Iterator[_T]: ...
@@ -179,7 +178,7 @@ def padded(
     iterable: Iterable[_T],
     *,
     n: Optional[int] = ...,
-    next_multiple: bool = ...
+    next_multiple: bool = ...,
 ) -> Iterator[Optional[_T]]: ...
 @overload
 def padded(
@@ -225,7 +224,7 @@ def zip_equal(
     __iter1: Iterable[_T],
     __iter2: Iterable[_T],
     __iter3: Iterable[_T],
-    *iterables: Iterable[_T]
+    *iterables: Iterable[_T],
 ) -> Iterator[Tuple[_T, ...]]: ...
 @overload
 def zip_offset(
@@ -233,7 +232,7 @@ def zip_offset(
     *,
     offsets: _SizedIterable[int],
     longest: bool = ...,
-    fillvalue: None = None
+    fillvalue: None = None,
 ) -> Iterator[Tuple[Optional[_T1]]]: ...
 @overload
 def zip_offset(
@@ -242,7 +241,7 @@ def zip_offset(
     *,
     offsets: _SizedIterable[int],
     longest: bool = ...,
-    fillvalue: None = None
+    fillvalue: None = None,
 ) -> Iterator[Tuple[Optional[_T1], Optional[_T2]]]: ...
 @overload
 def zip_offset(
@@ -252,7 +251,7 @@ def zip_offset(
     *iterables: Iterable[_T],
     offsets: _SizedIterable[int],
     longest: bool = ...,
-    fillvalue: None = None
+    fillvalue: None = None,
 ) -> Iterator[Tuple[Optional[_T], ...]]: ...
 @overload
 def zip_offset(
@@ -420,7 +419,7 @@ def difference(
     iterable: Iterable[_T],
     func: Callable[[_T, _T], _U] = ...,
     *,
-    initial: None = ...
+    initial: None = ...,
 ) -> Iterator[Union[_T, _U]]: ...
 @overload
 def difference(
@@ -529,12 +528,12 @@ def distinct_combinations(
 def filter_except(
     validator: Callable[[Any], object],
     iterable: Iterable[_T],
-    *exceptions: Type[BaseException]
+    *exceptions: Type[BaseException],
 ) -> Iterator[_T]: ...
 def map_except(
     function: Callable[[Any], _U],
     iterable: Iterable[_T],
-    *exceptions: Type[BaseException]
+    *exceptions: Type[BaseException],
 ) -> Iterator[_U]: ...
 def map_if(
     iterable: Iterable[Any],
@@ -610,7 +609,7 @@ def zip_broadcast(
     scalar_types: Union[
         type, Tuple[Union[type, Tuple[Any, ...]], ...], None
     ] = ...,
-    strict: bool = ...
+    strict: bool = ...,
 ) -> Iterable[Tuple[_T, ...]]: ...
 def unique_in_window(
     iterable: Iterable[_T], n: int, key: Optional[Callable[[_T], _U]] = ...
@@ -640,7 +639,7 @@ def minmax(
     iterable_or_value: Iterable[_SupportsLessThanT],
     *,
     key: None = None,
-    default: _U
+    default: _U,
 ) -> Union[_U, Tuple[_SupportsLessThanT, _SupportsLessThanT]]: ...
 @overload
 def minmax(
@@ -653,12 +652,23 @@ def minmax(
 def minmax(
     iterable_or_value: _SupportsLessThanT,
     __other: _SupportsLessThanT,
-    *others: _SupportsLessThanT
+    *others: _SupportsLessThanT,
 ) -> Tuple[_SupportsLessThanT, _SupportsLessThanT]: ...
 @overload
 def minmax(
     iterable_or_value: _T,
     __other: _T,
     *others: _T,
-    key: Callable[[_T], _SupportsLessThan]
+    key: Callable[[_T], _SupportsLessThan],
 ) -> Tuple[_T, _T]: ...
+def longest_common_prefix(
+    iterables: Iterable[Iterable[_T]],
+) -> Iterator[_T]: ...
+def iequals(*iterables: Iterable[object]) -> bool: ...
+def constrained_batches(
+    iterable: Iterable[object],
+    max_size: int,
+    max_count: Optional[int] = ...,
+    get_len: Callable[[_T], object] = ...,
+    strict: bool = ...,
+) -> Iterator[Tuple[_T]]: ...
index a2596423a4c3dbd15a357241477a0af0a531f9ec..8579620785fc3c5a0ed7a47a4f97dc52dced7e02 100644 (file)
@@ -7,11 +7,16 @@ Some backward-compatible usability improvements have been made.
 .. [1] http://docs.python.org/library/itertools.html#recipes
 
 """
-import warnings
+import math
+import operator
+
 from collections import deque
+from collections.abc import Sized
+from functools import reduce
 from itertools import (
     chain,
     combinations,
+    compress,
     count,
     cycle,
     groupby,
@@ -21,11 +26,11 @@ from itertools import (
     tee,
     zip_longest,
 )
-import operator
 from random import randrange, sample, choice
 
 __all__ = [
     'all_equal',
+    'batched',
     'before_and_after',
     'consume',
     'convolve',
@@ -41,6 +46,7 @@ __all__ = [
     'pad_none',
     'pairwise',
     'partition',
+    'polynomial_from_roots',
     'powerset',
     'prepend',
     'quantify',
@@ -50,7 +56,9 @@ __all__ = [
     'random_product',
     'repeatfunc',
     'roundrobin',
+    'sieve',
     'sliding_window',
+    'subslices',
     'tabulate',
     'tail',
     'take',
@@ -59,6 +67,8 @@ __all__ = [
     'unique_justseen',
 ]
 
+_marker = object()
+
 
 def take(n, iterable):
     """Return first *n* items of the iterable as a list.
@@ -102,7 +112,14 @@ def tail(n, iterable):
     ['E', 'F', 'G']
 
     """
-    return iter(deque(iterable, maxlen=n))
+    # If the given iterable has a length, then we can use islice to get its
+    # final elements. Note that if the iterable is not actually Iterable,
+    # either islice or deque will throw a TypeError. This is why we don't
+    # check if it is Iterable.
+    if isinstance(iterable, Sized):
+        yield from islice(iterable, max(0, len(iterable) - n), None)
+    else:
+        yield from iter(deque(iterable, maxlen=n))
 
 
 def consume(iterator, n=None):
@@ -284,20 +301,83 @@ else:
     pairwise.__doc__ = _pairwise.__doc__
 
 
-def grouper(iterable, n, fillvalue=None):
-    """Collect data into fixed-length chunks or blocks.
+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):
+    # 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)
 
-    >>> list(grouper('ABCDEFG', 3, 'x'))
+        # 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 grouper(iterable, n, incomplete='fill', fillvalue=None):
+    """Group elements from *iterable* into fixed-length groups of length *n*.
+
+    >>> list(grouper('ABCDEF', 3))
+    [('A', 'B', 'C'), ('D', 'E', 'F')]
+
+    The keyword arguments *incomplete* and *fillvalue* control what happens for
+    iterables whose length is not a multiple of *n*.
+
+    When *incomplete* is `'fill'`, the last group will contain instances of
+    *fillvalue*.
+
+    >>> list(grouper('ABCDEFG', 3, incomplete='fill', fillvalue='x'))
     [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')]
 
+    When *incomplete* is `'ignore'`, the last group will not be emitted.
+
+    >>> list(grouper('ABCDEFG', 3, incomplete='ignore', fillvalue='x'))
+    [('A', 'B', 'C'), ('D', 'E', 'F')]
+
+    When *incomplete* is `'strict'`, a subclass of `ValueError` will be raised.
+
+    >>> it = grouper('ABCDEFG', 3, incomplete='strict')
+    >>> list(it)  # doctest: +IGNORE_EXCEPTION_DETAIL
+    Traceback (most recent call last):
+    ...
+    UnequalIterablesError
+
     """
-    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)
+    if incomplete == 'fill':
+        return zip_longest(*args, fillvalue=fillvalue)
+    if incomplete == 'strict':
+        return _zip_equal(*args)
+    if incomplete == 'ignore':
+        return zip(*args)
+    else:
+        raise ValueError('Expected fill, strict, or ignore')
 
 
 def roundrobin(*iterables):
@@ -658,11 +738,12 @@ def before_and_after(predicate, it):
                 transition.append(elem)
                 return
 
-    def remainder_iterator():
-        yield from transition
-        yield from it
+    # Note: this is different from itertools recipes to allow nesting
+    # before_and_after remainders into before_and_after again. See tests
+    # for an example.
+    remainder_iterator = chain(transition, it)
 
-    return true_iterator(), remainder_iterator()
+    return true_iterator(), remainder_iterator
 
 
 def triplewise(iterable):
@@ -696,3 +777,65 @@ def sliding_window(iterable, n):
     for x in it:
         window.append(x)
         yield tuple(window)
+
+
+def subslices(iterable):
+    """Return all contiguous non-empty subslices of *iterable*.
+
+        >>> list(subslices('ABC'))
+        [['A'], ['A', 'B'], ['A', 'B', 'C'], ['B'], ['B', 'C'], ['C']]
+
+    This is similar to :func:`substrings`, but emits items in a different
+    order.
+    """
+    seq = list(iterable)
+    slices = starmap(slice, combinations(range(len(seq) + 1), 2))
+    return map(operator.getitem, repeat(seq), slices)
+
+
+def polynomial_from_roots(roots):
+    """Compute a polynomial's coefficients from its roots.
+
+    >>> roots = [5, -4, 3]  # (x - 5) * (x + 4) * (x - 3)
+    >>> polynomial_from_roots(roots)  # x^3 - 4 * x^2 - 17 * x + 60
+    [1, -4, -17, 60]
+    """
+    # Use math.prod for Python 3.8+,
+    prod = getattr(math, 'prod', lambda x: reduce(operator.mul, x, 1))
+    roots = list(map(operator.neg, roots))
+    return [
+        sum(map(prod, combinations(roots, k))) for k in range(len(roots) + 1)
+    ]
+
+
+def sieve(n):
+    """Yield the primes less than n.
+
+    >>> list(sieve(30))
+    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
+    """
+    isqrt = getattr(math, 'isqrt', lambda x: int(math.sqrt(x)))
+    limit = isqrt(n) + 1
+    data = bytearray([1]) * n
+    data[:2] = 0, 0
+    for p in compress(range(limit), data):
+        data[p + p : n : p] = bytearray(len(range(p + p, n, p)))
+
+    return compress(count(), data)
+
+
+def batched(iterable, n):
+    """Batch data into lists of length *n*. The last batch may be shorter.
+
+    >>> list(batched('ABCDEFG', 3))
+    [['A', 'B', 'C'], ['D', 'E', 'F'], ['G']]
+
+    This recipe is from the ``itertools`` docs. This library also provides
+    :func:`chunked`, which has a different implementation.
+    """
+    it = iter(iterable)
+    while True:
+        batch = list(islice(it, n))
+        if not batch:
+            break
+        yield batch
index 4648a41b5e51155d4db10cd5e221e8a7a9449201..29415c5a56a0bccac96abceb76927faee01494f3 100644 (file)
@@ -6,6 +6,7 @@ from typing import (
     Iterator,
     List,
     Optional,
+    Sequence,
     Tuple,
     TypeVar,
     Union,
@@ -39,21 +40,11 @@ def repeatfunc(
     func: Callable[..., _U], times: Optional[int] = ..., *args: Any
 ) -> Iterator[_U]: ...
 def pairwise(iterable: Iterable[_T]) -> Iterator[Tuple[_T, _T]]: ...
-@overload
 def grouper(
-    iterable: Iterable[_T], n: int
-) -> Iterator[Tuple[Optional[_T], ...]]: ...
-@overload
-def grouper(
-    iterable: Iterable[_T], n: int, fillvalue: _U
-) -> Iterator[Tuple[Union[_T, _U], ...]]: ...
-@overload
-def grouper(  # Deprecated interface
-    iterable: int, n: Iterable[_T]
-) -> Iterator[Tuple[Optional[_T], ...]]: ...
-@overload
-def grouper(  # Deprecated interface
-    iterable: int, n: Iterable[_T], fillvalue: _U
+    iterable: Iterable[_T],
+    n: int,
+    incomplete: str = ...,
+    fillvalue: _U = ...,
 ) -> Iterator[Tuple[Union[_T, _U], ...]]: ...
 def roundrobin(*iterables: Iterable[_T]) -> Iterator[_T]: ...
 def partition(
@@ -110,3 +101,10 @@ def triplewise(iterable: Iterable[_T]) -> Iterator[Tuple[_T, _T, _T]]: ...
 def sliding_window(
     iterable: Iterable[_T], n: int
 ) -> Iterator[Tuple[_T, ...]]: ...
+def subslices(iterable: Iterable[_T]) -> Iterator[List[_T]]: ...
+def polynomial_from_roots(roots: Sequence[int]) -> List[int]: ...
+def sieve(n: int) -> Iterator[int]: ...
+def batched(
+    iterable: Iterable[_T],
+    n: int,
+) -> Iterator[List[_T]]: ...
index 97cace1022fe4c138f5549ab48ca59afb96b3895..77b1ed967794eea571c637864688eca9ef88f8df 100644 (file)
@@ -9,17 +9,17 @@ packaging-21.3.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9
 packaging-21.3.dist-info/top_level.txt,sha256=zFdHrhWnPslzsiP455HutQsqPB6v0KCtNUMtUtrefDw,10\r
 packaging/__about__.py,sha256=ugASIO2w1oUyH8_COqQ2X_s0rDhjbhQC3yJocD03h2c,661\r
 packaging/__init__.py,sha256=b9Kk5MF7KxhhLgcDmiUWukN-LatWFxPdNug0joPhHSk,497\r
-packaging/__pycache__/__about__.cpython-310.pyc,,\r
-packaging/__pycache__/__init__.cpython-310.pyc,,\r
-packaging/__pycache__/_manylinux.cpython-310.pyc,,\r
-packaging/__pycache__/_musllinux.cpython-310.pyc,,\r
-packaging/__pycache__/_structures.cpython-310.pyc,,\r
-packaging/__pycache__/markers.cpython-310.pyc,,\r
-packaging/__pycache__/requirements.cpython-310.pyc,,\r
-packaging/__pycache__/specifiers.cpython-310.pyc,,\r
-packaging/__pycache__/tags.cpython-310.pyc,,\r
-packaging/__pycache__/utils.cpython-310.pyc,,\r
-packaging/__pycache__/version.cpython-310.pyc,,\r
+packaging/__pycache__/__about__.cpython-311.pyc,,\r
+packaging/__pycache__/__init__.cpython-311.pyc,,\r
+packaging/__pycache__/_manylinux.cpython-311.pyc,,\r
+packaging/__pycache__/_musllinux.cpython-311.pyc,,\r
+packaging/__pycache__/_structures.cpython-311.pyc,,\r
+packaging/__pycache__/markers.cpython-311.pyc,,\r
+packaging/__pycache__/requirements.cpython-311.pyc,,\r
+packaging/__pycache__/specifiers.cpython-311.pyc,,\r
+packaging/__pycache__/tags.cpython-311.pyc,,\r
+packaging/__pycache__/utils.cpython-311.pyc,,\r
+packaging/__pycache__/version.cpython-311.pyc,,\r
 packaging/_manylinux.py,sha256=XcbiXB-qcjv3bcohp6N98TMpOP4_j3m-iOA8ptK2GWY,11488\r
 packaging/_musllinux.py,sha256=_KGgY_qc7vhMGpoqss25n2hiLCNKRtvz9mCrS7gkqyc,4378\r
 packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431\r
diff --git a/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/INSTALLER b/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/INSTALLER
new file mode 100644 (file)
index 0000000..a1b589e
--- /dev/null
@@ -0,0 +1 @@
+pip
diff --git a/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/METADATA b/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/METADATA
new file mode 100644 (file)
index 0000000..608afde
--- /dev/null
@@ -0,0 +1,253 @@
+Metadata-Version: 2.1
+Name: platformdirs
+Version: 2.6.2
+Summary: A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir".
+Project-URL: Documentation, https://platformdirs.readthedocs.io
+Project-URL: Homepage, https://github.com/platformdirs/platformdirs
+Project-URL: Source, https://github.com/platformdirs/platformdirs
+Project-URL: Tracker, https://github.com/platformdirs/platformdirs/issues
+Maintainer-email: Bernát Gábor <gaborjbernat@gmail.com>, Julian Berman <Julian@GrayVines.com>, Ofek Lev <oss@ofek.dev>, Ronny Pfannschmidt <opensource@ronnypfannschmidt.de>
+License-File: LICENSE
+Keywords: application,cache,directory,log,user
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+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 :: 3.11
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Requires-Python: >=3.7
+Requires-Dist: typing-extensions>=4.4; python_version < '3.8'
+Provides-Extra: docs
+Requires-Dist: furo>=2022.12.7; extra == 'docs'
+Requires-Dist: proselint>=0.13; extra == 'docs'
+Requires-Dist: sphinx-autodoc-typehints>=1.19.5; extra == 'docs'
+Requires-Dist: sphinx>=5.3; extra == 'docs'
+Provides-Extra: test
+Requires-Dist: appdirs==1.4.4; extra == 'test'
+Requires-Dist: covdefaults>=2.2.2; extra == 'test'
+Requires-Dist: pytest-cov>=4; extra == 'test'
+Requires-Dist: pytest-mock>=3.10; extra == 'test'
+Requires-Dist: pytest>=7.2; extra == 'test'
+Description-Content-Type: text/x-rst
+
+The problem
+===========
+
+.. image:: https://github.com/platformdirs/platformdirs/workflows/Test/badge.svg
+   :target: https://github.com/platformdirs/platformdirs/actions?query=workflow%3ATest
+
+When writing desktop application, finding the right location to store user data
+and configuration varies per platform. Even for single-platform apps, there
+may by plenty of nuances in figuring out the right location.
+
+For example, if running on macOS, you should use::
+
+    ~/Library/Application Support/<AppName>
+
+If on Windows (at least English Win XP) that should be::
+
+    C:\Documents and Settings\<User>\Application Data\Local Settings\<AppAuthor>\<AppName>
+
+or possibly::
+
+    C:\Documents and Settings\<User>\Application Data\<AppAuthor>\<AppName>
+
+for `roaming profiles <https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-vista/cc766489(v=ws.10)>`_ but that is another story.
+
+On Linux (and other Unices), according to the `XDG Basedir Spec`_, it should be::
+
+    ~/.local/share/<AppName>
+
+.. _XDG Basedir Spec: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
+
+``platformdirs`` to the rescue
+==============================
+
+This kind of thing is what the ``platformdirs`` package is for.
+``platformdirs`` will help you choose an appropriate:
+
+- user data dir (``user_data_dir``)
+- user config dir (``user_config_dir``)
+- user cache dir (``user_cache_dir``)
+- site data dir (``site_data_dir``)
+- site config dir (``site_config_dir``)
+- user log dir (``user_log_dir``)
+- user documents dir (``user_documents_dir``)
+- user runtime dir (``user_runtime_dir``)
+
+And also:
+
+- Is slightly opinionated on the directory names used. Look for "OPINION" in
+  documentation and code for when an opinion is being applied.
+
+Example output
+==============
+
+On macOS:
+
+.. code-block:: pycon
+
+    >>> from platformdirs import *
+    >>> appname = "SuperApp"
+    >>> appauthor = "Acme"
+    >>> user_data_dir(appname, appauthor)
+    '/Users/trentm/Library/Application Support/SuperApp'
+    >>> site_data_dir(appname, appauthor)
+    '/Library/Application Support/SuperApp'
+    >>> user_cache_dir(appname, appauthor)
+    '/Users/trentm/Library/Caches/SuperApp'
+    >>> user_log_dir(appname, appauthor)
+    '/Users/trentm/Library/Logs/SuperApp'
+    >>> user_documents_dir()
+    '/Users/trentm/Documents'
+    >>> user_runtime_dir(appname, appauthor)
+    '/Users/trentm/Library/Caches/TemporaryItems/SuperApp'
+
+On Windows 7:
+
+.. code-block:: pycon
+
+    >>> from platformdirs import *
+    >>> appname = "SuperApp"
+    >>> appauthor = "Acme"
+    >>> user_data_dir(appname, appauthor)
+    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp'
+    >>> user_data_dir(appname, appauthor, roaming=True)
+    'C:\\Users\\trentm\\AppData\\Roaming\\Acme\\SuperApp'
+    >>> user_cache_dir(appname, appauthor)
+    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Cache'
+    >>> user_log_dir(appname, appauthor)
+    'C:\\Users\\trentm\\AppData\\Local\\Acme\\SuperApp\\Logs'
+    >>> user_documents_dir()
+    'C:\\Users\\trentm\\Documents'
+    >>> user_runtime_dir(appname, appauthor)
+    'C:\\Users\\trentm\\AppData\\Local\\Temp\\Acme\\SuperApp'
+
+On Linux:
+
+.. code-block:: pycon
+
+    >>> from platformdirs import *
+    >>> appname = "SuperApp"
+    >>> appauthor = "Acme"
+    >>> user_data_dir(appname, appauthor)
+    '/home/trentm/.local/share/SuperApp'
+    >>> site_data_dir(appname, appauthor)
+    '/usr/local/share/SuperApp'
+    >>> site_data_dir(appname, appauthor, multipath=True)
+    '/usr/local/share/SuperApp:/usr/share/SuperApp'
+    >>> user_cache_dir(appname, appauthor)
+    '/home/trentm/.cache/SuperApp'
+    >>> user_log_dir(appname, appauthor)
+    '/home/trentm/.cache/SuperApp/log'
+    >>> user_config_dir(appname)
+    '/home/trentm/.config/SuperApp'
+    >>> user_documents_dir()
+    '/home/trentm/Documents'
+    >>> user_runtime_dir(appname, appauthor)
+    '/run/user/{os.getuid()}/SuperApp'
+    >>> site_config_dir(appname)
+    '/etc/xdg/SuperApp'
+    >>> os.environ["XDG_CONFIG_DIRS"] = "/etc:/usr/local/etc"
+    >>> site_config_dir(appname, multipath=True)
+    '/etc/SuperApp:/usr/local/etc/SuperApp'
+
+On Android::
+
+    >>> from platformdirs import *
+    >>> appname = "SuperApp"
+    >>> appauthor = "Acme"
+    >>> user_data_dir(appname, appauthor)
+    '/data/data/com.myApp/files/SuperApp'
+    >>> user_cache_dir(appname, appauthor)
+    '/data/data/com.myApp/cache/SuperApp'
+    >>> user_log_dir(appname, appauthor)
+    '/data/data/com.myApp/cache/SuperApp/log'
+    >>> user_config_dir(appname)
+    '/data/data/com.myApp/shared_prefs/SuperApp'
+    >>> user_documents_dir()
+    '/storage/emulated/0/Documents'
+    >>> user_runtime_dir(appname, appauthor)
+    '/data/data/com.myApp/cache/SuperApp/tmp'
+
+Note: Some android apps like Termux and Pydroid are used as shells. These
+apps are used by the end user to emulate Linux environment. Presence of
+``SHELL`` environment variable is used by Platformdirs to differentiate
+between general android apps and android apps used as shells. Shell android
+apps also support ``XDG_*`` environment variables.
+
+
+``PlatformDirs`` for convenience
+================================
+
+.. code-block:: pycon
+
+    >>> from platformdirs import PlatformDirs
+    >>> dirs = PlatformDirs("SuperApp", "Acme")
+    >>> dirs.user_data_dir
+    '/Users/trentm/Library/Application Support/SuperApp'
+    >>> dirs.site_data_dir
+    '/Library/Application Support/SuperApp'
+    >>> dirs.user_cache_dir
+    '/Users/trentm/Library/Caches/SuperApp'
+    >>> dirs.user_log_dir
+    '/Users/trentm/Library/Logs/SuperApp'
+    >>> dirs.user_documents_dir
+    '/Users/trentm/Documents'
+    >>> dirs.user_runtime_dir
+    '/Users/trentm/Library/Caches/TemporaryItems/SuperApp'
+
+Per-version isolation
+=====================
+
+If you have multiple versions of your app in use that you want to be
+able to run side-by-side, then you may want version-isolation for these
+dirs::
+
+    >>> from platformdirs import PlatformDirs
+    >>> dirs = PlatformDirs("SuperApp", "Acme", version="1.0")
+    >>> dirs.user_data_dir
+    '/Users/trentm/Library/Application Support/SuperApp/1.0'
+    >>> dirs.site_data_dir
+    '/Library/Application Support/SuperApp/1.0'
+    >>> dirs.user_cache_dir
+    '/Users/trentm/Library/Caches/SuperApp/1.0'
+    >>> dirs.user_log_dir
+    '/Users/trentm/Library/Logs/SuperApp/1.0'
+    >>> dirs.user_documents_dir
+    '/Users/trentm/Documents'
+    >>> dirs.user_runtime_dir
+    '/Users/trentm/Library/Caches/TemporaryItems/SuperApp/1.0'
+
+Be wary of using this for configuration files though; you'll need to handle
+migrating configuration files manually.
+
+Why this Fork?
+==============
+
+This repository is a friendly fork of the wonderful work started by
+`ActiveState <https://github.com/ActiveState/appdirs>`_ who created
+``appdirs``, this package's ancestor.
+
+Maintaining an open source project is no easy task, particularly
+from within an organization, and the Python community is indebted
+to ``appdirs`` (and to Trent Mick and Jeff Rouse in particular) for
+creating an incredibly useful simple module, as evidenced by the wide
+number of users it has attracted over the years.
+
+Nonetheless, given the number of long-standing open issues
+and pull requests, and no clear path towards `ensuring
+that maintenance of the package would continue or grow
+<https://github.com/ActiveState/appdirs/issues/79>`_, this fork was
+created.
+
+Contributions are most welcome.
diff --git a/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/RECORD b/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/RECORD
new file mode 100644 (file)
index 0000000..843a5ba
--- /dev/null
@@ -0,0 +1,23 @@
+platformdirs-2.6.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+platformdirs-2.6.2.dist-info/METADATA,sha256=rDoFsb9-2tVym02IIeYCoKgGaCpY2v8xw8WWXywxhIM,9502\r
+platformdirs-2.6.2.dist-info/RECORD,,\r
+platformdirs-2.6.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+platformdirs-2.6.2.dist-info/WHEEL,sha256=NaLmgHHW_f9jTvv_wRh9vcK7c7EK9o5fwsIXMOzoGgM,87\r
+platformdirs-2.6.2.dist-info/licenses/LICENSE,sha256=KeD9YukphQ6G6yjD_czwzv30-pSHkBHP-z0NS-1tTbY,1089\r
+platformdirs/__init__.py,sha256=td0a-fHENmnG8ess2WRoysKv9ud5j6TQ-p_iUM_uE18,12864\r
+platformdirs/__main__.py,sha256=VsC0t5m-6f0YVr96PVks93G3EDF8MSNY4KpUMvPahDA,1164\r
+platformdirs/__pycache__/__init__.cpython-311.pyc,,\r
+platformdirs/__pycache__/__main__.cpython-311.pyc,,\r
+platformdirs/__pycache__/android.cpython-311.pyc,,\r
+platformdirs/__pycache__/api.cpython-311.pyc,,\r
+platformdirs/__pycache__/macos.cpython-311.pyc,,\r
+platformdirs/__pycache__/unix.cpython-311.pyc,,\r
+platformdirs/__pycache__/version.cpython-311.pyc,,\r
+platformdirs/__pycache__/windows.cpython-311.pyc,,\r
+platformdirs/android.py,sha256=GKizhyS7ESRiU67u8UnBJLm46goau9937EchXWbPBlk,4068\r
+platformdirs/api.py,sha256=MXKHXOL3eh_-trSok-JUTjAR_zjmmKF3rjREVABjP8s,4910\r
+platformdirs/macos.py,sha256=-3UXQewbT0yMhMdkzRXfXGAntmLIH7Qt4a9Hlf8I5_Y,2655\r
+platformdirs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+platformdirs/unix.py,sha256=P-WQjSSieE38DXjMDa1t4XHnKJQ5idEaKT0PyXwm8KQ,6911\r
+platformdirs/version.py,sha256=qaN-fw_htIgKUVXoAuAEVgKxQu3tZ9qE2eiKkWIS7LA,160\r
+platformdirs/windows.py,sha256=LOrXLgI0CjQldDo2zhOZYGYZ6g4e_cJOCB_pF9aMRWQ,6596\r
diff --git a/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/REQUESTED b/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/REQUESTED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/WHEEL b/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/WHEEL
new file mode 100644 (file)
index 0000000..6d80365
--- /dev/null
@@ -0,0 +1,4 @@
+Wheel-Version: 1.0
+Generator: hatchling 1.11.1
+Root-Is-Purelib: true
+Tag: py3-none-any
diff --git a/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/licenses/LICENSE b/pkg_resources/_vendor/platformdirs-2.6.2.dist-info/licenses/LICENSE
new file mode 100644 (file)
index 0000000..f35fed9
--- /dev/null
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2010-202x The platformdirs developers
+
+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.
diff --git a/pkg_resources/_vendor/platformdirs/__init__.py b/pkg_resources/_vendor/platformdirs/__init__.py
new file mode 100644 (file)
index 0000000..aef2821
--- /dev/null
@@ -0,0 +1,342 @@
+"""
+Utilities for determining application-specific dirs. See <https://github.com/platformdirs/platformdirs> for details and
+usage.
+"""
+from __future__ import annotations
+
+import os
+import sys
+from pathlib import Path
+
+if sys.version_info >= (3, 8):  # pragma: no cover (py38+)
+    from typing import Literal
+else:  # pragma: no cover (py38+)
+    from ..typing_extensions import Literal
+
+from .api import PlatformDirsABC
+from .version import __version__
+from .version import __version_tuple__ as __version_info__
+
+
+def _set_platform_dir_class() -> type[PlatformDirsABC]:
+    if sys.platform == "win32":
+        from .windows import Windows as Result
+    elif sys.platform == "darwin":
+        from .macos import MacOS as Result
+    else:
+        from .unix import Unix as Result
+
+    if os.getenv("ANDROID_DATA") == "/data" and os.getenv("ANDROID_ROOT") == "/system":
+
+        if os.getenv("SHELL") or os.getenv("PREFIX"):
+            return Result
+
+        from .android import _android_folder
+
+        if _android_folder() is not None:
+            from .android import Android
+
+            return Android  # return to avoid redefinition of result
+
+    return Result
+
+
+PlatformDirs = _set_platform_dir_class()  #: Currently active platform
+AppDirs = PlatformDirs  #: Backwards compatibility with appdirs
+
+
+def user_data_dir(
+    appname: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    roaming: bool = False,
+) -> str:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.version>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    multipath: bool = False,
+) -> str:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
+    :returns: data directory shared by users
+    """
+    return PlatformDirs(appname=appname, appauthor=appauthor, version=version, multipath=multipath).site_data_dir
+
+
+def user_config_dir(
+    appname: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    roaming: bool = False,
+) -> str:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.version>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    multipath: bool = False,
+) -> str:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    opinion: bool = True,
+) -> str:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    roaming: bool = False,
+) -> str:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.version>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    opinion: bool = True,
+) -> str:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    opinion: bool = True,
+) -> str:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    roaming: bool = False,
+) -> Path:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.version>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    multipath: bool = False,
+) -> Path:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param multipath: See `multipath <platformdirs.api.PlatformDirsABC.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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    roaming: bool = False,
+) -> Path:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.version>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    multipath: bool = False,
+) -> Path:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    opinion: bool = True,
+) -> Path:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    roaming: bool = False,
+) -> Path:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param roaming: See `roaming <platformdirs.api.PlatformDirsABC.version>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    opinion: bool = True,
+) -> Path:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
+    :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: str | None = None,
+    appauthor: str | None | Literal[False] = None,
+    version: str | None = None,
+    opinion: bool = True,
+) -> Path:
+    """
+    :param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
+    :param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
+    :param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
+    :param opinion: See `opinion <platformdirs.api.PlatformDirsABC.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",
+]
diff --git a/pkg_resources/_vendor/platformdirs/__main__.py b/pkg_resources/_vendor/platformdirs/__main__.py
new file mode 100644 (file)
index 0000000..0fc1edd
--- /dev/null
@@ -0,0 +1,46 @@
+from __future__ import annotations
+
+from 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()
diff --git a/pkg_resources/_vendor/platformdirs/android.py b/pkg_resources/_vendor/platformdirs/android.py
new file mode 100644 (file)
index 0000000..eda8093
--- /dev/null
@@ -0,0 +1,120 @@
+from __future__ import annotations
+
+import os
+import re
+import sys
+from functools import lru_cache
+from typing import cast
+
+from .api import PlatformDirsABC
+
+
+class Android(PlatformDirsABC):
+    """
+    Follows the guidance `from here <https://android.stackexchange.com/a/216132>`_. Makes use of the
+    `appname <platformdirs.api.PlatformDirsABC.appname>` and
+    `version <platformdirs.api.PlatformDirsABC.version>`.
+    """
+
+    @property
+    def user_data_dir(self) -> str:
+        """:return: data directory tied to the user, e.g. ``/data/user/<userid>/<packagename>/files/<AppName>``"""
+        return self._append_app_name_and_version(cast(str, _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/<userid>/<packagename>/shared_prefs/<AppName>``
+        """
+        return self._append_app_name_and_version(cast(str, _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/<userid>/<packagename>/cache/<AppName>``"""
+        return self._append_app_name_and_version(cast(str, _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/<userid>/<packagename>/cache/<AppName>/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/<userid>/<packagename>/cache/<AppName>/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 | None:
+    """:return: base folder for the Android OS or None if cannot be found"""
+    try:
+        # First try to get path to android app via pyjnius
+        from jnius import autoclass
+
+        Context = autoclass("android.content.Context")  # noqa: N806
+        result: str | None = 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:
+            result = None
+    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
+
+        Context = autoclass("android.content.Context")  # noqa: N806
+        Environment = autoclass("android.os.Environment")  # noqa: N806
+        documents_dir: str = Context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath()
+    except Exception:
+        documents_dir = "/storage/emulated/0/Documents"
+
+    return documents_dir
+
+
+__all__ = [
+    "Android",
+]
diff --git a/pkg_resources/_vendor/platformdirs/api.py b/pkg_resources/_vendor/platformdirs/api.py
new file mode 100644 (file)
index 0000000..6f6e2c2
--- /dev/null
@@ -0,0 +1,156 @@
+from __future__ import annotations
+
+import os
+import sys
+from abc import ABC, abstractmethod
+from pathlib import Path
+
+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: str | None = None,
+        appauthor: str | None | Literal[False] = None,
+        version: str | None = 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 ``<major>.<minor>``.
+        """
+        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 <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>`_).
+        """
+        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)
diff --git a/pkg_resources/_vendor/platformdirs/macos.py b/pkg_resources/_vendor/platformdirs/macos.py
new file mode 100644 (file)
index 0000000..a01337c
--- /dev/null
@@ -0,0 +1,64 @@
+from __future__ import annotations
+
+import os
+
+from .api import PlatformDirsABC
+
+
+class MacOS(PlatformDirsABC):
+    """
+    Platform directories for the macOS operating system. Follows the guidance from `Apple documentation
+    <https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html>`_.
+    Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>` and
+    `version <platformdirs.api.PlatformDirsABC.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",
+]
diff --git a/pkg_resources/_vendor/platformdirs/py.typed b/pkg_resources/_vendor/platformdirs/py.typed
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pkg_resources/_vendor/platformdirs/unix.py b/pkg_resources/_vendor/platformdirs/unix.py
new file mode 100644 (file)
index 0000000..9aca5a0
--- /dev/null
@@ -0,0 +1,181 @@
+from __future__ import annotations
+
+import os
+import sys
+from configparser import ConfigParser
+from pathlib import Path
+
+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 <https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_. 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 <platformdirs.api.PlatformDirsABC.appname>`,
+    `version <platformdirs.api.PlatformDirsABC.version>`,
+    `multipath <platformdirs.api.PlatformDirsABC.multipath>`,
+    `opinion <platformdirs.api.PlatformDirsABC.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 <platformdirs.api.PlatformDirsABC.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 <platformdirs.api.PlatformDirsABC.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_state_dir` if not opinionated else ``log`` in it
+        """
+        path = self.user_state_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) -> str | None:
+    """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",
+]
diff --git a/pkg_resources/_vendor/platformdirs/version.py b/pkg_resources/_vendor/platformdirs/version.py
new file mode 100644 (file)
index 0000000..9f6eb98
--- /dev/null
@@ -0,0 +1,4 @@
+# file generated by setuptools_scm
+# don't change, don't track in version control
+__version__ = version = '2.6.2'
+__version_tuple__ = version_tuple = (2, 6, 2)
diff --git a/pkg_resources/_vendor/platformdirs/windows.py b/pkg_resources/_vendor/platformdirs/windows.py
new file mode 100644 (file)
index 0000000..d5c27b3
--- /dev/null
@@ -0,0 +1,184 @@
+from __future__ import annotations
+
+import ctypes
+import os
+import sys
+from functools import lru_cache
+from typing import Callable
+
+from .api import PlatformDirsABC
+
+
+class Windows(PlatformDirsABC):
+    """`MSDN on where to store app data files
+    <http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120>`_.
+    Makes use of the
+    `appname <platformdirs.api.PlatformDirsABC.appname>`,
+    `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`,
+    `version <platformdirs.api.PlatformDirsABC.version>`,
+    `roaming <platformdirs.api.PlatformDirsABC.roaming>`,
+    `opinion <platformdirs.api.PlatformDirsABC.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: str | None = 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}")
+    if sys.platform != "win32":  # only needed for mypy type checker to know that this code runs only on Windows
+        raise NotImplementedError
+    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",
+]
diff --git a/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/INSTALLER b/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/INSTALLER
deleted file mode 100644 (file)
index a1b589e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pip
diff --git a/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/LICENSE b/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/LICENSE
deleted file mode 100644 (file)
index 1bf9852..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-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.
diff --git a/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/METADATA b/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/METADATA
deleted file mode 100644 (file)
index d6c8e9b..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-Metadata-Version: 2.1
-Name: pyparsing
-Version: 3.0.8
-Summary: pyparsing module - Classes and methods to define and execute parsing grammars
-Author-email: Paul McGuire <ptmcg.gm+pyparsing@gmail.com>
-Requires-Python: >=3.6.8
-Description-Content-Type: text/x-rst
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: Information Technology
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 3
-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 :: 3 :: Only
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
-Classifier: Typing :: Typed
-Requires-Dist: railroad-diagrams ; extra == "diagrams"
-Requires-Dist: jinja2 ; extra == "diagrams"
-Project-URL: Homepage, https://github.com/pyparsing/pyparsing/
-Provides-Extra: diagrams
-
-PyParsing -- A Python Parsing Module
-====================================
-
-|Build Status| |Coverage|
-
-Introduction
-============
-
-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. The pyparsing module provides a library of
-classes that client code uses to construct the grammar directly in
-Python code.
-
-*[Since first writing this description of pyparsing in late 2003, this
-technique for developing parsers has become more widespread, under the
-name Parsing Expression Grammars - PEGs. See more information on PEGs*
-`here <https://en.wikipedia.org/wiki/Parsing_expression_grammar>`__
-*.]*
-
-Here is a program to parse ``"Hello, World!"`` (or any greeting of the form
-``"salutation, addressee!"``):
-
-.. code:: python
-
-    from pyparsing import Word, alphas
-    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 '^' operator
-definitions.
-
-The parsed results returned from ``parseString()`` is a collection of type
-``ParseResults``, which 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
-
-The examples directory includes a simple SQL parser, simple CORBA IDL
-parser, a config file parser, a chemical formula parser, and a four-
-function algebraic notation parser, among many others.
-
-Documentation
-=============
-
-There are many examples in the online docstrings of the classes
-and methods in pyparsing. You can find them compiled into `online docs <https://pyparsing-docs.readthedocs.io/en/latest/>`__. Additional
-documentation resources and project info are listed in the online
-`GitHub wiki <https://github.com/pyparsing/pyparsing/wiki>`__. An
-entire directory of examples can be found `here <https://github.com/pyparsing/pyparsing/tree/master/examples>`__.
-
-License
-=======
-
-MIT License. See header of the `pyparsing.py <https://github.com/pyparsing/pyparsing/blob/master/pyparsing/__init__.py#L1-L23>`__ file.
-
-History
-=======
-
-See `CHANGES <https://github.com/pyparsing/pyparsing/blob/master/CHANGES>`__ file.
-
-.. |Build Status| image:: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml/badge.svg
-   :target: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml
-.. |Coverage| image:: https://codecov.io/gh/pyparsing/pyparsing/branch/master/graph/badge.svg
-  :target: https://codecov.io/gh/pyparsing/pyparsing
-
diff --git a/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/RECORD b/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/RECORD
deleted file mode 100644 (file)
index 72947b0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-pyparsing-3.0.8.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-pyparsing-3.0.8.dist-info/LICENSE,sha256=ENUSChaAWAT_2otojCIL-06POXQbVzIGBNRVowngGXI,1023
-pyparsing-3.0.8.dist-info/METADATA,sha256=dEvZBGz3Owm5LYEaqDeKb6e3ZgOrF48WaCI_PG1n5BE,4207
-pyparsing-3.0.8.dist-info/RECORD,,
-pyparsing-3.0.8.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-pyparsing-3.0.8.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81
-pyparsing/__init__.py,sha256=EMa1HCuq9HJhEDR8fUThu2gD0nl6Cs8FFEWZZ0eRCM8,9159
-pyparsing/__pycache__/__init__.cpython-38.pyc,,
-pyparsing/__pycache__/actions.cpython-38.pyc,,
-pyparsing/__pycache__/common.cpython-38.pyc,,
-pyparsing/__pycache__/core.cpython-38.pyc,,
-pyparsing/__pycache__/exceptions.cpython-38.pyc,,
-pyparsing/__pycache__/helpers.cpython-38.pyc,,
-pyparsing/__pycache__/results.cpython-38.pyc,,
-pyparsing/__pycache__/testing.cpython-38.pyc,,
-pyparsing/__pycache__/unicode.cpython-38.pyc,,
-pyparsing/__pycache__/util.cpython-38.pyc,,
-pyparsing/actions.py,sha256=60v7mETOBzc01YPH_qQD5isavgcSJpAfIKpzgjM3vaU,6429
-pyparsing/common.py,sha256=lFL97ooIeR75CmW5hjURZqwDCTgruqltcTCZ-ulLO2Q,12936
-pyparsing/core.py,sha256=zBzGw5vcSd58pB1QkYpY6O_XCcHVKX_nH5xglRx_L-M,213278
-pyparsing/diagram/__init__.py,sha256=oU_UEh6O5voKSFjUdq462_mpmURLOfUIsmWvxi1qgTQ,23003
-pyparsing/diagram/__pycache__/__init__.cpython-38.pyc,,
-pyparsing/diagram/template.jinja2,sha256=SfQ8SLktSBqI5W1DGcUVH1vdflRD6x2sQBApxrcNg7s,589
-pyparsing/exceptions.py,sha256=H4D9gqMavqmAFSsdrU_J6bO-jA-T-A7yvtXWZpooIUA,9030
-pyparsing/helpers.py,sha256=EyjpgDOc3ivwRsU4VXxAWdgIs5gaqMDaLWcwRh5mqxc,39007
-pyparsing/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-pyparsing/results.py,sha256=Hd6FAAh5sF8zGXpwsamdVqFUblIwyQf0FH0t7FCb1OY,25353
-pyparsing/testing.py,sha256=szs8AKZREZMhL0y0vsMfaTVAnpqPHetg6VKJBNmc4QY,13388
-pyparsing/unicode.py,sha256=IR-ioeGY29cZ49tG8Ts7ITPWWNP5G2DcZs58oa8zn44,10381
-pyparsing/util.py,sha256=kq772O5YSeXOSdP-M31EWpbH_ayj7BMHImBYo9xPD5M,6805
diff --git a/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/REQUESTED b/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/REQUESTED
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/WHEEL b/pkg_resources/_vendor/pyparsing-3.0.8.dist-info/WHEEL
deleted file mode 100644 (file)
index c727d14..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Wheel-Version: 1.0
-Generator: flit 3.6.0
-Root-Is-Purelib: true
-Tag: py3-none-any
index 7a4e49abebe07adc13fba36dfc8e1c1c84edd7f5..b07b9bd09e11ee442a09a664515e2f135a3d9079 100644 (file)
@@ -1,29 +1,29 @@
-pyparsing-3.0.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-pyparsing-3.0.9.dist-info/LICENSE,sha256=ENUSChaAWAT_2otojCIL-06POXQbVzIGBNRVowngGXI,1023
-pyparsing-3.0.9.dist-info/METADATA,sha256=h_fpm9rwvgZsE8v5YNF4IAo-IpaFWCOfUEm5MMByIiM,4207
-pyparsing-3.0.9.dist-info/RECORD,,
-pyparsing-3.0.9.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-pyparsing-3.0.9.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81
-pyparsing/__init__.py,sha256=52QH3lgPbJhba0estckoGPHRH8JvQSSCGoWiEn2m0bU,9159
-pyparsing/__pycache__/__init__.cpython-38.pyc,,
-pyparsing/__pycache__/actions.cpython-38.pyc,,
-pyparsing/__pycache__/common.cpython-38.pyc,,
-pyparsing/__pycache__/core.cpython-38.pyc,,
-pyparsing/__pycache__/exceptions.cpython-38.pyc,,
-pyparsing/__pycache__/helpers.cpython-38.pyc,,
-pyparsing/__pycache__/results.cpython-38.pyc,,
-pyparsing/__pycache__/testing.cpython-38.pyc,,
-pyparsing/__pycache__/unicode.cpython-38.pyc,,
-pyparsing/__pycache__/util.cpython-38.pyc,,
-pyparsing/actions.py,sha256=wU9i32e0y1ymxKE3OUwSHO-SFIrt1h_wv6Ws0GQjpNU,6426
-pyparsing/common.py,sha256=lFL97ooIeR75CmW5hjURZqwDCTgruqltcTCZ-ulLO2Q,12936
-pyparsing/core.py,sha256=u8GptQE_H6wMkl8OZhxeK1aAPIDXXNgwdShORBwBVS4,213310
-pyparsing/diagram/__init__.py,sha256=f_EfxahqrdkRVahmTwLJXkZ9EEDKNd-O7lBbpJYlE1g,23668
-pyparsing/diagram/__pycache__/__init__.cpython-38.pyc,,
-pyparsing/exceptions.py,sha256=3LbSafD32NYb1Tzt85GHNkhEAU1eZkTtNSk24cPMemo,9023
-pyparsing/helpers.py,sha256=QpUOjW0-psvueMwWb9bQpU2noqKCv98_wnw1VSzSdVo,39129
-pyparsing/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-pyparsing/results.py,sha256=HgNvWVXBdQP-Q6PtJfoCEeOJk2nwEvG-2KVKC5sGA30,25341
-pyparsing/testing.py,sha256=7tu4Abp4uSeJV0N_yEPRmmNUhpd18ZQP3CrX41DM814,13402
-pyparsing/unicode.py,sha256=fwuhMj30SQ165Cv7HJpu-rSxGbRm93kN9L4Ei7VGc1Y,10787
-pyparsing/util.py,sha256=kq772O5YSeXOSdP-M31EWpbH_ayj7BMHImBYo9xPD5M,6805
+pyparsing-3.0.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+pyparsing-3.0.9.dist-info/LICENSE,sha256=ENUSChaAWAT_2otojCIL-06POXQbVzIGBNRVowngGXI,1023\r
+pyparsing-3.0.9.dist-info/METADATA,sha256=h_fpm9rwvgZsE8v5YNF4IAo-IpaFWCOfUEm5MMByIiM,4207\r
+pyparsing-3.0.9.dist-info/RECORD,,\r
+pyparsing-3.0.9.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+pyparsing-3.0.9.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81\r
+pyparsing/__init__.py,sha256=52QH3lgPbJhba0estckoGPHRH8JvQSSCGoWiEn2m0bU,9159\r
+pyparsing/__pycache__/__init__.cpython-311.pyc,,\r
+pyparsing/__pycache__/actions.cpython-311.pyc,,\r
+pyparsing/__pycache__/common.cpython-311.pyc,,\r
+pyparsing/__pycache__/core.cpython-311.pyc,,\r
+pyparsing/__pycache__/exceptions.cpython-311.pyc,,\r
+pyparsing/__pycache__/helpers.cpython-311.pyc,,\r
+pyparsing/__pycache__/results.cpython-311.pyc,,\r
+pyparsing/__pycache__/testing.cpython-311.pyc,,\r
+pyparsing/__pycache__/unicode.cpython-311.pyc,,\r
+pyparsing/__pycache__/util.cpython-311.pyc,,\r
+pyparsing/actions.py,sha256=wU9i32e0y1ymxKE3OUwSHO-SFIrt1h_wv6Ws0GQjpNU,6426\r
+pyparsing/common.py,sha256=lFL97ooIeR75CmW5hjURZqwDCTgruqltcTCZ-ulLO2Q,12936\r
+pyparsing/core.py,sha256=u8GptQE_H6wMkl8OZhxeK1aAPIDXXNgwdShORBwBVS4,213310\r
+pyparsing/diagram/__init__.py,sha256=f_EfxahqrdkRVahmTwLJXkZ9EEDKNd-O7lBbpJYlE1g,23668\r
+pyparsing/diagram/__pycache__/__init__.cpython-311.pyc,,\r
+pyparsing/exceptions.py,sha256=3LbSafD32NYb1Tzt85GHNkhEAU1eZkTtNSk24cPMemo,9023\r
+pyparsing/helpers.py,sha256=QpUOjW0-psvueMwWb9bQpU2noqKCv98_wnw1VSzSdVo,39129\r
+pyparsing/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+pyparsing/results.py,sha256=HgNvWVXBdQP-Q6PtJfoCEeOJk2nwEvG-2KVKC5sGA30,25341\r
+pyparsing/testing.py,sha256=7tu4Abp4uSeJV0N_yEPRmmNUhpd18ZQP3CrX41DM814,13402\r
+pyparsing/unicode.py,sha256=fwuhMj30SQ165Cv7HJpu-rSxGbRm93kN9L4Ei7VGc1Y,10787\r
+pyparsing/util.py,sha256=kq772O5YSeXOSdP-M31EWpbH_ayj7BMHImBYo9xPD5M,6805\r
diff --git a/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/INSTALLER b/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/INSTALLER
new file mode 100644 (file)
index 0000000..a1b589e
--- /dev/null
@@ -0,0 +1 @@
+pip
diff --git a/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/LICENSE b/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/LICENSE
new file mode 100644 (file)
index 0000000..1df6b3b
--- /dev/null
@@ -0,0 +1,254 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations, which became
+Zope Corporation.  In 2001, the Python Software Foundation (PSF, see
+https://www.python.org/psf/) was formed, a non-profit organization
+created specifically to own Python-related Intellectual Property.
+Zope Corporation was a sponsoring member of the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+                    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        yes (2)
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2 and above   2.1.1       2001-now    PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+    because its license has a choice of law clause.  According to
+    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+    is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Python Software Foundation;
+All Rights Reserved" are retained in Python alone or in any derivative version
+prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, 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.
diff --git a/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/METADATA b/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/METADATA
new file mode 100644 (file)
index 0000000..1ed963a
--- /dev/null
@@ -0,0 +1,189 @@
+Metadata-Version: 2.1
+Name: typing_extensions
+Version: 4.4.0
+Summary: Backported and Experimental Type Hints for Python 3.7+
+Keywords: annotations,backport,checker,checking,function,hinting,hints,type,typechecking,typehinting,typehints,typing
+Author-email: "Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee" <levkivskyi@gmail.com>
+Requires-Python: >=3.7
+Description-Content-Type: text/markdown
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Python Software Foundation License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+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: Topic :: Software Development
+Project-URL: Bug Tracker, https://github.com/python/typing_extensions/issues
+Project-URL: Changes, https://github.com/python/typing_extensions/blob/main/CHANGELOG.md
+Project-URL: Documentation, https://typing.readthedocs.io/
+Project-URL: Home, https://github.com/python/typing_extensions
+Project-URL: Q & A, https://github.com/python/typing/discussions
+Project-URL: Repository, https://github.com/python/typing_extensions
+
+# Typing Extensions
+
+[![Chat at https://gitter.im/python/typing](https://badges.gitter.im/python/typing.svg)](https://gitter.im/python/typing)
+
+## Overview
+
+The `typing_extensions` module serves two related purposes:
+
+- Enable use of new type system features on older Python versions. For example,
+  `typing.TypeGuard` is new in Python 3.10, but `typing_extensions` allows
+  users on previous Python versions to use it too.
+- Enable experimentation with new type system PEPs before they are accepted and
+  added to the `typing` module.
+
+New features may be added to `typing_extensions` as soon as they are specified
+in a PEP that has been added to the [python/peps](https://github.com/python/peps)
+repository. If the PEP is accepted, the feature will then be added to `typing`
+for the next CPython release. No typing PEP has been rejected so far, so we
+haven't yet figured out how to deal with that possibility.
+
+Starting with version 4.0.0, `typing_extensions` uses
+[Semantic Versioning](https://semver.org/). The
+major version is incremented for all backwards-incompatible changes.
+Therefore, it's safe to depend
+on `typing_extensions` like this: `typing_extensions >=x.y, <(x+1)`,
+where `x.y` is the first version that includes all features you need.
+
+`typing_extensions` supports Python versions 3.7 and higher. In the future,
+support for older Python versions will be dropped some time after that version
+reaches end of life.
+
+## Included items
+
+This module currently contains the following:
+
+- Experimental features
+
+  - `override` (see PEP 698)
+  - The `default=` argument to `TypeVar`, `ParamSpec`, and `TypeVarTuple` (see PEP 696)
+  - The `infer_variance=` argument to `TypeVar` (see PEP 695)
+
+- In `typing` since Python 3.11
+
+  - `assert_never`
+  - `assert_type`
+  - `clear_overloads`
+  - `@dataclass_transform()` (see PEP 681)
+  - `get_overloads`
+  - `LiteralString` (see PEP 675)
+  - `Never`
+  - `NotRequired` (see PEP 655)
+  - `reveal_type`
+  - `Required` (see PEP 655)
+  - `Self` (see PEP 673)
+  - `TypeVarTuple` (see PEP 646; the `typing_extensions` version supports the `default=` argument from PEP 696)
+  - `Unpack` (see PEP 646)
+
+- In `typing` since Python 3.10
+
+  - `Concatenate` (see PEP 612)
+  - `ParamSpec` (see PEP 612; the `typing_extensions` version supports the `default=` argument from PEP 696)
+  - `ParamSpecArgs` (see PEP 612)
+  - `ParamSpecKwargs` (see PEP 612)
+  - `TypeAlias` (see PEP 613)
+  - `TypeGuard` (see PEP 647)
+  - `is_typeddict`
+
+- In `typing` since Python 3.9
+
+  - `Annotated` (see PEP 593)
+
+- In `typing` since Python 3.8
+
+  - `final` (see PEP 591)
+  - `Final` (see PEP 591)
+  - `Literal` (see PEP 586)
+  - `Protocol` (see PEP 544)
+  - `runtime_checkable` (see PEP 544)
+  - `TypedDict` (see PEP 589)
+  - `get_origin` (`typing_extensions` provides this function only in Python 3.7+)
+  - `get_args` (`typing_extensions` provides this function only in Python 3.7+)
+
+- In `typing` since Python 3.7
+
+  - `OrderedDict`
+
+- In `typing` since Python 3.5 or 3.6 (see [the typing documentation](https://docs.python.org/3.10/library/typing.html) for details)
+
+  - `AsyncContextManager`
+  - `AsyncGenerator`
+  - `AsyncIterable`
+  - `AsyncIterator`
+  - `Awaitable`
+  - `ChainMap`
+  - `ClassVar` (see PEP 526)
+  - `ContextManager`
+  - `Coroutine`
+  - `Counter`
+  - `DefaultDict`
+  - `Deque`
+  - `NewType`
+  - `NoReturn`
+  - `overload`
+  - `Text`
+  - `Type`
+  - `TYPE_CHECKING`
+  - `get_type_hints`
+
+- The following have always been present in `typing`, but the `typing_extensions` versions provide
+  additional features:
+
+  - `Any` (supports inheritance since Python 3.11)
+  - `NamedTuple` (supports multiple inheritance with `Generic` since Python 3.11)
+  - `TypeVar` (see PEPs 695 and 696)
+
+# Other Notes and Limitations
+
+Certain objects were changed after they were added to `typing`, and
+`typing_extensions` provides a backport even on newer Python versions:
+
+- `TypedDict` does not store runtime information
+  about which (if any) keys are non-required in Python 3.8, and does not
+  honor the `total` keyword with old-style `TypedDict()` in Python
+  3.9.0 and 3.9.1. `TypedDict` also does not support multiple inheritance
+  with `typing.Generic` on Python <3.11.
+- `get_origin` and `get_args` lack support for `Annotated` in
+  Python 3.8 and lack support for `ParamSpecArgs` and `ParamSpecKwargs`
+  in 3.9.
+- `@final` was changed in Python 3.11 to set the `.__final__` attribute.
+- `@overload` was changed in Python 3.11 to make function overloads
+  introspectable at runtime. In order to access overloads with
+  `typing_extensions.get_overloads()`, you must use
+  `@typing_extensions.overload`.
+- `NamedTuple` was changed in Python 3.11 to allow for multiple inheritance
+  with `typing.Generic`.
+- Since Python 3.11, it has been possible to inherit from `Any` at
+  runtime. `typing_extensions.Any` also provides this capability.
+- `TypeVar` gains two additional parameters, `default=` and `infer_variance=`,
+  in the draft PEPs 695 and 696, which are being considered for inclusion
+  in Python 3.12.
+
+There are a few types whose interface was modified between different
+versions of typing. For example, `typing.Sequence` was modified to
+subclass `typing.Reversible` as of Python 3.5.3.
+
+These changes are _not_ backported to prevent subtle compatibility
+issues when mixing the differing implementations of modified classes.
+
+Certain types have incorrect runtime behavior due to limitations of older
+versions of the typing module:
+
+- `ParamSpec` and `Concatenate` will not work with `get_args` and
+  `get_origin`. Certain PEP 612 special cases in user-defined
+  `Generic`s are also not available.
+
+These types are only guaranteed to work for static type checking.
+
+## Running tests
+
+To run tests, navigate into the appropriate source directory and run
+`test_typing_extensions.py`.
+
diff --git a/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/RECORD b/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/RECORD
new file mode 100644 (file)
index 0000000..b9e1bb0
--- /dev/null
@@ -0,0 +1,8 @@
+__pycache__/typing_extensions.cpython-311.pyc,,\r
+typing_extensions-4.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+typing_extensions-4.4.0.dist-info/LICENSE,sha256=x6-2XnVXB7n7kEhziaF20-09ADHVExr95FwjcV_16JE,12787\r
+typing_extensions-4.4.0.dist-info/METADATA,sha256=1zSh1eMLnLkLMMC6aZSGRKx3eRnivEGDFWGSVD1zqhA,7249\r
+typing_extensions-4.4.0.dist-info/RECORD,,\r
+typing_extensions-4.4.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+typing_extensions-4.4.0.dist-info/WHEEL,sha256=4TfKIB_xu-04bc2iKz6_zFt-gEFEEDU_31HGhqzOCE8,81\r
+typing_extensions.py,sha256=ipqWiq5AHzrwczt6c26AP05Llh6a5_GaXRpOBqbogHA,80078\r
diff --git a/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/REQUESTED b/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/REQUESTED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/WHEEL b/pkg_resources/_vendor/typing_extensions-4.4.0.dist-info/WHEEL
new file mode 100644 (file)
index 0000000..668ba4d
--- /dev/null
@@ -0,0 +1,4 @@
+Wheel-Version: 1.0
+Generator: flit 3.7.1
+Root-Is-Purelib: true
+Tag: py3-none-any
diff --git a/pkg_resources/_vendor/typing_extensions.py b/pkg_resources/_vendor/typing_extensions.py
new file mode 100644 (file)
index 0000000..ef42417
--- /dev/null
@@ -0,0 +1,2209 @@
+import abc
+import collections
+import collections.abc
+import functools
+import operator
+import sys
+import types as _types
+import typing
+
+
+__all__ = [
+    # Super-special typing primitives.
+    'Any',
+    'ClassVar',
+    'Concatenate',
+    'Final',
+    'LiteralString',
+    'ParamSpec',
+    'ParamSpecArgs',
+    'ParamSpecKwargs',
+    'Self',
+    'Type',
+    'TypeVar',
+    'TypeVarTuple',
+    'Unpack',
+
+    # ABCs (from collections.abc).
+    'Awaitable',
+    'AsyncIterator',
+    'AsyncIterable',
+    'Coroutine',
+    'AsyncGenerator',
+    'AsyncContextManager',
+    'ChainMap',
+
+    # Concrete collection types.
+    'ContextManager',
+    'Counter',
+    'Deque',
+    'DefaultDict',
+    'NamedTuple',
+    'OrderedDict',
+    'TypedDict',
+
+    # Structural checks, a.k.a. protocols.
+    'SupportsIndex',
+
+    # One-off things.
+    'Annotated',
+    'assert_never',
+    'assert_type',
+    'clear_overloads',
+    'dataclass_transform',
+    'get_overloads',
+    'final',
+    'get_args',
+    'get_origin',
+    'get_type_hints',
+    'IntVar',
+    'is_typeddict',
+    'Literal',
+    'NewType',
+    'overload',
+    'override',
+    'Protocol',
+    'reveal_type',
+    'runtime',
+    'runtime_checkable',
+    'Text',
+    'TypeAlias',
+    'TypeGuard',
+    'TYPE_CHECKING',
+    'Never',
+    'NoReturn',
+    'Required',
+    'NotRequired',
+]
+
+# for backward compatibility
+PEP_560 = True
+GenericMeta = type
+
+# The functions below are modified copies of typing internal helpers.
+# They are needed by _ProtocolMeta and they provide support for PEP 646.
+
+_marker = object()
+
+
+def _check_generic(cls, parameters, elen=_marker):
+    """Check correct count for parameters of a generic cls (internal helper).
+    This gives a nice error message in case of count mismatch.
+    """
+    if not elen:
+        raise TypeError(f"{cls} is not a generic class")
+    if elen is _marker:
+        if not hasattr(cls, "__parameters__") or not cls.__parameters__:
+            raise TypeError(f"{cls} is not a generic class")
+        elen = len(cls.__parameters__)
+    alen = len(parameters)
+    if alen != elen:
+        if hasattr(cls, "__parameters__"):
+            parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
+            num_tv_tuples = sum(isinstance(p, TypeVarTuple) for p in parameters)
+            if (num_tv_tuples > 0) and (alen >= elen - num_tv_tuples):
+                return
+        raise TypeError(f"Too {'many' if alen > elen else 'few'} parameters for {cls};"
+                        f" actual {alen}, expected {elen}")
+
+
+if sys.version_info >= (3, 10):
+    def _should_collect_from_parameters(t):
+        return isinstance(
+            t, (typing._GenericAlias, _types.GenericAlias, _types.UnionType)
+        )
+elif sys.version_info >= (3, 9):
+    def _should_collect_from_parameters(t):
+        return isinstance(t, (typing._GenericAlias, _types.GenericAlias))
+else:
+    def _should_collect_from_parameters(t):
+        return isinstance(t, typing._GenericAlias) and not t._special
+
+
+def _collect_type_vars(types, typevar_types=None):
+    """Collect all type variable contained in types in order of
+    first appearance (lexicographic order). For example::
+
+        _collect_type_vars((T, List[S, T])) == (T, S)
+    """
+    if typevar_types is None:
+        typevar_types = typing.TypeVar
+    tvars = []
+    for t in types:
+        if (
+            isinstance(t, typevar_types) and
+            t not in tvars and
+            not _is_unpack(t)
+        ):
+            tvars.append(t)
+        if _should_collect_from_parameters(t):
+            tvars.extend([t for t in t.__parameters__ if t not in tvars])
+    return tuple(tvars)
+
+
+NoReturn = typing.NoReturn
+
+# Some unconstrained type variables.  These are used by the container types.
+# (These are not for export.)
+T = typing.TypeVar('T')  # Any type.
+KT = typing.TypeVar('KT')  # Key type.
+VT = typing.TypeVar('VT')  # Value type.
+T_co = typing.TypeVar('T_co', covariant=True)  # Any type covariant containers.
+T_contra = typing.TypeVar('T_contra', contravariant=True)  # Ditto contravariant.
+
+
+if sys.version_info >= (3, 11):
+    from typing import Any
+else:
+
+    class _AnyMeta(type):
+        def __instancecheck__(self, obj):
+            if self is Any:
+                raise TypeError("typing_extensions.Any cannot be used with isinstance()")
+            return super().__instancecheck__(obj)
+
+        def __repr__(self):
+            if self is Any:
+                return "typing_extensions.Any"
+            return super().__repr__()
+
+    class Any(metaclass=_AnyMeta):
+        """Special type indicating an unconstrained type.
+        - Any is compatible with every type.
+        - Any assumed to have all methods.
+        - All values assumed to be instances of Any.
+        Note that all the above statements are true from the point of view of
+        static type checkers. At runtime, Any should not be used with instance
+        checks.
+        """
+        def __new__(cls, *args, **kwargs):
+            if cls is Any:
+                raise TypeError("Any cannot be instantiated")
+            return super().__new__(cls, *args, **kwargs)
+
+
+ClassVar = typing.ClassVar
+
+# On older versions of typing there is an internal class named "Final".
+# 3.8+
+if hasattr(typing, 'Final') and sys.version_info[:2] >= (3, 7):
+    Final = typing.Final
+# 3.7
+else:
+    class _FinalForm(typing._SpecialForm, _root=True):
+
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            item = typing._type_check(parameters,
+                                      f'{self._name} accepts only a single type.')
+            return typing._GenericAlias(self, (item,))
+
+    Final = _FinalForm('Final',
+                       doc="""A special typing construct to indicate that a name
+                       cannot be re-assigned or overridden in a subclass.
+                       For example:
+
+                           MAX_SIZE: Final = 9000
+                           MAX_SIZE += 1  # Error reported by type checker
+
+                           class Connection:
+                               TIMEOUT: Final[int] = 10
+                           class FastConnector(Connection):
+                               TIMEOUT = 1  # Error reported by type checker
+
+                       There is no runtime checking of these properties.""")
+
+if sys.version_info >= (3, 11):
+    final = typing.final
+else:
+    # @final exists in 3.8+, but we backport it for all versions
+    # before 3.11 to keep support for the __final__ attribute.
+    # See https://bugs.python.org/issue46342
+    def final(f):
+        """This decorator can be used to indicate to type checkers that
+        the decorated method cannot be overridden, and decorated class
+        cannot be subclassed. For example:
+
+            class Base:
+                @final
+                def done(self) -> None:
+                    ...
+            class Sub(Base):
+                def done(self) -> None:  # Error reported by type checker
+                    ...
+            @final
+            class Leaf:
+                ...
+            class Other(Leaf):  # Error reported by type checker
+                ...
+
+        There is no runtime checking of these properties. The decorator
+        sets the ``__final__`` attribute to ``True`` on the decorated object
+        to allow runtime introspection.
+        """
+        try:
+            f.__final__ = True
+        except (AttributeError, TypeError):
+            # Skip the attribute silently if it is not writable.
+            # AttributeError happens if the object has __slots__ or a
+            # read-only property, TypeError if it's a builtin class.
+            pass
+        return f
+
+
+def IntVar(name):
+    return typing.TypeVar(name)
+
+
+# 3.8+:
+if hasattr(typing, 'Literal'):
+    Literal = typing.Literal
+# 3.7:
+else:
+    class _LiteralForm(typing._SpecialForm, _root=True):
+
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            return typing._GenericAlias(self, parameters)
+
+    Literal = _LiteralForm('Literal',
+                           doc="""A type that can be used to indicate to type checkers
+                           that the corresponding value has a value literally equivalent
+                           to the provided parameter. For example:
+
+                               var: Literal[4] = 4
+
+                           The type checker understands that 'var' is literally equal to
+                           the value 4 and no other value.
+
+                           Literal[...] cannot be subclassed. There is no runtime
+                           checking verifying that the parameter is actually a value
+                           instead of a type.""")
+
+
+_overload_dummy = typing._overload_dummy  # noqa
+
+
+if hasattr(typing, "get_overloads"):  # 3.11+
+    overload = typing.overload
+    get_overloads = typing.get_overloads
+    clear_overloads = typing.clear_overloads
+else:
+    # {module: {qualname: {firstlineno: func}}}
+    _overload_registry = collections.defaultdict(
+        functools.partial(collections.defaultdict, dict)
+    )
+
+    def overload(func):
+        """Decorator for overloaded functions/methods.
+
+        In a stub file, place two or more stub definitions for the same
+        function in a row, each decorated with @overload.  For example:
+
+        @overload
+        def utf8(value: None) -> None: ...
+        @overload
+        def utf8(value: bytes) -> bytes: ...
+        @overload
+        def utf8(value: str) -> bytes: ...
+
+        In a non-stub file (i.e. a regular .py file), do the same but
+        follow it with an implementation.  The implementation should *not*
+        be decorated with @overload.  For example:
+
+        @overload
+        def utf8(value: None) -> None: ...
+        @overload
+        def utf8(value: bytes) -> bytes: ...
+        @overload
+        def utf8(value: str) -> bytes: ...
+        def utf8(value):
+            # implementation goes here
+
+        The overloads for a function can be retrieved at runtime using the
+        get_overloads() function.
+        """
+        # classmethod and staticmethod
+        f = getattr(func, "__func__", func)
+        try:
+            _overload_registry[f.__module__][f.__qualname__][
+                f.__code__.co_firstlineno
+            ] = func
+        except AttributeError:
+            # Not a normal function; ignore.
+            pass
+        return _overload_dummy
+
+    def get_overloads(func):
+        """Return all defined overloads for *func* as a sequence."""
+        # classmethod and staticmethod
+        f = getattr(func, "__func__", func)
+        if f.__module__ not in _overload_registry:
+            return []
+        mod_dict = _overload_registry[f.__module__]
+        if f.__qualname__ not in mod_dict:
+            return []
+        return list(mod_dict[f.__qualname__].values())
+
+    def clear_overloads():
+        """Clear all overloads in the registry."""
+        _overload_registry.clear()
+
+
+# This is not a real generic class.  Don't use outside annotations.
+Type = typing.Type
+
+# Various ABCs mimicking those in collections.abc.
+# A few are simply re-exported for completeness.
+
+
+Awaitable = typing.Awaitable
+Coroutine = typing.Coroutine
+AsyncIterable = typing.AsyncIterable
+AsyncIterator = typing.AsyncIterator
+Deque = typing.Deque
+ContextManager = typing.ContextManager
+AsyncContextManager = typing.AsyncContextManager
+DefaultDict = typing.DefaultDict
+
+# 3.7.2+
+if hasattr(typing, 'OrderedDict'):
+    OrderedDict = typing.OrderedDict
+# 3.7.0-3.7.2
+else:
+    OrderedDict = typing._alias(collections.OrderedDict, (KT, VT))
+
+Counter = typing.Counter
+ChainMap = typing.ChainMap
+AsyncGenerator = typing.AsyncGenerator
+NewType = typing.NewType
+Text = typing.Text
+TYPE_CHECKING = typing.TYPE_CHECKING
+
+
+_PROTO_WHITELIST = ['Callable', 'Awaitable',
+                    'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator',
+                    'Hashable', 'Sized', 'Container', 'Collection', 'Reversible',
+                    'ContextManager', 'AsyncContextManager']
+
+
+def _get_protocol_attrs(cls):
+    attrs = set()
+    for base in cls.__mro__[:-1]:  # without object
+        if base.__name__ in ('Protocol', 'Generic'):
+            continue
+        annotations = getattr(base, '__annotations__', {})
+        for attr in list(base.__dict__.keys()) + list(annotations.keys()):
+            if (not attr.startswith('_abc_') and attr not in (
+                    '__abstractmethods__', '__annotations__', '__weakref__',
+                    '_is_protocol', '_is_runtime_protocol', '__dict__',
+                    '__args__', '__slots__',
+                    '__next_in_mro__', '__parameters__', '__origin__',
+                    '__orig_bases__', '__extra__', '__tree_hash__',
+                    '__doc__', '__subclasshook__', '__init__', '__new__',
+                    '__module__', '_MutableMapping__marker', '_gorg')):
+                attrs.add(attr)
+    return attrs
+
+
+def _is_callable_members_only(cls):
+    return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls))
+
+
+def _maybe_adjust_parameters(cls):
+    """Helper function used in Protocol.__init_subclass__ and _TypedDictMeta.__new__.
+
+    The contents of this function are very similar
+    to logic found in typing.Generic.__init_subclass__
+    on the CPython main branch.
+    """
+    tvars = []
+    if '__orig_bases__' in cls.__dict__:
+        tvars = typing._collect_type_vars(cls.__orig_bases__)
+        # Look for Generic[T1, ..., Tn] or Protocol[T1, ..., Tn].
+        # If found, tvars must be a subset of it.
+        # If not found, tvars is it.
+        # Also check for and reject plain Generic,
+        # and reject multiple Generic[...] and/or Protocol[...].
+        gvars = None
+        for base in cls.__orig_bases__:
+            if (isinstance(base, typing._GenericAlias) and
+                    base.__origin__ in (typing.Generic, Protocol)):
+                # for error messages
+                the_base = base.__origin__.__name__
+                if gvars is not None:
+                    raise TypeError(
+                        "Cannot inherit from Generic[...]"
+                        " and/or Protocol[...] multiple types.")
+                gvars = base.__parameters__
+        if gvars is None:
+            gvars = tvars
+        else:
+            tvarset = set(tvars)
+            gvarset = set(gvars)
+            if not tvarset <= gvarset:
+                s_vars = ', '.join(str(t) for t in tvars if t not in gvarset)
+                s_args = ', '.join(str(g) for g in gvars)
+                raise TypeError(f"Some type variables ({s_vars}) are"
+                                f" not listed in {the_base}[{s_args}]")
+            tvars = gvars
+    cls.__parameters__ = tuple(tvars)
+
+
+# 3.8+
+if hasattr(typing, 'Protocol'):
+    Protocol = typing.Protocol
+# 3.7
+else:
+
+    def _no_init(self, *args, **kwargs):
+        if type(self)._is_protocol:
+            raise TypeError('Protocols cannot be instantiated')
+
+    class _ProtocolMeta(abc.ABCMeta):  # noqa: B024
+        # This metaclass is a bit unfortunate and exists only because of the lack
+        # of __instancehook__.
+        def __instancecheck__(cls, instance):
+            # We need this method for situations where attributes are
+            # assigned in __init__.
+            if ((not getattr(cls, '_is_protocol', False) or
+                 _is_callable_members_only(cls)) and
+                    issubclass(instance.__class__, cls)):
+                return True
+            if cls._is_protocol:
+                if all(hasattr(instance, attr) and
+                       (not callable(getattr(cls, attr, None)) or
+                        getattr(instance, attr) is not None)
+                       for attr in _get_protocol_attrs(cls)):
+                    return True
+            return super().__instancecheck__(instance)
+
+    class Protocol(metaclass=_ProtocolMeta):
+        # There is quite a lot of overlapping code with typing.Generic.
+        # Unfortunately it is hard to avoid this while these live in two different
+        # modules. The duplicated code will be removed when Protocol is moved to typing.
+        """Base class for protocol classes. Protocol classes are defined as::
+
+            class Proto(Protocol):
+                def meth(self) -> int:
+                    ...
+
+        Such classes are primarily used with static type checkers that recognize
+        structural subtyping (static duck-typing), for example::
+
+            class C:
+                def meth(self) -> int:
+                    return 0
+
+            def func(x: Proto) -> int:
+                return x.meth()
+
+            func(C())  # Passes static type check
+
+        See PEP 544 for details. Protocol classes decorated with
+        @typing_extensions.runtime act as simple-minded runtime protocol that checks
+        only the presence of given attributes, ignoring their type signatures.
+
+        Protocol classes can be generic, they are defined as::
+
+            class GenProto(Protocol[T]):
+                def meth(self) -> T:
+                    ...
+        """
+        __slots__ = ()
+        _is_protocol = True
+
+        def __new__(cls, *args, **kwds):
+            if cls is Protocol:
+                raise TypeError("Type Protocol cannot be instantiated; "
+                                "it can only be used as a base class")
+            return super().__new__(cls)
+
+        @typing._tp_cache
+        def __class_getitem__(cls, params):
+            if not isinstance(params, tuple):
+                params = (params,)
+            if not params and cls is not typing.Tuple:
+                raise TypeError(
+                    f"Parameter list to {cls.__qualname__}[...] cannot be empty")
+            msg = "Parameters to generic types must be types."
+            params = tuple(typing._type_check(p, msg) for p in params)  # noqa
+            if cls is Protocol:
+                # Generic can only be subscripted with unique type variables.
+                if not all(isinstance(p, typing.TypeVar) for p in params):
+                    i = 0
+                    while isinstance(params[i], typing.TypeVar):
+                        i += 1
+                    raise TypeError(
+                        "Parameters to Protocol[...] must all be type variables."
+                        f" Parameter {i + 1} is {params[i]}")
+                if len(set(params)) != len(params):
+                    raise TypeError(
+                        "Parameters to Protocol[...] must all be unique")
+            else:
+                # Subscripting a regular Generic subclass.
+                _check_generic(cls, params, len(cls.__parameters__))
+            return typing._GenericAlias(cls, params)
+
+        def __init_subclass__(cls, *args, **kwargs):
+            if '__orig_bases__' in cls.__dict__:
+                error = typing.Generic in cls.__orig_bases__
+            else:
+                error = typing.Generic in cls.__bases__
+            if error:
+                raise TypeError("Cannot inherit from plain Generic")
+            _maybe_adjust_parameters(cls)
+
+            # Determine if this is a protocol or a concrete subclass.
+            if not cls.__dict__.get('_is_protocol', None):
+                cls._is_protocol = any(b is Protocol for b in cls.__bases__)
+
+            # Set (or override) the protocol subclass hook.
+            def _proto_hook(other):
+                if not cls.__dict__.get('_is_protocol', None):
+                    return NotImplemented
+                if not getattr(cls, '_is_runtime_protocol', False):
+                    if sys._getframe(2).f_globals['__name__'] in ['abc', 'functools']:
+                        return NotImplemented
+                    raise TypeError("Instance and class checks can only be used with"
+                                    " @runtime protocols")
+                if not _is_callable_members_only(cls):
+                    if sys._getframe(2).f_globals['__name__'] in ['abc', 'functools']:
+                        return NotImplemented
+                    raise TypeError("Protocols with non-method members"
+                                    " don't support issubclass()")
+                if not isinstance(other, type):
+                    # Same error as for issubclass(1, int)
+                    raise TypeError('issubclass() arg 1 must be a class')
+                for attr in _get_protocol_attrs(cls):
+                    for base in other.__mro__:
+                        if attr in base.__dict__:
+                            if base.__dict__[attr] is None:
+                                return NotImplemented
+                            break
+                        annotations = getattr(base, '__annotations__', {})
+                        if (isinstance(annotations, typing.Mapping) and
+                                attr in annotations and
+                                isinstance(other, _ProtocolMeta) and
+                                other._is_protocol):
+                            break
+                    else:
+                        return NotImplemented
+                return True
+            if '__subclasshook__' not in cls.__dict__:
+                cls.__subclasshook__ = _proto_hook
+
+            # We have nothing more to do for non-protocols.
+            if not cls._is_protocol:
+                return
+
+            # Check consistency of bases.
+            for base in cls.__bases__:
+                if not (base in (object, typing.Generic) or
+                        base.__module__ == 'collections.abc' and
+                        base.__name__ in _PROTO_WHITELIST or
+                        isinstance(base, _ProtocolMeta) and base._is_protocol):
+                    raise TypeError('Protocols can only inherit from other'
+                                    f' protocols, got {repr(base)}')
+            cls.__init__ = _no_init
+
+
+# 3.8+
+if hasattr(typing, 'runtime_checkable'):
+    runtime_checkable = typing.runtime_checkable
+# 3.7
+else:
+    def runtime_checkable(cls):
+        """Mark a protocol class as a runtime protocol, so that it
+        can be used with isinstance() and issubclass(). Raise TypeError
+        if applied to a non-protocol class.
+
+        This allows a simple-minded structural check very similar to the
+        one-offs in collections.abc such as Hashable.
+        """
+        if not isinstance(cls, _ProtocolMeta) or not cls._is_protocol:
+            raise TypeError('@runtime_checkable can be only applied to protocol classes,'
+                            f' got {cls!r}')
+        cls._is_runtime_protocol = True
+        return cls
+
+
+# Exists for backwards compatibility.
+runtime = runtime_checkable
+
+
+# 3.8+
+if hasattr(typing, 'SupportsIndex'):
+    SupportsIndex = typing.SupportsIndex
+# 3.7
+else:
+    @runtime_checkable
+    class SupportsIndex(Protocol):
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __index__(self) -> int:
+            pass
+
+
+if hasattr(typing, "Required"):
+    # The standard library TypedDict in Python 3.8 does not store runtime information
+    # about which (if any) keys are optional.  See https://bugs.python.org/issue38834
+    # The standard library TypedDict in Python 3.9.0/1 does not honour the "total"
+    # keyword with old-style TypedDict().  See https://bugs.python.org/issue42059
+    # The standard library TypedDict below Python 3.11 does not store runtime
+    # information about optional and required keys when using Required or NotRequired.
+    # Generic TypedDicts are also impossible using typing.TypedDict on Python <3.11.
+    TypedDict = typing.TypedDict
+    _TypedDictMeta = typing._TypedDictMeta
+    is_typeddict = typing.is_typeddict
+else:
+    def _check_fails(cls, other):
+        try:
+            if sys._getframe(1).f_globals['__name__'] not in ['abc',
+                                                              'functools',
+                                                              'typing']:
+                # Typed dicts are only for static structural subtyping.
+                raise TypeError('TypedDict does not support instance and class checks')
+        except (AttributeError, ValueError):
+            pass
+        return False
+
+    def _dict_new(*args, **kwargs):
+        if not args:
+            raise TypeError('TypedDict.__new__(): not enough arguments')
+        _, args = args[0], args[1:]  # allow the "cls" keyword be passed
+        return dict(*args, **kwargs)
+
+    _dict_new.__text_signature__ = '($cls, _typename, _fields=None, /, **kwargs)'
+
+    def _typeddict_new(*args, total=True, **kwargs):
+        if not args:
+            raise TypeError('TypedDict.__new__(): not enough arguments')
+        _, args = args[0], args[1:]  # allow the "cls" keyword be passed
+        if args:
+            typename, args = args[0], args[1:]  # allow the "_typename" keyword be passed
+        elif '_typename' in kwargs:
+            typename = kwargs.pop('_typename')
+            import warnings
+            warnings.warn("Passing '_typename' as keyword argument is deprecated",
+                          DeprecationWarning, stacklevel=2)
+        else:
+            raise TypeError("TypedDict.__new__() missing 1 required positional "
+                            "argument: '_typename'")
+        if args:
+            try:
+                fields, = args  # allow the "_fields" keyword be passed
+            except ValueError:
+                raise TypeError('TypedDict.__new__() takes from 2 to 3 '
+                                f'positional arguments but {len(args) + 2} '
+                                'were given')
+        elif '_fields' in kwargs and len(kwargs) == 1:
+            fields = kwargs.pop('_fields')
+            import warnings
+            warnings.warn("Passing '_fields' as keyword argument is deprecated",
+                          DeprecationWarning, stacklevel=2)
+        else:
+            fields = None
+
+        if fields is None:
+            fields = kwargs
+        elif kwargs:
+            raise TypeError("TypedDict takes either a dict or keyword arguments,"
+                            " but not both")
+
+        ns = {'__annotations__': dict(fields)}
+        try:
+            # Setting correct module is necessary to make typed dict classes pickleable.
+            ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__')
+        except (AttributeError, ValueError):
+            pass
+
+        return _TypedDictMeta(typename, (), ns, total=total)
+
+    _typeddict_new.__text_signature__ = ('($cls, _typename, _fields=None,'
+                                         ' /, *, total=True, **kwargs)')
+
+    class _TypedDictMeta(type):
+        def __init__(cls, name, bases, ns, total=True):
+            super().__init__(name, bases, ns)
+
+        def __new__(cls, name, bases, ns, total=True):
+            # Create new typed dict class object.
+            # This method is called directly when TypedDict is subclassed,
+            # or via _typeddict_new when TypedDict is instantiated. This way
+            # TypedDict supports all three syntaxes described in its docstring.
+            # Subclasses and instances of TypedDict return actual dictionaries
+            # via _dict_new.
+            ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new
+            # Don't insert typing.Generic into __bases__ here,
+            # or Generic.__init_subclass__ will raise TypeError
+            # in the super().__new__() call.
+            # Instead, monkey-patch __bases__ onto the class after it's been created.
+            tp_dict = super().__new__(cls, name, (dict,), ns)
+
+            if any(issubclass(base, typing.Generic) for base in bases):
+                tp_dict.__bases__ = (typing.Generic, dict)
+                _maybe_adjust_parameters(tp_dict)
+
+            annotations = {}
+            own_annotations = ns.get('__annotations__', {})
+            msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
+            own_annotations = {
+                n: typing._type_check(tp, msg) for n, tp in own_annotations.items()
+            }
+            required_keys = set()
+            optional_keys = set()
+
+            for base in bases:
+                annotations.update(base.__dict__.get('__annotations__', {}))
+                required_keys.update(base.__dict__.get('__required_keys__', ()))
+                optional_keys.update(base.__dict__.get('__optional_keys__', ()))
+
+            annotations.update(own_annotations)
+            for annotation_key, annotation_type in own_annotations.items():
+                annotation_origin = get_origin(annotation_type)
+                if annotation_origin is Annotated:
+                    annotation_args = get_args(annotation_type)
+                    if annotation_args:
+                        annotation_type = annotation_args[0]
+                        annotation_origin = get_origin(annotation_type)
+
+                if annotation_origin is Required:
+                    required_keys.add(annotation_key)
+                elif annotation_origin is NotRequired:
+                    optional_keys.add(annotation_key)
+                elif total:
+                    required_keys.add(annotation_key)
+                else:
+                    optional_keys.add(annotation_key)
+
+            tp_dict.__annotations__ = annotations
+            tp_dict.__required_keys__ = frozenset(required_keys)
+            tp_dict.__optional_keys__ = frozenset(optional_keys)
+            if not hasattr(tp_dict, '__total__'):
+                tp_dict.__total__ = total
+            return tp_dict
+
+        __instancecheck__ = __subclasscheck__ = _check_fails
+
+    TypedDict = _TypedDictMeta('TypedDict', (dict,), {})
+    TypedDict.__module__ = __name__
+    TypedDict.__doc__ = \
+        """A simple typed name space. At runtime it is equivalent to a plain dict.
+
+        TypedDict creates a dictionary type that expects all of its
+        instances to have a certain set of keys, with each key
+        associated with a value of a consistent type. This expectation
+        is not checked at runtime but is only enforced by type checkers.
+        Usage::
+
+            class Point2D(TypedDict):
+                x: int
+                y: int
+                label: str
+
+            a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # OK
+            b: Point2D = {'z': 3, 'label': 'bad'}           # Fails type check
+
+            assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
+
+        The type info can be accessed via the Point2D.__annotations__ dict, and
+        the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
+        TypedDict supports two additional equivalent forms::
+
+            Point2D = TypedDict('Point2D', x=int, y=int, label=str)
+            Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
+
+        The class syntax is only supported in Python 3.6+, while two other
+        syntax forms work for Python 2.7 and 3.2+
+        """
+
+    if hasattr(typing, "_TypedDictMeta"):
+        _TYPEDDICT_TYPES = (typing._TypedDictMeta, _TypedDictMeta)
+    else:
+        _TYPEDDICT_TYPES = (_TypedDictMeta,)
+
+    def is_typeddict(tp):
+        """Check if an annotation is a TypedDict class
+
+        For example::
+            class Film(TypedDict):
+                title: str
+                year: int
+
+            is_typeddict(Film)  # => True
+            is_typeddict(Union[list, str])  # => False
+        """
+        return isinstance(tp, tuple(_TYPEDDICT_TYPES))
+
+
+if hasattr(typing, "assert_type"):
+    assert_type = typing.assert_type
+
+else:
+    def assert_type(__val, __typ):
+        """Assert (to the type checker) that the value is of the given type.
+
+        When the type checker encounters a call to assert_type(), it
+        emits an error if the value is not of the specified type::
+
+            def greet(name: str) -> None:
+                assert_type(name, str)  # ok
+                assert_type(name, int)  # type checker error
+
+        At runtime this returns the first argument unchanged and otherwise
+        does nothing.
+        """
+        return __val
+
+
+if hasattr(typing, "Required"):
+    get_type_hints = typing.get_type_hints
+else:
+    import functools
+    import types
+
+    # replaces _strip_annotations()
+    def _strip_extras(t):
+        """Strips Annotated, Required and NotRequired from a given type."""
+        if isinstance(t, _AnnotatedAlias):
+            return _strip_extras(t.__origin__)
+        if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired):
+            return _strip_extras(t.__args__[0])
+        if isinstance(t, typing._GenericAlias):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return t.copy_with(stripped_args)
+        if hasattr(types, "GenericAlias") and isinstance(t, types.GenericAlias):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return types.GenericAlias(t.__origin__, stripped_args)
+        if hasattr(types, "UnionType") and isinstance(t, types.UnionType):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return functools.reduce(operator.or_, stripped_args)
+
+        return t
+
+    def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
+        """Return type hints for an object.
+
+        This is often the same as obj.__annotations__, but it handles
+        forward references encoded as string literals, adds Optional[t] if a
+        default value equal to None is set and recursively replaces all
+        'Annotated[T, ...]', 'Required[T]' or 'NotRequired[T]' with 'T'
+        (unless 'include_extras=True').
+
+        The argument may be a module, class, method, or function. The annotations
+        are returned as a dictionary. For classes, annotations include also
+        inherited members.
+
+        TypeError is raised if the argument is not of a type that can contain
+        annotations, and an empty dictionary is returned if no annotations are
+        present.
+
+        BEWARE -- the behavior of globalns and localns is counterintuitive
+        (unless you are familiar with how eval() and exec() work).  The
+        search order is locals first, then globals.
+
+        - If no dict arguments are passed, an attempt is made to use the
+          globals from obj (or the respective module's globals for classes),
+          and these are also used as the locals.  If the object does not appear
+          to have globals, an empty dictionary is used.
+
+        - If one dict argument is passed, it is used for both globals and
+          locals.
+
+        - If two dict arguments are passed, they specify globals and
+          locals, respectively.
+        """
+        if hasattr(typing, "Annotated"):
+            hint = typing.get_type_hints(
+                obj, globalns=globalns, localns=localns, include_extras=True
+            )
+        else:
+            hint = typing.get_type_hints(obj, globalns=globalns, localns=localns)
+        if include_extras:
+            return hint
+        return {k: _strip_extras(t) for k, t in hint.items()}
+
+
+# Python 3.9+ has PEP 593 (Annotated)
+if hasattr(typing, 'Annotated'):
+    Annotated = typing.Annotated
+    # Not exported and not a public API, but needed for get_origin() and get_args()
+    # to work.
+    _AnnotatedAlias = typing._AnnotatedAlias
+# 3.7-3.8
+else:
+    class _AnnotatedAlias(typing._GenericAlias, _root=True):
+        """Runtime representation of an annotated type.
+
+        At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't'
+        with extra annotations. The alias behaves like a normal typing alias,
+        instantiating is the same as instantiating the underlying type, binding
+        it to types is also the same.
+        """
+        def __init__(self, origin, metadata):
+            if isinstance(origin, _AnnotatedAlias):
+                metadata = origin.__metadata__ + metadata
+                origin = origin.__origin__
+            super().__init__(origin, origin)
+            self.__metadata__ = metadata
+
+        def copy_with(self, params):
+            assert len(params) == 1
+            new_type = params[0]
+            return _AnnotatedAlias(new_type, self.__metadata__)
+
+        def __repr__(self):
+            return (f"typing_extensions.Annotated[{typing._type_repr(self.__origin__)}, "
+                    f"{', '.join(repr(a) for a in self.__metadata__)}]")
+
+        def __reduce__(self):
+            return operator.getitem, (
+                Annotated, (self.__origin__,) + self.__metadata__
+            )
+
+        def __eq__(self, other):
+            if not isinstance(other, _AnnotatedAlias):
+                return NotImplemented
+            if self.__origin__ != other.__origin__:
+                return False
+            return self.__metadata__ == other.__metadata__
+
+        def __hash__(self):
+            return hash((self.__origin__, self.__metadata__))
+
+    class Annotated:
+        """Add context specific metadata to a type.
+
+        Example: Annotated[int, runtime_check.Unsigned] indicates to the
+        hypothetical runtime_check module that this type is an unsigned int.
+        Every other consumer of this type can ignore this metadata and treat
+        this type as int.
+
+        The first argument to Annotated must be a valid type (and will be in
+        the __origin__ field), the remaining arguments are kept as a tuple in
+        the __extra__ field.
+
+        Details:
+
+        - It's an error to call `Annotated` with less than two arguments.
+        - Nested Annotated are flattened::
+
+            Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3]
+
+        - Instantiating an annotated type is equivalent to instantiating the
+        underlying type::
+
+            Annotated[C, Ann1](5) == C(5)
+
+        - Annotated can be used as a generic type alias::
+
+            Optimized = Annotated[T, runtime.Optimize()]
+            Optimized[int] == Annotated[int, runtime.Optimize()]
+
+            OptimizedList = Annotated[List[T], runtime.Optimize()]
+            OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
+        """
+
+        __slots__ = ()
+
+        def __new__(cls, *args, **kwargs):
+            raise TypeError("Type Annotated cannot be instantiated.")
+
+        @typing._tp_cache
+        def __class_getitem__(cls, params):
+            if not isinstance(params, tuple) or len(params) < 2:
+                raise TypeError("Annotated[...] should be used "
+                                "with at least two arguments (a type and an "
+                                "annotation).")
+            allowed_special_forms = (ClassVar, Final)
+            if get_origin(params[0]) in allowed_special_forms:
+                origin = params[0]
+            else:
+                msg = "Annotated[t, ...]: t must be a type."
+                origin = typing._type_check(params[0], msg)
+            metadata = tuple(params[1:])
+            return _AnnotatedAlias(origin, metadata)
+
+        def __init_subclass__(cls, *args, **kwargs):
+            raise TypeError(
+                f"Cannot subclass {cls.__module__}.Annotated"
+            )
+
+# Python 3.8 has get_origin() and get_args() but those implementations aren't
+# Annotated-aware, so we can't use those. Python 3.9's versions don't support
+# ParamSpecArgs and ParamSpecKwargs, so only Python 3.10's versions will do.
+if sys.version_info[:2] >= (3, 10):
+    get_origin = typing.get_origin
+    get_args = typing.get_args
+# 3.7-3.9
+else:
+    try:
+        # 3.9+
+        from typing import _BaseGenericAlias
+    except ImportError:
+        _BaseGenericAlias = typing._GenericAlias
+    try:
+        # 3.9+
+        from typing import GenericAlias as _typing_GenericAlias
+    except ImportError:
+        _typing_GenericAlias = typing._GenericAlias
+
+    def get_origin(tp):
+        """Get the unsubscripted version of a type.
+
+        This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
+        and Annotated. Return None for unsupported types. Examples::
+
+            get_origin(Literal[42]) is Literal
+            get_origin(int) is None
+            get_origin(ClassVar[int]) is ClassVar
+            get_origin(Generic) is Generic
+            get_origin(Generic[T]) is Generic
+            get_origin(Union[T, int]) is Union
+            get_origin(List[Tuple[T, T]][int]) == list
+            get_origin(P.args) is P
+        """
+        if isinstance(tp, _AnnotatedAlias):
+            return Annotated
+        if isinstance(tp, (typing._GenericAlias, _typing_GenericAlias, _BaseGenericAlias,
+                           ParamSpecArgs, ParamSpecKwargs)):
+            return tp.__origin__
+        if tp is typing.Generic:
+            return typing.Generic
+        return None
+
+    def get_args(tp):
+        """Get type arguments with all substitutions performed.
+
+        For unions, basic simplifications used by Union constructor are performed.
+        Examples::
+            get_args(Dict[str, int]) == (str, int)
+            get_args(int) == ()
+            get_args(Union[int, Union[T, int], str][int]) == (int, str)
+            get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
+            get_args(Callable[[], T][int]) == ([], int)
+        """
+        if isinstance(tp, _AnnotatedAlias):
+            return (tp.__origin__,) + tp.__metadata__
+        if isinstance(tp, (typing._GenericAlias, _typing_GenericAlias)):
+            if getattr(tp, "_special", False):
+                return ()
+            res = tp.__args__
+            if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis:
+                res = (list(res[:-1]), res[-1])
+            return res
+        return ()
+
+
+# 3.10+
+if hasattr(typing, 'TypeAlias'):
+    TypeAlias = typing.TypeAlias
+# 3.9
+elif sys.version_info[:2] >= (3, 9):
+    class _TypeAliasForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    @_TypeAliasForm
+    def TypeAlias(self, parameters):
+        """Special marker indicating that an assignment should
+        be recognized as a proper type alias definition by type
+        checkers.
+
+        For example::
+
+            Predicate: TypeAlias = Callable[..., bool]
+
+        It's invalid when used anywhere except as in the example above.
+        """
+        raise TypeError(f"{self} is not subscriptable")
+# 3.7-3.8
+else:
+    class _TypeAliasForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    TypeAlias = _TypeAliasForm('TypeAlias',
+                               doc="""Special marker indicating that an assignment should
+                               be recognized as a proper type alias definition by type
+                               checkers.
+
+                               For example::
+
+                                   Predicate: TypeAlias = Callable[..., bool]
+
+                               It's invalid when used anywhere except as in the example
+                               above.""")
+
+
+class _DefaultMixin:
+    """Mixin for TypeVarLike defaults."""
+
+    __slots__ = ()
+
+    def __init__(self, default):
+        if isinstance(default, (tuple, list)):
+            self.__default__ = tuple((typing._type_check(d, "Default must be a type")
+                                      for d in default))
+        elif default:
+            self.__default__ = typing._type_check(default, "Default must be a type")
+        else:
+            self.__default__ = None
+
+
+# Add default and infer_variance parameters from PEP 696 and 695
+class TypeVar(typing.TypeVar, _DefaultMixin, _root=True):
+    """Type variable."""
+
+    __module__ = 'typing'
+
+    def __init__(self, name, *constraints, bound=None,
+                 covariant=False, contravariant=False,
+                 default=None, infer_variance=False):
+        super().__init__(name, *constraints, bound=bound, covariant=covariant,
+                         contravariant=contravariant)
+        _DefaultMixin.__init__(self, default)
+        self.__infer_variance__ = infer_variance
+
+        # for pickling:
+        try:
+            def_mod = sys._getframe(1).f_globals.get('__name__', '__main__')
+        except (AttributeError, ValueError):
+            def_mod = None
+        if def_mod != 'typing_extensions':
+            self.__module__ = def_mod
+
+
+# Python 3.10+ has PEP 612
+if hasattr(typing, 'ParamSpecArgs'):
+    ParamSpecArgs = typing.ParamSpecArgs
+    ParamSpecKwargs = typing.ParamSpecKwargs
+# 3.7-3.9
+else:
+    class _Immutable:
+        """Mixin to indicate that object should not be copied."""
+        __slots__ = ()
+
+        def __copy__(self):
+            return self
+
+        def __deepcopy__(self, memo):
+            return self
+
+    class ParamSpecArgs(_Immutable):
+        """The args for a ParamSpec object.
+
+        Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.
+
+        ParamSpecArgs objects have a reference back to their ParamSpec:
+
+        P.args.__origin__ is P
+
+        This type is meant for runtime introspection and has no special meaning to
+        static type checkers.
+        """
+        def __init__(self, origin):
+            self.__origin__ = origin
+
+        def __repr__(self):
+            return f"{self.__origin__.__name__}.args"
+
+        def __eq__(self, other):
+            if not isinstance(other, ParamSpecArgs):
+                return NotImplemented
+            return self.__origin__ == other.__origin__
+
+    class ParamSpecKwargs(_Immutable):
+        """The kwargs for a ParamSpec object.
+
+        Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.
+
+        ParamSpecKwargs objects have a reference back to their ParamSpec:
+
+        P.kwargs.__origin__ is P
+
+        This type is meant for runtime introspection and has no special meaning to
+        static type checkers.
+        """
+        def __init__(self, origin):
+            self.__origin__ = origin
+
+        def __repr__(self):
+            return f"{self.__origin__.__name__}.kwargs"
+
+        def __eq__(self, other):
+            if not isinstance(other, ParamSpecKwargs):
+                return NotImplemented
+            return self.__origin__ == other.__origin__
+
+# 3.10+
+if hasattr(typing, 'ParamSpec'):
+
+    # Add default Parameter - PEP 696
+    class ParamSpec(typing.ParamSpec, _DefaultMixin, _root=True):
+        """Parameter specification variable."""
+
+        __module__ = 'typing'
+
+        def __init__(self, name, *, bound=None, covariant=False, contravariant=False,
+                     default=None):
+            super().__init__(name, bound=bound, covariant=covariant,
+                             contravariant=contravariant)
+            _DefaultMixin.__init__(self, default)
+
+            # for pickling:
+            try:
+                def_mod = sys._getframe(1).f_globals.get('__name__', '__main__')
+            except (AttributeError, ValueError):
+                def_mod = None
+            if def_mod != 'typing_extensions':
+                self.__module__ = def_mod
+
+# 3.7-3.9
+else:
+
+    # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
+    class ParamSpec(list, _DefaultMixin):
+        """Parameter specification variable.
+
+        Usage::
+
+           P = ParamSpec('P')
+
+        Parameter specification variables exist primarily for the benefit of static
+        type checkers.  They are used to forward the parameter types of one
+        callable to another callable, a pattern commonly found in higher order
+        functions and decorators.  They are only valid when used in ``Concatenate``,
+        or s the first argument to ``Callable``. In Python 3.10 and higher,
+        they are also supported in user-defined Generics at runtime.
+        See class Generic for more information on generic types.  An
+        example for annotating a decorator::
+
+           T = TypeVar('T')
+           P = ParamSpec('P')
+
+           def add_logging(f: Callable[P, T]) -> Callable[P, T]:
+               '''A type-safe decorator to add logging to a function.'''
+               def inner(*args: P.args, **kwargs: P.kwargs) -> T:
+                   logging.info(f'{f.__name__} was called')
+                   return f(*args, **kwargs)
+               return inner
+
+           @add_logging
+           def add_two(x: float, y: float) -> float:
+               '''Add two numbers together.'''
+               return x + y
+
+        Parameter specification variables defined with covariant=True or
+        contravariant=True can be used to declare covariant or contravariant
+        generic types.  These keyword arguments are valid, but their actual semantics
+        are yet to be decided.  See PEP 612 for details.
+
+        Parameter specification variables can be introspected. e.g.:
+
+           P.__name__ == 'T'
+           P.__bound__ == None
+           P.__covariant__ == False
+           P.__contravariant__ == False
+
+        Note that only parameter specification variables defined in global scope can
+        be pickled.
+        """
+
+        # Trick Generic __parameters__.
+        __class__ = typing.TypeVar
+
+        @property
+        def args(self):
+            return ParamSpecArgs(self)
+
+        @property
+        def kwargs(self):
+            return ParamSpecKwargs(self)
+
+        def __init__(self, name, *, bound=None, covariant=False, contravariant=False,
+                     default=None):
+            super().__init__([self])
+            self.__name__ = name
+            self.__covariant__ = bool(covariant)
+            self.__contravariant__ = bool(contravariant)
+            if bound:
+                self.__bound__ = typing._type_check(bound, 'Bound must be a type.')
+            else:
+                self.__bound__ = None
+            _DefaultMixin.__init__(self, default)
+
+            # for pickling:
+            try:
+                def_mod = sys._getframe(1).f_globals.get('__name__', '__main__')
+            except (AttributeError, ValueError):
+                def_mod = None
+            if def_mod != 'typing_extensions':
+                self.__module__ = def_mod
+
+        def __repr__(self):
+            if self.__covariant__:
+                prefix = '+'
+            elif self.__contravariant__:
+                prefix = '-'
+            else:
+                prefix = '~'
+            return prefix + self.__name__
+
+        def __hash__(self):
+            return object.__hash__(self)
+
+        def __eq__(self, other):
+            return self is other
+
+        def __reduce__(self):
+            return self.__name__
+
+        # Hack to get typing._type_check to pass.
+        def __call__(self, *args, **kwargs):
+            pass
+
+
+# 3.7-3.9
+if not hasattr(typing, 'Concatenate'):
+    # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
+    class _ConcatenateGenericAlias(list):
+
+        # Trick Generic into looking into this for __parameters__.
+        __class__ = typing._GenericAlias
+
+        # Flag in 3.8.
+        _special = False
+
+        def __init__(self, origin, args):
+            super().__init__(args)
+            self.__origin__ = origin
+            self.__args__ = args
+
+        def __repr__(self):
+            _type_repr = typing._type_repr
+            return (f'{_type_repr(self.__origin__)}'
+                    f'[{", ".join(_type_repr(arg) for arg in self.__args__)}]')
+
+        def __hash__(self):
+            return hash((self.__origin__, self.__args__))
+
+        # Hack to get typing._type_check to pass in Generic.
+        def __call__(self, *args, **kwargs):
+            pass
+
+        @property
+        def __parameters__(self):
+            return tuple(
+                tp for tp in self.__args__ if isinstance(tp, (typing.TypeVar, ParamSpec))
+            )
+
+
+# 3.7-3.9
+@typing._tp_cache
+def _concatenate_getitem(self, parameters):
+    if parameters == ():
+        raise TypeError("Cannot take a Concatenate of no types.")
+    if not isinstance(parameters, tuple):
+        parameters = (parameters,)
+    if not isinstance(parameters[-1], ParamSpec):
+        raise TypeError("The last parameter to Concatenate should be a "
+                        "ParamSpec variable.")
+    msg = "Concatenate[arg, ...]: each arg must be a type."
+    parameters = tuple(typing._type_check(p, msg) for p in parameters)
+    return _ConcatenateGenericAlias(self, parameters)
+
+
+# 3.10+
+if hasattr(typing, 'Concatenate'):
+    Concatenate = typing.Concatenate
+    _ConcatenateGenericAlias = typing._ConcatenateGenericAlias # noqa
+# 3.9
+elif sys.version_info[:2] >= (3, 9):
+    @_TypeAliasForm
+    def Concatenate(self, parameters):
+        """Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a
+        higher order function which adds, removes or transforms parameters of a
+        callable.
+
+        For example::
+
+           Callable[Concatenate[int, P], int]
+
+        See PEP 612 for detailed information.
+        """
+        return _concatenate_getitem(self, parameters)
+# 3.7-8
+else:
+    class _ConcatenateForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            return _concatenate_getitem(self, parameters)
+
+    Concatenate = _ConcatenateForm(
+        'Concatenate',
+        doc="""Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a
+        higher order function which adds, removes or transforms parameters of a
+        callable.
+
+        For example::
+
+           Callable[Concatenate[int, P], int]
+
+        See PEP 612 for detailed information.
+        """)
+
+# 3.10+
+if hasattr(typing, 'TypeGuard'):
+    TypeGuard = typing.TypeGuard
+# 3.9
+elif sys.version_info[:2] >= (3, 9):
+    class _TypeGuardForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    @_TypeGuardForm
+    def TypeGuard(self, parameters):
+        """Special typing form used to annotate the return type of a user-defined
+        type guard function.  ``TypeGuard`` only accepts a single type argument.
+        At runtime, functions marked this way should return a boolean.
+
+        ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static
+        type checkers to determine a more precise type of an expression within a
+        program's code flow.  Usually type narrowing is done by analyzing
+        conditional code flow and applying the narrowing to a block of code.  The
+        conditional expression here is sometimes referred to as a "type guard".
+
+        Sometimes it would be convenient to use a user-defined boolean function
+        as a type guard.  Such a function should use ``TypeGuard[...]`` as its
+        return type to alert static type checkers to this intention.
+
+        Using  ``-> TypeGuard`` tells the static type checker that for a given
+        function:
+
+        1. The return value is a boolean.
+        2. If the return value is ``True``, the type of its argument
+        is the type inside ``TypeGuard``.
+
+        For example::
+
+            def is_str(val: Union[str, float]):
+                # "isinstance" type guard
+                if isinstance(val, str):
+                    # Type of ``val`` is narrowed to ``str``
+                    ...
+                else:
+                    # Else, type of ``val`` is narrowed to ``float``.
+                    ...
+
+        Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower
+        form of ``TypeA`` (it can even be a wider form) and this may lead to
+        type-unsafe results.  The main reason is to allow for things like
+        narrowing ``List[object]`` to ``List[str]`` even though the latter is not
+        a subtype of the former, since ``List`` is invariant.  The responsibility of
+        writing type-safe type guards is left to the user.
+
+        ``TypeGuard`` also works with type variables.  For more information, see
+        PEP 647 (User-Defined Type Guards).
+        """
+        item = typing._type_check(parameters, f'{self} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+# 3.7-3.8
+else:
+    class _TypeGuardForm(typing._SpecialForm, _root=True):
+
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            item = typing._type_check(parameters,
+                                      f'{self._name} accepts only a single type')
+            return typing._GenericAlias(self, (item,))
+
+    TypeGuard = _TypeGuardForm(
+        'TypeGuard',
+        doc="""Special typing form used to annotate the return type of a user-defined
+        type guard function.  ``TypeGuard`` only accepts a single type argument.
+        At runtime, functions marked this way should return a boolean.
+
+        ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static
+        type checkers to determine a more precise type of an expression within a
+        program's code flow.  Usually type narrowing is done by analyzing
+        conditional code flow and applying the narrowing to a block of code.  The
+        conditional expression here is sometimes referred to as a "type guard".
+
+        Sometimes it would be convenient to use a user-defined boolean function
+        as a type guard.  Such a function should use ``TypeGuard[...]`` as its
+        return type to alert static type checkers to this intention.
+
+        Using  ``-> TypeGuard`` tells the static type checker that for a given
+        function:
+
+        1. The return value is a boolean.
+        2. If the return value is ``True``, the type of its argument
+        is the type inside ``TypeGuard``.
+
+        For example::
+
+            def is_str(val: Union[str, float]):
+                # "isinstance" type guard
+                if isinstance(val, str):
+                    # Type of ``val`` is narrowed to ``str``
+                    ...
+                else:
+                    # Else, type of ``val`` is narrowed to ``float``.
+                    ...
+
+        Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower
+        form of ``TypeA`` (it can even be a wider form) and this may lead to
+        type-unsafe results.  The main reason is to allow for things like
+        narrowing ``List[object]`` to ``List[str]`` even though the latter is not
+        a subtype of the former, since ``List`` is invariant.  The responsibility of
+        writing type-safe type guards is left to the user.
+
+        ``TypeGuard`` also works with type variables.  For more information, see
+        PEP 647 (User-Defined Type Guards).
+        """)
+
+
+# Vendored from cpython typing._SpecialFrom
+class _SpecialForm(typing._Final, _root=True):
+    __slots__ = ('_name', '__doc__', '_getitem')
+
+    def __init__(self, getitem):
+        self._getitem = getitem
+        self._name = getitem.__name__
+        self.__doc__ = getitem.__doc__
+
+    def __getattr__(self, item):
+        if item in {'__name__', '__qualname__'}:
+            return self._name
+
+        raise AttributeError(item)
+
+    def __mro_entries__(self, bases):
+        raise TypeError(f"Cannot subclass {self!r}")
+
+    def __repr__(self):
+        return f'typing_extensions.{self._name}'
+
+    def __reduce__(self):
+        return self._name
+
+    def __call__(self, *args, **kwds):
+        raise TypeError(f"Cannot instantiate {self!r}")
+
+    def __or__(self, other):
+        return typing.Union[self, other]
+
+    def __ror__(self, other):
+        return typing.Union[other, self]
+
+    def __instancecheck__(self, obj):
+        raise TypeError(f"{self} cannot be used with isinstance()")
+
+    def __subclasscheck__(self, cls):
+        raise TypeError(f"{self} cannot be used with issubclass()")
+
+    @typing._tp_cache
+    def __getitem__(self, parameters):
+        return self._getitem(self, parameters)
+
+
+if hasattr(typing, "LiteralString"):
+    LiteralString = typing.LiteralString
+else:
+    @_SpecialForm
+    def LiteralString(self, params):
+        """Represents an arbitrary literal string.
+
+        Example::
+
+          from typing_extensions import LiteralString
+
+          def query(sql: LiteralString) -> ...:
+              ...
+
+          query("SELECT * FROM table")  # ok
+          query(f"SELECT * FROM {input()}")  # not ok
+
+        See PEP 675 for details.
+
+        """
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, "Self"):
+    Self = typing.Self
+else:
+    @_SpecialForm
+    def Self(self, params):
+        """Used to spell the type of "self" in classes.
+
+        Example::
+
+          from typing import Self
+
+          class ReturnsSelf:
+              def parse(self, data: bytes) -> Self:
+                  ...
+                  return self
+
+        """
+
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, "Never"):
+    Never = typing.Never
+else:
+    @_SpecialForm
+    def Never(self, params):
+        """The bottom type, a type that has no members.
+
+        This can be used to define a function that should never be
+        called, or a function that never returns::
+
+            from typing_extensions import Never
+
+            def never_call_me(arg: Never) -> None:
+                pass
+
+            def int_or_str(arg: int | str) -> None:
+                never_call_me(arg)  # type checker error
+                match arg:
+                    case int():
+                        print("It's an int")
+                    case str():
+                        print("It's a str")
+                    case _:
+                        never_call_me(arg)  # ok, arg is of type Never
+
+        """
+
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, 'Required'):
+    Required = typing.Required
+    NotRequired = typing.NotRequired
+elif sys.version_info[:2] >= (3, 9):
+    class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    @_ExtensionsSpecialForm
+    def Required(self, parameters):
+        """A special typing construct to mark a key of a total=False TypedDict
+        as required. For example:
+
+            class Movie(TypedDict, total=False):
+                title: Required[str]
+                year: int
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+
+        There is no runtime checking that a required key is actually provided
+        when instantiating a related TypedDict.
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+
+    @_ExtensionsSpecialForm
+    def NotRequired(self, parameters):
+        """A special typing construct to mark a key of a TypedDict as
+        potentially missing. For example:
+
+            class Movie(TypedDict):
+                title: str
+                year: NotRequired[int]
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+
+else:
+    class _RequiredForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            item = typing._type_check(parameters,
+                                      f'{self._name} accepts only a single type.')
+            return typing._GenericAlias(self, (item,))
+
+    Required = _RequiredForm(
+        'Required',
+        doc="""A special typing construct to mark a key of a total=False TypedDict
+        as required. For example:
+
+            class Movie(TypedDict, total=False):
+                title: Required[str]
+                year: int
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+
+        There is no runtime checking that a required key is actually provided
+        when instantiating a related TypedDict.
+        """)
+    NotRequired = _RequiredForm(
+        'NotRequired',
+        doc="""A special typing construct to mark a key of a TypedDict as
+        potentially missing. For example:
+
+            class Movie(TypedDict):
+                title: str
+                year: NotRequired[int]
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+        """)
+
+
+if hasattr(typing, "Unpack"):  # 3.11+
+    Unpack = typing.Unpack
+elif sys.version_info[:2] >= (3, 9):
+    class _UnpackSpecialForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+    class _UnpackAlias(typing._GenericAlias, _root=True):
+        __class__ = typing.TypeVar
+
+    @_UnpackSpecialForm
+    def Unpack(self, parameters):
+        """A special typing construct to unpack a variadic type. For example:
+
+            Shape = TypeVarTuple('Shape')
+            Batch = NewType('Batch', int)
+
+            def add_batch_axis(
+                x: Array[Unpack[Shape]]
+            ) -> Array[Batch, Unpack[Shape]]: ...
+
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
+        return _UnpackAlias(self, (item,))
+
+    def _is_unpack(obj):
+        return isinstance(obj, _UnpackAlias)
+
+else:
+    class _UnpackAlias(typing._GenericAlias, _root=True):
+        __class__ = typing.TypeVar
+
+    class _UnpackForm(typing._SpecialForm, _root=True):
+        def __repr__(self):
+            return 'typing_extensions.' + self._name
+
+        def __getitem__(self, parameters):
+            item = typing._type_check(parameters,
+                                      f'{self._name} accepts only a single type.')
+            return _UnpackAlias(self, (item,))
+
+    Unpack = _UnpackForm(
+        'Unpack',
+        doc="""A special typing construct to unpack a variadic type. For example:
+
+            Shape = TypeVarTuple('Shape')
+            Batch = NewType('Batch', int)
+
+            def add_batch_axis(
+                x: Array[Unpack[Shape]]
+            ) -> Array[Batch, Unpack[Shape]]: ...
+
+        """)
+
+    def _is_unpack(obj):
+        return isinstance(obj, _UnpackAlias)
+
+
+if hasattr(typing, "TypeVarTuple"):  # 3.11+
+
+    # Add default Parameter - PEP 696
+    class TypeVarTuple(typing.TypeVarTuple, _DefaultMixin, _root=True):
+        """Type variable tuple."""
+
+        def __init__(self, name, *, default=None):
+            super().__init__(name)
+            _DefaultMixin.__init__(self, default)
+
+            # for pickling:
+            try:
+                def_mod = sys._getframe(1).f_globals.get('__name__', '__main__')
+            except (AttributeError, ValueError):
+                def_mod = None
+            if def_mod != 'typing_extensions':
+                self.__module__ = def_mod
+
+else:
+    class TypeVarTuple(_DefaultMixin):
+        """Type variable tuple.
+
+        Usage::
+
+            Ts = TypeVarTuple('Ts')
+
+        In the same way that a normal type variable is a stand-in for a single
+        type such as ``int``, a type variable *tuple* is a stand-in for a *tuple*
+        type such as ``Tuple[int, str]``.
+
+        Type variable tuples can be used in ``Generic`` declarations.
+        Consider the following example::
+
+            class Array(Generic[*Ts]): ...
+
+        The ``Ts`` type variable tuple here behaves like ``tuple[T1, T2]``,
+        where ``T1`` and ``T2`` are type variables. To use these type variables
+        as type parameters of ``Array``, we must *unpack* the type variable tuple using
+        the star operator: ``*Ts``. The signature of ``Array`` then behaves
+        as if we had simply written ``class Array(Generic[T1, T2]): ...``.
+        In contrast to ``Generic[T1, T2]``, however, ``Generic[*Shape]`` allows
+        us to parameterise the class with an *arbitrary* number of type parameters.
+
+        Type variable tuples can be used anywhere a normal ``TypeVar`` can.
+        This includes class definitions, as shown above, as well as function
+        signatures and variable annotations::
+
+            class Array(Generic[*Ts]):
+
+                def __init__(self, shape: Tuple[*Ts]):
+                    self._shape: Tuple[*Ts] = shape
+
+                def get_shape(self) -> Tuple[*Ts]:
+                    return self._shape
+
+            shape = (Height(480), Width(640))
+            x: Array[Height, Width] = Array(shape)
+            y = abs(x)  # Inferred type is Array[Height, Width]
+            z = x + x   #        ...    is Array[Height, Width]
+            x.get_shape()  #     ...    is tuple[Height, Width]
+
+        """
+
+        # Trick Generic __parameters__.
+        __class__ = typing.TypeVar
+
+        def __iter__(self):
+            yield self.__unpacked__
+
+        def __init__(self, name, *, default=None):
+            self.__name__ = name
+            _DefaultMixin.__init__(self, default)
+
+            # for pickling:
+            try:
+                def_mod = sys._getframe(1).f_globals.get('__name__', '__main__')
+            except (AttributeError, ValueError):
+                def_mod = None
+            if def_mod != 'typing_extensions':
+                self.__module__ = def_mod
+
+            self.__unpacked__ = Unpack[self]
+
+        def __repr__(self):
+            return self.__name__
+
+        def __hash__(self):
+            return object.__hash__(self)
+
+        def __eq__(self, other):
+            return self is other
+
+        def __reduce__(self):
+            return self.__name__
+
+        def __init_subclass__(self, *args, **kwds):
+            if '_root' not in kwds:
+                raise TypeError("Cannot subclass special typing classes")
+
+
+if hasattr(typing, "reveal_type"):
+    reveal_type = typing.reveal_type
+else:
+    def reveal_type(__obj: T) -> T:
+        """Reveal the inferred type of a variable.
+
+        When a static type checker encounters a call to ``reveal_type()``,
+        it will emit the inferred type of the argument::
+
+            x: int = 1
+            reveal_type(x)
+
+        Running a static type checker (e.g., ``mypy``) on this example
+        will produce output similar to 'Revealed type is "builtins.int"'.
+
+        At runtime, the function prints the runtime type of the
+        argument and returns it unchanged.
+
+        """
+        print(f"Runtime type is {type(__obj).__name__!r}", file=sys.stderr)
+        return __obj
+
+
+if hasattr(typing, "assert_never"):
+    assert_never = typing.assert_never
+else:
+    def assert_never(__arg: Never) -> Never:
+        """Assert to the type checker that a line of code is unreachable.
+
+        Example::
+
+            def int_or_str(arg: int | str) -> None:
+                match arg:
+                    case int():
+                        print("It's an int")
+                    case str():
+                        print("It's a str")
+                    case _:
+                        assert_never(arg)
+
+        If a type checker finds that a call to assert_never() is
+        reachable, it will emit an error.
+
+        At runtime, this throws an exception when called.
+
+        """
+        raise AssertionError("Expected code to be unreachable")
+
+
+if hasattr(typing, 'dataclass_transform'):
+    dataclass_transform = typing.dataclass_transform
+else:
+    def dataclass_transform(
+        *,
+        eq_default: bool = True,
+        order_default: bool = False,
+        kw_only_default: bool = False,
+        field_specifiers: typing.Tuple[
+            typing.Union[typing.Type[typing.Any], typing.Callable[..., typing.Any]],
+            ...
+        ] = (),
+        **kwargs: typing.Any,
+    ) -> typing.Callable[[T], T]:
+        """Decorator that marks a function, class, or metaclass as providing
+        dataclass-like behavior.
+
+        Example:
+
+            from typing_extensions import dataclass_transform
+
+            _T = TypeVar("_T")
+
+            # Used on a decorator function
+            @dataclass_transform()
+            def create_model(cls: type[_T]) -> type[_T]:
+                ...
+                return cls
+
+            @create_model
+            class CustomerModel:
+                id: int
+                name: str
+
+            # Used on a base class
+            @dataclass_transform()
+            class ModelBase: ...
+
+            class CustomerModel(ModelBase):
+                id: int
+                name: str
+
+            # Used on a metaclass
+            @dataclass_transform()
+            class ModelMeta(type): ...
+
+            class ModelBase(metaclass=ModelMeta): ...
+
+            class CustomerModel(ModelBase):
+                id: int
+                name: str
+
+        Each of the ``CustomerModel`` classes defined in this example will now
+        behave similarly to a dataclass created with the ``@dataclasses.dataclass``
+        decorator. For example, the type checker will synthesize an ``__init__``
+        method.
+
+        The arguments to this decorator can be used to customize this behavior:
+        - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be
+          True or False if it is omitted by the caller.
+        - ``order_default`` indicates whether the ``order`` parameter is
+          assumed to be True or False if it is omitted by the caller.
+        - ``kw_only_default`` indicates whether the ``kw_only`` parameter is
+          assumed to be True or False if it is omitted by the caller.
+        - ``field_specifiers`` specifies a static list of supported classes
+          or functions that describe fields, similar to ``dataclasses.field()``.
+
+        At runtime, this decorator records its arguments in the
+        ``__dataclass_transform__`` attribute on the decorated object.
+
+        See PEP 681 for details.
+
+        """
+        def decorator(cls_or_fn):
+            cls_or_fn.__dataclass_transform__ = {
+                "eq_default": eq_default,
+                "order_default": order_default,
+                "kw_only_default": kw_only_default,
+                "field_specifiers": field_specifiers,
+                "kwargs": kwargs,
+            }
+            return cls_or_fn
+        return decorator
+
+
+if hasattr(typing, "override"):
+    override = typing.override
+else:
+    _F = typing.TypeVar("_F", bound=typing.Callable[..., typing.Any])
+
+    def override(__arg: _F) -> _F:
+        """Indicate that a method is intended to override a method in a base class.
+
+        Usage:
+
+            class Base:
+                def method(self) -> None: ...
+                    pass
+
+            class Child(Base):
+                @override
+                def method(self) -> None:
+                    super().method()
+
+        When this decorator is applied to a method, the type checker will
+        validate that it overrides a method with the same name on a base class.
+        This helps prevent bugs that may occur when a base class is changed
+        without an equivalent change to a child class.
+
+        See PEP 698 for details.
+
+        """
+        return __arg
+
+
+# We have to do some monkey patching to deal with the dual nature of
+# Unpack/TypeVarTuple:
+# - We want Unpack to be a kind of TypeVar so it gets accepted in
+#   Generic[Unpack[Ts]]
+# - We want it to *not* be treated as a TypeVar for the purposes of
+#   counting generic parameters, so that when we subscript a generic,
+#   the runtime doesn't try to substitute the Unpack with the subscripted type.
+if not hasattr(typing, "TypeVarTuple"):
+    typing._collect_type_vars = _collect_type_vars
+    typing._check_generic = _check_generic
+
+
+# Backport typing.NamedTuple as it exists in Python 3.11.
+# In 3.11, the ability to define generic `NamedTuple`s was supported.
+# This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8.
+if sys.version_info >= (3, 11):
+    NamedTuple = typing.NamedTuple
+else:
+    def _caller():
+        try:
+            return sys._getframe(2).f_globals.get('__name__', '__main__')
+        except (AttributeError, ValueError):  # For platforms without _getframe()
+            return None
+
+    def _make_nmtuple(name, types, module, defaults=()):
+        fields = [n for n, t in types]
+        annotations = {n: typing._type_check(t, f"field {n} annotation must be a type")
+                       for n, t in types}
+        nm_tpl = collections.namedtuple(name, fields,
+                                        defaults=defaults, module=module)
+        nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = annotations
+        # The `_field_types` attribute was removed in 3.9;
+        # in earlier versions, it is the same as the `__annotations__` attribute
+        if sys.version_info < (3, 9):
+            nm_tpl._field_types = annotations
+        return nm_tpl
+
+    _prohibited_namedtuple_fields = typing._prohibited
+    _special_namedtuple_fields = frozenset({'__module__', '__name__', '__annotations__'})
+
+    class _NamedTupleMeta(type):
+        def __new__(cls, typename, bases, ns):
+            assert _NamedTuple in bases
+            for base in bases:
+                if base is not _NamedTuple and base is not typing.Generic:
+                    raise TypeError(
+                        'can only inherit from a NamedTuple type and Generic')
+            bases = tuple(tuple if base is _NamedTuple else base for base in bases)
+            types = ns.get('__annotations__', {})
+            default_names = []
+            for field_name in types:
+                if field_name in ns:
+                    default_names.append(field_name)
+                elif default_names:
+                    raise TypeError(f"Non-default namedtuple field {field_name} "
+                                    f"cannot follow default field"
+                                    f"{'s' if len(default_names) > 1 else ''} "
+                                    f"{', '.join(default_names)}")
+            nm_tpl = _make_nmtuple(
+                typename, types.items(),
+                defaults=[ns[n] for n in default_names],
+                module=ns['__module__']
+            )
+            nm_tpl.__bases__ = bases
+            if typing.Generic in bases:
+                class_getitem = typing.Generic.__class_getitem__.__func__
+                nm_tpl.__class_getitem__ = classmethod(class_getitem)
+            # update from user namespace without overriding special namedtuple attributes
+            for key in ns:
+                if key in _prohibited_namedtuple_fields:
+                    raise AttributeError("Cannot overwrite NamedTuple attribute " + key)
+                elif key not in _special_namedtuple_fields and key not in nm_tpl._fields:
+                    setattr(nm_tpl, key, ns[key])
+            if typing.Generic in bases:
+                nm_tpl.__init_subclass__()
+            return nm_tpl
+
+    def NamedTuple(__typename, __fields=None, **kwargs):
+        if __fields is None:
+            __fields = kwargs.items()
+        elif kwargs:
+            raise TypeError("Either list of fields or keywords"
+                            " can be provided to NamedTuple, not both")
+        return _make_nmtuple(__typename, __fields, module=_caller())
+
+    NamedTuple.__doc__ = typing.NamedTuple.__doc__
+    _NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {})
+
+    # On 3.8+, alter the signature so that it matches typing.NamedTuple.
+    # The signature of typing.NamedTuple on >=3.8 is invalid syntax in Python 3.7,
+    # so just leave the signature as it is on 3.7.
+    if sys.version_info >= (3, 8):
+        NamedTuple.__text_signature__ = '(typename, fields=None, /, **kwargs)'
+
+    def _namedtuple_mro_entries(bases):
+        assert NamedTuple in bases
+        return (_NamedTuple,)
+
+    NamedTuple.__mro_entries__ = _namedtuple_mro_entries
index 8e015069a5927893df3c3652e4b5c31544716fc2..e1774da37b5fdbc807d29e24ad130114ddc3f8ab 100644 (file)
@@ -1,6 +1,10 @@
 packaging==21.3
 pyparsing==3.0.9
-appdirs==1.4.3
+
+platformdirs==2.6.2
+# required for platformdirs on Python < 3.8
+typing_extensions==4.4.0
+
 jaraco.text==3.7.0
 # required for jaraco.text on older Pythons
 importlib_resources==5.4.0
index 38d0b21ad96d8b31288881fc874e26922d0b8e54..0a88551ce0dc90d0d384c90c47750ffaad5b39c8 100644 (file)
@@ -1,4 +1,4 @@
-__pycache__/zipp.cpython-310.pyc,,\r
+__pycache__/zipp.cpython-311.pyc,,\r
 zipp-3.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
 zipp-3.7.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
 zipp-3.7.0.dist-info/METADATA,sha256=ZLzgaXTyZX_MxTU0lcGfhdPY4CjFrT_3vyQ2Fo49pl8,2261\r
index 70897eea6287802112e775476a52daeabd871d41..bacc5d77a295022195054db27267d70725f1d4b3 100644 (file)
@@ -58,7 +58,8 @@ class VendorImporter:
         """Return a module spec for vendored names."""
         return (
             importlib.util.spec_from_loader(fullname, self)
-            if self._module_matches_namespace(fullname) else None
+            if self._module_matches_namespace(fullname)
+            else None
         )
 
     def install(self):
@@ -70,7 +71,11 @@ class VendorImporter:
 
 
 names = (
-    'packaging', 'pyparsing', 'appdirs', 'jaraco', 'importlib_resources',
+    'packaging',
+    'pyparsing',
+    'platformdirs',
+    'jaraco',
+    'importlib_resources',
     'more_itertools',
 )
 VendorImporter(__name__, names).install()
index 937b72c861ac8bad321cf566c7d481ba83375296..cd0e6b0b569ab041e10c35f126f5886672595a13 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = setuptools
-version = 65.7.0
+version = 66.0.0
 author = Python Packaging Authority
 author_email = distutils-sig@python.org
 description = Easily download, build, install, upgrade, and uninstall Python packages
index d8c2dff6280879a678e0b4543a1465a5090b0dc6..60c443f235e48c866054e9d6a0f0c554c795b2d7 100644 (file)
@@ -6,14 +6,14 @@ importlib_metadata-4.11.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
 importlib_metadata-4.11.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92\r
 importlib_metadata-4.11.1.dist-info/top_level.txt,sha256=CO3fD9yylANiXkrMo4qHLV_mqXL2sC5JFKgt1yWAT-A,19\r
 importlib_metadata/__init__.py,sha256=Wkh_tb0u0Ds_615ByV9VLLjqgoOWirwMY8EW40oO3nM,30122\r
-importlib_metadata/__pycache__/__init__.cpython-310.pyc,,\r
-importlib_metadata/__pycache__/_adapters.cpython-310.pyc,,\r
-importlib_metadata/__pycache__/_collections.cpython-310.pyc,,\r
-importlib_metadata/__pycache__/_compat.cpython-310.pyc,,\r
-importlib_metadata/__pycache__/_functools.cpython-310.pyc,,\r
-importlib_metadata/__pycache__/_itertools.cpython-310.pyc,,\r
-importlib_metadata/__pycache__/_meta.cpython-310.pyc,,\r
-importlib_metadata/__pycache__/_text.cpython-310.pyc,,\r
+importlib_metadata/__pycache__/__init__.cpython-311.pyc,,\r
+importlib_metadata/__pycache__/_adapters.cpython-311.pyc,,\r
+importlib_metadata/__pycache__/_collections.cpython-311.pyc,,\r
+importlib_metadata/__pycache__/_compat.cpython-311.pyc,,\r
+importlib_metadata/__pycache__/_functools.cpython-311.pyc,,\r
+importlib_metadata/__pycache__/_itertools.cpython-311.pyc,,\r
+importlib_metadata/__pycache__/_meta.cpython-311.pyc,,\r
+importlib_metadata/__pycache__/_text.cpython-311.pyc,,\r
 importlib_metadata/_adapters.py,sha256=B6fCi5-8mLVDFUZj3krI5nAo-mKp1dH_qIavyIyFrJs,1862\r
 importlib_metadata/_collections.py,sha256=CJ0OTCHIjWA0ZIVS4voORAsn2R4R2cQBEtPsZEJpASY,743\r
 importlib_metadata/_compat.py,sha256=EU2XCFBPFByuI0Of6XkAuBYbzqSyjwwwwqmsK4ccna0,1826\r
index 7a68a2f26c1dbd4d6aa8b2863731e4264f9be145..7f579ddb1c103d245584f0eb2ed927da1987303c 100644 (file)
@@ -6,15 +6,15 @@ importlib_resources-5.4.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
 importlib_resources-5.4.0.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92\r
 importlib_resources-5.4.0.dist-info/top_level.txt,sha256=fHIjHU1GZwAjvcydpmUnUrTnbvdiWjG4OEVZK8by0TQ,20\r
 importlib_resources/__init__.py,sha256=zuA0lbRgtVVCcAztM0z5LuBiOCV9L_3qtI6mW2p5xAg,525\r
-importlib_resources/__pycache__/__init__.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_adapters.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_common.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_compat.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_itertools.cpython-310.pyc,,\r
-importlib_resources/__pycache__/_legacy.cpython-310.pyc,,\r
-importlib_resources/__pycache__/abc.cpython-310.pyc,,\r
-importlib_resources/__pycache__/readers.cpython-310.pyc,,\r
-importlib_resources/__pycache__/simple.cpython-310.pyc,,\r
+importlib_resources/__pycache__/__init__.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_adapters.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_common.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_compat.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_itertools.cpython-311.pyc,,\r
+importlib_resources/__pycache__/_legacy.cpython-311.pyc,,\r
+importlib_resources/__pycache__/abc.cpython-311.pyc,,\r
+importlib_resources/__pycache__/readers.cpython-311.pyc,,\r
+importlib_resources/__pycache__/simple.cpython-311.pyc,,\r
 importlib_resources/_adapters.py,sha256=o51tP2hpVtohP33gSYyAkGNpLfYDBqxxYsadyiRZi1E,4504\r
 importlib_resources/_common.py,sha256=iIxAaQhotSh6TLLUEfL_ynU2fzEeyHMz9JcL46mUhLg,2741\r
 importlib_resources/_compat.py,sha256=3LpkIfeN9x4oXjRea5TxZP5VYhPlzuVRhGe-hEv-S0s,2704\r
@@ -25,34 +25,34 @@ importlib_resources/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
 importlib_resources/readers.py,sha256=_9QLGQ5AzrED3PY8S2Zf8V6yLR0-nqqYqtQmgleDJzY,3566\r
 importlib_resources/simple.py,sha256=xt0qhXbwt3bZ86zuaaKbTiE9A0mDbwu0saRjUq_pcY0,2836\r
 importlib_resources/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/__pycache__/__init__.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/_compat.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_contents.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_files.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_open.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_path.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_read.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_reader.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/test_resource.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/update-zips.cpython-310.pyc,,\r
-importlib_resources/tests/__pycache__/util.cpython-310.pyc,,\r
+importlib_resources/tests/__pycache__/__init__.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/_compat.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_contents.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_files.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_open.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_path.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_read.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_reader.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/test_resource.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/update-zips.cpython-311.pyc,,\r
+importlib_resources/tests/__pycache__/util.cpython-311.pyc,,\r
 importlib_resources/tests/_compat.py,sha256=QGI_4p0DXybypoYvw0kr3jfQqvls3p8u4wy4Wvf0Z_o,435\r
 importlib_resources/tests/data01/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data01/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data01/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data01/binary.file,sha256=BU7ewdAhH2JP7Qy8qdT5QAsOSRxDdCryxbCr6_DJkNg,4\r
 importlib_resources/tests/data01/subdirectory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data01/subdirectory/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data01/subdirectory/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data01/subdirectory/binary.file,sha256=BU7ewdAhH2JP7Qy8qdT5QAsOSRxDdCryxbCr6_DJkNg,4\r
 importlib_resources/tests/data01/utf-16.file,sha256=t5q9qhxX0rYqItBOM8D3ylwG-RHrnOYteTLtQr6sF7g,44\r
 importlib_resources/tests/data01/utf-8.file,sha256=kwWgYG4yQ-ZF2X_WA66EjYPmxJRn-w8aSOiS9e8tKYY,20\r
 importlib_resources/tests/data02/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data02/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data02/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data02/one/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data02/one/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data02/one/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data02/one/resource1.txt,sha256=10flKac7c-XXFzJ3t-AB5MJjlBy__dSZvPE_dOm2q6U,13\r
 importlib_resources/tests/data02/two/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/data02/two/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/data02/two/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/data02/two/resource2.txt,sha256=lt2jbN3TMn9QiFKM832X39bU_62UptDdUkoYzkvEbl0,13\r
 importlib_resources/tests/namespacedata01/binary.file,sha256=BU7ewdAhH2JP7Qy8qdT5QAsOSRxDdCryxbCr6_DJkNg,4\r
 importlib_resources/tests/namespacedata01/utf-16.file,sha256=t5q9qhxX0rYqItBOM8D3ylwG-RHrnOYteTLtQr6sF7g,44\r
@@ -68,8 +68,8 @@ importlib_resources/tests/test_resource.py,sha256=DqfLNc9kaN5obqxU8kn0sRUWMf9Myg
 importlib_resources/tests/update-zips.py,sha256=x3iJVqWnMM5qp4Oob2Pl3o6Yi03sUjEv_5Wf-UCg3ps,1415\r
 importlib_resources/tests/util.py,sha256=X1j-0C96pu3_tmtJuLhzfBfcfMenOphDLkxtCt5j7t4,5309\r
 importlib_resources/tests/zipdata01/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/zipdata01/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/zipdata01/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/zipdata01/ziptestdata.zip,sha256=z5Of4dsv3T0t-46B0MsVhxlhsPGMz28aUhJDWpj3_oY,876\r
 importlib_resources/tests/zipdata02/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-importlib_resources/tests/zipdata02/__pycache__/__init__.cpython-310.pyc,,\r
+importlib_resources/tests/zipdata02/__pycache__/__init__.cpython-311.pyc,,\r
 importlib_resources/tests/zipdata02/ziptestdata.zip,sha256=ydI-_j-xgQ7tDxqBp9cjOqXBGxUp6ZBbwVJu6Xj-nrY,698\r
diff --git a/setuptools/_vendor/jaraco.context-4.1.1.dist-info/INSTALLER b/setuptools/_vendor/jaraco.context-4.1.1.dist-info/INSTALLER
deleted file mode 100644 (file)
index a1b589e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pip
diff --git a/setuptools/_vendor/jaraco.context-4.1.1.dist-info/LICENSE b/setuptools/_vendor/jaraco.context-4.1.1.dist-info/LICENSE
deleted file mode 100644 (file)
index 353924b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright Jason R. Coombs
-
-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.
diff --git a/setuptools/_vendor/jaraco.context-4.1.1.dist-info/METADATA b/setuptools/_vendor/jaraco.context-4.1.1.dist-info/METADATA
deleted file mode 100644 (file)
index 908711b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-Metadata-Version: 2.1
-Name: jaraco.context
-Version: 4.1.1
-Summary: Context managers by jaraco
-Home-page: https://github.com/jaraco/jaraco.context
-Author: Jason R. Coombs
-Author-email: jaraco@jaraco.com
-License: UNKNOWN
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3 :: Only
-Requires-Python: >=3.6
-License-File: LICENSE
-Provides-Extra: docs
-Requires-Dist: sphinx ; extra == 'docs'
-Requires-Dist: jaraco.packaging (>=8.2) ; extra == 'docs'
-Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
-Provides-Extra: testing
-Requires-Dist: pytest (>=6) ; extra == 'testing'
-Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
-Requires-Dist: pytest-flake8 ; extra == 'testing'
-Requires-Dist: pytest-cov ; extra == 'testing'
-Requires-Dist: pytest-enabler (>=1.0.1) ; extra == 'testing'
-Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
-Requires-Dist: pytest-mypy ; (platform_python_implementation != "PyPy") and extra == 'testing'
-
-.. image:: https://img.shields.io/pypi/v/jaraco.context.svg
-   :target: `PyPI link`_
-
-.. image:: https://img.shields.io/pypi/pyversions/jaraco.context.svg
-   :target: `PyPI link`_
-
-.. _PyPI link: https://pypi.org/project/jaraco.context
-
-.. image:: https://github.com/jaraco/jaraco.context/workflows/tests/badge.svg
-   :target: https://github.com/jaraco/jaraco.context/actions?query=workflow%3A%22tests%22
-   :alt: tests
-
-.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
-   :target: https://github.com/psf/black
-   :alt: Code style: Black
-
-.. image:: https://readthedocs.org/projects/jaracocontext/badge/?version=latest
-   :target: https://jaracocontext.readthedocs.io/en/latest/?badge=latest
-
-.. image:: https://img.shields.io/badge/skeleton-2021-informational
-   :target: https://blog.jaraco.com/skeleton
-
-
diff --git a/setuptools/_vendor/jaraco.context-4.1.1.dist-info/RECORD b/setuptools/_vendor/jaraco.context-4.1.1.dist-info/RECORD
deleted file mode 100644 (file)
index f40d48c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-jaraco.context-4.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
-jaraco.context-4.1.1.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
-jaraco.context-4.1.1.dist-info/METADATA,sha256=bvqDGCk6Z7TkohUqr5XZm19SbF9mVxrtXjN6uF_BAMQ,2031\r
-jaraco.context-4.1.1.dist-info/RECORD,,\r
-jaraco.context-4.1.1.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92\r
-jaraco.context-4.1.1.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
-jaraco/__pycache__/context.cpython-310.pyc,,\r
-jaraco/context.py,sha256=7X1tpCLc5EN45iWGzGcsH0Unx62REIkvtRvglj0SiUA,5420\r
diff --git a/setuptools/_vendor/jaraco.context-4.1.1.dist-info/WHEEL b/setuptools/_vendor/jaraco.context-4.1.1.dist-info/WHEEL
deleted file mode 100644 (file)
index 5bad85f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.0)
-Root-Is-Purelib: true
-Tag: py3-none-any
-
diff --git a/setuptools/_vendor/jaraco.context-4.1.1.dist-info/top_level.txt b/setuptools/_vendor/jaraco.context-4.1.1.dist-info/top_level.txt
deleted file mode 100644 (file)
index f6205a5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-jaraco
diff --git a/setuptools/_vendor/jaraco.context-4.2.0.dist-info/INSTALLER b/setuptools/_vendor/jaraco.context-4.2.0.dist-info/INSTALLER
new file mode 100644 (file)
index 0000000..a1b589e
--- /dev/null
@@ -0,0 +1 @@
+pip
diff --git a/setuptools/_vendor/jaraco.context-4.2.0.dist-info/LICENSE b/setuptools/_vendor/jaraco.context-4.2.0.dist-info/LICENSE
new file mode 100644 (file)
index 0000000..353924b
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright Jason R. Coombs
+
+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.
diff --git a/setuptools/_vendor/jaraco.context-4.2.0.dist-info/METADATA b/setuptools/_vendor/jaraco.context-4.2.0.dist-info/METADATA
new file mode 100644 (file)
index 0000000..34d372e
--- /dev/null
@@ -0,0 +1,67 @@
+Metadata-Version: 2.1
+Name: jaraco.context
+Version: 4.2.0
+Summary: Context managers by jaraco
+Home-page: https://github.com/jaraco/jaraco.context
+Author: Jason R. Coombs
+Author-email: jaraco@jaraco.com
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Requires-Python: >=3.7
+License-File: LICENSE
+Provides-Extra: docs
+Requires-Dist: sphinx (>=3.5) ; extra == 'docs'
+Requires-Dist: jaraco.packaging (>=9) ; extra == 'docs'
+Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
+Requires-Dist: furo ; extra == 'docs'
+Requires-Dist: jaraco.tidelift (>=1.4) ; extra == 'docs'
+Provides-Extra: testing
+Requires-Dist: pytest (>=6) ; extra == 'testing'
+Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
+Requires-Dist: pytest-flake8 ; extra == 'testing'
+Requires-Dist: flake8 (<5) ; extra == 'testing'
+Requires-Dist: pytest-cov ; extra == 'testing'
+Requires-Dist: pytest-enabler (>=1.3) ; extra == 'testing'
+Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
+Requires-Dist: pytest-mypy (>=0.9.1) ; (platform_python_implementation != "PyPy") and extra == 'testing'
+
+.. image:: https://img.shields.io/pypi/v/jaraco.context.svg
+   :target: https://pypi.org/project/jaraco.context
+
+.. image:: https://img.shields.io/pypi/pyversions/jaraco.context.svg
+
+.. image:: https://github.com/jaraco/jaraco.context/workflows/tests/badge.svg
+   :target: https://github.com/jaraco/jaraco.context/actions?query=workflow%3A%22tests%22
+   :alt: tests
+
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
+   :target: https://github.com/psf/black
+   :alt: Code style: Black
+
+.. image:: https://readthedocs.org/projects/jaracocontext/badge/?version=latest
+   :target: https://jaracocontext.readthedocs.io/en/latest/?badge=latest
+
+.. image:: https://img.shields.io/badge/skeleton-2022-informational
+   :target: https://blog.jaraco.com/skeleton
+
+.. image:: https://tidelift.com/badges/package/pypi/jaraco.context
+   :target: https://tidelift.com/subscription/pkg/pypi-jaraco.context?utm_source=pypi-jaraco.context&utm_medium=readme
+
+For Enterprise
+==============
+
+Available as part of the Tidelift Subscription.
+
+This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.
+
+`Learn more <https://tidelift.com/subscription/pkg/pypi-jaraco.context?utm_source=pypi-jaraco.context&utm_medium=referral&utm_campaign=github>`_.
+
+Security Contact
+================
+
+To report a security vulnerability, please use the
+`Tidelift security contact <https://tidelift.com/security>`_.
+Tidelift will coordinate the fix and disclosure.
diff --git a/setuptools/_vendor/jaraco.context-4.2.0.dist-info/RECORD b/setuptools/_vendor/jaraco.context-4.2.0.dist-info/RECORD
new file mode 100644 (file)
index 0000000..a34ec80
--- /dev/null
@@ -0,0 +1,8 @@
+jaraco.context-4.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+jaraco.context-4.2.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
+jaraco.context-4.2.0.dist-info/METADATA,sha256=6gWxpGoBWTzl4e8J1HisvNsL79YB4t1DG7ziQj-0k9Y,2883\r
+jaraco.context-4.2.0.dist-info/RECORD,,\r
+jaraco.context-4.2.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92\r
+jaraco.context-4.2.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
+jaraco/__pycache__/context.cpython-311.pyc,,\r
+jaraco/context.py,sha256=NvdB7ArVCDrhtexOnOwSv4ScDuueGbf9LRiOSCqPn6Y,6488\r
diff --git a/setuptools/_vendor/jaraco.context-4.2.0.dist-info/WHEEL b/setuptools/_vendor/jaraco.context-4.2.0.dist-info/WHEEL
new file mode 100644 (file)
index 0000000..57e3d84
--- /dev/null
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.38.4)
+Root-Is-Purelib: true
+Tag: py3-none-any
+
diff --git a/setuptools/_vendor/jaraco.context-4.2.0.dist-info/top_level.txt b/setuptools/_vendor/jaraco.context-4.2.0.dist-info/top_level.txt
new file mode 100644 (file)
index 0000000..f6205a5
--- /dev/null
@@ -0,0 +1 @@
+jaraco
diff --git a/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/INSTALLER b/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/INSTALLER
deleted file mode 100644 (file)
index a1b589e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pip
diff --git a/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/LICENSE b/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/LICENSE
deleted file mode 100644 (file)
index 353924b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright Jason R. Coombs
-
-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.
diff --git a/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/METADATA b/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/METADATA
deleted file mode 100644 (file)
index 12dfbdd..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-Metadata-Version: 2.1
-Name: jaraco.functools
-Version: 3.5.0
-Summary: Functools like those found in stdlib
-Home-page: https://github.com/jaraco/jaraco.functools
-Author: Jason R. Coombs
-Author-email: jaraco@jaraco.com
-License: UNKNOWN
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3 :: Only
-Requires-Python: >=3.7
-License-File: LICENSE
-Requires-Dist: more-itertools
-Provides-Extra: docs
-Requires-Dist: sphinx ; extra == 'docs'
-Requires-Dist: jaraco.packaging (>=8.2) ; extra == 'docs'
-Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
-Provides-Extra: testing
-Requires-Dist: pytest (>=6) ; extra == 'testing'
-Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
-Requires-Dist: pytest-flake8 ; extra == 'testing'
-Requires-Dist: pytest-cov ; extra == 'testing'
-Requires-Dist: pytest-enabler (>=1.0.1) ; extra == 'testing'
-Requires-Dist: jaraco.classes ; extra == 'testing'
-Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
-Requires-Dist: pytest-mypy ; (platform_python_implementation != "PyPy") and extra == 'testing'
-
-.. image:: https://img.shields.io/pypi/v/jaraco.functools.svg
-   :target: `PyPI link`_
-
-.. image:: https://img.shields.io/pypi/pyversions/jaraco.functools.svg
-
-.. image:: https://img.shields.io/travis/jaraco/jaraco.functools/master.svg
-   :target: `PyPI link`_
-
-.. _PyPI link: https://pypi.org/project/jaraco.functools
-
-.. image:: https://github.com/jaraco/jaraco.functools/workflows/tests/badge.svg
-   :target: https://github.com/jaraco/jaraco.functools/actions?query=workflow%3A%22tests%22
-   :alt: tests
-
-.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
-   :target: https://github.com/psf/black
-   :alt: Code style: Black
-
-.. image:: https://readthedocs.org/projects/jaracofunctools/badge/?version=latest
-   :target: https://jaracofunctools.readthedocs.io/en/latest/?badge=latest
-
-.. image:: https://img.shields.io/badge/skeleton-2021-informational
-   :target: https://blog.jaraco.com/skeleton
-
-Additional functools in the spirit of stdlib's functools.
-
-
diff --git a/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/RECORD b/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/RECORD
deleted file mode 100644 (file)
index fbda3d1..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-jaraco.functools-3.5.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
-jaraco.functools-3.5.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
-jaraco.functools-3.5.0.dist-info/METADATA,sha256=cE9C7u9bo_GjLAuw4nML67a25kUaPDiHn4j03lG4jd0,2276\r
-jaraco.functools-3.5.0.dist-info/RECORD,,\r
-jaraco.functools-3.5.0.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92\r
-jaraco.functools-3.5.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
-jaraco/__pycache__/functools.cpython-310.pyc,,\r
-jaraco/functools.py,sha256=PtEHbXZstgVJrwje4GvJOsz5pEbgslOcgEn2EJNpr2c,13494\r
diff --git a/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/WHEEL b/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/WHEEL
deleted file mode 100644 (file)
index 5bad85f..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.0)
-Root-Is-Purelib: true
-Tag: py3-none-any
-
diff --git a/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/top_level.txt b/setuptools/_vendor/jaraco.functools-3.5.0.dist-info/top_level.txt
deleted file mode 100644 (file)
index f6205a5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-jaraco
diff --git a/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/INSTALLER b/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/INSTALLER
new file mode 100644 (file)
index 0000000..a1b589e
--- /dev/null
@@ -0,0 +1 @@
+pip
diff --git a/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/LICENSE b/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/LICENSE
new file mode 100644 (file)
index 0000000..353924b
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright Jason R. Coombs
+
+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.
diff --git a/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/METADATA b/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/METADATA
new file mode 100644 (file)
index 0000000..fa8f021
--- /dev/null
@@ -0,0 +1,75 @@
+Metadata-Version: 2.1
+Name: jaraco.functools
+Version: 3.5.2
+Summary: Functools like those found in stdlib
+Home-page: https://github.com/jaraco/jaraco.functools
+Author: Jason R. Coombs
+Author-email: jaraco@jaraco.com
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Requires-Python: >=3.7
+License-File: LICENSE
+Requires-Dist: more-itertools
+Provides-Extra: docs
+Requires-Dist: sphinx (>=3.5) ; extra == 'docs'
+Requires-Dist: jaraco.packaging (>=9) ; extra == 'docs'
+Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
+Requires-Dist: jaraco.tidelift (>=1.4) ; extra == 'docs'
+Provides-Extra: testing
+Requires-Dist: pytest (>=6) ; extra == 'testing'
+Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
+Requires-Dist: pytest-flake8 ; extra == 'testing'
+Requires-Dist: flake8 (<5) ; extra == 'testing'
+Requires-Dist: pytest-cov ; extra == 'testing'
+Requires-Dist: pytest-enabler (>=1.3) ; extra == 'testing'
+Requires-Dist: jaraco.classes ; extra == 'testing'
+Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
+Requires-Dist: pytest-mypy (>=0.9.1) ; (platform_python_implementation != "PyPy") and extra == 'testing'
+
+.. image:: https://img.shields.io/pypi/v/jaraco.functools.svg
+   :target: `PyPI link`_
+
+.. image:: https://img.shields.io/pypi/pyversions/jaraco.functools.svg
+
+.. image:: https://img.shields.io/travis/jaraco/jaraco.functools/master.svg
+   :target: `PyPI link`_
+
+.. _PyPI link: https://pypi.org/project/jaraco.functools
+
+.. image:: https://github.com/jaraco/jaraco.functools/workflows/tests/badge.svg
+   :target: https://github.com/jaraco/jaraco.functools/actions?query=workflow%3A%22tests%22
+   :alt: tests
+
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
+   :target: https://github.com/psf/black
+   :alt: Code style: Black
+
+.. image:: https://readthedocs.org/projects/jaracofunctools/badge/?version=latest
+   :target: https://jaracofunctools.readthedocs.io/en/latest/?badge=latest
+
+.. image:: https://img.shields.io/badge/skeleton-2022-informational
+   :target: https://blog.jaraco.com/skeleton
+
+.. image:: https://tidelift.com/badges/package/pypi/jaraco.functools
+   :target: https://tidelift.com/subscription/pkg/pypi-jaraco.functools?utm_source=pypi-jaraco.functools&utm_medium=readme
+
+Additional functools in the spirit of stdlib's functools.
+
+For Enterprise
+==============
+
+Available as part of the Tidelift Subscription.
+
+This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.
+
+`Learn more <https://tidelift.com/subscription/pkg/pypi-jaraco.functools?utm_source=pypi-jaraco.functools&utm_medium=referral&utm_campaign=github>`_.
+
+Security Contact
+================
+
+To report a security vulnerability, please use the
+`Tidelift security contact <https://tidelift.com/security>`_.
+Tidelift will coordinate the fix and disclosure.
diff --git a/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/RECORD b/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/RECORD
new file mode 100644 (file)
index 0000000..127b826
--- /dev/null
@@ -0,0 +1,8 @@
+jaraco.functools-3.5.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+jaraco.functools-3.5.2.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
+jaraco.functools-3.5.2.dist-info/METADATA,sha256=ZIViwS4ZOmaWwA5ArwZ_xXQGR9WDnUSzx-0MO5kGPi8,3154\r
+jaraco.functools-3.5.2.dist-info/RECORD,,\r
+jaraco.functools-3.5.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92\r
+jaraco.functools-3.5.2.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
+jaraco/__pycache__/functools.cpython-311.pyc,,\r
+jaraco/functools.py,sha256=PtEHbXZstgVJrwje4GvJOsz5pEbgslOcgEn2EJNpr2c,13494\r
diff --git a/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/WHEEL b/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/WHEEL
new file mode 100644 (file)
index 0000000..becc9a6
--- /dev/null
@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.37.1)
+Root-Is-Purelib: true
+Tag: py3-none-any
+
diff --git a/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/top_level.txt b/setuptools/_vendor/jaraco.functools-3.5.2.dist-info/top_level.txt
new file mode 100644 (file)
index 0000000..f6205a5
--- /dev/null
@@ -0,0 +1 @@
+jaraco
index 916ad7d3f81087cea1a463df4b315b27a4089138..dd471b070829ecac87c98a302c5eb71337c44d1c 100644 (file)
@@ -7,4 +7,4 @@ jaraco.text-3.7.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FG
 jaraco.text-3.7.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7\r
 jaraco/text/Lorem ipsum.txt,sha256=N_7c_79zxOufBY9HZ3yzMgOkNv-TkOTTio4BydrSjgs,1335\r
 jaraco/text/__init__.py,sha256=I56MW2ZFwPrYXIxzqxMBe2A1t-T4uZBgEgAKe9-JoqM,15538\r
-jaraco/text/__pycache__/__init__.cpython-310.pyc,,\r
+jaraco/text/__pycache__/__init__.cpython-311.pyc,,\r
index 87a4e3dca299c4201ac50f6ef589dc73f1c45576..818f16f364c1a529985df5fbf81155eae4c24a45 100644 (file)
@@ -211,3 +211,43 @@ class suppress(contextlib.suppress, contextlib.ContextDecorator):
     ...     {}['']
     >>> key_error()
     """
+
+
+class on_interrupt(contextlib.ContextDecorator):
+    """
+    Replace a KeyboardInterrupt with SystemExit(1)
+
+    >>> def do_interrupt():
+    ...     raise KeyboardInterrupt()
+    >>> on_interrupt('error')(do_interrupt)()
+    Traceback (most recent call last):
+    ...
+    SystemExit: 1
+    >>> on_interrupt('error', code=255)(do_interrupt)()
+    Traceback (most recent call last):
+    ...
+    SystemExit: 255
+    >>> on_interrupt('suppress')(do_interrupt)()
+    >>> with __import__('pytest').raises(KeyboardInterrupt):
+    ...     on_interrupt('ignore')(do_interrupt)()
+    """
+
+    def __init__(
+        self,
+        action='error',
+        # py3.7 compat
+        # /,
+        code=1,
+    ):
+        self.action = action
+        self.code = code
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exctype, excinst, exctb):
+        if exctype is not KeyboardInterrupt or self.action == 'ignore':
+            return
+        elif self.action == 'error':
+            raise SystemExit(self.code) from excinst
+        return self.action == 'suppress'
index 36ffbd8653e228ca6c4cfc8b7f45dc2ce76b8f5d..c3cbb8338241e51923587cc0673044354e13e2d9 100644 (file)
@@ -7,9 +7,9 @@ more_itertools-8.8.0.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQ
 more_itertools-8.8.0.dist-info/top_level.txt,sha256=fAuqRXu9LPhxdB9ujJowcFOu1rZ8wzSpOW9_jlKis6M,15\r
 more_itertools/__init__.py,sha256=C7sXffHTXM3P-iaLPPfqfmDoxOflQMJLcM7ed9p3jak,82\r
 more_itertools/__init__.pyi,sha256=5B3eTzON1BBuOLob1vCflyEb2lSd6usXQQ-Cv-hXkeA,43\r
-more_itertools/__pycache__/__init__.cpython-310.pyc,,\r
-more_itertools/__pycache__/more.cpython-310.pyc,,\r
-more_itertools/__pycache__/recipes.cpython-310.pyc,,\r
+more_itertools/__pycache__/__init__.cpython-311.pyc,,\r
+more_itertools/__pycache__/more.cpython-311.pyc,,\r
+more_itertools/__pycache__/recipes.cpython-311.pyc,,\r
 more_itertools/more.py,sha256=DlZa8v6JihVwfQ5zHidOA-xDE0orcQIUyxVnCaUoDKE,117968\r
 more_itertools/more.pyi,sha256=r32pH2raBC1zih3evK4fyvAXvrUamJqc6dgV7QCRL_M,14977\r
 more_itertools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
index db6e12f2dcc2619d58d30fb58627bb0d6813f2d4..4c64d142b95b296ef444adb0d3e29b147935a465 100644 (file)
@@ -153,5 +153,3 @@ look up an entry by its index.
 
 OrderedSet is automatically tested on Python 2.7, 3.4, 3.5, 3.6, and 3.7.
 We've checked more informally that it works on PyPy and PyPy3.
-
-
index 89579a07cad1abb3d0cc86bdc2ae49b222df21b8..6d85b247eaf6f0d545379dd66411840a726caff5 100644 (file)
@@ -1,9 +1,9 @@
-__pycache__/ordered_set.cpython-310.pyc,,\r
+__pycache__/ordered_set.cpython-311.pyc,,\r
 ordered_set-3.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
-ordered_set-3.1.1.dist-info/METADATA,sha256=uGvfFaNmhcl69lGdHmyOXc30N3U6Jn8DByfh_VHEPpw,5359\r
+ordered_set-3.1.1.dist-info/METADATA,sha256=qEaJM9CbGNixB_jvfohisKbXTUjcef6nCCcBJju6f4U,5357\r
 ordered_set-3.1.1.dist-info/MIT-LICENSE,sha256=TvRE7qUSUBcd0ols7wgNf3zDEEJWW7kv7WDRySrMBBE,1071\r
 ordered_set-3.1.1.dist-info/RECORD,,\r
 ordered_set-3.1.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
-ordered_set-3.1.1.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110\r
+ordered_set-3.1.1.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110\r
 ordered_set-3.1.1.dist-info/top_level.txt,sha256=NTY2_aDi1Do9fl3Z9EmWPxasFkUeW2dzO2D3RDx5CfM,12\r
 ordered_set.py,sha256=dbaCcs27dyN9gnMWGF5nA_BrVn6Q-NrjKYJpV9_fgBs,15130\r
index 0b18a281107a0448a9980396d9d324ea2aa7a7f8..9d8f872bbf2275e6d1785238e90b0321f4b6f323 100644 (file)
@@ -1,5 +1,5 @@
 Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.1)
+Generator: bdist_wheel (0.38.4)
 Root-Is-Purelib: true
 Tag: py2-none-any
 Tag: py3-none-any
index 97cace1022fe4c138f5549ab48ca59afb96b3895..77b1ed967794eea571c637864688eca9ef88f8df 100644 (file)
@@ -9,17 +9,17 @@ packaging-21.3.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9
 packaging-21.3.dist-info/top_level.txt,sha256=zFdHrhWnPslzsiP455HutQsqPB6v0KCtNUMtUtrefDw,10\r
 packaging/__about__.py,sha256=ugASIO2w1oUyH8_COqQ2X_s0rDhjbhQC3yJocD03h2c,661\r
 packaging/__init__.py,sha256=b9Kk5MF7KxhhLgcDmiUWukN-LatWFxPdNug0joPhHSk,497\r
-packaging/__pycache__/__about__.cpython-310.pyc,,\r
-packaging/__pycache__/__init__.cpython-310.pyc,,\r
-packaging/__pycache__/_manylinux.cpython-310.pyc,,\r
-packaging/__pycache__/_musllinux.cpython-310.pyc,,\r
-packaging/__pycache__/_structures.cpython-310.pyc,,\r
-packaging/__pycache__/markers.cpython-310.pyc,,\r
-packaging/__pycache__/requirements.cpython-310.pyc,,\r
-packaging/__pycache__/specifiers.cpython-310.pyc,,\r
-packaging/__pycache__/tags.cpython-310.pyc,,\r
-packaging/__pycache__/utils.cpython-310.pyc,,\r
-packaging/__pycache__/version.cpython-310.pyc,,\r
+packaging/__pycache__/__about__.cpython-311.pyc,,\r
+packaging/__pycache__/__init__.cpython-311.pyc,,\r
+packaging/__pycache__/_manylinux.cpython-311.pyc,,\r
+packaging/__pycache__/_musllinux.cpython-311.pyc,,\r
+packaging/__pycache__/_structures.cpython-311.pyc,,\r
+packaging/__pycache__/markers.cpython-311.pyc,,\r
+packaging/__pycache__/requirements.cpython-311.pyc,,\r
+packaging/__pycache__/specifiers.cpython-311.pyc,,\r
+packaging/__pycache__/tags.cpython-311.pyc,,\r
+packaging/__pycache__/utils.cpython-311.pyc,,\r
+packaging/__pycache__/version.cpython-311.pyc,,\r
 packaging/_manylinux.py,sha256=XcbiXB-qcjv3bcohp6N98TMpOP4_j3m-iOA8ptK2GWY,11488\r
 packaging/_musllinux.py,sha256=_KGgY_qc7vhMGpoqss25n2hiLCNKRtvz9mCrS7gkqyc,4378\r
 packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431\r
index 7a4e49abebe07adc13fba36dfc8e1c1c84edd7f5..b07b9bd09e11ee442a09a664515e2f135a3d9079 100644 (file)
@@ -1,29 +1,29 @@
-pyparsing-3.0.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-pyparsing-3.0.9.dist-info/LICENSE,sha256=ENUSChaAWAT_2otojCIL-06POXQbVzIGBNRVowngGXI,1023
-pyparsing-3.0.9.dist-info/METADATA,sha256=h_fpm9rwvgZsE8v5YNF4IAo-IpaFWCOfUEm5MMByIiM,4207
-pyparsing-3.0.9.dist-info/RECORD,,
-pyparsing-3.0.9.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-pyparsing-3.0.9.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81
-pyparsing/__init__.py,sha256=52QH3lgPbJhba0estckoGPHRH8JvQSSCGoWiEn2m0bU,9159
-pyparsing/__pycache__/__init__.cpython-38.pyc,,
-pyparsing/__pycache__/actions.cpython-38.pyc,,
-pyparsing/__pycache__/common.cpython-38.pyc,,
-pyparsing/__pycache__/core.cpython-38.pyc,,
-pyparsing/__pycache__/exceptions.cpython-38.pyc,,
-pyparsing/__pycache__/helpers.cpython-38.pyc,,
-pyparsing/__pycache__/results.cpython-38.pyc,,
-pyparsing/__pycache__/testing.cpython-38.pyc,,
-pyparsing/__pycache__/unicode.cpython-38.pyc,,
-pyparsing/__pycache__/util.cpython-38.pyc,,
-pyparsing/actions.py,sha256=wU9i32e0y1ymxKE3OUwSHO-SFIrt1h_wv6Ws0GQjpNU,6426
-pyparsing/common.py,sha256=lFL97ooIeR75CmW5hjURZqwDCTgruqltcTCZ-ulLO2Q,12936
-pyparsing/core.py,sha256=u8GptQE_H6wMkl8OZhxeK1aAPIDXXNgwdShORBwBVS4,213310
-pyparsing/diagram/__init__.py,sha256=f_EfxahqrdkRVahmTwLJXkZ9EEDKNd-O7lBbpJYlE1g,23668
-pyparsing/diagram/__pycache__/__init__.cpython-38.pyc,,
-pyparsing/exceptions.py,sha256=3LbSafD32NYb1Tzt85GHNkhEAU1eZkTtNSk24cPMemo,9023
-pyparsing/helpers.py,sha256=QpUOjW0-psvueMwWb9bQpU2noqKCv98_wnw1VSzSdVo,39129
-pyparsing/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-pyparsing/results.py,sha256=HgNvWVXBdQP-Q6PtJfoCEeOJk2nwEvG-2KVKC5sGA30,25341
-pyparsing/testing.py,sha256=7tu4Abp4uSeJV0N_yEPRmmNUhpd18ZQP3CrX41DM814,13402
-pyparsing/unicode.py,sha256=fwuhMj30SQ165Cv7HJpu-rSxGbRm93kN9L4Ei7VGc1Y,10787
-pyparsing/util.py,sha256=kq772O5YSeXOSdP-M31EWpbH_ayj7BMHImBYo9xPD5M,6805
+pyparsing-3.0.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+pyparsing-3.0.9.dist-info/LICENSE,sha256=ENUSChaAWAT_2otojCIL-06POXQbVzIGBNRVowngGXI,1023\r
+pyparsing-3.0.9.dist-info/METADATA,sha256=h_fpm9rwvgZsE8v5YNF4IAo-IpaFWCOfUEm5MMByIiM,4207\r
+pyparsing-3.0.9.dist-info/RECORD,,\r
+pyparsing-3.0.9.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+pyparsing-3.0.9.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81\r
+pyparsing/__init__.py,sha256=52QH3lgPbJhba0estckoGPHRH8JvQSSCGoWiEn2m0bU,9159\r
+pyparsing/__pycache__/__init__.cpython-311.pyc,,\r
+pyparsing/__pycache__/actions.cpython-311.pyc,,\r
+pyparsing/__pycache__/common.cpython-311.pyc,,\r
+pyparsing/__pycache__/core.cpython-311.pyc,,\r
+pyparsing/__pycache__/exceptions.cpython-311.pyc,,\r
+pyparsing/__pycache__/helpers.cpython-311.pyc,,\r
+pyparsing/__pycache__/results.cpython-311.pyc,,\r
+pyparsing/__pycache__/testing.cpython-311.pyc,,\r
+pyparsing/__pycache__/unicode.cpython-311.pyc,,\r
+pyparsing/__pycache__/util.cpython-311.pyc,,\r
+pyparsing/actions.py,sha256=wU9i32e0y1ymxKE3OUwSHO-SFIrt1h_wv6Ws0GQjpNU,6426\r
+pyparsing/common.py,sha256=lFL97ooIeR75CmW5hjURZqwDCTgruqltcTCZ-ulLO2Q,12936\r
+pyparsing/core.py,sha256=u8GptQE_H6wMkl8OZhxeK1aAPIDXXNgwdShORBwBVS4,213310\r
+pyparsing/diagram/__init__.py,sha256=f_EfxahqrdkRVahmTwLJXkZ9EEDKNd-O7lBbpJYlE1g,23668\r
+pyparsing/diagram/__pycache__/__init__.cpython-311.pyc,,\r
+pyparsing/exceptions.py,sha256=3LbSafD32NYb1Tzt85GHNkhEAU1eZkTtNSk24cPMemo,9023\r
+pyparsing/helpers.py,sha256=QpUOjW0-psvueMwWb9bQpU2noqKCv98_wnw1VSzSdVo,39129\r
+pyparsing/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+pyparsing/results.py,sha256=HgNvWVXBdQP-Q6PtJfoCEeOJk2nwEvG-2KVKC5sGA30,25341\r
+pyparsing/testing.py,sha256=7tu4Abp4uSeJV0N_yEPRmmNUhpd18ZQP3CrX41DM814,13402\r
+pyparsing/unicode.py,sha256=fwuhMj30SQ165Cv7HJpu-rSxGbRm93kN9L4Ei7VGc1Y,10787\r
+pyparsing/util.py,sha256=kq772O5YSeXOSdP-M31EWpbH_ayj7BMHImBYo9xPD5M,6805\r
index 2d93fa2cffa6b5a3808e320fb9f8cc4cd8c35c58..5f7a6b06b3c7a4b5a57d42cc98237a737e237163 100644 (file)
@@ -1,15 +1,15 @@
-tomli-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-tomli-2.0.1.dist-info/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072
-tomli-2.0.1.dist-info/METADATA,sha256=zPDceKmPwJGLWtZykrHixL7WVXWmJGzZ1jyRT5lCoPI,8875
-tomli-2.0.1.dist-info/RECORD,,
-tomli-2.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-tomli-2.0.1.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81
-tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396
-tomli/__pycache__/__init__.cpython-38.pyc,,
-tomli/__pycache__/_parser.cpython-38.pyc,,
-tomli/__pycache__/_re.cpython-38.pyc,,
-tomli/__pycache__/_types.cpython-38.pyc,,
-tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633
-tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943
-tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
-tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
+tomli-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
+tomli-2.0.1.dist-info/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072\r
+tomli-2.0.1.dist-info/METADATA,sha256=zPDceKmPwJGLWtZykrHixL7WVXWmJGzZ1jyRT5lCoPI,8875\r
+tomli-2.0.1.dist-info/RECORD,,\r
+tomli-2.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0\r
+tomli-2.0.1.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81\r
+tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396\r
+tomli/__pycache__/__init__.cpython-311.pyc,,\r
+tomli/__pycache__/_parser.cpython-311.pyc,,\r
+tomli/__pycache__/_re.cpython-311.pyc,,\r
+tomli/__pycache__/_types.cpython-311.pyc,,\r
+tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633\r
+tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943\r
+tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254\r
+tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26\r
index 9a7f60078f2ca2d5971115b278796460fee4c77f..786de8542d2af35de3dd7ab39267fac8110307b6 100644 (file)
@@ -1,4 +1,4 @@
-__pycache__/typing_extensions.cpython-310.pyc,,\r
+__pycache__/typing_extensions.cpython-311.pyc,,\r
 typing_extensions-4.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
 typing_extensions-4.0.1.dist-info/LICENSE,sha256=_xfOlOECAk3raHc-scx0ynbaTmWPNzUx8Kwi1oprsa0,12755\r
 typing_extensions-4.0.1.dist-info/METADATA,sha256=iZ_5HONZZBXtF4kroz-IPZYIl9M8IE1B00R82dWcBqE,1736\r
index 38d0b21ad96d8b31288881fc874e26922d0b8e54..0a88551ce0dc90d0d384c90c47750ffaad5b39c8 100644 (file)
@@ -1,4 +1,4 @@
-__pycache__/zipp.cpython-310.pyc,,\r
+__pycache__/zipp.cpython-311.pyc,,\r
 zipp-3.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4\r
 zipp-3.7.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050\r
 zipp-3.7.0.dist-info/METADATA,sha256=ZLzgaXTyZX_MxTU0lcGfhdPY4CjFrT_3vyQ2Fo49pl8,2261\r
index 95c818453ea15bf6975226afddef3037e763ca44..1885efb00f24bbd3f0ca30e4eaf580b48c438e63 100644 (file)
@@ -155,7 +155,7 @@ class InfoCommon:
         if self.tag_build:
             version += self.tag_build
         if self.tag_date:
-            version += time.strftime("-%Y%m%d")
+            version += time.strftime("%Y%m%d")
         return version
     vtags = property(tags)
 
index 362e26f3e1aa1dad364a0ec3cbbe9213191b1067..bec418353e0681936616ba0ac7e39f607deb3ee8 100644 (file)
@@ -169,39 +169,35 @@ def distros_for_filename(filename, metadata=None):
 def interpret_distro_name(
     location, basename, metadata, py_version=None, precedence=SOURCE_DIST, platform=None
 ):
-    """Generate alternative interpretations of a source distro name
+    """Generate the interpretation 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,
-        )
+    # find the pivot (p) that splits the name from the version.
+    # infer the version as the first item that has a digit.
+    for p in range(len(parts)):
+        if parts[p][:1].isdigit():
+            break
+    else:
+        p = len(parts)
+
+    yield Distribution(
+        location,
+        metadata,
+        '-'.join(parts[:p]),
+        '-'.join(parts[p:]),
+        py_version=py_version,
+        precedence=precedence,
+        platform=platform
+    )
 
 
 def unique_values(func):
index 350e6429a90343b6fc40428d562d44d3f1c4a41b..45b0d7fbb40d7fa7671b67a0f226783e7d3fb180 100644 (file)
@@ -19,19 +19,18 @@ read = partial(pathlib.Path.read_text, encoding="utf-8")
 
 class TestDistInfo:
 
-    metadata_base = DALS("""
+    metadata_base = DALS(
+        """
         Metadata-Version: 1.2
         Requires-Dist: splort (==4)
         Provides-Extra: baz
         Requires-Dist: quux (>=1.1); extra == 'baz'
-        """)
+        """
+    )
 
     @classmethod
     def build_metadata(cls, **kwargs):
-        lines = (
-            '{key}: {value}\n'.format(**locals())
-            for key, value in kwargs.items()
-        )
+        lines = ('{key}: {value}\n'.format(**locals()) for key, value in kwargs.items())
         return cls.metadata_base + ''.join(lines)
 
     @pytest.fixture
@@ -59,8 +58,7 @@ class TestDistInfo:
 
     def test_distinfo(self, metadata):
         dists = dict(
-            (d.project_name, d)
-            for d in pkg_resources.find_distributions(metadata)
+            (d.project_name, d) for d in pkg_resources.find_distributions(metadata)
         )
 
         assert len(dists) == 2, dists
@@ -84,13 +82,16 @@ class TestDistInfo:
             assert d.extras == ['baz']
 
     def test_invalid_version(self, tmp_path):
+        """
+        Supplying an invalid version crashes dist_info.
+        """
         config = "[metadata]\nname=proj\nversion=42\n[egg_info]\ntag_build=invalid!!!\n"
         (tmp_path / "setup.cfg").write_text(config, encoding="utf-8")
         msg = re.compile("invalid version", re.M | re.I)
-        output = run_command("dist_info", cwd=tmp_path)
-        assert msg.search(output)
-        dist_info = next(tmp_path.glob("*.dist-info"))
-        assert dist_info.name.startswith("proj-42")
+        proc = run_command_inner("dist_info", cwd=tmp_path, check=False)
+        assert proc.returncode
+        assert msg.search(proc.stdout)
+        assert not list(tmp_path.glob("*.dist-info"))
 
     def test_tag_arguments(self, tmp_path):
         config = """
@@ -116,7 +117,7 @@ class TestDistInfo:
     def test_output_dir(self, tmp_path, keep_egg_info):
         config = "[metadata]\nname=proj\nversion=42\n"
         (tmp_path / "setup.cfg").write_text(config, encoding="utf-8")
-        out = (tmp_path / "__out")
+        out = tmp_path / "__out"
         out.mkdir()
         opts = ["--keep-egg-info"] if keep_egg_info else []
         run_command("dist_info", "--output-dir", out, *opts, cwd=tmp_path)
@@ -133,7 +134,9 @@ class TestWheelCompatibility:
     """Make sure the .dist-info directory produced with the ``dist_info`` command
     is the same as the one produced by ``bdist_wheel``.
     """
-    SETUPCFG = DALS("""
+
+    SETUPCFG = DALS(
+        """
     [metadata]
     name = {name}
     version = {version}
@@ -149,7 +152,8 @@ class TestWheelCompatibility:
         executable-name = my_package.module:function
     discover =
         myproj = my_package.other_module:function
-    """)
+    """
+    )
 
     EGG_INFO_OPTS = [
         # Related: #3088 #2872
@@ -189,7 +193,17 @@ class TestWheelCompatibility:
             assert read(dist_info / file) == read(wheel_dist_info / file)
 
 
-def run_command(*cmd, **kwargs):
-    opts = {"stderr": subprocess.STDOUT, "text": True, **kwargs}
+def run_command_inner(*cmd, **kwargs):
+    opts = {
+        "stderr": subprocess.STDOUT,
+        "stdout": subprocess.PIPE,
+        "text": True,
+        'check': True,
+        **kwargs,
+    }
     cmd = [sys.executable, "-c", "__import__('setuptools').setup()", *map(str, cmd)]
-    return subprocess.check_output(cmd, **opts)
+    return subprocess.run(cmd, **opts)
+
+
+def run_command(*args, **kwargs):
+    return run_command_inner(*args, **kwargs).stdout
index 7b0bf1124dc891c3e2628ee385f9f41a35fa6984..8b5356dc8e8cb1cbe12da6c2b42b5a45b1594072 100644 (file)
@@ -180,7 +180,7 @@ class TestPackageIndex:
         for v, vc in versions:
             dists = list(
                 setuptools.package_index.distros_for_url(
-                    'http://example.com/example.zip#egg=example-' + v
+                    'http://example.com/example-foo.zip#egg=example-foo-' + v
                 )
             )
             assert dists[0].version == ''
index 8a122ad7783fac479e8e04e73b27e6e2994dacf8..9b7cf729ba2b29f065041bee931a8620e4188eac 100644 (file)
@@ -89,26 +89,36 @@ def rewrite_more_itertools(pkg_files: Path):
     more_file.write_text(text)
 
 
+def rewrite_platformdirs(pkg_files: Path):
+    """
+    Replace some absolute imports with relative ones.
+    """
+    init = pkg_files.joinpath('__init__.py')
+    text = init.read_text()
+    text = text.replace('from platformdirs.', 'from .')
+    text = text.replace('from typing_extensions', 'from ..typing_extensions')
+    init.write_text(text)
+
+
 def clean(vendor):
     """
     Remove all files out of the vendor directory except the meta
     data (as pip uninstall doesn't support -t).
     """
-    remove_all(
-        path
-        for path in vendor.glob('*')
-        if path.basename() != 'vendored.txt'
-    )
+    remove_all(path for path in vendor.glob('*') if path.basename() != 'vendored.txt')
 
 
 def install(vendor):
     clean(vendor)
     install_args = [
         sys.executable,
-        '-m', 'pip',
+        '-m',
+        'pip',
         'install',
-        '-r', str(vendor / 'vendored.txt'),
-        '-t', str(vendor),
+        '-r',
+        str(vendor / 'vendored.txt'),
+        '-t',
+        str(vendor),
     ]
     subprocess.check_call(install_args)
     (vendor / '__init__.py').write_text('')
@@ -122,6 +132,7 @@ def update_pkg_resources():
     rewrite_jaraco(vendor / 'jaraco', 'pkg_resources.extern')
     rewrite_importlib_resources(vendor / 'importlib_resources', 'pkg_resources.extern')
     rewrite_more_itertools(vendor / "more_itertools")
+    rewrite_platformdirs(vendor / "platformdirs")
 
 
 def update_setuptools():