mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-04-07 04:26:52 +00:00
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
This commit is contained in:
parent
72ad6dc953
commit
f4cd1ba0d6
813 changed files with 66015 additions and 58839 deletions
|
|
@ -13,32 +13,33 @@ The package resource API is designed to work with normal filesystem packages,
|
|||
.zip files and with custom PEP 302 loaders that support the ``get_data()``
|
||||
method.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import os
|
||||
import io
|
||||
import time
|
||||
import re
|
||||
import types
|
||||
import zipfile
|
||||
import zipimport
|
||||
import warnings
|
||||
import stat
|
||||
import functools
|
||||
import pkgutil
|
||||
import operator
|
||||
import platform
|
||||
import collections
|
||||
import plistlib
|
||||
import email.parser
|
||||
import errno
|
||||
import functools
|
||||
import importlib
|
||||
import inspect
|
||||
import io
|
||||
import itertools
|
||||
import ntpath
|
||||
import operator
|
||||
import os
|
||||
import pkgutil
|
||||
import platform
|
||||
import plistlib
|
||||
import posixpath
|
||||
import re
|
||||
import stat
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
import itertools
|
||||
import inspect
|
||||
import ntpath
|
||||
import posixpath
|
||||
import importlib
|
||||
import time
|
||||
import types
|
||||
import warnings
|
||||
import zipfile
|
||||
import zipimport
|
||||
from pkgutil import get_importer
|
||||
|
||||
try:
|
||||
|
|
@ -78,11 +79,6 @@ __import__('pkg_resources.extern.packaging.specifiers')
|
|||
__import__('pkg_resources.extern.packaging.requirements')
|
||||
__import__('pkg_resources.extern.packaging.markers')
|
||||
|
||||
if sys.version_info < (3, 5):
|
||||
raise RuntimeError("Python 3.5 or later is required")
|
||||
|
||||
# declare some globals that will be defined later to
|
||||
# satisfy the linters.
|
||||
require = None
|
||||
working_set = None
|
||||
add_activation_listener = None
|
||||
|
|
@ -174,9 +170,9 @@ def get_supported_platform():
|
|||
"""
|
||||
plat = get_build_platform()
|
||||
m = macosVersionString.match(plat)
|
||||
if m is not None and sys.platform == "darwin":
|
||||
if m is not None and sys.platform == 'darwin':
|
||||
try:
|
||||
plat = 'macosx-%s-%s' % ('.'.join(_macos_vers()[:2]), m.group(3))
|
||||
plat = 'macosx-{}-{}'.format('.'.join(_macos_vers()[:2]), m.group(3))
|
||||
except ValueError:
|
||||
# not macOS
|
||||
pass
|
||||
|
|
@ -248,7 +244,7 @@ class VersionConflict(ResolutionError):
|
|||
Requirement.
|
||||
"""
|
||||
|
||||
_template = "{self.dist} is installed but {self.req} is required"
|
||||
_template = '{self.dist} is installed but {self.req} is required'
|
||||
|
||||
@property
|
||||
def dist(self):
|
||||
|
|
@ -288,8 +284,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):
|
||||
|
|
@ -378,11 +376,11 @@ def get_build_platform():
|
|||
from sysconfig import get_platform
|
||||
|
||||
plat = get_platform()
|
||||
if sys.platform == "darwin" and not plat.startswith('macosx-'):
|
||||
if sys.platform == 'darwin' and not plat.startswith('macosx-'):
|
||||
try:
|
||||
version = _macos_vers()
|
||||
machine = os.uname()[4].replace(" ", "_")
|
||||
return "macosx-%d.%d-%s" % (
|
||||
machine = os.uname()[4].replace(' ', '_')
|
||||
return 'macosx-%d.%d-%s' % (
|
||||
int(version[0]), int(version[1]),
|
||||
_macos_arch(machine),
|
||||
)
|
||||
|
|
@ -393,8 +391,8 @@ def get_build_platform():
|
|||
return plat
|
||||
|
||||
|
||||
macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)")
|
||||
darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)")
|
||||
macosVersionString = re.compile(r'macosx-(\d+)\.(\d+)-(.*)')
|
||||
darwinVersionString = re.compile(r'darwin-(\d+)\.(\d+)\.(\d+)-(.*)')
|
||||
# XXX backward compat
|
||||
get_platform = get_build_platform
|
||||
|
||||
|
|
@ -423,9 +421,9 @@ def compatible_platforms(provided, required):
|
|||
provDarwin = darwinVersionString.match(provided)
|
||||
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":
|
||||
macosversion = '{}.{}'.format(reqMac.group(1), reqMac.group(2))
|
||||
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
|
||||
|
|
@ -465,7 +463,7 @@ def get_distribution(dist):
|
|||
if isinstance(dist, Requirement):
|
||||
dist = get_provider(dist)
|
||||
if not isinstance(dist, Distribution):
|
||||
raise TypeError("Expected string, Requirement, or Distribution", dist)
|
||||
raise TypeError('Expected string, Requirement, or Distribution', dist)
|
||||
return dist
|
||||
|
||||
|
||||
|
|
@ -698,8 +696,10 @@ class WorkingSet:
|
|||
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, # noqa: C901
|
||||
replace_conflicting=False, extras=None,
|
||||
):
|
||||
"""List all distributions needed to (recursively) meet `requirements`
|
||||
|
||||
`requirements` must be a sequence of ``Requirement`` objects. `env`,
|
||||
|
|
@ -765,7 +765,7 @@ class WorkingSet:
|
|||
ws = WorkingSet([])
|
||||
dist = best[req.key] = env.best_match(
|
||||
req, ws, installer,
|
||||
replace_conflicting=replace_conflicting
|
||||
replace_conflicting=replace_conflicting,
|
||||
)
|
||||
if dist is None:
|
||||
requirers = required_by.get(req, None)
|
||||
|
|
@ -791,7 +791,8 @@ class WorkingSet:
|
|||
return to_activate
|
||||
|
||||
def find_plugins(
|
||||
self, plugin_env, full_env=None, installer=None, fallback=True):
|
||||
self, plugin_env, full_env=None, installer=None, fallback=True,
|
||||
):
|
||||
"""Find all activatable distributions in `plugin_env`
|
||||
|
||||
Example usage::
|
||||
|
|
@ -911,7 +912,7 @@ class WorkingSet:
|
|||
def __getstate__(self):
|
||||
return (
|
||||
self.entries[:], self.entry_keys.copy(), self.by_key.copy(),
|
||||
self.callbacks[:]
|
||||
self.callbacks[:],
|
||||
)
|
||||
|
||||
def __setstate__(self, e_k_b_c):
|
||||
|
|
@ -947,7 +948,8 @@ class Environment:
|
|||
|
||||
def __init__(
|
||||
self, search_path=None, platform=get_supported_platform(),
|
||||
python=PY_MAJOR):
|
||||
python=PY_MAJOR,
|
||||
):
|
||||
"""Snapshot distributions available on a search path
|
||||
|
||||
Any distributions found on `search_path` are added to the environment.
|
||||
|
|
@ -977,9 +979,9 @@ class Environment:
|
|||
is returned.
|
||||
"""
|
||||
py_compat = (
|
||||
self.python is None
|
||||
or dist.py_version is None
|
||||
or dist.py_version == self.python
|
||||
self.python is None or
|
||||
dist.py_version is None or
|
||||
dist.py_version == self.python
|
||||
)
|
||||
return py_compat and compatible_platforms(dist.platform, self.platform)
|
||||
|
||||
|
|
@ -1023,7 +1025,8 @@ class Environment:
|
|||
dists.sort(key=operator.attrgetter('hashcmp'), reverse=True)
|
||||
|
||||
def best_match(
|
||||
self, req, working_set, installer=None, replace_conflicting=False):
|
||||
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
|
||||
|
|
@ -1077,7 +1080,7 @@ class Environment:
|
|||
for dist in other[project]:
|
||||
self.add(dist)
|
||||
else:
|
||||
raise TypeError("Can't add %r to environment" % (other,))
|
||||
raise TypeError("Can't add {!r} to environment".format(other))
|
||||
return self
|
||||
|
||||
def __add__(self, other):
|
||||
|
|
@ -1122,31 +1125,31 @@ 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
|
||||
resource_name,
|
||||
)
|
||||
|
||||
def resource_filename(self, package_or_requirement, resource_name):
|
||||
"""Return a true filesystem path for specified resource"""
|
||||
return get_provider(package_or_requirement).get_resource_filename(
|
||||
self, resource_name
|
||||
self, resource_name,
|
||||
)
|
||||
|
||||
def resource_stream(self, package_or_requirement, resource_name):
|
||||
"""Return a readable file-like object for specified resource"""
|
||||
return get_provider(package_or_requirement).get_resource_stream(
|
||||
self, resource_name
|
||||
self, resource_name,
|
||||
)
|
||||
|
||||
def resource_string(self, package_or_requirement, resource_name):
|
||||
"""Return specified resource as a string"""
|
||||
return get_provider(package_or_requirement).get_resource_string(
|
||||
self, resource_name
|
||||
self, resource_name,
|
||||
)
|
||||
|
||||
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
|
||||
resource_name,
|
||||
)
|
||||
|
||||
def extraction_error(self):
|
||||
|
|
@ -1220,13 +1223,13 @@ class ResourceManager:
|
|||
mode = os.stat(path).st_mode
|
||||
if mode & stat.S_IWOTH or mode & stat.S_IWGRP:
|
||||
msg = (
|
||||
"Extraction path is writable by group/others "
|
||||
"and vulnerable to attack when "
|
||||
"used with get_resource_filename ({path}). "
|
||||
"Consider a more secure "
|
||||
"location (set with .set_extraction_path or the "
|
||||
"PYTHON_EGG_CACHE environment variable)."
|
||||
).format(**locals())
|
||||
f'Extraction path is writable by group/others '
|
||||
f'and vulnerable to attack when '
|
||||
f'used with get_resource_filename ({path}). '
|
||||
f'Consider a more secure '
|
||||
f'location (set with .set_extraction_path or the '
|
||||
f'PYTHON_EGG_CACHE environment variable).'
|
||||
)
|
||||
warnings.warn(msg, UserWarning)
|
||||
|
||||
def postprocess(self, tempname, filename):
|
||||
|
|
@ -1270,7 +1273,7 @@ class ResourceManager:
|
|||
"""
|
||||
if self.cached_files:
|
||||
raise ValueError(
|
||||
"Can't change extraction path, files already extracted"
|
||||
"Can't change extraction path, files already extracted",
|
||||
)
|
||||
|
||||
self.extraction_path = path
|
||||
|
|
@ -1296,8 +1299,8 @@ def get_default_cache():
|
|||
named "Python-Eggs".
|
||||
"""
|
||||
return (
|
||||
os.environ.get('PYTHON_EGG_CACHE')
|
||||
or appdirs.user_cache_dir(appname='Python-Eggs')
|
||||
os.environ.get('PYTHON_EGG_CACHE') or
|
||||
appdirs.user_cache_dir(appname='Python-Eggs')
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1402,7 +1405,7 @@ class NullProvider:
|
|||
|
||||
def get_metadata(self, name):
|
||||
if not self.egg_info:
|
||||
return ""
|
||||
return ''
|
||||
path = self._get_metadata_path(name)
|
||||
value = self._get(path)
|
||||
try:
|
||||
|
|
@ -1410,7 +1413,7 @@ class NullProvider:
|
|||
except UnicodeDecodeError as exc:
|
||||
# Include the path in the error message to simplify
|
||||
# troubleshooting, and without changing the exception type.
|
||||
exc.reason += ' in {} file at path: {}'.format(name, path)
|
||||
exc.reason += f' in {name} file at path: {path}'
|
||||
raise
|
||||
|
||||
def get_metadata_lines(self, name):
|
||||
|
|
@ -1434,8 +1437,7 @@ 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()),
|
||||
f'Script {script!r} not found in metadata at {self.egg_info!r}',
|
||||
)
|
||||
script_text = self.get_metadata(script).replace('\r\n', '\n')
|
||||
script_text = script_text.replace('\r', '\n')
|
||||
|
|
@ -1449,24 +1451,24 @@ class NullProvider:
|
|||
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)
|
||||
|
||||
def _has(self, path):
|
||||
raise NotImplementedError(
|
||||
"Can't perform this operation for unregistered loader type"
|
||||
"Can't perform this operation for unregistered loader type",
|
||||
)
|
||||
|
||||
def _isdir(self, path):
|
||||
raise NotImplementedError(
|
||||
"Can't perform this operation for unregistered loader type"
|
||||
"Can't perform this operation for unregistered loader type",
|
||||
)
|
||||
|
||||
def _listdir(self, path):
|
||||
raise NotImplementedError(
|
||||
"Can't perform this operation for unregistered loader type"
|
||||
"Can't perform this operation for unregistered loader type",
|
||||
)
|
||||
|
||||
def _fn(self, base, resource_name):
|
||||
|
|
@ -1536,7 +1538,7 @@ is not allowed.
|
|||
if not invalid:
|
||||
return
|
||||
|
||||
msg = "Use of .. or absolute path in a resource path is not allowed."
|
||||
msg = 'Use of .. or absolute path in a resource path is not allowed.'
|
||||
|
||||
# Aggressively disallow Windows absolute paths
|
||||
if ntpath.isabs(path) and not posixpath.isabs(path):
|
||||
|
|
@ -1545,7 +1547,7 @@ is not allowed.
|
|||
# for compatibility, warn; in future
|
||||
# raise ValueError(msg)
|
||||
warnings.warn(
|
||||
msg[:-1] + " and will raise exceptions in a future release.",
|
||||
msg[:-1] + ' and will raise exceptions in a future release.',
|
||||
DeprecationWarning,
|
||||
stacklevel=4,
|
||||
)
|
||||
|
|
@ -1554,7 +1556,7 @@ is not allowed.
|
|||
if hasattr(self.loader, 'get_data'):
|
||||
return self.loader.get_data(path)
|
||||
raise NotImplementedError(
|
||||
"Can't perform this operation for loaders without 'get_data()'"
|
||||
"Can't perform this operation for loaders without 'get_data()'",
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1708,7 +1710,7 @@ class ZipProvider(EggProvider):
|
|||
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)
|
||||
'{} is not a subpath of {}'.format(fspath, self.zip_pre),
|
||||
)
|
||||
|
||||
def _parts(self, zip_path):
|
||||
|
|
@ -1718,7 +1720,7 @@ class ZipProvider(EggProvider):
|
|||
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)
|
||||
'{} is not a subpath of {}'.format(fspath, self.egg_root),
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
@ -1728,7 +1730,7 @@ class ZipProvider(EggProvider):
|
|||
def get_resource_filename(self, manager, resource_name):
|
||||
if not self.egg_name:
|
||||
raise NotImplementedError(
|
||||
"resource_filename() only supported for .egg, not .zip"
|
||||
'resource_filename() only supported for .egg, not .zip',
|
||||
)
|
||||
# no need to lock for extraction, since we use temp names
|
||||
zip_path = self._resource_to_zip(resource_name)
|
||||
|
|
@ -1753,7 +1755,7 @@ 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)
|
||||
manager, os.path.join(zip_path, name),
|
||||
)
|
||||
# return the extracted directory name
|
||||
return os.path.dirname(last)
|
||||
|
|
@ -1761,19 +1763,21 @@ class ZipProvider(EggProvider):
|
|||
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 OSError(
|
||||
'"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)
|
||||
self.egg_name, self._parts(zip_path),
|
||||
)
|
||||
|
||||
if self._is_current(real_path, zip_path):
|
||||
return real_path
|
||||
|
||||
outf, tmpnam = _mkstemp(
|
||||
".$extract",
|
||||
'.$extract',
|
||||
dir=os.path.dirname(real_path),
|
||||
)
|
||||
os.write(outf, self.loader.get_data(zip_path))
|
||||
|
|
@ -1784,7 +1788,7 @@ class ZipProvider(EggProvider):
|
|||
try:
|
||||
rename(tmpnam, real_path)
|
||||
|
||||
except os.error:
|
||||
except OSError:
|
||||
if os.path.isfile(real_path):
|
||||
if self._is_current(real_path, zip_path):
|
||||
# the file became current since it was checked above,
|
||||
|
|
@ -1797,7 +1801,7 @@ class ZipProvider(EggProvider):
|
|||
return real_path
|
||||
raise
|
||||
|
||||
except os.error:
|
||||
except OSError:
|
||||
# report a user-friendly error
|
||||
manager.extraction_error()
|
||||
|
||||
|
|
@ -1888,9 +1892,9 @@ class FileMetadata(EmptyProvider):
|
|||
|
||||
def get_metadata(self, name):
|
||||
if name != 'PKG-INFO':
|
||||
raise KeyError("No metadata except PKG-INFO is available")
|
||||
raise KeyError('No metadata except PKG-INFO is available')
|
||||
|
||||
with io.open(self.path, encoding='utf-8', errors="replace") as f:
|
||||
with open(self.path, encoding='utf-8', errors='replace') as f:
|
||||
metadata = f.read()
|
||||
self._warn_on_replacement(metadata)
|
||||
return metadata
|
||||
|
|
@ -1898,7 +1902,7 @@ class FileMetadata(EmptyProvider):
|
|||
def _warn_on_replacement(self, metadata):
|
||||
replacement_char = '<EFBFBD>'
|
||||
if replacement_char in metadata:
|
||||
tmpl = "{self.path} could not be properly decoded in UTF-8"
|
||||
tmpl = '{self.path} could not be properly decoded in UTF-8'
|
||||
msg = tmpl.format(**locals())
|
||||
warnings.warn(msg)
|
||||
|
||||
|
|
@ -1984,8 +1988,7 @@ def find_eggs_in_zip(importer, path_item, only=False):
|
|||
if _is_egg_path(subitem):
|
||||
subpath = os.path.join(path_item, subitem)
|
||||
dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath)
|
||||
for dist in dists:
|
||||
yield dist
|
||||
yield from dists
|
||||
elif subitem.lower().endswith(('.dist-info', '.egg-info')):
|
||||
subpath = os.path.join(path_item, subitem)
|
||||
submeta = EggMetadata(zipimport.zipimporter(subpath))
|
||||
|
|
@ -2036,8 +2039,8 @@ def find_on_path(importer, path_item, only=False):
|
|||
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, os.path.join(path_item, 'EGG-INFO'),
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
|
|
@ -2060,8 +2063,7 @@ def find_on_path(importer, path_item, only=False):
|
|||
for entry in path_item_entries:
|
||||
fullpath = os.path.join(path_item, entry)
|
||||
factory = dist_factory(path_item, entry, only)
|
||||
for dist in factory(fullpath):
|
||||
yield dist
|
||||
yield from factory(fullpath)
|
||||
|
||||
|
||||
def dist_factory(path_item, entry, only):
|
||||
|
|
@ -2092,6 +2094,7 @@ class NoDists:
|
|||
>>> list(NoDists()('anything'))
|
||||
[]
|
||||
"""
|
||||
|
||||
def __bool__(self):
|
||||
return False
|
||||
|
||||
|
|
@ -2195,7 +2198,7 @@ def _handle_ns(packageName, path_item):
|
|||
except AttributeError:
|
||||
# capture warnings due to #1111
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
warnings.simplefilter('ignore')
|
||||
loader = importer.find_module(packageName)
|
||||
|
||||
if loader is None:
|
||||
|
|
@ -2206,7 +2209,7 @@ def _handle_ns(packageName, path_item):
|
|||
module.__path__ = []
|
||||
_set_parent_ns(packageName)
|
||||
elif not hasattr(module, '__path__'):
|
||||
raise TypeError("Not a package:", packageName)
|
||||
raise TypeError('Not a package:', packageName)
|
||||
handler = _find_adapter(_namespace_handlers, importer)
|
||||
subpath = handler(importer, path_item, packageName, module)
|
||||
if subpath is not None:
|
||||
|
|
@ -2269,7 +2272,7 @@ def declare_namespace(packageName):
|
|||
try:
|
||||
path = sys.modules[parent].__path__
|
||||
except AttributeError as e:
|
||||
raise TypeError("Not a package:", parent) from e
|
||||
raise TypeError('Not a package:', parent) from e
|
||||
|
||||
# Track what packages are namespaces, so when new path items are added,
|
||||
# they can be updated
|
||||
|
|
@ -2326,8 +2329,13 @@ 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
|
||||
|
|
@ -2396,7 +2404,7 @@ def yield_lines(strs):
|
|||
yield s
|
||||
|
||||
|
||||
MODULE = re.compile(r"\w+(\.\w+)*$").match
|
||||
MODULE = re.compile(r'\w+(\.\w+)*$').match
|
||||
EGG_NAME = re.compile(
|
||||
r"""
|
||||
(?P<name>[^-]+) (
|
||||
|
|
@ -2416,7 +2424,7 @@ class EntryPoint:
|
|||
|
||||
def __init__(self, name, module_name, attrs=(), extras=(), dist=None):
|
||||
if not MODULE(module_name):
|
||||
raise ValueError("Invalid module name", module_name)
|
||||
raise ValueError('Invalid module name', module_name)
|
||||
self.name = name
|
||||
self.module_name = module_name
|
||||
self.attrs = tuple(attrs)
|
||||
|
|
@ -2424,7 +2432,7 @@ class EntryPoint:
|
|||
self.dist = dist
|
||||
|
||||
def __str__(self):
|
||||
s = "%s = %s" % (self.name, self.module_name)
|
||||
s = '{} = {}'.format(self.name, self.module_name)
|
||||
if self.attrs:
|
||||
s += ':' + '.'.join(self.attrs)
|
||||
if self.extras:
|
||||
|
|
@ -2432,7 +2440,7 @@ class EntryPoint:
|
|||
return s
|
||||
|
||||
def __repr__(self):
|
||||
return "EntryPoint.parse(%r)" % str(self)
|
||||
return 'EntryPoint.parse(%r)' % str(self)
|
||||
|
||||
def load(self, require=True, *args, **kwargs):
|
||||
"""
|
||||
|
|
@ -2440,8 +2448,8 @@ class EntryPoint:
|
|||
"""
|
||||
if not require or args or kwargs:
|
||||
warnings.warn(
|
||||
"Parameters to load are deprecated. Call .resolve and "
|
||||
".require separately.",
|
||||
'Parameters to load are deprecated. Call .resolve and '
|
||||
'.require separately.',
|
||||
PkgResourcesDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
|
@ -2478,7 +2486,7 @@ class EntryPoint:
|
|||
r'=\s*'
|
||||
r'(?P<module>[\w.]+)\s*'
|
||||
r'(:\s*(?P<attr>[\w.]+))?\s*'
|
||||
r'(?P<extras>\[.*\])?\s*$'
|
||||
r'(?P<extras>\[.*\])?\s*$',
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
|
@ -2514,12 +2522,12 @@ class EntryPoint:
|
|||
def parse_group(cls, group, lines, dist=None):
|
||||
"""Parse an entry point group"""
|
||||
if not MODULE(group):
|
||||
raise ValueError("Invalid group name", group)
|
||||
raise ValueError('Invalid group name', group)
|
||||
this = {}
|
||||
for line in yield_lines(lines):
|
||||
ep = cls.parse(line, dist)
|
||||
if ep.name in this:
|
||||
raise ValueError("Duplicate entry point", group, ep.name)
|
||||
raise ValueError('Duplicate entry point', group, ep.name)
|
||||
this[ep.name] = ep
|
||||
return this
|
||||
|
||||
|
|
@ -2535,10 +2543,10 @@ class EntryPoint:
|
|||
if group is None:
|
||||
if not lines:
|
||||
continue
|
||||
raise ValueError("Entry points must be listed in groups")
|
||||
raise ValueError('Entry points must be listed in groups')
|
||||
group = group.strip()
|
||||
if group in maps:
|
||||
raise ValueError("Duplicate group name", group)
|
||||
raise ValueError('Duplicate group name', group)
|
||||
maps[group] = cls.parse_group(group, lines, dist)
|
||||
return maps
|
||||
|
||||
|
|
@ -2563,7 +2571,8 @@ class Distribution:
|
|||
def __init__(
|
||||
self, location=None, metadata=None, project_name=None,
|
||||
version=None, py_version=PY_MAJOR, platform=None,
|
||||
precedence=EGG_DIST):
|
||||
precedence=EGG_DIST,
|
||||
):
|
||||
self.project_name = safe_name(project_name or 'Unknown')
|
||||
if version is not None:
|
||||
self._version = safe_version(version)
|
||||
|
|
@ -2583,11 +2592,11 @@ class Distribution:
|
|||
match = EGG_NAME(basename)
|
||||
if match:
|
||||
project_name, version, py_version, platform = match.group(
|
||||
'name', 'ver', 'pyver', 'plat'
|
||||
'name', 'ver', 'pyver', 'plat',
|
||||
)
|
||||
return cls(
|
||||
location, metadata, project_name=project_name, version=version,
|
||||
py_version=py_version, platform=platform, **kw
|
||||
py_version=py_version, platform=platform, **kw,
|
||||
)._reload_version()
|
||||
|
||||
def _reload_version(self):
|
||||
|
|
@ -2642,7 +2651,7 @@ class Distribution:
|
|||
|
||||
@property
|
||||
def parsed_version(self):
|
||||
if not hasattr(self, "_parsed_version"):
|
||||
if not hasattr(self, '_parsed_version'):
|
||||
self._parsed_version = parse_version(self.version)
|
||||
|
||||
return self._parsed_version
|
||||
|
|
@ -2712,8 +2721,8 @@ 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 = []
|
||||
|
|
@ -2739,7 +2748,7 @@ class Distribution:
|
|||
deps.extend(dm[safe_extra(ext)])
|
||||
except KeyError as e:
|
||||
raise UnknownExtra(
|
||||
"%s has no such extra feature %r" % (self, ext)
|
||||
'{} has no such extra feature {!r}'.format(self, ext),
|
||||
) from e
|
||||
return deps
|
||||
|
||||
|
|
@ -2762,8 +2771,7 @@ class Distribution:
|
|||
|
||||
def _get_metadata(self, name):
|
||||
if self.has_metadata(name):
|
||||
for line in self.get_metadata_lines(name):
|
||||
yield line
|
||||
yield from self.get_metadata_lines(name)
|
||||
|
||||
def _get_version(self):
|
||||
lines = self._get_metadata(self.PKG_INFO)
|
||||
|
|
@ -2784,9 +2792,9 @@ class Distribution:
|
|||
|
||||
def egg_name(self):
|
||||
"""Return what this distribution's standard .egg filename should be"""
|
||||
filename = "%s-%s-py%s" % (
|
||||
filename = '{}-{}-py{}'.format(
|
||||
to_filename(self.project_name), to_filename(self.version),
|
||||
self.py_version or PY_MAJOR
|
||||
self.py_version or PY_MAJOR,
|
||||
)
|
||||
|
||||
if self.platform:
|
||||
|
|
@ -2795,7 +2803,7 @@ class Distribution:
|
|||
|
||||
def __repr__(self):
|
||||
if self.location:
|
||||
return "%s (%s)" % (self, self.location)
|
||||
return '{} ({})'.format(self, self.location)
|
||||
else:
|
||||
return str(self)
|
||||
|
||||
|
|
@ -2804,8 +2812,8 @@ class Distribution:
|
|||
version = getattr(self, 'version', None)
|
||||
except ValueError:
|
||||
version = None
|
||||
version = version or "[unknown version]"
|
||||
return "%s %s" % (self.project_name, version)
|
||||
version = version or '[unknown version]'
|
||||
return '{} {}'.format(self.project_name, version)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""Delegate all unrecognized public attributes to .metadata provider"""
|
||||
|
|
@ -2815,26 +2823,26 @@ class Distribution:
|
|||
|
||||
def __dir__(self):
|
||||
return list(
|
||||
set(super(Distribution, self).__dir__())
|
||||
| set(
|
||||
set(super().__dir__()) |
|
||||
{
|
||||
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
|
||||
**kw,
|
||||
)
|
||||
|
||||
def as_requirement(self):
|
||||
"""Return a ``Requirement`` that matches this distribution exactly"""
|
||||
if isinstance(self.parsed_version, packaging.version.Version):
|
||||
spec = "%s==%s" % (self.project_name, self.parsed_version)
|
||||
spec = '{}=={}'.format(self.project_name, self.parsed_version)
|
||||
else:
|
||||
spec = "%s===%s" % (self.project_name, self.parsed_version)
|
||||
spec = '{}==={}'.format(self.project_name, self.parsed_version)
|
||||
|
||||
return Requirement.parse(spec)
|
||||
|
||||
|
|
@ -2842,7 +2850,7 @@ class Distribution:
|
|||
"""Return the `name` entry point of `group` or raise ImportError"""
|
||||
ep = self.get_entry_info(group, name)
|
||||
if ep is None:
|
||||
raise ImportError("Entry point %r not found" % ((group, name),))
|
||||
raise ImportError('Entry point {!r} not found'.format((group, name)))
|
||||
return ep.load()
|
||||
|
||||
def get_entry_map(self, group=None):
|
||||
|
|
@ -2851,7 +2859,7 @@ class Distribution:
|
|||
ep_map = self._ep_map
|
||||
except AttributeError:
|
||||
ep_map = self._ep_map = EntryPoint.parse_map(
|
||||
self._get_metadata('entry_points.txt'), self
|
||||
self._get_metadata('entry_points.txt'), self,
|
||||
)
|
||||
if group is not None:
|
||||
return ep_map.get(group, {})
|
||||
|
|
@ -2938,25 +2946,29 @@ 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"
|
||||
" to sys.path" % (modname, fn, self.location),
|
||||
'Module %s was already imported from %s, but %s is being added'
|
||||
' to sys.path' % (modname, fn, self.location),
|
||||
)
|
||||
|
||||
def has_version(self):
|
||||
try:
|
||||
self.version
|
||||
except ValueError:
|
||||
issue_warning("Unbuilt egg for " + repr(self))
|
||||
issue_warning('Unbuilt egg for ' + repr(self))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
@ -2998,7 +3010,7 @@ class DistInfoDistribution(Distribution):
|
|||
w/metadata, .dist-info style.
|
||||
"""
|
||||
PKG_INFO = 'METADATA'
|
||||
EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])")
|
||||
EQEQ = re.compile(r'([\(,])\s*(\d.*?)\s*([,\)])')
|
||||
|
||||
@property
|
||||
def _parsed_pkg_info(self):
|
||||
|
|
@ -3085,18 +3097,19 @@ def parse_requirements(strs):
|
|||
|
||||
|
||||
class RequirementParseError(packaging.requirements.InvalidRequirement):
|
||||
"Compatibility wrapper for InvalidRequirement"
|
||||
'Compatibility wrapper for InvalidRequirement'
|
||||
|
||||
|
||||
class Requirement(packaging.requirements.Requirement):
|
||||
def __init__(self, requirement_string):
|
||||
"""DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
|
||||
super(Requirement, self).__init__(requirement_string)
|
||||
super().__init__(requirement_string)
|
||||
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]
|
||||
(spec.operator, spec.version) for spec in self.specifier
|
||||
]
|
||||
self.extras = tuple(map(safe_extra, self.extras))
|
||||
self.hashCmp = (
|
||||
self.key,
|
||||
|
|
@ -3132,7 +3145,7 @@ class Requirement(packaging.requirements.Requirement):
|
|||
return self.__hash
|
||||
|
||||
def __repr__(self):
|
||||
return "Requirement.parse(%r)" % str(self)
|
||||
return 'Requirement.parse(%r)' % str(self)
|
||||
|
||||
@staticmethod
|
||||
def parse(s):
|
||||
|
|
@ -3167,7 +3180,7 @@ def ensure_directory(path):
|
|||
def _bypass_ensure_directory(path):
|
||||
"""Sandbox-bypassing version of ensure_directory()"""
|
||||
if not WRITE_SUPPORT:
|
||||
raise IOError('"os.mkdir" not supported on this platform.')
|
||||
raise OSError('"os.mkdir" not supported on this platform.')
|
||||
dirname, filename = split(path)
|
||||
if dirname and filename and not isdir(dirname):
|
||||
_bypass_ensure_directory(dirname)
|
||||
|
|
@ -3188,14 +3201,14 @@ def split_sections(s):
|
|||
section = None
|
||||
content = []
|
||||
for line in yield_lines(s):
|
||||
if line.startswith("["):
|
||||
if line.endswith("]"):
|
||||
if line.startswith('['):
|
||||
if line.endswith(']'):
|
||||
if section or content:
|
||||
yield section, content
|
||||
section = line[1:-1].strip()
|
||||
content = []
|
||||
else:
|
||||
raise ValueError("Invalid section heading", line)
|
||||
raise ValueError('Invalid section heading', line)
|
||||
else:
|
||||
content.append(line)
|
||||
|
||||
|
|
@ -3218,7 +3231,7 @@ def _mkstemp(*args, **kw):
|
|||
# randomly just because they use pkg_resources. We want to append the rule
|
||||
# because we want earlier uses of filterwarnings to take precedence over this
|
||||
# one.
|
||||
warnings.filterwarnings("ignore", category=PEP440Warning, append=True)
|
||||
warnings.filterwarnings('ignore', category=PEP440Warning, append=True)
|
||||
|
||||
|
||||
# from jaraco.functools 1.3
|
||||
|
|
@ -3229,7 +3242,7 @@ def _call_aside(f, *args, **kwargs):
|
|||
|
||||
@_call_aside
|
||||
def _initialize(g=globals()):
|
||||
"Set up global resource manager (deliberately not state-saved)"
|
||||
'Set up global resource manager (deliberately not state-saved)'
|
||||
manager = ResourceManager()
|
||||
g['_manager'] = manager
|
||||
g.update(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
#!/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.
|
||||
|
|
@ -12,6 +10,7 @@ See <http://github.com/ActiveState/appdirs> for details and usage.
|
|||
# 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
|
||||
from __future__ import annotations
|
||||
|
||||
__version_info__ = (1, 4, 3)
|
||||
__version__ = '.'.join(map(str, __version_info__))
|
||||
|
|
@ -28,11 +27,11 @@ if PY3:
|
|||
if sys.platform.startswith('java'):
|
||||
import platform
|
||||
os_name = platform.java_ver()[3][0]
|
||||
if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc.
|
||||
if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc.
|
||||
system = 'win32'
|
||||
elif os_name.startswith('Mac'): # "Mac OS X", etc.
|
||||
elif os_name.startswith('Mac'): # "Mac OS X", etc.
|
||||
system = 'darwin'
|
||||
else: # "Linux", "SunOS", "FreeBSD", etc.
|
||||
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.
|
||||
|
|
@ -41,7 +40,6 @@ 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.
|
||||
|
||||
|
|
@ -74,10 +72,10 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
|
|||
For Unix, we follow the XDG spec and support $XDG_DATA_HOME.
|
||||
That means, by default "~/.local/share/<AppName>".
|
||||
"""
|
||||
if system == "win32":
|
||||
if system == 'win32':
|
||||
if appauthor is None:
|
||||
appauthor = appname
|
||||
const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA"
|
||||
const = roaming and 'CSIDL_APPDATA' or 'CSIDL_LOCAL_APPDATA'
|
||||
path = os.path.normpath(_get_win_folder(const))
|
||||
if appname:
|
||||
if appauthor is not False:
|
||||
|
|
@ -89,7 +87,7 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
|
|||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
else:
|
||||
path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share"))
|
||||
path = os.getenv('XDG_DATA_HOME', os.path.expanduser('~/.local/share'))
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
if appname and version:
|
||||
|
|
@ -128,10 +126,10 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
|
|||
|
||||
WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
|
||||
"""
|
||||
if system == "win32":
|
||||
if system == 'win32':
|
||||
if appauthor is None:
|
||||
appauthor = appname
|
||||
path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA"))
|
||||
path = os.path.normpath(_get_win_folder('CSIDL_COMMON_APPDATA'))
|
||||
if appname:
|
||||
if appauthor is not False:
|
||||
path = os.path.join(path, appauthor, appname)
|
||||
|
|
@ -144,8 +142,10 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
|
|||
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']))
|
||||
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:
|
||||
|
|
@ -192,10 +192,10 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
|
|||
For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME.
|
||||
That means, by default "~/.config/<AppName>".
|
||||
"""
|
||||
if system in ["win32", "darwin"]:
|
||||
if system in ['win32', 'darwin']:
|
||||
path = user_data_dir(appname, appauthor, None, roaming)
|
||||
else:
|
||||
path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config"))
|
||||
path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
if appname and version:
|
||||
|
|
@ -233,7 +233,7 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
|
|||
|
||||
WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
|
||||
"""
|
||||
if system in ["win32", "darwin"]:
|
||||
if system in ['win32', 'darwin']:
|
||||
path = site_data_dir(appname, appauthor)
|
||||
if appname and version:
|
||||
path = os.path.join(path, version)
|
||||
|
|
@ -287,17 +287,17 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
|
|||
OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value.
|
||||
This can be disabled with the `opinion=False` option.
|
||||
"""
|
||||
if system == "win32":
|
||||
if system == 'win32':
|
||||
if appauthor is None:
|
||||
appauthor = appname
|
||||
path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA"))
|
||||
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")
|
||||
path = os.path.join(path, 'Cache')
|
||||
elif system == 'darwin':
|
||||
path = os.path.expanduser('~/Library/Caches')
|
||||
if appname:
|
||||
|
|
@ -342,10 +342,10 @@ def user_state_dir(appname=None, appauthor=None, version=None, roaming=False):
|
|||
|
||||
That means, by default "~/.local/state/<AppName>".
|
||||
"""
|
||||
if system in ["win32", "darwin"]:
|
||||
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"))
|
||||
path = os.getenv('XDG_STATE_HOME', os.path.expanduser('~/.local/state'))
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
if appname and version:
|
||||
|
|
@ -385,29 +385,33 @@ def user_log_dir(appname=None, appauthor=None, version=None, opinion=True):
|
|||
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":
|
||||
if system == 'darwin':
|
||||
path = os.path.join(
|
||||
os.path.expanduser('~/Library/Logs'),
|
||||
appname)
|
||||
elif system == "win32":
|
||||
appname,
|
||||
)
|
||||
elif system == 'win32':
|
||||
path = user_data_dir(appname, appauthor, version)
|
||||
version = False
|
||||
if opinion:
|
||||
path = os.path.join(path, "Logs")
|
||||
path = os.path.join(path, 'Logs')
|
||||
else:
|
||||
path = user_cache_dir(appname, appauthor, version)
|
||||
version = False
|
||||
if opinion:
|
||||
path = os.path.join(path, "log")
|
||||
path = os.path.join(path, 'log')
|
||||
if appname and version:
|
||||
path = os.path.join(path, version)
|
||||
return path
|
||||
|
||||
|
||||
class AppDirs(object):
|
||||
class AppDirs:
|
||||
"""Convenience wrapper for getting application dirs."""
|
||||
def __init__(self, appname=None, appauthor=None, version=None,
|
||||
roaming=False, multipath=False):
|
||||
|
||||
def __init__(
|
||||
self, appname=None, appauthor=None, version=None,
|
||||
roaming=False, multipath=False,
|
||||
):
|
||||
self.appname = appname
|
||||
self.appauthor = appauthor
|
||||
self.version = version
|
||||
|
|
@ -416,38 +420,52 @@ class AppDirs(object):
|
|||
|
||||
@property
|
||||
def user_data_dir(self):
|
||||
return user_data_dir(self.appname, self.appauthor,
|
||||
version=self.version, roaming=self.roaming)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
return user_log_dir(
|
||||
self.appname, self.appauthor,
|
||||
version=self.version,
|
||||
)
|
||||
|
||||
|
||||
#---- internal support stuff
|
||||
|
|
@ -458,19 +476,19 @@ def _get_win_folder_from_registry(csidl_name):
|
|||
names.
|
||||
"""
|
||||
if PY3:
|
||||
import winreg as _winreg
|
||||
import winreg as _winreg
|
||||
else:
|
||||
import _winreg
|
||||
import _winreg
|
||||
|
||||
shell_folder_name = {
|
||||
"CSIDL_APPDATA": "AppData",
|
||||
"CSIDL_COMMON_APPDATA": "Common AppData",
|
||||
"CSIDL_LOCAL_APPDATA": "Local AppData",
|
||||
'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"
|
||||
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders',
|
||||
)
|
||||
dir, type = _winreg.QueryValueEx(key, shell_folder_name)
|
||||
return dir
|
||||
|
|
@ -507,9 +525,9 @@ def _get_win_folder_with_ctypes(csidl_name):
|
|||
import ctypes
|
||||
|
||||
csidl_const = {
|
||||
"CSIDL_APPDATA": 26,
|
||||
"CSIDL_COMMON_APPDATA": 35,
|
||||
"CSIDL_LOCAL_APPDATA": 28,
|
||||
'CSIDL_APPDATA': 26,
|
||||
'CSIDL_COMMON_APPDATA': 35,
|
||||
'CSIDL_LOCAL_APPDATA': 28,
|
||||
}[csidl_name]
|
||||
|
||||
buf = ctypes.create_unicode_buffer(1024)
|
||||
|
|
@ -529,6 +547,7 @@ def _get_win_folder_with_ctypes(csidl_name):
|
|||
|
||||
return buf.value
|
||||
|
||||
|
||||
def _get_win_folder_with_jna(csidl_name):
|
||||
import array
|
||||
from com.sun import jna
|
||||
|
|
@ -538,7 +557,7 @@ def _get_win_folder_with_jna(csidl_name):
|
|||
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")
|
||||
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>.
|
||||
|
|
@ -551,11 +570,12 @@ def _get_win_folder_with_jna(csidl_name):
|
|||
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")
|
||||
dir = jna.Native.toString(buf.tostring()).rstrip('\0')
|
||||
|
||||
return dir
|
||||
|
||||
if system == "win32":
|
||||
|
||||
if system == 'win32':
|
||||
try:
|
||||
import win32com.shell
|
||||
_get_win_folder = _get_win_folder_with_pywin32
|
||||
|
|
@ -573,36 +593,38 @@ if system == "win32":
|
|||
|
||||
#---- self test code
|
||||
|
||||
if __name__ == "__main__":
|
||||
appname = "MyApp"
|
||||
appauthor = "MyCompany"
|
||||
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")
|
||||
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 %s --' % __version__)
|
||||
|
||||
print("-- app dirs (with optional 'version')")
|
||||
dirs = AppDirs(appname, appauthor, version="1.0")
|
||||
dirs = AppDirs(appname, appauthor, version='1.0')
|
||||
for prop in props:
|
||||
print("%s: %s" % (prop, getattr(dirs, prop)))
|
||||
print('{}: {}'.format(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('{}: {}'.format(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('{}: {}'.format(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)))
|
||||
print('{}: {}'.format(prop, getattr(dirs, prop)))
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = [
|
||||
"__title__",
|
||||
"__summary__",
|
||||
"__uri__",
|
||||
"__version__",
|
||||
"__author__",
|
||||
"__email__",
|
||||
"__license__",
|
||||
"__copyright__",
|
||||
'__title__',
|
||||
'__summary__',
|
||||
'__uri__',
|
||||
'__version__',
|
||||
'__author__',
|
||||
'__email__',
|
||||
'__license__',
|
||||
'__copyright__',
|
||||
]
|
||||
|
||||
__title__ = "packaging"
|
||||
__summary__ = "Core utilities for Python packages"
|
||||
__uri__ = "https://github.com/pypa/packaging"
|
||||
__title__ = 'packaging'
|
||||
__summary__ = 'Core utilities for Python packages'
|
||||
__uri__ = 'https://github.com/pypa/packaging'
|
||||
|
||||
__version__ = "20.4"
|
||||
__version__ = '20.4'
|
||||
|
||||
__author__ = "Donald Stufft and individual contributors"
|
||||
__email__ = "donald@stufft.io"
|
||||
__author__ = 'Donald Stufft and individual contributors'
|
||||
__email__ = 'donald@stufft.io'
|
||||
|
||||
__license__ = "BSD-2-Clause or Apache-2.0"
|
||||
__copyright__ = "Copyright 2014-2019 %s" % __author__
|
||||
__license__ = 'BSD-2-Clause or Apache-2.0'
|
||||
__copyright__ = 'Copyright 2014-2019 %s' % __author__
|
||||
|
|
|
|||
|
|
@ -1,26 +1,24 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
from .__about__ import (
|
||||
__author__,
|
||||
__copyright__,
|
||||
__email__,
|
||||
__license__,
|
||||
__summary__,
|
||||
__title__,
|
||||
__uri__,
|
||||
__version__,
|
||||
)
|
||||
from .__about__ import __author__
|
||||
from .__about__ import __copyright__
|
||||
from .__about__ import __email__
|
||||
from .__about__ import __license__
|
||||
from .__about__ import __summary__
|
||||
from .__about__ import __title__
|
||||
from .__about__ import __uri__
|
||||
from .__about__ import __version__
|
||||
|
||||
__all__ = [
|
||||
"__title__",
|
||||
"__summary__",
|
||||
"__uri__",
|
||||
"__version__",
|
||||
"__author__",
|
||||
"__email__",
|
||||
"__license__",
|
||||
"__copyright__",
|
||||
'__title__',
|
||||
'__summary__',
|
||||
'__uri__',
|
||||
'__version__',
|
||||
'__author__',
|
||||
'__email__',
|
||||
'__license__',
|
||||
'__copyright__',
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
|
|
@ -35,4 +35,4 @@ def with_metaclass(meta, *bases):
|
|||
# type: (Type[Any], str, Tuple[Any], Dict[Any, Any]) -> Any
|
||||
return meta(name, bases, d)
|
||||
|
||||
return type.__new__(metaclass, "temporary_class", (), {})
|
||||
return type.__new__(metaclass, 'temporary_class', (), {})
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class InfinityType(object):
|
||||
class InfinityType:
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "Infinity"
|
||||
return 'Infinity'
|
||||
|
||||
def __hash__(self):
|
||||
# type: () -> int
|
||||
|
|
@ -45,10 +45,10 @@ class InfinityType(object):
|
|||
Infinity = InfinityType()
|
||||
|
||||
|
||||
class NegativeInfinityType(object):
|
||||
class NegativeInfinityType:
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "-Infinity"
|
||||
return '-Infinity'
|
||||
|
||||
def __hash__(self):
|
||||
# type: () -> int
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@ In packaging, all static-typing related imports should be guarded as follows:
|
|||
|
||||
Ref: https://github.com/python/mypy/issues/3216
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ["TYPE_CHECKING", "cast"]
|
||||
__all__ = ['TYPE_CHECKING', 'cast']
|
||||
|
||||
# The TYPE_CHECKING constant defined by the typing module is False at runtime
|
||||
# but True while type checking.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,27 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
import operator
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
|
||||
from pkg_resources.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd
|
||||
from pkg_resources.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString
|
||||
from pkg_resources.extern.pyparsing import Forward
|
||||
from pkg_resources.extern.pyparsing import Group
|
||||
from pkg_resources.extern.pyparsing import Literal as L # noqa
|
||||
from pkg_resources.extern.pyparsing import ParseException
|
||||
from pkg_resources.extern.pyparsing import ParseResults
|
||||
from pkg_resources.extern.pyparsing import QuotedString
|
||||
from pkg_resources.extern.pyparsing import stringEnd
|
||||
from pkg_resources.extern.pyparsing import stringStart
|
||||
from pkg_resources.extern.pyparsing import ZeroOrMore
|
||||
|
||||
from ._compat import string_types
|
||||
from ._typing import TYPE_CHECKING
|
||||
from .specifiers import Specifier, InvalidSpecifier
|
||||
from .specifiers import InvalidSpecifier
|
||||
from .specifiers import Specifier
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
||||
|
|
@ -23,11 +30,11 @@ if TYPE_CHECKING: # pragma: no cover
|
|||
|
||||
|
||||
__all__ = [
|
||||
"InvalidMarker",
|
||||
"UndefinedComparison",
|
||||
"UndefinedEnvironmentName",
|
||||
"Marker",
|
||||
"default_environment",
|
||||
'InvalidMarker',
|
||||
'UndefinedComparison',
|
||||
'UndefinedEnvironmentName',
|
||||
'Marker',
|
||||
'default_environment',
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -50,7 +57,7 @@ class UndefinedEnvironmentName(ValueError):
|
|||
"""
|
||||
|
||||
|
||||
class Node(object):
|
||||
class Node:
|
||||
def __init__(self, value):
|
||||
# type: (Any) -> None
|
||||
self.value = value
|
||||
|
|
@ -61,7 +68,7 @@ class Node(object):
|
|||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "<{0}({1!r})>".format(self.__class__.__name__, str(self))
|
||||
return f'<{self.__class__.__name__}({str(self)!r})>'
|
||||
|
||||
def serialize(self):
|
||||
# type: () -> str
|
||||
|
|
@ -77,7 +84,7 @@ class Variable(Node):
|
|||
class Value(Node):
|
||||
def serialize(self):
|
||||
# type: () -> str
|
||||
return '"{0}"'.format(self)
|
||||
return f'"{self}"'
|
||||
|
||||
|
||||
class Op(Node):
|
||||
|
|
@ -87,54 +94,54 @@ class Op(Node):
|
|||
|
||||
|
||||
VARIABLE = (
|
||||
L("implementation_version")
|
||||
| L("platform_python_implementation")
|
||||
| L("implementation_name")
|
||||
| L("python_full_version")
|
||||
| L("platform_release")
|
||||
| L("platform_version")
|
||||
| L("platform_machine")
|
||||
| L("platform_system")
|
||||
| L("python_version")
|
||||
| L("sys_platform")
|
||||
| L("os_name")
|
||||
| L("os.name") # PEP-345
|
||||
| L("sys.platform") # PEP-345
|
||||
| L("platform.version") # PEP-345
|
||||
| L("platform.machine") # PEP-345
|
||||
| L("platform.python_implementation") # PEP-345
|
||||
| L("python_implementation") # undocumented setuptools legacy
|
||||
| L("extra") # PEP-508
|
||||
L('implementation_version') |
|
||||
L('platform_python_implementation') |
|
||||
L('implementation_name') |
|
||||
L('python_full_version') |
|
||||
L('platform_release') |
|
||||
L('platform_version') |
|
||||
L('platform_machine') |
|
||||
L('platform_system') |
|
||||
L('python_version') |
|
||||
L('sys_platform') |
|
||||
L('os_name') |
|
||||
L('os.name') | # PEP-345
|
||||
L('sys.platform') | # PEP-345
|
||||
L('platform.version') | # PEP-345
|
||||
L('platform.machine') | # PEP-345
|
||||
L('platform.python_implementation') | # PEP-345
|
||||
L('python_implementation') | # undocumented setuptools legacy
|
||||
L('extra') # PEP-508
|
||||
)
|
||||
ALIASES = {
|
||||
"os.name": "os_name",
|
||||
"sys.platform": "sys_platform",
|
||||
"platform.version": "platform_version",
|
||||
"platform.machine": "platform_machine",
|
||||
"platform.python_implementation": "platform_python_implementation",
|
||||
"python_implementation": "platform_python_implementation",
|
||||
'os.name': 'os_name',
|
||||
'sys.platform': 'sys_platform',
|
||||
'platform.version': 'platform_version',
|
||||
'platform.machine': 'platform_machine',
|
||||
'platform.python_implementation': 'platform_python_implementation',
|
||||
'python_implementation': 'platform_python_implementation',
|
||||
}
|
||||
VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))
|
||||
|
||||
VERSION_CMP = (
|
||||
L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<")
|
||||
L('===') | L('==') | L('>=') | L('<=') | L('!=') | L('~=') | L('>') | L('<')
|
||||
)
|
||||
|
||||
MARKER_OP = VERSION_CMP | L("not in") | L("in")
|
||||
MARKER_OP = VERSION_CMP | L('not in') | L('in')
|
||||
MARKER_OP.setParseAction(lambda s, l, t: Op(t[0]))
|
||||
|
||||
MARKER_VALUE = QuotedString("'") | QuotedString('"')
|
||||
MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0]))
|
||||
|
||||
BOOLOP = L("and") | L("or")
|
||||
BOOLOP = L('and') | L('or')
|
||||
|
||||
MARKER_VAR = VARIABLE | MARKER_VALUE
|
||||
|
||||
MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR)
|
||||
MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0]))
|
||||
|
||||
LPAREN = L("(").suppress()
|
||||
RPAREN = L(")").suppress()
|
||||
LPAREN = L('(').suppress()
|
||||
RPAREN = L(')').suppress()
|
||||
|
||||
MARKER_EXPR = Forward()
|
||||
MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN)
|
||||
|
|
@ -161,40 +168,40 @@ def _format_marker(marker, first=True):
|
|||
# the rest of this function so that we don't get extraneous () on the
|
||||
# outside.
|
||||
if (
|
||||
isinstance(marker, list)
|
||||
and len(marker) == 1
|
||||
and isinstance(marker[0], (list, tuple))
|
||||
isinstance(marker, list) and
|
||||
len(marker) == 1 and
|
||||
isinstance(marker[0], (list, tuple))
|
||||
):
|
||||
return _format_marker(marker[0])
|
||||
|
||||
if isinstance(marker, list):
|
||||
inner = (_format_marker(m, first=False) for m in marker)
|
||||
if first:
|
||||
return " ".join(inner)
|
||||
return ' '.join(inner)
|
||||
else:
|
||||
return "(" + " ".join(inner) + ")"
|
||||
return '(' + ' '.join(inner) + ')'
|
||||
elif isinstance(marker, tuple):
|
||||
return " ".join([m.serialize() for m in marker])
|
||||
return ' '.join([m.serialize() for m in marker])
|
||||
else:
|
||||
return marker
|
||||
|
||||
|
||||
_operators = {
|
||||
"in": lambda lhs, rhs: lhs in rhs,
|
||||
"not in": lambda lhs, rhs: lhs not in rhs,
|
||||
"<": operator.lt,
|
||||
"<=": operator.le,
|
||||
"==": operator.eq,
|
||||
"!=": operator.ne,
|
||||
">=": operator.ge,
|
||||
">": operator.gt,
|
||||
'in': lambda lhs, rhs: lhs in rhs,
|
||||
'not in': lambda lhs, rhs: lhs not in rhs,
|
||||
'<': operator.lt,
|
||||
'<=': operator.le,
|
||||
'==': operator.eq,
|
||||
'!=': operator.ne,
|
||||
'>=': operator.ge,
|
||||
'>': operator.gt,
|
||||
} # type: Dict[str, Operator]
|
||||
|
||||
|
||||
def _eval_op(lhs, op, rhs):
|
||||
# type: (str, Op, str) -> bool
|
||||
try:
|
||||
spec = Specifier("".join([op.serialize(), rhs]))
|
||||
spec = Specifier(''.join([op.serialize(), rhs]))
|
||||
except InvalidSpecifier:
|
||||
pass
|
||||
else:
|
||||
|
|
@ -203,13 +210,13 @@ def _eval_op(lhs, op, rhs):
|
|||
oper = _operators.get(op.serialize()) # type: Optional[Operator]
|
||||
if oper is None:
|
||||
raise UndefinedComparison(
|
||||
"Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs)
|
||||
f'Undefined {op!r} on {lhs!r} and {rhs!r}.',
|
||||
)
|
||||
|
||||
return oper(lhs, rhs)
|
||||
|
||||
|
||||
class Undefined(object):
|
||||
class Undefined:
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -222,7 +229,7 @@ def _get_env(environment, name):
|
|||
|
||||
if isinstance(value, Undefined):
|
||||
raise UndefinedEnvironmentName(
|
||||
"{0!r} does not exist in evaluation environment.".format(name)
|
||||
f'{name!r} does not exist in evaluation environment.',
|
||||
)
|
||||
|
||||
return value
|
||||
|
|
@ -249,8 +256,8 @@ def _evaluate_markers(markers, environment):
|
|||
|
||||
groups[-1].append(_eval_op(lhs_value, op, rhs_value))
|
||||
else:
|
||||
assert marker in ["and", "or"]
|
||||
if marker == "or":
|
||||
assert marker in ['and', 'or']
|
||||
if marker == 'or':
|
||||
groups.append([])
|
||||
|
||||
return any(all(item) for item in groups)
|
||||
|
|
@ -258,48 +265,48 @@ def _evaluate_markers(markers, environment):
|
|||
|
||||
def format_full_version(info):
|
||||
# type: (sys._version_info) -> str
|
||||
version = "{0.major}.{0.minor}.{0.micro}".format(info)
|
||||
version = '{0.major}.{0.minor}.{0.micro}'.format(info)
|
||||
kind = info.releaselevel
|
||||
if kind != "final":
|
||||
if kind != 'final':
|
||||
version += kind[0] + str(info.serial)
|
||||
return version
|
||||
|
||||
|
||||
def default_environment():
|
||||
# type: () -> Dict[str, str]
|
||||
if hasattr(sys, "implementation"):
|
||||
if hasattr(sys, 'implementation'):
|
||||
# Ignoring the `sys.implementation` reference for type checking due to
|
||||
# mypy not liking that the attribute doesn't exist in Python 2.7 when
|
||||
# run with the `--py27` flag.
|
||||
iver = format_full_version(sys.implementation.version) # type: ignore
|
||||
implementation_name = sys.implementation.name # type: ignore
|
||||
else:
|
||||
iver = "0"
|
||||
implementation_name = ""
|
||||
iver = '0'
|
||||
implementation_name = ''
|
||||
|
||||
return {
|
||||
"implementation_name": implementation_name,
|
||||
"implementation_version": iver,
|
||||
"os_name": os.name,
|
||||
"platform_machine": platform.machine(),
|
||||
"platform_release": platform.release(),
|
||||
"platform_system": platform.system(),
|
||||
"platform_version": platform.version(),
|
||||
"python_full_version": platform.python_version(),
|
||||
"platform_python_implementation": platform.python_implementation(),
|
||||
"python_version": ".".join(platform.python_version_tuple()[:2]),
|
||||
"sys_platform": sys.platform,
|
||||
'implementation_name': implementation_name,
|
||||
'implementation_version': iver,
|
||||
'os_name': os.name,
|
||||
'platform_machine': platform.machine(),
|
||||
'platform_release': platform.release(),
|
||||
'platform_system': platform.system(),
|
||||
'platform_version': platform.version(),
|
||||
'python_full_version': platform.python_version(),
|
||||
'platform_python_implementation': platform.python_implementation(),
|
||||
'python_version': '.'.join(platform.python_version_tuple()[:2]),
|
||||
'sys_platform': sys.platform,
|
||||
}
|
||||
|
||||
|
||||
class Marker(object):
|
||||
class Marker:
|
||||
def __init__(self, marker):
|
||||
# type: (str) -> None
|
||||
try:
|
||||
self._markers = _coerce_parse_result(MARKER.parseString(marker))
|
||||
except ParseException as e:
|
||||
err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
|
||||
marker, marker[e.loc : e.loc + 8]
|
||||
err_str = 'Invalid marker: {!r}, parse error at {!r}'.format(
|
||||
marker, marker[e.loc: e.loc + 8],
|
||||
)
|
||||
raise InvalidMarker(err_str)
|
||||
|
||||
|
|
@ -309,7 +316,7 @@ class Marker(object):
|
|||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "<Marker({0!r})>".format(str(self))
|
||||
return f'<Marker({str(self)!r})>'
|
||||
|
||||
def evaluate(self, environment=None):
|
||||
# type: (Optional[Dict[str, str]]) -> bool
|
||||
|
|
|
|||
|
|
@ -1,19 +1,29 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
import string
|
||||
import re
|
||||
|
||||
from pkg_resources.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException
|
||||
from pkg_resources.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine
|
||||
from pkg_resources.extern.pyparsing import Literal as L # noqa
|
||||
import string
|
||||
from urllib import parse as urlparse
|
||||
|
||||
from pkg_resources.extern.pyparsing import Combine
|
||||
from pkg_resources.extern.pyparsing import Literal as L # noqa
|
||||
from pkg_resources.extern.pyparsing import Optional
|
||||
from pkg_resources.extern.pyparsing import originalTextFor
|
||||
from pkg_resources.extern.pyparsing import ParseException
|
||||
from pkg_resources.extern.pyparsing import Regex
|
||||
from pkg_resources.extern.pyparsing import stringEnd
|
||||
from pkg_resources.extern.pyparsing import stringStart
|
||||
from pkg_resources.extern.pyparsing import Word
|
||||
from pkg_resources.extern.pyparsing import ZeroOrMore
|
||||
|
||||
from ._typing import TYPE_CHECKING
|
||||
from .markers import MARKER_EXPR, Marker
|
||||
from .specifiers import LegacySpecifier, Specifier, SpecifierSet
|
||||
from .markers import Marker
|
||||
from .markers import MARKER_EXPR
|
||||
from .specifiers import LegacySpecifier
|
||||
from .specifiers import Specifier
|
||||
from .specifiers import SpecifierSet
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from typing import List
|
||||
|
|
@ -27,43 +37,43 @@ class InvalidRequirement(ValueError):
|
|||
|
||||
ALPHANUM = Word(string.ascii_letters + string.digits)
|
||||
|
||||
LBRACKET = L("[").suppress()
|
||||
RBRACKET = L("]").suppress()
|
||||
LPAREN = L("(").suppress()
|
||||
RPAREN = L(")").suppress()
|
||||
COMMA = L(",").suppress()
|
||||
SEMICOLON = L(";").suppress()
|
||||
AT = L("@").suppress()
|
||||
LBRACKET = L('[').suppress()
|
||||
RBRACKET = L(']').suppress()
|
||||
LPAREN = L('(').suppress()
|
||||
RPAREN = L(')').suppress()
|
||||
COMMA = L(',').suppress()
|
||||
SEMICOLON = L(';').suppress()
|
||||
AT = L('@').suppress()
|
||||
|
||||
PUNCTUATION = Word("-_.")
|
||||
PUNCTUATION = Word('-_.')
|
||||
IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM)
|
||||
IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
|
||||
|
||||
NAME = IDENTIFIER("name")
|
||||
NAME = IDENTIFIER('name')
|
||||
EXTRA = IDENTIFIER
|
||||
|
||||
URI = Regex(r"[^ ]+")("url")
|
||||
URI = Regex(r'[^ ]+')('url')
|
||||
URL = AT + URI
|
||||
|
||||
EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
|
||||
EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
|
||||
EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)('extras')
|
||||
|
||||
VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
|
||||
VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
|
||||
|
||||
VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
|
||||
VERSION_MANY = Combine(
|
||||
VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False
|
||||
)("_raw_spec")
|
||||
_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
|
||||
_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "")
|
||||
VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=',', adjacent=False,
|
||||
)('_raw_spec')
|
||||
_VERSION_SPEC = Optional((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)
|
||||
_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
|
||||
|
||||
VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
|
||||
VERSION_SPEC = originalTextFor(_VERSION_SPEC)('specifier')
|
||||
VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
|
||||
|
||||
MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
|
||||
MARKER_EXPR = originalTextFor(MARKER_EXPR())('marker')
|
||||
MARKER_EXPR.setParseAction(
|
||||
lambda s, l, t: Marker(s[t._original_start : t._original_end])
|
||||
lambda s, l, t: Marker(s[t._original_start: t._original_end]),
|
||||
)
|
||||
MARKER_SEPARATOR = SEMICOLON
|
||||
MARKER = MARKER_SEPARATOR + MARKER_EXPR
|
||||
|
|
@ -76,10 +86,10 @@ NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARK
|
|||
REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
|
||||
# pkg_resources.extern.pyparsing isn't thread safe during initialization, so we do it eagerly, see
|
||||
# issue #104
|
||||
REQUIREMENT.parseString("x[]")
|
||||
REQUIREMENT.parseString('x[]')
|
||||
|
||||
|
||||
class Requirement(object):
|
||||
class Requirement:
|
||||
"""Parse a requirement.
|
||||
|
||||
Parse a given requirement string into its parts, such as name, specifier,
|
||||
|
|
@ -98,21 +108,21 @@ class Requirement(object):
|
|||
req = REQUIREMENT.parseString(requirement_string)
|
||||
except ParseException as e:
|
||||
raise InvalidRequirement(
|
||||
'Parse error at "{0!r}": {1}'.format(
|
||||
requirement_string[e.loc : e.loc + 8], e.msg
|
||||
)
|
||||
'Parse error at "{!r}": {}'.format(
|
||||
requirement_string[e.loc: e.loc + 8], e.msg,
|
||||
),
|
||||
)
|
||||
|
||||
self.name = req.name
|
||||
if req.url:
|
||||
parsed_url = urlparse.urlparse(req.url)
|
||||
if parsed_url.scheme == "file":
|
||||
if parsed_url.scheme == 'file':
|
||||
if urlparse.urlunparse(parsed_url) != req.url:
|
||||
raise InvalidRequirement("Invalid URL given")
|
||||
raise InvalidRequirement('Invalid URL given')
|
||||
elif not (parsed_url.scheme and parsed_url.netloc) or (
|
||||
not parsed_url.scheme and not parsed_url.netloc
|
||||
):
|
||||
raise InvalidRequirement("Invalid URL: {0}".format(req.url))
|
||||
raise InvalidRequirement(f'Invalid URL: {req.url}')
|
||||
self.url = req.url
|
||||
else:
|
||||
self.url = None
|
||||
|
|
@ -125,21 +135,21 @@ class Requirement(object):
|
|||
parts = [self.name] # type: List[str]
|
||||
|
||||
if self.extras:
|
||||
parts.append("[{0}]".format(",".join(sorted(self.extras))))
|
||||
parts.append('[{}]'.format(','.join(sorted(self.extras))))
|
||||
|
||||
if self.specifier:
|
||||
parts.append(str(self.specifier))
|
||||
|
||||
if self.url:
|
||||
parts.append("@ {0}".format(self.url))
|
||||
parts.append(f'@ {self.url}')
|
||||
if self.marker:
|
||||
parts.append(" ")
|
||||
parts.append(' ')
|
||||
|
||||
if self.marker:
|
||||
parts.append("; {0}".format(self.marker))
|
||||
parts.append(f'; {self.marker}')
|
||||
|
||||
return "".join(parts)
|
||||
return ''.join(parts)
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "<Requirement({0!r})>".format(str(self))
|
||||
return f'<Requirement({str(self)!r})>'
|
||||
|
|
|
|||
|
|
@ -1,17 +1,20 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
import functools
|
||||
import itertools
|
||||
import re
|
||||
|
||||
from ._compat import string_types, with_metaclass
|
||||
from ._compat import string_types
|
||||
from ._compat import with_metaclass
|
||||
from ._typing import TYPE_CHECKING
|
||||
from .utils import canonicalize_version
|
||||
from .version import Version, LegacyVersion, parse
|
||||
from .version import LegacyVersion
|
||||
from .version import parse
|
||||
from .version import Version
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from typing import (
|
||||
|
|
@ -105,15 +108,15 @@ class _IndividualSpecifier(BaseSpecifier):
|
|||
|
||||
_operators = {} # type: Dict[str, str]
|
||||
|
||||
def __init__(self, spec="", prereleases=None):
|
||||
def __init__(self, spec='', prereleases=None):
|
||||
# type: (str, Optional[bool]) -> None
|
||||
match = self._regex.search(spec)
|
||||
if not match:
|
||||
raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
|
||||
raise InvalidSpecifier(f"Invalid specifier: '{spec}'")
|
||||
|
||||
self._spec = (
|
||||
match.group("operator").strip(),
|
||||
match.group("version").strip(),
|
||||
match.group('operator').strip(),
|
||||
match.group('version').strip(),
|
||||
) # type: Tuple[str, str]
|
||||
|
||||
# Store whether or not this Specifier should accept prereleases
|
||||
|
|
@ -122,16 +125,16 @@ class _IndividualSpecifier(BaseSpecifier):
|
|||
def __repr__(self):
|
||||
# type: () -> str
|
||||
pre = (
|
||||
", prereleases={0!r}".format(self.prereleases)
|
||||
f', prereleases={self.prereleases!r}'
|
||||
if self._prereleases is not None
|
||||
else ""
|
||||
else ''
|
||||
)
|
||||
|
||||
return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre)
|
||||
return f'<{self.__class__.__name__}({str(self)!r}{pre})>'
|
||||
|
||||
def __str__(self):
|
||||
# type: () -> str
|
||||
return "{0}{1}".format(*self._spec)
|
||||
return '{}{}'.format(*self._spec)
|
||||
|
||||
@property
|
||||
def _canonical_spec(self):
|
||||
|
|
@ -169,7 +172,7 @@ class _IndividualSpecifier(BaseSpecifier):
|
|||
def _get_operator(self, op):
|
||||
# type: (str) -> CallableOperator
|
||||
operator_callable = getattr(
|
||||
self, "_compare_{0}".format(self._operators[op])
|
||||
self, f'_compare_{self._operators[op]}',
|
||||
) # type: CallableOperator
|
||||
return operator_callable
|
||||
|
||||
|
|
@ -231,7 +234,7 @@ class _IndividualSpecifier(BaseSpecifier):
|
|||
yielded = False
|
||||
found_prereleases = []
|
||||
|
||||
kw = {"prereleases": prereleases if prereleases is not None else True}
|
||||
kw = {'prereleases': prereleases if prereleases is not None else True}
|
||||
|
||||
# Attempt to iterate over all the values in the iterable and if any of
|
||||
# them match, yield them.
|
||||
|
|
@ -274,15 +277,15 @@ class LegacySpecifier(_IndividualSpecifier):
|
|||
)
|
||||
"""
|
||||
|
||||
_regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
|
||||
_regex = re.compile(r'^\s*' + _regex_str + r'\s*$', re.VERBOSE | re.IGNORECASE)
|
||||
|
||||
_operators = {
|
||||
"==": "equal",
|
||||
"!=": "not_equal",
|
||||
"<=": "less_than_equal",
|
||||
">=": "greater_than_equal",
|
||||
"<": "less_than",
|
||||
">": "greater_than",
|
||||
'==': 'equal',
|
||||
'!=': 'not_equal',
|
||||
'<=': 'less_than_equal',
|
||||
'>=': 'greater_than_equal',
|
||||
'<': 'less_than',
|
||||
'>': 'greater_than',
|
||||
}
|
||||
|
||||
def _coerce_version(self, version):
|
||||
|
|
@ -317,7 +320,7 @@ class LegacySpecifier(_IndividualSpecifier):
|
|||
|
||||
|
||||
def _require_version_compare(
|
||||
fn # type: (Callable[[Specifier, ParsedVersion, str], bool])
|
||||
fn, # type: (Callable[[Specifier, ParsedVersion, str], bool])
|
||||
):
|
||||
# type: (...) -> Callable[[Specifier, ParsedVersion, str], bool]
|
||||
@functools.wraps(fn)
|
||||
|
|
@ -425,17 +428,17 @@ class Specifier(_IndividualSpecifier):
|
|||
)
|
||||
"""
|
||||
|
||||
_regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
|
||||
_regex = re.compile(r'^\s*' + _regex_str + r'\s*$', re.VERBOSE | re.IGNORECASE)
|
||||
|
||||
_operators = {
|
||||
"~=": "compatible",
|
||||
"==": "equal",
|
||||
"!=": "not_equal",
|
||||
"<=": "less_than_equal",
|
||||
">=": "greater_than_equal",
|
||||
"<": "less_than",
|
||||
">": "greater_than",
|
||||
"===": "arbitrary",
|
||||
'~=': 'compatible',
|
||||
'==': 'equal',
|
||||
'!=': 'not_equal',
|
||||
'<=': 'less_than_equal',
|
||||
'>=': 'greater_than_equal',
|
||||
'<': 'less_than',
|
||||
'>': 'greater_than',
|
||||
'===': 'arbitrary',
|
||||
}
|
||||
|
||||
@_require_version_compare
|
||||
|
|
@ -451,20 +454,20 @@ class Specifier(_IndividualSpecifier):
|
|||
# We want everything but the last item in the version, but we want to
|
||||
# ignore post and dev releases and we want to treat the pre-release as
|
||||
# it's own separate segment.
|
||||
prefix = ".".join(
|
||||
prefix = '.'.join(
|
||||
list(
|
||||
itertools.takewhile(
|
||||
lambda x: (not x.startswith("post") and not x.startswith("dev")),
|
||||
lambda x: (not x.startswith('post') and not x.startswith('dev')),
|
||||
_version_split(spec),
|
||||
)
|
||||
)[:-1]
|
||||
),
|
||||
)[:-1],
|
||||
)
|
||||
|
||||
# Add the prefix notation to the end of our string
|
||||
prefix += ".*"
|
||||
prefix += '.*'
|
||||
|
||||
return self._get_operator(">=")(prospective, spec) and self._get_operator("==")(
|
||||
prospective, prefix
|
||||
return self._get_operator('>=')(prospective, spec) and self._get_operator('==')(
|
||||
prospective, prefix,
|
||||
)
|
||||
|
||||
@_require_version_compare
|
||||
|
|
@ -472,7 +475,7 @@ class Specifier(_IndividualSpecifier):
|
|||
# type: (ParsedVersion, str) -> bool
|
||||
|
||||
# We need special logic to handle prefix matching
|
||||
if spec.endswith(".*"):
|
||||
if spec.endswith('.*'):
|
||||
# In the case of prefix matching we want to ignore local segment.
|
||||
prospective = Version(prospective.public)
|
||||
# Split the spec out by dots, and pretend that there is an implicit
|
||||
|
|
@ -492,7 +495,7 @@ class Specifier(_IndividualSpecifier):
|
|||
# Pad out our two sides with zeros so that they both equal the same
|
||||
# length.
|
||||
padded_spec, padded_prospective = _pad_version(
|
||||
split_spec, shortened_prospective
|
||||
split_spec, shortened_prospective,
|
||||
)
|
||||
|
||||
return padded_prospective == padded_spec
|
||||
|
|
@ -608,10 +611,10 @@ class Specifier(_IndividualSpecifier):
|
|||
# operators, and if they are if they are including an explicit
|
||||
# prerelease.
|
||||
operator, version = self._spec
|
||||
if operator in ["==", ">=", "<=", "~=", "==="]:
|
||||
if operator in ['==', '>=', '<=', '~=', '===']:
|
||||
# The == specifier can include a trailing .*, if it does we
|
||||
# want to remove before parsing.
|
||||
if operator == "==" and version.endswith(".*"):
|
||||
if operator == '==' and version.endswith('.*'):
|
||||
version = version[:-2]
|
||||
|
||||
# Parse the version, and if it is a pre-release than this
|
||||
|
|
@ -627,13 +630,13 @@ class Specifier(_IndividualSpecifier):
|
|||
self._prereleases = value
|
||||
|
||||
|
||||
_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
|
||||
_prefix_regex = re.compile(r'^([0-9]+)((?:a|b|c|rc)[0-9]+)$')
|
||||
|
||||
|
||||
def _version_split(version):
|
||||
# type: (str) -> List[str]
|
||||
result = [] # type: List[str]
|
||||
for item in version.split("."):
|
||||
for item in version.split('.'):
|
||||
match = _prefix_regex.search(item)
|
||||
if match:
|
||||
result.extend(match.groups())
|
||||
|
|
@ -651,23 +654,23 @@ def _pad_version(left, right):
|
|||
right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
|
||||
|
||||
# Get the rest of our versions
|
||||
left_split.append(left[len(left_split[0]) :])
|
||||
right_split.append(right[len(right_split[0]) :])
|
||||
left_split.append(left[len(left_split[0]):])
|
||||
right_split.append(right[len(right_split[0]):])
|
||||
|
||||
# Insert our padding
|
||||
left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
|
||||
right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))
|
||||
left_split.insert(1, ['0'] * max(0, len(right_split[0]) - len(left_split[0])))
|
||||
right_split.insert(1, ['0'] * max(0, len(left_split[0]) - len(right_split[0])))
|
||||
|
||||
return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split)))
|
||||
|
||||
|
||||
class SpecifierSet(BaseSpecifier):
|
||||
def __init__(self, specifiers="", prereleases=None):
|
||||
def __init__(self, specifiers='', prereleases=None):
|
||||
# type: (str, Optional[bool]) -> None
|
||||
|
||||
# Split on , to break each individual specifier into it's own item, and
|
||||
# strip each item to remove leading/trailing whitespace.
|
||||
split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
|
||||
split_specifiers = [s.strip() for s in specifiers.split(',') if s.strip()]
|
||||
|
||||
# Parsed each individual specifier, attempting first to make it a
|
||||
# Specifier and falling back to a LegacySpecifier.
|
||||
|
|
@ -688,16 +691,16 @@ class SpecifierSet(BaseSpecifier):
|
|||
def __repr__(self):
|
||||
# type: () -> str
|
||||
pre = (
|
||||
", prereleases={0!r}".format(self.prereleases)
|
||||
f', prereleases={self.prereleases!r}'
|
||||
if self._prereleases is not None
|
||||
else ""
|
||||
else ''
|
||||
)
|
||||
|
||||
return "<SpecifierSet({0!r}{1})>".format(str(self), pre)
|
||||
return f'<SpecifierSet({str(self)!r}{pre})>'
|
||||
|
||||
def __str__(self):
|
||||
# type: () -> str
|
||||
return ",".join(sorted(str(s) for s in self._specs))
|
||||
return ','.join(sorted(str(s) for s in self._specs))
|
||||
|
||||
def __hash__(self):
|
||||
# type: () -> int
|
||||
|
|
@ -721,8 +724,8 @@ class SpecifierSet(BaseSpecifier):
|
|||
specifier._prereleases = self._prereleases
|
||||
else:
|
||||
raise ValueError(
|
||||
"Cannot combine SpecifierSets with True and False prerelease "
|
||||
"overrides."
|
||||
'Cannot combine SpecifierSets with True and False prerelease '
|
||||
'overrides.',
|
||||
)
|
||||
|
||||
return specifier
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import annotations
|
||||
|
||||
import distutils.util
|
||||
|
||||
|
|
@ -46,18 +45,18 @@ if TYPE_CHECKING: # pragma: no cover
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
INTERPRETER_SHORT_NAMES = {
|
||||
"python": "py", # Generic.
|
||||
"cpython": "cp",
|
||||
"pypy": "pp",
|
||||
"ironpython": "ip",
|
||||
"jython": "jy",
|
||||
'python': 'py', # Generic.
|
||||
'cpython': 'cp',
|
||||
'pypy': 'pp',
|
||||
'ironpython': 'ip',
|
||||
'jython': 'jy',
|
||||
} # type: Dict[str, str]
|
||||
|
||||
|
||||
_32_BIT_INTERPRETER = sys.maxsize <= 2 ** 32
|
||||
|
||||
|
||||
class Tag(object):
|
||||
class Tag:
|
||||
"""
|
||||
A representation of the tag triple for a wheel.
|
||||
|
||||
|
|
@ -65,7 +64,7 @@ class Tag(object):
|
|||
is also supported.
|
||||
"""
|
||||
|
||||
__slots__ = ["_interpreter", "_abi", "_platform"]
|
||||
__slots__ = ['_interpreter', '_abi', '_platform']
|
||||
|
||||
def __init__(self, interpreter, abi, platform):
|
||||
# type: (str, str, str) -> None
|
||||
|
|
@ -94,9 +93,9 @@ class Tag(object):
|
|||
return NotImplemented
|
||||
|
||||
return (
|
||||
(self.platform == other.platform)
|
||||
and (self.abi == other.abi)
|
||||
and (self.interpreter == other.interpreter)
|
||||
(self.platform == other.platform) and
|
||||
(self.abi == other.abi) and
|
||||
(self.interpreter == other.interpreter)
|
||||
)
|
||||
|
||||
def __hash__(self):
|
||||
|
|
@ -105,11 +104,11 @@ class Tag(object):
|
|||
|
||||
def __str__(self):
|
||||
# type: () -> str
|
||||
return "{}-{}-{}".format(self._interpreter, self._abi, self._platform)
|
||||
return f'{self._interpreter}-{self._abi}-{self._platform}'
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "<{self} @ {self_id}>".format(self=self, self_id=id(self))
|
||||
return f'<{self} @ {id(self)}>'
|
||||
|
||||
|
||||
def parse_tag(tag):
|
||||
|
|
@ -121,10 +120,10 @@ def parse_tag(tag):
|
|||
compressed tag set.
|
||||
"""
|
||||
tags = set()
|
||||
interpreters, abis, platforms = tag.split("-")
|
||||
for interpreter in interpreters.split("."):
|
||||
for abi in abis.split("."):
|
||||
for platform_ in platforms.split("."):
|
||||
interpreters, abis, platforms = tag.split('-')
|
||||
for interpreter in interpreters.split('.'):
|
||||
for abi in abis.split('.'):
|
||||
for platform_ in platforms.split('.'):
|
||||
tags.add(Tag(interpreter, abi, platform_))
|
||||
return frozenset(tags)
|
||||
|
||||
|
|
@ -136,13 +135,13 @@ def _warn_keyword_parameter(func_name, kwargs):
|
|||
"""
|
||||
if not kwargs:
|
||||
return False
|
||||
elif len(kwargs) > 1 or "warn" not in kwargs:
|
||||
kwargs.pop("warn", None)
|
||||
elif len(kwargs) > 1 or 'warn' not in kwargs:
|
||||
kwargs.pop('warn', None)
|
||||
arg = next(iter(kwargs.keys()))
|
||||
raise TypeError(
|
||||
"{}() got an unexpected keyword argument {!r}".format(func_name, arg)
|
||||
f'{func_name}() got an unexpected keyword argument {arg!r}',
|
||||
)
|
||||
return kwargs["warn"]
|
||||
return kwargs['warn']
|
||||
|
||||
|
||||
def _get_config_var(name, warn=False):
|
||||
|
|
@ -150,14 +149,14 @@ def _get_config_var(name, warn=False):
|
|||
value = sysconfig.get_config_var(name)
|
||||
if value is None and warn:
|
||||
logger.debug(
|
||||
"Config variable '%s' is unset, Python ABI tag may be incorrect", name
|
||||
"Config variable '%s' is unset, Python ABI tag may be incorrect", name,
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
def _normalize_string(string):
|
||||
# type: (str) -> str
|
||||
return string.replace(".", "_").replace("-", "_")
|
||||
return string.replace('.', '_').replace('-', '_')
|
||||
|
||||
|
||||
def _abi3_applies(python_version):
|
||||
|
|
@ -175,33 +174,33 @@ def _cpython_abis(py_version, warn=False):
|
|||
py_version = tuple(py_version) # To allow for version comparison.
|
||||
abis = []
|
||||
version = _version_nodot(py_version[:2])
|
||||
debug = pymalloc = ucs4 = ""
|
||||
with_debug = _get_config_var("Py_DEBUG", warn)
|
||||
has_refcount = hasattr(sys, "gettotalrefcount")
|
||||
debug = pymalloc = ucs4 = ''
|
||||
with_debug = _get_config_var('Py_DEBUG', warn)
|
||||
has_refcount = hasattr(sys, 'gettotalrefcount')
|
||||
# Windows doesn't set Py_DEBUG, so checking for support of debug-compiled
|
||||
# extension modules is the best option.
|
||||
# https://github.com/pypa/pip/issues/3383#issuecomment-173267692
|
||||
has_ext = "_d.pyd" in EXTENSION_SUFFIXES
|
||||
has_ext = '_d.pyd' in EXTENSION_SUFFIXES
|
||||
if with_debug or (with_debug is None and (has_refcount or has_ext)):
|
||||
debug = "d"
|
||||
debug = 'd'
|
||||
if py_version < (3, 8):
|
||||
with_pymalloc = _get_config_var("WITH_PYMALLOC", warn)
|
||||
with_pymalloc = _get_config_var('WITH_PYMALLOC', warn)
|
||||
if with_pymalloc or with_pymalloc is None:
|
||||
pymalloc = "m"
|
||||
pymalloc = 'm'
|
||||
if py_version < (3, 3):
|
||||
unicode_size = _get_config_var("Py_UNICODE_SIZE", warn)
|
||||
unicode_size = _get_config_var('Py_UNICODE_SIZE', warn)
|
||||
if unicode_size == 4 or (
|
||||
unicode_size is None and sys.maxunicode == 0x10FFFF
|
||||
):
|
||||
ucs4 = "u"
|
||||
ucs4 = 'u'
|
||||
elif debug:
|
||||
# Debug builds can also load "normal" extension modules.
|
||||
# We can also assume no UCS-4 or pymalloc requirement.
|
||||
abis.append("cp{version}".format(version=version))
|
||||
abis.append(f'cp{version}')
|
||||
abis.insert(
|
||||
0,
|
||||
"cp{version}{debug}{pymalloc}{ucs4}".format(
|
||||
version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4
|
||||
'cp{version}{debug}{pymalloc}{ucs4}'.format(
|
||||
version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4,
|
||||
),
|
||||
)
|
||||
return abis
|
||||
|
|
@ -211,7 +210,7 @@ def cpython_tags(
|
|||
python_version=None, # type: Optional[PythonVersion]
|
||||
abis=None, # type: Optional[Iterable[str]]
|
||||
platforms=None, # type: Optional[Iterable[str]]
|
||||
**kwargs # type: bool
|
||||
**kwargs, # type: bool
|
||||
):
|
||||
# type: (...) -> Iterator[Tag]
|
||||
"""
|
||||
|
|
@ -229,11 +228,11 @@ def cpython_tags(
|
|||
If 'abi3' or 'none' are specified in 'abis' then they will be yielded at
|
||||
their normal position and not at the beginning.
|
||||
"""
|
||||
warn = _warn_keyword_parameter("cpython_tags", kwargs)
|
||||
warn = _warn_keyword_parameter('cpython_tags', kwargs)
|
||||
if not python_version:
|
||||
python_version = sys.version_info[:2]
|
||||
|
||||
interpreter = "cp{}".format(_version_nodot(python_version[:2]))
|
||||
interpreter = f'cp{_version_nodot(python_version[:2])}'
|
||||
|
||||
if abis is None:
|
||||
if len(python_version) > 1:
|
||||
|
|
@ -242,7 +241,7 @@ def cpython_tags(
|
|||
abis = []
|
||||
abis = list(abis)
|
||||
# 'abi3' and 'none' are explicitly handled later.
|
||||
for explicit_abi in ("abi3", "none"):
|
||||
for explicit_abi in ('abi3', 'none'):
|
||||
try:
|
||||
abis.remove(explicit_abi)
|
||||
except ValueError:
|
||||
|
|
@ -253,23 +252,21 @@ def cpython_tags(
|
|||
for platform_ in platforms:
|
||||
yield Tag(interpreter, abi, platform_)
|
||||
if _abi3_applies(python_version):
|
||||
for tag in (Tag(interpreter, "abi3", platform_) for platform_ in platforms):
|
||||
yield tag
|
||||
for tag in (Tag(interpreter, "none", platform_) for platform_ in platforms):
|
||||
yield tag
|
||||
yield from (Tag(interpreter, 'abi3', platform_) for platform_ in platforms)
|
||||
yield from (Tag(interpreter, 'none', platform_) for platform_ in platforms)
|
||||
|
||||
if _abi3_applies(python_version):
|
||||
for minor_version in range(python_version[1] - 1, 1, -1):
|
||||
for platform_ in platforms:
|
||||
interpreter = "cp{version}".format(
|
||||
version=_version_nodot((python_version[0], minor_version))
|
||||
interpreter = 'cp{version}'.format(
|
||||
version=_version_nodot((python_version[0], minor_version)),
|
||||
)
|
||||
yield Tag(interpreter, "abi3", platform_)
|
||||
yield Tag(interpreter, 'abi3', platform_)
|
||||
|
||||
|
||||
def _generic_abi():
|
||||
# type: () -> Iterator[str]
|
||||
abi = sysconfig.get_config_var("SOABI")
|
||||
abi = sysconfig.get_config_var('SOABI')
|
||||
if abi:
|
||||
yield _normalize_string(abi)
|
||||
|
||||
|
|
@ -278,7 +275,7 @@ def generic_tags(
|
|||
interpreter=None, # type: Optional[str]
|
||||
abis=None, # type: Optional[Iterable[str]]
|
||||
platforms=None, # type: Optional[Iterable[str]]
|
||||
**kwargs # type: bool
|
||||
**kwargs, # type: bool
|
||||
):
|
||||
# type: (...) -> Iterator[Tag]
|
||||
"""
|
||||
|
|
@ -289,17 +286,17 @@ def generic_tags(
|
|||
|
||||
The "none" ABI will be added if it was not explicitly provided.
|
||||
"""
|
||||
warn = _warn_keyword_parameter("generic_tags", kwargs)
|
||||
warn = _warn_keyword_parameter('generic_tags', kwargs)
|
||||
if not interpreter:
|
||||
interp_name = interpreter_name()
|
||||
interp_version = interpreter_version(warn=warn)
|
||||
interpreter = "".join([interp_name, interp_version])
|
||||
interpreter = ''.join([interp_name, interp_version])
|
||||
if abis is None:
|
||||
abis = _generic_abi()
|
||||
platforms = list(platforms or _platform_tags())
|
||||
abis = list(abis)
|
||||
if "none" not in abis:
|
||||
abis.append("none")
|
||||
if 'none' not in abis:
|
||||
abis.append('none')
|
||||
for abi in abis:
|
||||
for platform_ in platforms:
|
||||
yield Tag(interpreter, abi, platform_)
|
||||
|
|
@ -314,11 +311,11 @@ def _py_interpreter_range(py_version):
|
|||
all previous versions of that major version.
|
||||
"""
|
||||
if len(py_version) > 1:
|
||||
yield "py{version}".format(version=_version_nodot(py_version[:2]))
|
||||
yield "py{major}".format(major=py_version[0])
|
||||
yield f'py{_version_nodot(py_version[:2])}'
|
||||
yield f'py{py_version[0]}'
|
||||
if len(py_version) > 1:
|
||||
for minor in range(py_version[1] - 1, -1, -1):
|
||||
yield "py{version}".format(version=_version_nodot((py_version[0], minor)))
|
||||
yield f'py{_version_nodot((py_version[0], minor))}'
|
||||
|
||||
|
||||
def compatible_tags(
|
||||
|
|
@ -340,11 +337,11 @@ def compatible_tags(
|
|||
platforms = list(platforms or _platform_tags())
|
||||
for version in _py_interpreter_range(python_version):
|
||||
for platform_ in platforms:
|
||||
yield Tag(version, "none", platform_)
|
||||
yield Tag(version, 'none', platform_)
|
||||
if interpreter:
|
||||
yield Tag(interpreter, "none", "any")
|
||||
yield Tag(interpreter, 'none', 'any')
|
||||
for version in _py_interpreter_range(python_version):
|
||||
yield Tag(version, "none", "any")
|
||||
yield Tag(version, 'none', 'any')
|
||||
|
||||
|
||||
def _mac_arch(arch, is_32bit=_32_BIT_INTERPRETER):
|
||||
|
|
@ -352,37 +349,37 @@ def _mac_arch(arch, is_32bit=_32_BIT_INTERPRETER):
|
|||
if not is_32bit:
|
||||
return arch
|
||||
|
||||
if arch.startswith("ppc"):
|
||||
return "ppc"
|
||||
if arch.startswith('ppc'):
|
||||
return 'ppc'
|
||||
|
||||
return "i386"
|
||||
return 'i386'
|
||||
|
||||
|
||||
def _mac_binary_formats(version, cpu_arch):
|
||||
# type: (MacVersion, str) -> List[str]
|
||||
formats = [cpu_arch]
|
||||
if cpu_arch == "x86_64":
|
||||
if cpu_arch == 'x86_64':
|
||||
if version < (10, 4):
|
||||
return []
|
||||
formats.extend(["intel", "fat64", "fat32"])
|
||||
formats.extend(['intel', 'fat64', 'fat32'])
|
||||
|
||||
elif cpu_arch == "i386":
|
||||
elif cpu_arch == 'i386':
|
||||
if version < (10, 4):
|
||||
return []
|
||||
formats.extend(["intel", "fat32", "fat"])
|
||||
formats.extend(['intel', 'fat32', 'fat'])
|
||||
|
||||
elif cpu_arch == "ppc64":
|
||||
elif cpu_arch == 'ppc64':
|
||||
# TODO: Need to care about 32-bit PPC for ppc64 through 10.2?
|
||||
if version > (10, 5) or version < (10, 4):
|
||||
return []
|
||||
formats.append("fat64")
|
||||
formats.append('fat64')
|
||||
|
||||
elif cpu_arch == "ppc":
|
||||
elif cpu_arch == 'ppc':
|
||||
if version > (10, 6):
|
||||
return []
|
||||
formats.extend(["fat32", "fat"])
|
||||
formats.extend(['fat32', 'fat'])
|
||||
|
||||
formats.append("universal")
|
||||
formats.append('universal')
|
||||
return formats
|
||||
|
||||
|
||||
|
|
@ -398,7 +395,7 @@ def mac_platforms(version=None, arch=None):
|
|||
"""
|
||||
version_str, _, cpu_arch = platform.mac_ver() # type: ignore
|
||||
if version is None:
|
||||
version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2])))
|
||||
version = cast('MacVersion', tuple(map(int, version_str.split('.')[:2])))
|
||||
else:
|
||||
version = version
|
||||
if arch is None:
|
||||
|
|
@ -409,7 +406,7 @@ def mac_platforms(version=None, arch=None):
|
|||
compat_version = version[0], minor_version
|
||||
binary_formats = _mac_binary_formats(compat_version, arch)
|
||||
for binary_format in binary_formats:
|
||||
yield "macosx_{major}_{minor}_{binary_format}".format(
|
||||
yield 'macosx_{major}_{minor}_{binary_format}'.format(
|
||||
major=compat_version[0],
|
||||
minor=compat_version[1],
|
||||
binary_format=binary_format,
|
||||
|
|
@ -423,7 +420,7 @@ def _is_manylinux_compatible(name, glibc_version):
|
|||
try:
|
||||
import _manylinux # noqa
|
||||
|
||||
return bool(getattr(_manylinux, name + "_compatible"))
|
||||
return bool(getattr(_manylinux, name + '_compatible'))
|
||||
except (ImportError, AttributeError):
|
||||
# Fall through to heuristic check below.
|
||||
pass
|
||||
|
|
@ -449,7 +446,7 @@ def _glibc_version_string_confstr():
|
|||
try:
|
||||
# os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17".
|
||||
version_string = os.confstr( # type: ignore[attr-defined] # noqa: F821
|
||||
"CS_GNU_LIBC_VERSION"
|
||||
'CS_GNU_LIBC_VERSION',
|
||||
)
|
||||
assert version_string is not None
|
||||
_, version = version_string.split() # type: Tuple[str, str]
|
||||
|
|
@ -488,7 +485,7 @@ def _glibc_version_string_ctypes():
|
|||
version_str = gnu_get_libc_version() # type: str
|
||||
# py2 / py3 compatibility:
|
||||
if not isinstance(version_str, str):
|
||||
version_str = version_str.decode("ascii")
|
||||
version_str = version_str.decode('ascii')
|
||||
|
||||
return version_str
|
||||
|
||||
|
|
@ -502,17 +499,17 @@ def _check_glibc_version(version_str, required_major, minimum_minor):
|
|||
# random junk that might come after the minor version -- this might happen
|
||||
# in patched/forked versions of glibc (e.g. Linaro's version of glibc
|
||||
# uses version strings like "2.20-2014.11"). See gh-3588.
|
||||
m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
|
||||
m = re.match(r'(?P<major>[0-9]+)\.(?P<minor>[0-9]+)', version_str)
|
||||
if not m:
|
||||
warnings.warn(
|
||||
"Expected glibc version with 2 components major.minor,"
|
||||
" got: %s" % version_str,
|
||||
'Expected glibc version with 2 components major.minor,'
|
||||
' got: %s' % version_str,
|
||||
RuntimeWarning,
|
||||
)
|
||||
return False
|
||||
return (
|
||||
int(m.group("major")) == required_major
|
||||
and int(m.group("minor")) >= minimum_minor
|
||||
int(m.group('major')) == required_major and
|
||||
int(m.group('minor')) >= minimum_minor
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -528,7 +525,7 @@ def _have_compatible_glibc(required_major, minimum_minor):
|
|||
# identify the architecture of the running executable in some cases, so we
|
||||
# determine it dynamically by reading the information from the running
|
||||
# process. This only applies on Linux, which uses the ELF format.
|
||||
class _ELFFileHeader(object):
|
||||
class _ELFFileHeader:
|
||||
# https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header
|
||||
class _InvalidELFFileHeader(ValueError):
|
||||
"""
|
||||
|
|
@ -554,28 +551,28 @@ class _ELFFileHeader(object):
|
|||
# type: (str) -> int
|
||||
try:
|
||||
(result,) = struct.unpack(
|
||||
fmt, file.read(struct.calcsize(fmt))
|
||||
fmt, file.read(struct.calcsize(fmt)),
|
||||
) # type: (int, )
|
||||
except struct.error:
|
||||
raise _ELFFileHeader._InvalidELFFileHeader()
|
||||
return result
|
||||
|
||||
self.e_ident_magic = unpack(">I")
|
||||
self.e_ident_magic = unpack('>I')
|
||||
if self.e_ident_magic != self.ELF_MAGIC_NUMBER:
|
||||
raise _ELFFileHeader._InvalidELFFileHeader()
|
||||
self.e_ident_class = unpack("B")
|
||||
self.e_ident_class = unpack('B')
|
||||
if self.e_ident_class not in {self.ELFCLASS32, self.ELFCLASS64}:
|
||||
raise _ELFFileHeader._InvalidELFFileHeader()
|
||||
self.e_ident_data = unpack("B")
|
||||
self.e_ident_data = unpack('B')
|
||||
if self.e_ident_data not in {self.ELFDATA2LSB, self.ELFDATA2MSB}:
|
||||
raise _ELFFileHeader._InvalidELFFileHeader()
|
||||
self.e_ident_version = unpack("B")
|
||||
self.e_ident_osabi = unpack("B")
|
||||
self.e_ident_abiversion = unpack("B")
|
||||
self.e_ident_version = unpack('B')
|
||||
self.e_ident_osabi = unpack('B')
|
||||
self.e_ident_abiversion = unpack('B')
|
||||
self.e_ident_pad = file.read(7)
|
||||
format_h = "<H" if self.e_ident_data == self.ELFDATA2LSB else ">H"
|
||||
format_i = "<I" if self.e_ident_data == self.ELFDATA2LSB else ">I"
|
||||
format_q = "<Q" if self.e_ident_data == self.ELFDATA2LSB else ">Q"
|
||||
format_h = '<H' if self.e_ident_data == self.ELFDATA2LSB else '>H'
|
||||
format_i = '<I' if self.e_ident_data == self.ELFDATA2LSB else '>I'
|
||||
format_q = '<Q' if self.e_ident_data == self.ELFDATA2LSB else '>Q'
|
||||
format_p = format_i if self.e_ident_class == self.ELFCLASS32 else format_q
|
||||
self.e_type = unpack(format_h)
|
||||
self.e_machine = unpack(format_h)
|
||||
|
|
@ -595,9 +592,9 @@ class _ELFFileHeader(object):
|
|||
def _get_elf_header():
|
||||
# type: () -> Optional[_ELFFileHeader]
|
||||
try:
|
||||
with open(sys.executable, "rb") as f:
|
||||
with open(sys.executable, 'rb') as f:
|
||||
elf_header = _ELFFileHeader(f)
|
||||
except (IOError, OSError, TypeError, _ELFFileHeader._InvalidELFFileHeader):
|
||||
except (OSError, TypeError, _ELFFileHeader._InvalidELFFileHeader):
|
||||
return None
|
||||
return elf_header
|
||||
|
||||
|
|
@ -635,9 +632,9 @@ def _is_linux_i686():
|
|||
|
||||
def _have_compatible_manylinux_abi(arch):
|
||||
# type: (str) -> bool
|
||||
if arch == "armv7l":
|
||||
if arch == 'armv7l':
|
||||
return _is_linux_armhf()
|
||||
if arch == "i686":
|
||||
if arch == 'i686':
|
||||
return _is_linux_i686()
|
||||
return True
|
||||
|
||||
|
|
@ -646,32 +643,32 @@ def _linux_platforms(is_32bit=_32_BIT_INTERPRETER):
|
|||
# type: (bool) -> Iterator[str]
|
||||
linux = _normalize_string(distutils.util.get_platform())
|
||||
if is_32bit:
|
||||
if linux == "linux_x86_64":
|
||||
linux = "linux_i686"
|
||||
elif linux == "linux_aarch64":
|
||||
linux = "linux_armv7l"
|
||||
if linux == 'linux_x86_64':
|
||||
linux = 'linux_i686'
|
||||
elif linux == 'linux_aarch64':
|
||||
linux = 'linux_armv7l'
|
||||
manylinux_support = []
|
||||
_, arch = linux.split("_", 1)
|
||||
_, arch = linux.split('_', 1)
|
||||
if _have_compatible_manylinux_abi(arch):
|
||||
if arch in {"x86_64", "i686", "aarch64", "armv7l", "ppc64", "ppc64le", "s390x"}:
|
||||
if arch in {'x86_64', 'i686', 'aarch64', 'armv7l', 'ppc64', 'ppc64le', 's390x'}:
|
||||
manylinux_support.append(
|
||||
("manylinux2014", (2, 17))
|
||||
('manylinux2014', (2, 17)),
|
||||
) # CentOS 7 w/ glibc 2.17 (PEP 599)
|
||||
if arch in {"x86_64", "i686"}:
|
||||
if arch in {'x86_64', 'i686'}:
|
||||
manylinux_support.append(
|
||||
("manylinux2010", (2, 12))
|
||||
('manylinux2010', (2, 12)),
|
||||
) # CentOS 6 w/ glibc 2.12 (PEP 571)
|
||||
manylinux_support.append(
|
||||
("manylinux1", (2, 5))
|
||||
('manylinux1', (2, 5)),
|
||||
) # CentOS 5 w/ glibc 2.5 (PEP 513)
|
||||
manylinux_support_iter = iter(manylinux_support)
|
||||
for name, glibc_version in manylinux_support_iter:
|
||||
if _is_manylinux_compatible(name, glibc_version):
|
||||
yield linux.replace("linux", name)
|
||||
yield linux.replace('linux', name)
|
||||
break
|
||||
# Support for a later manylinux implies support for an earlier version.
|
||||
for name, _ in manylinux_support_iter:
|
||||
yield linux.replace("linux", name)
|
||||
yield linux.replace('linux', name)
|
||||
yield linux
|
||||
|
||||
|
||||
|
|
@ -685,9 +682,9 @@ def _platform_tags():
|
|||
"""
|
||||
Provides the platform tags for this installation.
|
||||
"""
|
||||
if platform.system() == "Darwin":
|
||||
if platform.system() == 'Darwin':
|
||||
return mac_platforms()
|
||||
elif platform.system() == "Linux":
|
||||
elif platform.system() == 'Linux':
|
||||
return _linux_platforms()
|
||||
else:
|
||||
return _generic_platforms()
|
||||
|
|
@ -711,8 +708,8 @@ def interpreter_version(**kwargs):
|
|||
"""
|
||||
Returns the version of the running interpreter.
|
||||
"""
|
||||
warn = _warn_keyword_parameter("interpreter_version", kwargs)
|
||||
version = _get_config_var("py_version_nodot", warn=warn)
|
||||
warn = _warn_keyword_parameter('interpreter_version', kwargs)
|
||||
version = _get_config_var('py_version_nodot', warn=warn)
|
||||
if version:
|
||||
version = str(version)
|
||||
else:
|
||||
|
|
@ -723,9 +720,9 @@ def interpreter_version(**kwargs):
|
|||
def _version_nodot(version):
|
||||
# type: (PythonVersion) -> str
|
||||
if any(v >= 10 for v in version):
|
||||
sep = "_"
|
||||
sep = '_'
|
||||
else:
|
||||
sep = ""
|
||||
sep = ''
|
||||
return sep.join(map(str, version))
|
||||
|
||||
|
||||
|
|
@ -737,15 +734,12 @@ def sys_tags(**kwargs):
|
|||
The order of the sequence corresponds to priority order for the
|
||||
interpreter, from most to least important.
|
||||
"""
|
||||
warn = _warn_keyword_parameter("sys_tags", kwargs)
|
||||
warn = _warn_keyword_parameter('sys_tags', kwargs)
|
||||
|
||||
interp_name = interpreter_name()
|
||||
if interp_name == "cp":
|
||||
for tag in cpython_tags(warn=warn):
|
||||
yield tag
|
||||
if interp_name == 'cp':
|
||||
yield from cpython_tags(warn=warn)
|
||||
else:
|
||||
for tag in generic_tags():
|
||||
yield tag
|
||||
yield from generic_tags()
|
||||
|
||||
for tag in compatible_tags():
|
||||
yield tag
|
||||
yield from compatible_tags()
|
||||
|
|
|
|||
|
|
@ -1,26 +1,28 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
from ._typing import TYPE_CHECKING, cast
|
||||
from .version import InvalidVersion, Version
|
||||
from ._typing import cast
|
||||
from ._typing import TYPE_CHECKING
|
||||
from .version import InvalidVersion
|
||||
from .version import Version
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from typing import NewType, Union
|
||||
|
||||
NormalizedName = NewType("NormalizedName", str)
|
||||
NormalizedName = NewType('NormalizedName', str)
|
||||
|
||||
_canonicalize_regex = re.compile(r"[-_.]+")
|
||||
_canonicalize_regex = re.compile(r'[-_.]+')
|
||||
|
||||
|
||||
def canonicalize_name(name):
|
||||
# type: (str) -> NormalizedName
|
||||
# This is taken from PEP 503.
|
||||
value = _canonicalize_regex.sub("-", name).lower()
|
||||
return cast("NormalizedName", value)
|
||||
value = _canonicalize_regex.sub('-', name).lower()
|
||||
return cast('NormalizedName', value)
|
||||
|
||||
|
||||
def canonicalize_version(_version):
|
||||
|
|
@ -40,26 +42,26 @@ def canonicalize_version(_version):
|
|||
|
||||
# Epoch
|
||||
if version.epoch != 0:
|
||||
parts.append("{0}!".format(version.epoch))
|
||||
parts.append(f'{version.epoch}!')
|
||||
|
||||
# Release segment
|
||||
# NB: This strips trailing '.0's to normalize
|
||||
parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release)))
|
||||
parts.append(re.sub(r'(\.0)+$', '', '.'.join(str(x) for x in version.release)))
|
||||
|
||||
# Pre-release
|
||||
if version.pre is not None:
|
||||
parts.append("".join(str(x) for x in version.pre))
|
||||
parts.append(''.join(str(x) for x in version.pre))
|
||||
|
||||
# Post-release
|
||||
if version.post is not None:
|
||||
parts.append(".post{0}".format(version.post))
|
||||
parts.append(f'.post{version.post}')
|
||||
|
||||
# Development release
|
||||
if version.dev is not None:
|
||||
parts.append(".dev{0}".format(version.dev))
|
||||
parts.append(f'.dev{version.dev}')
|
||||
|
||||
# Local version segment
|
||||
if version.local is not None:
|
||||
parts.append("+{0}".format(version.local))
|
||||
parts.append(f'+{version.local}')
|
||||
|
||||
return "".join(parts)
|
||||
return ''.join(parts)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
# This file is dual licensed under the terms of the Apache License, Version
|
||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
||||
# for complete details.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from __future__ import annotations
|
||||
|
||||
import collections
|
||||
import itertools
|
||||
import re
|
||||
|
||||
from ._structures import Infinity, NegativeInfinity
|
||||
from ._structures import Infinity
|
||||
from ._structures import NegativeInfinity
|
||||
from ._typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
|
|
@ -30,18 +31,18 @@ if TYPE_CHECKING: # pragma: no cover
|
|||
],
|
||||
]
|
||||
CmpKey = Tuple[
|
||||
int, Tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType
|
||||
int, Tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType,
|
||||
]
|
||||
LegacyCmpKey = Tuple[int, Tuple[str, ...]]
|
||||
VersionComparisonMethod = Callable[
|
||||
[Union[CmpKey, LegacyCmpKey], Union[CmpKey, LegacyCmpKey]], bool
|
||||
[Union[CmpKey, LegacyCmpKey], Union[CmpKey, LegacyCmpKey]], bool,
|
||||
]
|
||||
|
||||
__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"]
|
||||
__all__ = ['parse', 'Version', 'LegacyVersion', 'InvalidVersion', 'VERSION_PATTERN']
|
||||
|
||||
|
||||
_Version = collections.namedtuple(
|
||||
"_Version", ["epoch", "release", "dev", "pre", "post", "local"]
|
||||
'_Version', ['epoch', 'release', 'dev', 'pre', 'post', 'local'],
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -64,7 +65,7 @@ class InvalidVersion(ValueError):
|
|||
"""
|
||||
|
||||
|
||||
class _BaseVersion(object):
|
||||
class _BaseVersion:
|
||||
_key = None # type: Union[CmpKey, LegacyCmpKey]
|
||||
|
||||
def __hash__(self):
|
||||
|
|
@ -115,7 +116,7 @@ class LegacyVersion(_BaseVersion):
|
|||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "<LegacyVersion({0})>".format(repr(str(self)))
|
||||
return f'<LegacyVersion({repr(str(self))})>'
|
||||
|
||||
@property
|
||||
def public(self):
|
||||
|
|
@ -173,14 +174,14 @@ class LegacyVersion(_BaseVersion):
|
|||
return False
|
||||
|
||||
|
||||
_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE)
|
||||
_legacy_version_component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE)
|
||||
|
||||
_legacy_version_replacement_map = {
|
||||
"pre": "c",
|
||||
"preview": "c",
|
||||
"-": "final-",
|
||||
"rc": "c",
|
||||
"dev": "@",
|
||||
'pre': 'c',
|
||||
'preview': 'c',
|
||||
'-': 'final-',
|
||||
'rc': 'c',
|
||||
'dev': '@',
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -189,17 +190,17 @@ def _parse_version_parts(s):
|
|||
for part in _legacy_version_component_re.split(s):
|
||||
part = _legacy_version_replacement_map.get(part, part)
|
||||
|
||||
if not part or part == ".":
|
||||
if not part or part == '.':
|
||||
continue
|
||||
|
||||
if part[:1] in "0123456789":
|
||||
if part[:1] in '0123456789':
|
||||
# pad for numeric comparison
|
||||
yield part.zfill(8)
|
||||
else:
|
||||
yield "*" + part
|
||||
yield '*' + part
|
||||
|
||||
# ensure that alpha/beta/candidate are before final
|
||||
yield "*final"
|
||||
yield '*final'
|
||||
|
||||
|
||||
def _legacy_cmpkey(version):
|
||||
|
|
@ -215,14 +216,14 @@ def _legacy_cmpkey(version):
|
|||
# it's adoption of the packaging library.
|
||||
parts = [] # type: List[str]
|
||||
for part in _parse_version_parts(version.lower()):
|
||||
if part.startswith("*"):
|
||||
if part.startswith('*'):
|
||||
# remove "-" before a prerelease tag
|
||||
if part < "*final":
|
||||
while parts and parts[-1] == "*final-":
|
||||
if part < '*final':
|
||||
while parts and parts[-1] == '*final-':
|
||||
parts.pop()
|
||||
|
||||
# remove trailing zeros from each series of numeric parts
|
||||
while parts and parts[-1] == "00000000":
|
||||
while parts and parts[-1] == '00000000':
|
||||
parts.pop()
|
||||
|
||||
parts.append(part)
|
||||
|
|
@ -266,7 +267,7 @@ VERSION_PATTERN = r"""
|
|||
|
||||
class Version(_BaseVersion):
|
||||
|
||||
_regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE)
|
||||
_regex = re.compile(r'^\s*' + VERSION_PATTERN + r'\s*$', re.VERBOSE | re.IGNORECASE)
|
||||
|
||||
def __init__(self, version):
|
||||
# type: (str) -> None
|
||||
|
|
@ -274,18 +275,18 @@ class Version(_BaseVersion):
|
|||
# Validate the version and parse it into pieces
|
||||
match = self._regex.search(version)
|
||||
if not match:
|
||||
raise InvalidVersion("Invalid version: '{0}'".format(version))
|
||||
raise InvalidVersion(f"Invalid version: '{version}'")
|
||||
|
||||
# Store the parsed out pieces of the version
|
||||
self._version = _Version(
|
||||
epoch=int(match.group("epoch")) if match.group("epoch") else 0,
|
||||
release=tuple(int(i) for i in match.group("release").split(".")),
|
||||
pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")),
|
||||
epoch=int(match.group('epoch')) if match.group('epoch') else 0,
|
||||
release=tuple(int(i) for i in match.group('release').split('.')),
|
||||
pre=_parse_letter_version(match.group('pre_l'), match.group('pre_n')),
|
||||
post=_parse_letter_version(
|
||||
match.group("post_l"), match.group("post_n1") or match.group("post_n2")
|
||||
match.group('post_l'), match.group('post_n1') or match.group('post_n2'),
|
||||
),
|
||||
dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")),
|
||||
local=_parse_local_version(match.group("local")),
|
||||
dev=_parse_letter_version(match.group('dev_l'), match.group('dev_n')),
|
||||
local=_parse_local_version(match.group('local')),
|
||||
)
|
||||
|
||||
# Generate a key which will be used for sorting
|
||||
|
|
@ -300,7 +301,7 @@ class Version(_BaseVersion):
|
|||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "<Version({0})>".format(repr(str(self)))
|
||||
return f'<Version({repr(str(self))})>'
|
||||
|
||||
def __str__(self):
|
||||
# type: () -> str
|
||||
|
|
@ -308,28 +309,28 @@ class Version(_BaseVersion):
|
|||
|
||||
# Epoch
|
||||
if self.epoch != 0:
|
||||
parts.append("{0}!".format(self.epoch))
|
||||
parts.append(f'{self.epoch}!')
|
||||
|
||||
# Release segment
|
||||
parts.append(".".join(str(x) for x in self.release))
|
||||
parts.append('.'.join(str(x) for x in self.release))
|
||||
|
||||
# Pre-release
|
||||
if self.pre is not None:
|
||||
parts.append("".join(str(x) for x in self.pre))
|
||||
parts.append(''.join(str(x) for x in self.pre))
|
||||
|
||||
# Post-release
|
||||
if self.post is not None:
|
||||
parts.append(".post{0}".format(self.post))
|
||||
parts.append(f'.post{self.post}')
|
||||
|
||||
# Development release
|
||||
if self.dev is not None:
|
||||
parts.append(".dev{0}".format(self.dev))
|
||||
parts.append(f'.dev{self.dev}')
|
||||
|
||||
# Local version segment
|
||||
if self.local is not None:
|
||||
parts.append("+{0}".format(self.local))
|
||||
parts.append(f'+{self.local}')
|
||||
|
||||
return "".join(parts)
|
||||
return ''.join(parts)
|
||||
|
||||
@property
|
||||
def epoch(self):
|
||||
|
|
@ -363,14 +364,14 @@ class Version(_BaseVersion):
|
|||
def local(self):
|
||||
# type: () -> Optional[str]
|
||||
if self._version.local:
|
||||
return ".".join(str(x) for x in self._version.local)
|
||||
return '.'.join(str(x) for x in self._version.local)
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def public(self):
|
||||
# type: () -> str
|
||||
return str(self).split("+", 1)[0]
|
||||
return str(self).split('+', 1)[0]
|
||||
|
||||
@property
|
||||
def base_version(self):
|
||||
|
|
@ -379,12 +380,12 @@ class Version(_BaseVersion):
|
|||
|
||||
# Epoch
|
||||
if self.epoch != 0:
|
||||
parts.append("{0}!".format(self.epoch))
|
||||
parts.append(f'{self.epoch}!')
|
||||
|
||||
# Release segment
|
||||
parts.append(".".join(str(x) for x in self.release))
|
||||
parts.append('.'.join(str(x) for x in self.release))
|
||||
|
||||
return "".join(parts)
|
||||
return ''.join(parts)
|
||||
|
||||
@property
|
||||
def is_prerelease(self):
|
||||
|
|
@ -435,27 +436,27 @@ def _parse_letter_version(
|
|||
# We consider some words to be alternate spellings of other words and
|
||||
# in those cases we want to normalize the spellings to our preferred
|
||||
# spelling.
|
||||
if letter == "alpha":
|
||||
letter = "a"
|
||||
elif letter == "beta":
|
||||
letter = "b"
|
||||
elif letter in ["c", "pre", "preview"]:
|
||||
letter = "rc"
|
||||
elif letter in ["rev", "r"]:
|
||||
letter = "post"
|
||||
if letter == 'alpha':
|
||||
letter = 'a'
|
||||
elif letter == 'beta':
|
||||
letter = 'b'
|
||||
elif letter in ['c', 'pre', 'preview']:
|
||||
letter = 'rc'
|
||||
elif letter in ['rev', 'r']:
|
||||
letter = 'post'
|
||||
|
||||
return letter, int(number)
|
||||
if not letter and number:
|
||||
# We assume if we are given a number, but we are not given a letter
|
||||
# then this is using the implicit post release syntax (e.g. 1.0-1)
|
||||
letter = "post"
|
||||
letter = 'post'
|
||||
|
||||
return letter, int(number)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
_local_version_separators = re.compile(r"[\._-]")
|
||||
_local_version_separators = re.compile(r'[\._-]')
|
||||
|
||||
|
||||
def _parse_local_version(local):
|
||||
|
|
@ -487,7 +488,7 @@ def _cmpkey(
|
|||
# re-reverse it back into the correct order and make it a tuple and use
|
||||
# that for our sorting key.
|
||||
_release = tuple(
|
||||
reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release))))
|
||||
reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release)))),
|
||||
)
|
||||
|
||||
# We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
|
||||
|
|
@ -529,7 +530,7 @@ def _cmpkey(
|
|||
# - Shorter versions sort before longer versions when the prefixes
|
||||
# match exactly
|
||||
_local = tuple(
|
||||
(i, "") if isinstance(i, int) else (NegativeInfinity, i) for i in local
|
||||
(i, '') if isinstance(i, int) else (NegativeInfinity, i) for i in local
|
||||
)
|
||||
|
||||
return epoch, _release, _pre, _post, _dev, _local
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
|
||||
|
|
@ -42,10 +44,10 @@ class VendorImporter:
|
|||
pass
|
||||
else:
|
||||
raise ImportError(
|
||||
"The '{target}' package is required; "
|
||||
"normally this is bundled with this package so if you get "
|
||||
"this warning, consult the packager of your "
|
||||
"distribution.".format(**locals())
|
||||
f"The '{target}' package is required; "
|
||||
f'normally this is bundled with this package so if you get '
|
||||
f'this warning, consult the packager of your '
|
||||
f'distribution.',
|
||||
)
|
||||
|
||||
def create_module(self, spec):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import setuptools
|
||||
setuptools.setup(
|
||||
name="my-test-package",
|
||||
version="1.0",
|
||||
name='my-test-package',
|
||||
version='1.0',
|
||||
zip_safe=True,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue