Upgrade outdated vendored deps

- Upgrade outdated `pip_shims` and `requirementslib` deps ahead of
  release
- Upgrade `importlib-metadata`

Signed-off-by: Dan Ryan <dan.ryan@canonical.com>
This commit is contained in:
Dan Ryan
2020-04-22 13:58:02 -04:00
parent 478e4c5f37
commit 16c1cc6ebd
18 changed files with 1568 additions and 117 deletions
+3
View File
@@ -6,3 +6,6 @@ Add and update vendored dependencies to accommodate ``safety`` vendoring:
- **certifi** ``2019.11.28`` => ``2020.4.5.1``
- **pyparsing** ``2.4.6`` => ``2.4.7``
- **resolvelib** ``0.2.2`` => ``0.3.0``
- **importlib-metadata** ``1.5.1`` => ``1.6.0``
- **pip-shims** ``0.5.1`` => ``0.5.2``
- **requirementslib** ``1.5.5`` => ``1.5.6``
+13 -2
View File
@@ -28,6 +28,7 @@ from ._compat import (
MetaPathFinder,
email_message_from_string,
PyPy_repr,
unique_ordered,
)
from importlib import import_module
from itertools import starmap
@@ -95,6 +96,16 @@ class EntryPoint(
attrs = filter(None, (match.group('attr') or '').split('.'))
return functools.reduce(getattr, attrs, module)
@property
def module(self):
match = self.pattern.match(self.value)
return match.group('module')
@property
def attr(self):
match = self.pattern.match(self.value)
return match.group('attr')
@property
def extras(self):
match = self.pattern.match(self.value)
@@ -425,8 +436,8 @@ class FastPath:
names = zip_path.root.namelist()
self.joinpath = zip_path.joinpath
return (
posixpath.split(child)[0]
return unique_ordered(
child.split(posixpath.sep, 1)[0]
for child in names
)
+17
View File
@@ -15,9 +15,11 @@ if sys.version_info > (3,): # pragma: nocover
NotADirectoryError = builtins.NotADirectoryError
PermissionError = builtins.PermissionError
map = builtins.map
from itertools import filterfalse
else: # pragma: nocover
from backports.configparser import ConfigParser
from itertools import imap as map # type: ignore
from itertools import ifilterfalse as filterfalse
import contextlib2 as contextlib
FileNotFoundError = IOError, OSError
IsADirectoryError = IOError, OSError
@@ -131,3 +133,18 @@ class PyPy_repr:
if affected: # pragma: nocover
__repr__ = __compat_repr__
del affected
# from itertools recipes
def unique_everseen(iterable): # pragma: nocover
"List unique elements, preserving order. Remember all elements ever seen."
seen = set()
seen_add = seen.add
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
unique_ordered = (
unique_everseen if sys.version_info < (3, 7) else dict.fromkeys)
+11
View File
@@ -2,6 +2,17 @@
importlib_metadata NEWS
=========================
v1.6.0
======
* Added ``module`` and ``attr`` attributes to ``EntryPoint``
v1.5.2
======
* Fix redundant entries from ``FastPath.zip_children``.
Closes #117.
v1.5.1
======
+9 -1
View File
@@ -70,7 +70,9 @@ Entry points
The ``entry_points()`` function returns a dictionary of all entry points,
keyed by group. Entry points are represented by ``EntryPoint`` instances;
each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and
a ``.load()`` method to resolve the value::
a ``.load()`` method to resolve the value. There are also ``.module``,
``.attr``, and ``.extras`` attributes for getting the components of the
``.value`` attribute::
>>> eps = entry_points()
>>> list(eps)
@@ -79,6 +81,12 @@ a ``.load()`` method to resolve the value::
>>> wheel = [ep for ep in scripts if ep.name == 'wheel'][0]
>>> wheel
EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
>>> wheel.module
'wheel.cli'
>>> wheel.attr
'main'
>>> wheel.extras
[]
>>> main = wheel.load()
>>> main
<function main at 0x103528488>
+6
View File
@@ -250,3 +250,9 @@ class TestEntryPoints(unittest.TestCase):
"""
with self.assertRaises(Exception):
json.dumps(self.ep)
def test_module(self):
assert self.ep.module == 'value'
def test_attr(self):
assert self.ep.attr is None
+8 -1
View File
@@ -1,7 +1,10 @@
import sys
import unittest
from .. import distribution, entry_points, files, PackageNotFoundError, version
from .. import (
distribution, entry_points, files, PackageNotFoundError,
version, distributions,
)
try:
from importlib.resources import path
@@ -52,6 +55,10 @@ class TestZip(unittest.TestCase):
path = str(file.dist.locate_file(file))
assert '.whl/' in path, path
def test_one_distribution(self):
dists = list(distributions(path=sys.path[:1]))
assert len(dists) == 1
class TestEgg(TestZip):
def setUp(self):
+1 -1
View File
@@ -5,7 +5,7 @@ import sys
from . import shims
__version__ = "0.5.1"
__version__ = "0.5.2"
if "pip_shims" in sys.modules:
+146 -78
View File
@@ -19,6 +19,8 @@ from packaging import specifiers
from .environment import MYPY_RUNNING
from .utils import (
call_function_with_correct_args,
filter_allowed_args,
get_allowed_args,
get_method_args,
nullcontext,
suppress_setattr,
@@ -65,6 +67,7 @@ if MYPY_RUNNING:
TCommandInstance = TypeVar("TCommandInstance")
TCmdDict = Dict[str, Union[Tuple[str, str, str], TCommandInstance]]
TInstallRequirement = TypeVar("TInstallRequirement")
TFormatControl = TypeVar("TFormatControl")
TShimmedCmdDict = Union[TShim, TCmdDict]
TWheelCache = TypeVar("TWheelCache")
TPreparer = TypeVar("TPreparer")
@@ -352,11 +355,11 @@ def ensure_resolution_dirs(**kwargs):
@contextlib.contextmanager
def wheel_cache(
wheel_cache_provider, # type: TShimmedFunc
tempdir_manager_provider, # type: TShimmedFunc
cache_dir, # type: str
cache_dir=None, # type: str
format_control=None, # type: Any
wheel_cache_provider=None, # type: TShimmedFunc
format_control_provider=None, # type: Optional[TShimmedFunc]
tempdir_manager_provider=None, # type: TShimmedFunc
):
tempdir_manager_provider = resolve_possible_shim(tempdir_manager_provider)
wheel_cache_provider = resolve_possible_shim(wheel_cache_provider)
@@ -490,6 +493,7 @@ def get_requirement_set(
cache_dir=None, # type: Optional[str]
options=None, # type: Optional[Values]
install_cmd_provider=None, # type: Optional[TShimmedFunc]
wheel_cache_provider=None, # type: Optional[TShimmedFunc]
):
# (...) -> TRequirementSet
"""
@@ -499,6 +503,8 @@ def get_requirement_set(
invalid parameters will be ignored if they are not needed to generate a
requirement set on the current pip version.
:param :class:`~pip_shims.models.ShimmedPathCollection` wheel_cache_provider: A
context manager provider which resolves to a `WheelCache` instance
:param install_command: A :class:`~pip._internal.commands.install.InstallCommand`
instance which is used to generate the finder.
:param :class:`~pip_shims.models.ShimmedPathCollection` req_set_provider: A provider
@@ -538,6 +544,7 @@ def get_requirement_set(
:return: A new requirement set instance
:rtype: :class:`~pip._internal.req.req_set.RequirementSet`
"""
wheel_cache_provider = resolve_possible_shim(wheel_cache_provider)
req_set_provider = resolve_possible_shim(req_set_provider)
if install_command is None:
install_cmd_provider = resolve_possible_shim(install_cmd_provider)
@@ -565,10 +572,13 @@ def get_requirement_set(
)
if session is None and "session" in required_args:
session = get_session(install_cmd=install_command, options=options)
results["wheel_cache"] = wheel_cache
results["session"] = session
results["wheel_download_dir"] = wheel_download_dir
return call_function_with_correct_args(req_set_provider, **results)
with ExitStack() as stack:
if wheel_cache is None:
wheel_cache = stack.enter_context(wheel_cache_provider(cache_dir=cache_dir))
results["wheel_cache"] = wheel_cache
results["session"] = session
results["wheel_download_dir"] = wheel_download_dir
return call_function_with_correct_args(req_set_provider, **results)
def get_package_finder(
@@ -665,11 +675,11 @@ def get_package_finder(
):
if target_python and not received_python:
tags = target_python.get_tags()
version_impl = set([t[0] for t in tags])
version_impl = {t[0] for t in tags}
# impls = set([v[:2] for v in version_impl])
# impls.remove("py")
# impl = next(iter(impls), "py") if not target_python
versions = set([v[2:] for v in version_impl])
versions = {v[2:] for v in version_impl}
build_kwargs.update(
{
"platform": target_python.platform,
@@ -689,6 +699,7 @@ def get_package_finder(
def shim_unpack(
unpack_fn, # type: TShimmedFunc
download_dir, # type str
tempdir_manager_provider, # type: TShimmedFunc
ireq=None, # type: Optional[Any]
link=None, # type: Optional[Any]
location=None, # type Optional[str],
@@ -708,6 +719,8 @@ def shim_unpack(
:param unpack_fn: A callable or shim referring to the pip implementation
:type unpack_fn: Callable
:param str download_dir: The directory to download the file to
:param TShimmedFunc tempdir_manager_provider: A callable or shim referring to
`global_tempdir_manager` function from pip or a shimmed no-op context manager
:param Optional[:class:`~pip._internal.req.req_install.InstallRequirement`] ireq:
an Install Requirement instance, defaults to None
:param Optional[:class:`~pip._internal.models.link.Link`] link: A Link instance,
@@ -727,31 +740,33 @@ def shim_unpack(
"""
unpack_fn = resolve_possible_shim(unpack_fn)
downloader_provider = resolve_possible_shim(downloader_provider)
tempdir_manager_provider = resolve_possible_shim(tempdir_manager_provider)
required_args = inspect.getargs(unpack_fn.__code__).args # type: ignore
unpack_kwargs = {"download_dir": download_dir}
if ireq:
if not link and ireq.link:
link = ireq.link
if only_download is None:
only_download = ireq.is_wheel
if hashes is None:
hashes = ireq.hashes(True)
if location is None and getattr(ireq, "source_dir", None):
location = ireq.source_dir
unpack_kwargs.update({"link": link, "location": location})
if hashes is not None and "hashes" in required_args:
unpack_kwargs["hashes"] = hashes
if "progress_bar" in required_args:
unpack_kwargs["progress_bar"] = progress_bar
if only_download is not None and "only_download" in required_args:
unpack_kwargs["only_download"] = only_download
if session is not None and "session" in required_args:
unpack_kwargs["session"] = session
if "downloader" in required_args and downloader_provider is not None:
assert session is not None
assert progress_bar is not None
unpack_kwargs["downloader"] = downloader_provider(session, progress_bar)
return unpack_fn(**unpack_kwargs) # type: ignore
with tempdir_manager_provider():
if ireq:
if not link and ireq.link:
link = ireq.link
if only_download is None:
only_download = ireq.is_wheel
if hashes is None:
hashes = ireq.hashes(True)
if location is None and getattr(ireq, "source_dir", None):
location = ireq.source_dir
unpack_kwargs.update({"link": link, "location": location})
if hashes is not None and "hashes" in required_args:
unpack_kwargs["hashes"] = hashes
if "progress_bar" in required_args:
unpack_kwargs["progress_bar"] = progress_bar
if only_download is not None and "only_download" in required_args:
unpack_kwargs["only_download"] = only_download
if session is not None and "session" in required_args:
unpack_kwargs["session"] = session
if "downloader" in required_args and downloader_provider is not None:
assert session is not None
assert progress_bar is not None
unpack_kwargs["downloader"] = downloader_provider(session, progress_bar)
return unpack_fn(**unpack_kwargs) # type: ignore
def _ensure_finder(
@@ -860,7 +875,7 @@ def make_preparer(
preparer_fn = resolve_possible_shim(preparer_fn)
downloader_provider = resolve_possible_shim(downloader_provider)
finder_provider = resolve_possible_shim(finder_provider)
required_args = inspect.getargs(preparer_fn.__init__.__code__).args # type: ignore
required_args, required_kwargs = get_allowed_args(preparer_fn) # type: ignore
if not req_tracker and not req_tracker_fn and "req_tracker" in required_args:
raise TypeError("No requirement tracker and no req tracker generator found!")
if "downloader" in required_args and not downloader_provider:
@@ -918,6 +933,38 @@ def make_preparer(
yield result
@contextlib.contextmanager
def _ensure_wheel_cache(
wheel_cache=None, # type: Optional[Type[TWheelCache]]
wheel_cache_provider=None, # type: Optional[Callable]
format_control=None, # type: Optional[TFormatControl]
format_control_provider=None, # type: Optional[Type[TShimmedFunc]]
options=None, # type: Optional[Values]
cache_dir=None, # type: Optional[str]
):
if wheel_cache is not None:
yield wheel_cache
elif wheel_cache_provider is not None:
with ExitStack() as stack:
cache_dir = getattr(options, "cache_dir", cache_dir)
format_control = getattr(
options,
"format_control",
format_control_provider(None, None), # TFormatControl
)
wheel_cache = stack.enter_context(
wheel_cache_provider(cache_dir, format_control)
)
yield wheel_cache
def get_ireq_output_path(wheel_cache, ireq):
if getattr(wheel_cache, "get_path_for_link", None):
return wheel_cache.get_path_for_link(ireq.link)
elif getattr(wheel_cache, "cached_wheel", None):
return wheel_cache.cached_wheel(ireq.link, ireq.name).url_without_fragment
def get_resolver(
resolver_fn, # type: TShimmedFunc
install_req_provider=None, # type: Optional[TShimmedFunc]
@@ -938,6 +985,7 @@ def get_resolver(
make_install_req=None, # type: Optional[Callable]
install_cmd_provider=None, # type: Optional[TShimmedFunc]
install_cmd=None, # type: Optional[TCommandInstance]
use_pep517=True, # type: bool
):
# (...) -> TResolver
"""
@@ -985,6 +1033,7 @@ def get_resolver(
to the resolver for actually generating install requirements, if necessary
:param Optional[TCommandInstance] install_cmd: The install command used to create
the finder, session, and options if needed, defaults to None.
:param bool use_pep517: Whether to use the pep517 build process.
:return: A new resolver instance.
:rtype: :class:`~pip._internal.legacy_resolve.Resolver`
@@ -1049,7 +1098,7 @@ def get_resolver(
continue
elif val is None and install_cmd is None:
raise TypeError(
"Preparer requires a {0} but did not receive one "
"Preparer requires a {} but did not receive one "
"and cannot generate one".format(arg)
)
elif arg == "session" and val is None:
@@ -1059,26 +1108,21 @@ def get_resolver(
resolver_kwargs[arg] = val
if "make_install_req" in required_args:
if make_install_req is None and install_req_provider is not None:
make_install_req_kwargs = {
"isolated": isolated,
"wheel_cache": wheel_cache,
"use_pep517": use_pep517,
}
factory_args, factory_kwargs = filter_allowed_args(
install_req_provider, **make_install_req_kwargs
)
make_install_req = functools.partial(
install_req_provider,
isolated=isolated,
wheel_cache=wheel_cache,
# use_pep517=use_pep517,
install_req_provider, *factory_args, **factory_kwargs
)
assert make_install_req is not None
resolver_kwargs["make_install_req"] = make_install_req
if "isolated" in required_args:
resolver_kwargs["isolated"] = isolated
if "wheel_cache" in required_args:
if wheel_cache is None and wheel_cache_provider is not None:
cache_dir = getattr(options, "cache_dir", None)
format_control = getattr(
options,
"format_control",
format_control_provider(None, None), # type: ignore
)
wheel_cache = wheel_cache_provider(cache_dir, format_control)
resolver_kwargs["wheel_cache"] = wheel_cache
resolver_kwargs.update(
{
"upgrade_strategy": upgrade_strategy,
@@ -1090,6 +1134,15 @@ def get_resolver(
"preparer": preparer,
}
)
if "wheel_cache" in required_args:
with _ensure_wheel_cache(
wheel_cache=wheel_cache,
wheel_cache_provider=wheel_cache_provider,
format_control_provider=format_control_provider,
options=options,
) as wheel_cache:
resolver_kwargs["wheel_cache"] = wheel_cache
return resolver_fn(**resolver_kwargs) # type: ignore
return resolver_fn(**resolver_kwargs) # type: ignore
@@ -1255,22 +1308,29 @@ def resolve( # noqa:C901
if session is None:
session = get_session(install_cmd=install_command, options=options)
if finder is None:
finder = finder_provider(install_command, options=options, session=session) # type: ignore
finder = finder_provider(
install_command, options=options, session=session
) # type: ignore
format_control = getattr(options, "format_control", None)
if not format_control:
format_control = format_control_provider(None, None) # type: ignore
wheel_cache = wheel_cache_provider(
kwargs["cache_dir"], format_control
wheel_cache = ctx.enter_context(
wheel_cache_provider(kwargs["cache_dir"], format_control)
) # type: ignore
ireq.is_direct = True # type: ignore
build_location_kwargs = {"build_dir": kwargs["build_dir"], "autodelete": True}
call_function_with_correct_args(ireq.build_location, **build_location_kwargs)
# ireq.build_location(kwargs["build_dir"]) # type: ignore
if reqset_provider is None:
raise TypeError(
"cannot resolve without a requirement set provider... failed!"
)
reqset = reqset_provider(install_command, options=options, session=session, wheel_download_dir=wheel_download_dir, **kwargs) # type: ignore
reqset = reqset_provider(
install_command,
options=options,
session=session,
wheel_download_dir=wheel_download_dir,
**kwargs
) # type: ignore
if getattr(reqset, "prepare_files", None):
reqset.add_requirement(ireq)
results = reqset.prepare_files(finder)
@@ -1293,7 +1353,6 @@ def resolve( # noqa:C901
"use_user_site": use_user_site,
"require_hashes": require_hashes,
}
# with req_tracker_provider() as req_tracker:
if isinstance(req_tracker_provider, (types.FunctionType, functools.partial)):
preparer_args["req_tracker"] = ctx.enter_context(req_tracker_provider())
resolver_keys = [
@@ -1338,7 +1397,7 @@ def resolve( # noqa:C901
return results
def build_wheel(
def build_wheel( # noqa:C901
req=None, # type: Optional[TInstallRequirement]
reqset=None, # type: Optional[Union[TReqSet, Iterable[TInstallRequirement]]]
output_dir=None, # type: Optional[str]
@@ -1368,8 +1427,9 @@ def build_wheel(
build_many_provider=None, # type: Optional[TShimmedFunc]
install_command_provider=None, # type: Optional[TShimmedFunc]
finder_provider=None, # type: Optional[TShimmedFunc]
reqset_provider=None, # type: Optional[TShimmedFunc]
):
# type: (...) -> Optional[Union[str, Tuple[List[TInstallRequirement], List[TInstallRequirement]]]]
# type: (...) -> Generator[Union[str, Tuple[List[TInstallRequirement], ...]], None, None]
"""
Build a wheel or a set of wheels
@@ -1421,19 +1481,21 @@ def build_wheel(
:param Optional[TShimmedFunc] install_command_provider: A shim for providing new
install command instances
:param TShimmedFunc finder_provider: A provider to package finder instances
:param TShimmedFunc reqset_provider: A provider for requirement set generation
:return: A tuple of successful and failed install requirements or else a path to
a wheel
:rtype: Optional[Union[str, Tuple[List[TInstallRequirement], List[TInstallRequirement]]]]
"""
wheel_cache_provider = resolve_possible_shim(wheel_cache_provider)
preparer = resolve_possible_shim(preparer)
preparer_provider = resolve_possible_shim(preparer_provider)
wheel_builder_provider = resolve_possible_shim(wheel_builder_provider)
build_one_provider = resolve_possible_shim(build_one_provider)
build_one_inside_env_provider = resolve_possible_shim(build_one_inside_env_provider)
build_many_provider = resolve_possible_shim(build_many_provider)
install_cmd_provider = resolve_possible_shim(install_command_provider)
format_control_provider = resolve_possible_shim(format_control_provider)
finder_provider = resolve_possible_shim(finder_provider)
finder_provider = resolve_possible_shim(finder_provider) or get_package_finder
reqset_provider = resolve_possible_shim(reqset_provider)
global_options = [] if global_options is None else global_options
build_options = [] if build_options is None else build_options
options = None
@@ -1447,25 +1509,31 @@ def build_wheel(
}
if not req and not reqset:
raise TypeError("Must provide either a requirement or requirement set to build")
if wheel_cache is None and (reqset is not None or output_dir is None):
if install_command is None:
assert isinstance(install_cmd_provider, (type, functools.partial))
install_command = install_cmd_provider()
kwargs, options = populate_options(install_command, options, **kwarg_map)
format_control = getattr(options, "format_control", None)
if not format_control:
format_control = format_control_provider(None, None) # type: ignore
wheel_cache = wheel_cache_provider(options.cache_dir, format_control)
if req and not reqset and not output_dir:
output_dir = wheel_cache.get_path_for_link(req.link)
if not reqset and build_one_provider:
yield build_one_provider(req, output_dir, build_options, global_options)
elif build_many_provider:
yield build_many_provider(
reqset, wheel_cache, build_options, global_options, check_binary_allowed
)
else:
with ExitStack() as ctx:
with ExitStack() as ctx:
kwargs = kwarg_map.copy()
if wheel_cache is None and (reqset is not None or output_dir is None):
if install_command is None:
assert isinstance(install_cmd_provider, (type, functools.partial))
install_command = install_cmd_provider()
kwargs, options = populate_options(install_command, options, **kwarg_map)
format_control = getattr(options, "format_control", None)
if not format_control:
format_control = format_control_provider(None, None) # type: ignore
wheel_cache = ctx.enter_context(
wheel_cache_provider(options.cache_dir, format_control)
)
if req and not reqset and not output_dir:
output_dir = get_ireq_output_path(wheel_cache, req)
if not reqset and build_one_provider:
yield build_one_provider(req, output_dir, build_options, global_options)
elif build_many_provider:
yield build_many_provider(
reqset, wheel_cache, build_options, global_options, check_binary_allowed
)
else:
builder_args, builder_kwargs = get_allowed_args(wheel_builder_provider)
if "requirement_set" in builder_args and not reqset:
reqset = reqset_provider()
if session is None and finder is None:
session = get_session(install_cmd=install_command, options=options)
finder = finder_provider(
@@ -1503,7 +1571,7 @@ def build_wheel(
)
if req and not reqset:
if not output_dir:
output_dir = wheel_cache.get_path_for_link(req.link)
output_dir = get_ireq_output_path(wheel_cache, req)
if use_pep517 is not None:
req.use_pep517 = use_pep517
yield builder._build_one(req, output_dir)
+38 -22
View File
@@ -104,6 +104,9 @@ PIP_VERSION_SET = {
"19.2.3",
"19.3",
"19.3.1",
"20.0",
"20.0.1",
"20.0.2",
}
@@ -140,9 +143,9 @@ class PipVersion(Sequence):
parsed_version = self._parse()
if base_import_path is None:
if parsed_version >= parse_version("10.0.0"):
base_import_path = "{0}._internal".format(BASE_IMPORT_PATH)
base_import_path = "{}._internal".format(BASE_IMPORT_PATH)
else:
base_import_path = "{0}".format(BASE_IMPORT_PATH)
base_import_path = "{}".format(BASE_IMPORT_PATH)
self.base_import_path = base_import_path
self.parsed_version = parsed_version
@@ -175,13 +178,12 @@ class PipVersion(Sequence):
def __str__(self):
# type: () -> str
return "{0!s}".format(self.parsed_version)
return "{!s}".format(self.parsed_version)
def __repr__(self):
# type: () -> str
return (
"<PipVersion {0!r}, Path: {1!r}, Vendor Path: {2!r}, "
"Parsed Version: {3!r}>"
"<PipVersion {!r}, Path: {!r}, Vendor Path: {!r}, " "Parsed Version: {!r}>"
).format(
self.version,
self.base_import_path,
@@ -253,17 +255,17 @@ class PipVersionRange(Sequence):
def __str__(self):
# type: () -> str
return "{0!s} -> {1!s}".format(self._versions[0], self._versions[-1])
return "{!s} -> {!s}".format(self._versions[0], self._versions[-1])
@property
def base_import_paths(self):
# type: () -> Set[str]
return set([version.base_import_path for version in self._versions])
return {version.base_import_path for version in self._versions}
@property
def vendor_import_paths(self):
# type: () -> Set[str]
return set([version.vendor_import_path for version in self._versions])
return {version.vendor_import_path for version in self._versions}
def is_valid(self):
# type: () -> bool
@@ -430,7 +432,7 @@ class ShimmedPath(object):
if not self.is_class:
return provided
if not inspect.isclass(provided):
raise TypeError("Provided argument is not a class: {0!r}".format(provided))
raise TypeError("Provided argument is not a class: {!r}".format(provided))
methods = self._parse_provides_dict(
self.provided_methods, prepend_arg_to_callables="self"
)
@@ -554,9 +556,7 @@ class ShimmedPath(object):
imported, result = self._shim_parent(imported, attribute_name)
if result is not None:
result = self._ensure_functions(result)
full_import_path = "{0}.{1}".format(
self.calculated_module_path, attribute_name
)
full_import_path = "{}.{}".format(self.calculated_module_path, attribute_name)
self._imported = imported
assert isinstance(result, types.ModuleType)
self._provided = result
@@ -921,13 +921,6 @@ unpack_url = ShimmedPathCollection("unpack_url", ImportTypes.FUNCTION)
unpack_url.create_path("download.unpack_url", "7.0.0", "19.3.9")
unpack_url.create_path("operations.prepare.unpack_url", "20.0", "9999")
shim_unpack = ShimmedPathCollection("shim_unpack", ImportTypes.FUNCTION)
shim_unpack.set_default(
functools.partial(
compat.shim_unpack, unpack_fn=unpack_url, downloader_provider=Downloader
)
)
is_installable_dir = ShimmedPathCollection("is_installable_dir", ImportTypes.FUNCTION)
is_installable_dir.create_path("utils.misc.is_installable_dir", "10.0.0", "9999")
is_installable_dir.create_path("utils.is_installable_dir", "7.0.0", "9.0.3")
@@ -1036,6 +1029,16 @@ global_tempdir_manager.create_path(
"utils.temp_dir.global_tempdir_manager", "7.0.0", "9999"
)
shim_unpack = ShimmedPathCollection("shim_unpack", ImportTypes.FUNCTION)
shim_unpack.set_default(
functools.partial(
compat.shim_unpack,
unpack_fn=unpack_url,
downloader_provider=Downloader,
tempdir_manager_provider=global_tempdir_manager,
)
)
get_requirement_tracker = ShimmedPathCollection(
"get_requirement_tracker", ImportTypes.CONTEXTMANAGER
)
@@ -1128,6 +1131,17 @@ DEV_PKGS.create_path("commands.freeze.DEV_PKGS", "9.0.0", "9999")
DEV_PKGS.set_default({"setuptools", "pip", "distribute", "wheel"})
wheel_cache = ShimmedPathCollection("wheel_cache", ImportTypes.FUNCTION)
wheel_cache.set_default(
functools.partial(
compat.wheel_cache,
wheel_cache_provider=WheelCache,
tempdir_manager_provider=global_tempdir_manager,
format_control_provider=FormatControl,
)
)
get_package_finder = ShimmedPathCollection("get_package_finder", ImportTypes.FUNCTION)
get_package_finder.set_default(
functools.partial(
@@ -1158,7 +1172,7 @@ get_resolver.set_default(
install_cmd_provider=InstallCommand,
resolver_fn=Resolver,
install_req_provider=install_req_from_req_string,
wheel_cache_provider=WheelCache,
wheel_cache_provider=wheel_cache,
format_control_provider=FormatControl,
)
)
@@ -1170,6 +1184,7 @@ get_requirement_set.set_default(
compat.get_requirement_set,
install_cmd_provider=InstallCommand,
req_set_provider=RequirementSet,
wheel_cache_provider=wheel_cache,
)
)
@@ -1182,7 +1197,7 @@ resolve.set_default(
reqset_provider=get_requirement_set,
finder_provider=get_package_finder,
resolver_provider=get_resolver,
wheel_cache_provider=WheelCache,
wheel_cache_provider=wheel_cache,
format_control_provider=FormatControl,
make_preparer_provider=make_preparer,
req_tracker_provider=get_requirement_tracker,
@@ -1196,12 +1211,13 @@ build_wheel.set_default(
functools.partial(
compat.build_wheel,
install_command_provider=InstallCommand,
wheel_cache_provider=WheelCache,
wheel_cache_provider=wheel_cache,
wheel_builder_provider=WheelBuilder,
build_one_provider=build_one,
build_one_inside_env_provider=build_one_inside_env,
build_many_provider=build,
preparer_provider=make_preparer,
format_control_provider=FormatControl,
reqset_provider=get_requirement_set,
)
)
+23
View File
@@ -440,3 +440,26 @@ def call_function_with_correct_args(fn, **provided_kwargs):
continue
kwargs[arg] = provided_kwargs[arg]
return fn(*args, **kwargs)
def filter_allowed_args(fn, **provided_kwargs):
# type: (Callable, Dict[str, Any]) -> Tuple[List[Any], Dict[str, Any]]
"""
Given a function and a kwarg mapping, return only those kwargs used in the function.
:param Callable fn: A function to inspect
:param Dict[str, Any] kwargs: A mapping of kwargs to filter
:return: A new, filtered kwarg mapping
:rtype: Tuple[List[Any], Dict[str, Any]]
"""
args = []
kwargs = {}
func_args, func_kwargs = get_allowed_args(fn)
for arg in func_args:
if arg in provided_kwargs:
args.append(provided_kwargs[arg])
for arg in func_kwargs:
if arg not in provided_kwargs:
continue
kwargs[arg] = provided_kwargs[arg]
return args, kwargs
+1 -1
View File
@@ -10,7 +10,7 @@ from .models.lockfile import Lockfile
from .models.pipfile import Pipfile
from .models.requirements import Requirement
__version__ = "1.5.4"
__version__ = "1.5.6"
logger = logging.getLogger(__name__)
+39 -5
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import itertools
import operator
import re
import attr
import distlib.markers
@@ -196,15 +197,19 @@ def _get_specs(specset):
return sorted(result, key=operator.itemgetter(1))
# TODO: Rename this to something meaningful
def _group_by_op(specs):
# type: (Union[Set[Specifier], SpecifierSet]) -> Iterator
specs = [_get_specs(x) for x in list(specs)]
flattened = [(op, version) for spec in specs for op, version in spec]
flattened = [
((op, len(version) > 2), version) for spec in specs for op, version in spec
]
specs = sorted(flattened)
grouping = itertools.groupby(specs, key=operator.itemgetter(0))
return grouping
# TODO: rename this to something meaningful
def normalize_specifier_set(specs):
# type: (Union[str, SpecifierSet]) -> Optional[Set[Specifier]]
"""Given a specifier set, a string, or an iterable, normalize the specifiers
@@ -235,6 +240,8 @@ def normalize_specifier_set(specs):
return normalize_specifier_set(SpecifierSet(",".join(spec_list)))
# TODO: Check if this is used by anything public otherwise make it private
# And rename it to something meaningful
def get_sorted_version_string(version_set):
# type: (Set[AnyStr]) -> AnyStr
version_list = sorted(
@@ -244,6 +251,9 @@ def get_sorted_version_string(version_set):
return version
# TODO: Rename this to something meaningful
# TODO: Add a deprecation decorator and deprecate this -- i'm sure it's used
# in other libraries
@lru_cache(maxsize=1024)
def cleanup_pyspecs(specs, joiner="or"):
specs = normalize_specifier_set(specs)
@@ -275,7 +285,8 @@ def cleanup_pyspecs(specs, joiner="or"):
"==": lambda x: "in" if len(x) > 1 else "==",
}
translation_keys = list(translation_map.keys())
for op, versions in _group_by_op(tuple(specs)):
for op_and_version_type, versions in _group_by_op(tuple(specs)):
op = op_and_version_type[0]
versions = [version[1] for version in versions]
versions = sorted(dedup(versions))
op_key = next(iter(k for k in translation_keys if op in k), None)
@@ -284,10 +295,11 @@ def cleanup_pyspecs(specs, joiner="or"):
version_value = translation_map[op_key][joiner](versions)
if op in op_translations:
op = op_translations[op](versions)
results[op] = version_value
return sorted([(k, v) for k, v in results.items()], key=operator.itemgetter(1))
results[(op, op_and_version_type[1])] = version_value
return sorted([(k[0], v) for k, v in results.items()], key=operator.itemgetter(1))
# TODO: Rename this to something meaningful
@lru_cache(maxsize=1024)
def fix_version_tuple(version_tuple):
# type: (Tuple[AnyStr, AnyStr]) -> Tuple[AnyStr, AnyStr]
@@ -302,6 +314,7 @@ def fix_version_tuple(version_tuple):
return (op, version)
# TODO: Rename this to something meaningful, deprecate it (See prior function)
@lru_cache(maxsize=128)
def get_versions(specset, group_by_operator=True):
# type: (Union[Set[Specifier], SpecifierSet], bool) -> List[Tuple[STRING_TYPE, STRING_TYPE]]
@@ -590,6 +603,7 @@ def get_specset(marker_list):
return specifiers
# TODO: Refactor this (reduce complexity)
def parse_marker_dict(marker_dict):
op = marker_dict["op"]
lhs = marker_dict["lhs"]
@@ -658,9 +672,16 @@ def parse_marker_dict(marker_dict):
return specset, finalized_marker
def _contains_micro_version(version_string):
return re.search("\d+\.\d+\.\d+", version_string) is not None
def format_pyversion(parts):
op, val = parts
return "python_version {0} '{1}'".format(op, val)
version_marker = (
"python_full_version" if _contains_micro_version(val) else "python_version"
)
return "{0} {1} '{2}'".format(version_marker, op, val)
def normalize_marker_str(marker):
@@ -699,3 +720,16 @@ def marker_from_specifier(spec):
marker_segments.append(format_pyversion(marker_segment))
marker_str = " and ".join(marker_segments).replace('"', "'")
return Marker(marker_str)
def merge_markers(m1, m2):
# type: (Marker, Marker) -> Optional[Marker]
if not all((m1, m2)):
return next(iter(v for v in (m1, m2) if v), None)
m1 = _ensure_marker(m1)
m2 = _ensure_marker(m2)
_markers = [] # type: List[Marker]
for marker in (m1, m2):
_markers.append(str(marker))
marker_str = " and ".join([normalize_marker_str(m) for m in _markers if m])
return _ensure_marker(normalize_marker_str(marker_str))
File diff suppressed because it is too large Load Diff
+4
View File
@@ -164,6 +164,10 @@ class Pipfile(object):
# type: () -> Union[plette.pipfiles.Pipfile, PipfileLoader]
return self.projectfile.model
@property
def root(self):
return self.path.parent
@property
def extended_keys(self):
return [
+5 -2
View File
@@ -679,7 +679,7 @@ AST_COMPARATORS = dict(
(ast.And, operator.and_),
(ast.Or, operator.or_),
(ast.Not, operator.not_),
(ast.In, operator.contains),
(ast.In, lambda a, b: operator.contains(b, a)),
)
)
@@ -746,6 +746,9 @@ def ast_unparse(item, initial_mapping=False, analyzer=None, recurse=True): # no
unparsed = item.s
elif isinstance(item, ast.Subscript):
unparsed = unparse(item.value)
if not initial_mapping:
if isinstance(item.slice, ast.Index):
unparsed = unparsed[unparse(item.slice.value)]
elif any(isinstance(item, k) for k in AST_BINOP_MAP.keys()):
unparsed = AST_BINOP_MAP[type(item)]
elif isinstance(item, ast.Num):
@@ -789,7 +792,7 @@ def ast_unparse(item, initial_mapping=False, analyzer=None, recurse=True): # no
elif isinstance(item, constant):
unparsed = item.value
elif isinstance(item, ast.Compare):
if isinstance(item.left, ast.Attribute):
if isinstance(item.left, ast.Attribute) or isinstance(item.left, ast.Str):
import importlib
left = unparse(item.left)
+1 -1
View File
@@ -723,7 +723,7 @@ def get_pinned_version(ireq):
except AttributeError:
raise TypeError("Expected InstallRequirement, not {}".format(type(ireq).__name__))
if ireq.editable:
if getattr(ireq, "editable", False):
raise ValueError("InstallRequirement is editable")
if not specifier:
raise ValueError("InstallRequirement has no version specification")
+3 -3
View File
@@ -26,7 +26,7 @@ requests==2.23.0
idna==2.9
urllib3==1.25.9
certifi==2020.4.5.1
requirementslib==1.5.5
requirementslib==1.5.6
attrs==19.3.0
distlib==0.3.0
packaging==20.3
@@ -39,7 +39,7 @@ semver==2.9.0
toml==0.10.0
cached-property==1.5.1
vistir==0.5.0
pip-shims==0.5.1
pip-shims==0.5.2
contextlib2==0.6.0.post1
funcsigs==1.0.2
enum34==1.1.6
@@ -50,7 +50,7 @@ resolvelib==0.3.0
backports.functools_lru_cache==1.5
pep517==0.8.2
zipp==0.6.0
importlib_metadata==1.5.1
importlib_metadata==1.6.0
importlib-resources==1.4.0
more-itertools==5.0.0
git+https://github.com/sarugaku/passa.git@master#egg=passa