Skip to content

Commit

Permalink
Merge pull request #4255 from pypa/bugfix/4226
Browse files Browse the repository at this point in the history
  • Loading branch information
techalchemy committed May 19, 2020
2 parents 760f7af + f81cec0 commit edce45c
Show file tree
Hide file tree
Showing 73 changed files with 9,383 additions and 798 deletions.
1 change: 1 addition & 0 deletions news/3976.bugfix.rst
@@ -0,0 +1 @@
Fixed a bug which prevented resolution of direct URL dependencies which have PEP508 style direct url VCS sub-dependencies with subdirectories.
1 change: 1 addition & 0 deletions news/4226.bugfix.rst
@@ -0,0 +1 @@
``Requires-Python`` values specifying constraint versions of python starting from ``1.x`` will now be parsed successfully.
11 changes: 11 additions & 0 deletions news/4226.vendor.rst
@@ -0,0 +1,11 @@
Updated vendored dependencies to latest versions for security and bug fixes:

- **requirementslib** ``1.5.8`` => ``1.5.9``
- **vistir** ``0.5.0`` => ``0.5.1``
- **jinja2** ``2.11.1`` => ``2.11.2``
- **click** ``7.1.1`` => ``7.1.2``
- **dateutil** ``(none)`` => ``2.8.1``
- **backports.functools_lru_cache** ``1.5.0`` => ``1.6.1``
- **enum34** ``1.1.6`` => ``1.1.10``
- **toml** ``0.10.0`` => ``0.10.1``
- **importlib_resources** ``1.4.0`` => ``1.5.0``
15 changes: 6 additions & 9 deletions pipenv/utils.py
Expand Up @@ -586,7 +586,7 @@ def get_deps_from_req(cls, req, resolver=None):
constraints.add(line)
# ensure the top level entry remains as provided
# note that we shouldn't pin versions for editable vcs deps
if (not req.is_vcs or (req.is_vcs and not req.editable)):
if not req.is_vcs:
if req.specifiers:
locked_deps[name]["version"] = req.specifiers
elif parsed_line.setup_info and parsed_line.setup_info.version:
Expand Down Expand Up @@ -997,6 +997,8 @@ def clean_results(self):
for req, ireq in reqs:
if (req.vcs and req.editable and not req.is_direct_url):
continue
elif req.normalized_name in self.skipped.keys():
continue
collected_hashes = self.collect_hashes(ireq)
req = req.add_hashes(collected_hashes)
if not collected_hashes and self._should_include_hash(ireq):
Expand Down Expand Up @@ -1041,9 +1043,9 @@ def format_requirement_for_lockfile(req, markers_lookup, index_lookup, hashes=No
entry["version"] = pf_entry.lstrip("=")
else:
entry.update(pf_entry)
if version is not None:
if version is not None and not req.is_vcs:
entry["version"] = version
if req.line_instance.is_direct_url:
if req.line_instance.is_direct_url and not req.is_vcs:
entry["file"] = req.req.uri
if hashes:
entry["hashes"] = sorted(set(hashes))
Expand All @@ -1054,7 +1056,7 @@ def format_requirement_for_lockfile(req, markers_lookup, index_lookup, hashes=No
entry.update({"markers": markers})
entry = translate_markers(entry)
if req.vcs or req.editable:
for key in ("index", "version"):
for key in ("index", "version", "file"):
try:
del entry[key]
except KeyError:
Expand Down Expand Up @@ -1879,11 +1881,6 @@ def get_vcs_deps(
lockfile[name] = requirement.pipfile_entry[1]
lockfile[name]['ref'] = commit_hash
result.append(requirement)
version = requirement.specifiers
if not version and requirement.specifiers:
version = requirement.specifiers
if version:
lockfile[name]['version'] = version
except OSError:
continue
return result, lockfile
Expand Down
4 changes: 2 additions & 2 deletions pipenv/vendor/appdirs.py
Expand Up @@ -13,8 +13,8 @@
# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html
# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html

__version_info__ = (1, 4, 3)
__version__ = '.'.join(map(str, __version_info__))
__version__ = "1.4.4"
__version_info__ = tuple(int(segment) for segment in __version__.split("."))


import sys
Expand Down
7 changes: 4 additions & 3 deletions pipenv/vendor/backports/enum/__init__.py
Expand Up @@ -4,7 +4,7 @@

__all__ = ['Enum', 'IntEnum', 'unique']

version = 1, 1, 6
version = 1, 1, 10

pyver = float('%s.%s' % _sys.version_info[:2])

Expand Down Expand Up @@ -183,7 +183,8 @@ def __new__(metacls, cls, bases, classdict):
else:
del classdict['_order_']
if pyver < 3.0:
_order_ = _order_.replace(',', ' ').split()
if isinstance(_order_, basestring):
_order_ = _order_.replace(',', ' ').split()
aliases = [name for name in members if name not in _order_]
_order_ += aliases

Expand Down Expand Up @@ -463,7 +464,7 @@ def _create_(cls, class_name, names=None, module=None, type=None, start=1):
_order_.append(member_name)
# only set _order_ in classdict if name/value was not from a mapping
if not isinstance(item, basestring):
classdict['_order_'] = ' '.join(_order_)
classdict['_order_'] = _order_
enum_class = metacls.__new__(metacls, class_name, bases, classdict)

# TODO: replace the frame hack if a blessed way to know the calling
Expand Down
50 changes: 31 additions & 19 deletions pipenv/vendor/backports/functools_lru_cache.py
Expand Up @@ -8,10 +8,12 @@


@functools.wraps(functools.update_wrapper)
def update_wrapper(wrapper,
wrapped,
assigned = functools.WRAPPER_ASSIGNMENTS,
updated = functools.WRAPPER_UPDATES):
def update_wrapper(
wrapper,
wrapped,
assigned=functools.WRAPPER_ASSIGNMENTS,
updated=functools.WRAPPER_UPDATES,
):
"""
Patch two bugs in functools.update_wrapper.
"""
Expand All @@ -34,10 +36,17 @@ def __hash__(self):
return self.hashvalue


def _make_key(args, kwds, typed,
kwd_mark=(object(),),
fasttypes=set([int, str, frozenset, type(None)]),
sorted=sorted, tuple=tuple, type=type, len=len):
def _make_key(
args,
kwds,
typed,
kwd_mark=(object(),),
fasttypes=set([int, str, frozenset, type(None)]),
sorted=sorted,
tuple=tuple,
type=type,
len=len,
):
'Make a cache key from optionally typed positional and keyword arguments'
key = args
if kwds:
Expand Down Expand Up @@ -82,16 +91,16 @@ def lru_cache(maxsize=100, typed=False):
def decorating_function(user_function):

cache = dict()
stats = [0, 0] # make statistics updateable non-locally
HITS, MISSES = 0, 1 # names for the stats fields
stats = [0, 0] # make statistics updateable non-locally
HITS, MISSES = 0, 1 # names for the stats fields
make_key = _make_key
cache_get = cache.get # bound method to lookup key or return None
_len = len # localize the global len() function
lock = RLock() # because linkedlist updates aren't threadsafe
root = [] # root of the circular doubly linked list
root[:] = [root, root, None, None] # initialize by pointing to self
nonlocal_root = [root] # make updateable non-locally
PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields
cache_get = cache.get # bound method to lookup key or return None
_len = len # localize the global len() function
lock = RLock() # because linkedlist updates aren't threadsafe
root = [] # root of the circular doubly linked list
root[:] = [root, root, None, None] # initialize by pointing to self
nonlocal_root = [root] # make updateable non-locally
PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields

if maxsize == 0:

Expand All @@ -106,7 +115,9 @@ def wrapper(*args, **kwds):
def wrapper(*args, **kwds):
# simple caching without ordering or size limit
key = make_key(args, kwds, typed)
result = cache_get(key, root) # root used here as a unique not-found sentinel
result = cache_get(
key, root
) # root used here as a unique not-found sentinel
if result is not root:
stats[HITS] += 1
return result
Expand All @@ -123,7 +134,8 @@ def wrapper(*args, **kwds):
with lock:
link = cache_get(key)
if link is not None:
# record recent use of the key by moving it to the front of the list
# record recent use of the key by moving it
# to the front of the list
root, = nonlocal_root
link_prev, link_next, key, result = link
link_prev[NEXT] = link_next
Expand Down
2 changes: 1 addition & 1 deletion pipenv/vendor/click/__init__.py
Expand Up @@ -76,4 +76,4 @@
# literals.
disable_unicode_literals_warning = False

__version__ = "7.1.1"
__version__ = "7.1.2"
4 changes: 0 additions & 4 deletions pipenv/vendor/click/_compat.py
Expand Up @@ -174,8 +174,6 @@ def seekable(self):
iteritems = lambda x: x.iteritems()
range_type = xrange

from pipes import quote as shlex_quote

def is_bytes(x):
return isinstance(x, (buffer, bytearray))

Expand Down Expand Up @@ -284,8 +282,6 @@ def filename_to_ui(value):
isidentifier = lambda x: x.isidentifier()
iteritems = lambda x: iter(x.items())

from shlex import quote as shlex_quote

def is_bytes(x):
return isinstance(x, (bytes, memoryview, bytearray))

Expand Down
22 changes: 9 additions & 13 deletions pipenv/vendor/click/_termui_impl.py
Expand Up @@ -17,7 +17,6 @@
from ._compat import isatty
from ._compat import open_stream
from ._compat import range_type
from ._compat import shlex_quote
from ._compat import strip_ansi
from ._compat import term_len
from ._compat import WIN
Expand Down Expand Up @@ -346,10 +345,7 @@ def pager(generator, color=None):
fd, filename = tempfile.mkstemp()
os.close(fd)
try:
if (
hasattr(os, "system")
and os.system("more {}".format(shlex_quote(filename))) == 0
):
if hasattr(os, "system") and os.system('more "{}"'.format(filename)) == 0:
return _pipepager(generator, "more", color)
return _nullpager(stdout, generator, color)
finally:
Expand Down Expand Up @@ -418,7 +414,7 @@ def _tempfilepager(generator, cmd, color):
with open_stream(filename, "wb")[0] as f:
f.write(text.encode(encoding))
try:
os.system("{} {}".format(shlex_quote(cmd), shlex_quote(filename)))
os.system('{} "{}"'.format(cmd, filename))
finally:
os.unlink(filename)

Expand Down Expand Up @@ -463,9 +459,7 @@ def edit_file(self, filename):
environ = None
try:
c = subprocess.Popen(
"{} {}".format(shlex_quote(editor), shlex_quote(filename)),
env=environ,
shell=True,
'{} "{}"'.format(editor, filename), env=environ, shell=True,
)
exit_code = c.wait()
if exit_code != 0:
Expand Down Expand Up @@ -536,16 +530,18 @@ def _unquote_file(url):
elif WIN:
if locate:
url = _unquote_file(url)
args = "explorer /select,{}".format(shlex_quote(url))
args = 'explorer /select,"{}"'.format(_unquote_file(url.replace('"', "")))
else:
args = 'start {} "" {}'.format("/WAIT" if wait else "", shlex_quote(url))
args = 'start {} "" "{}"'.format(
"/WAIT" if wait else "", url.replace('"', "")
)
return os.system(args)
elif CYGWIN:
if locate:
url = _unquote_file(url)
args = "cygstart {}".format(shlex_quote(os.path.dirname(url)))
args = 'cygstart "{}"'.format(os.path.dirname(url).replace('"', ""))
else:
args = "cygstart {} {}".format("-w" if wait else "", shlex_quote(url))
args = 'cygstart {} "{}"'.format("-w" if wait else "", url.replace('"', ""))
return os.system(args)

try:
Expand Down
54 changes: 54 additions & 0 deletions pipenv/vendor/dateutil/LICENSE
@@ -0,0 +1,54 @@
Copyright 2017- Paul Ganssle <paul@ganssle.io>
Copyright 2017- dateutil contributors (see AUTHORS file)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

The above license applies to all contributions after 2017-12-01, as well as
all contributions that have been re-licensed (see AUTHORS file for the list of
contributors who have re-licensed their code).
--------------------------------------------------------------------------------
dateutil - Extensions to the standard Python datetime module.

Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net>
Copyright (c) 2012-2014 - Tomi Pieviläinen <tomi.pievilainen@iki.fi>
Copyright (c) 2014-2016 - Yaron de Leeuw <me@jarondl.net>
Copyright (c) 2015- - Paul Ganssle <paul@ganssle.io>
Copyright (c) 2015- - dateutil contributors (see AUTHORS file)

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The above BSD License Applies to all code, even that also covered by Apache 2.0.
8 changes: 8 additions & 0 deletions pipenv/vendor/dateutil/__init__.py
@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
try:
from ._version import version as __version__
except ImportError:
__version__ = 'unknown'

__all__ = ['easter', 'parser', 'relativedelta', 'rrule', 'tz',
'utils', 'zoneinfo']
43 changes: 43 additions & 0 deletions pipenv/vendor/dateutil/_common.py
@@ -0,0 +1,43 @@
"""
Common code used in multiple modules.
"""


class weekday(object):
__slots__ = ["weekday", "n"]

def __init__(self, weekday, n=None):
self.weekday = weekday
self.n = n

def __call__(self, n):
if n == self.n:
return self
else:
return self.__class__(self.weekday, n)

def __eq__(self, other):
try:
if self.weekday != other.weekday or self.n != other.n:
return False
except AttributeError:
return False
return True

def __hash__(self):
return hash((
self.weekday,
self.n,
))

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

def __repr__(self):
s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday]
if not self.n:
return s
else:
return "%s(%+d)" % (s, self.n)

# vim:ts=4:sw=4:et
4 changes: 4 additions & 0 deletions pipenv/vendor/dateutil/_version.py
@@ -0,0 +1,4 @@
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '2.8.1'

0 comments on commit edce45c

Please sign in to comment.