mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-04-13 06:24:16 +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
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from .more import * # noqa
|
||||
from .recipes import * # noqa
|
||||
|
||||
|
|
|
|||
|
|
@ -1,39 +1,55 @@
|
|||
import warnings
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import Counter, defaultdict, deque, abc
|
||||
import warnings
|
||||
from collections import abc
|
||||
from collections import Counter
|
||||
from collections import defaultdict
|
||||
from collections import deque
|
||||
from collections.abc import Sequence
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from functools import partial, reduce, wraps
|
||||
from heapq import merge, heapify, heapreplace, heappop
|
||||
from itertools import (
|
||||
chain,
|
||||
compress,
|
||||
count,
|
||||
cycle,
|
||||
dropwhile,
|
||||
groupby,
|
||||
islice,
|
||||
repeat,
|
||||
starmap,
|
||||
takewhile,
|
||||
tee,
|
||||
zip_longest,
|
||||
)
|
||||
from math import exp, factorial, floor, log
|
||||
from queue import Empty, Queue
|
||||
from random import random, randrange, uniform
|
||||
from operator import itemgetter, mul, sub, gt, lt
|
||||
from sys import hexversion, maxsize
|
||||
from functools import partial
|
||||
from functools import reduce
|
||||
from functools import wraps
|
||||
from heapq import heapify
|
||||
from heapq import heappop
|
||||
from heapq import heapreplace
|
||||
from heapq import merge
|
||||
from itertools import chain
|
||||
from itertools import compress
|
||||
from itertools import count
|
||||
from itertools import cycle
|
||||
from itertools import dropwhile
|
||||
from itertools import groupby
|
||||
from itertools import islice
|
||||
from itertools import repeat
|
||||
from itertools import starmap
|
||||
from itertools import takewhile
|
||||
from itertools import tee
|
||||
from itertools import zip_longest
|
||||
from math import exp
|
||||
from math import factorial
|
||||
from math import floor
|
||||
from math import log
|
||||
from operator import gt
|
||||
from operator import itemgetter
|
||||
from operator import lt
|
||||
from operator import mul
|
||||
from operator import sub
|
||||
from queue import Empty
|
||||
from queue import Queue
|
||||
from random import random
|
||||
from random import randrange
|
||||
from random import uniform
|
||||
from sys import hexversion
|
||||
from sys import maxsize
|
||||
from time import monotonic
|
||||
|
||||
from .recipes import (
|
||||
consume,
|
||||
flatten,
|
||||
pairwise,
|
||||
powerset,
|
||||
take,
|
||||
unique_everseen,
|
||||
)
|
||||
from .recipes import consume
|
||||
from .recipes import flatten
|
||||
from .recipes import pairwise
|
||||
from .recipes import powerset
|
||||
from .recipes import take
|
||||
from .recipes import unique_everseen
|
||||
|
||||
__all__ = [
|
||||
'AbortThread',
|
||||
|
|
@ -180,7 +196,7 @@ def first(iterable, default=_marker):
|
|||
if default is _marker:
|
||||
raise ValueError(
|
||||
'first() was called on an empty iterable, and no '
|
||||
'default value was provided.'
|
||||
'default value was provided.',
|
||||
) from e
|
||||
return default
|
||||
|
||||
|
|
@ -209,7 +225,7 @@ def last(iterable, default=_marker):
|
|||
if default is _marker:
|
||||
raise ValueError(
|
||||
'last() was called on an empty iterable, and no default was '
|
||||
'provided.'
|
||||
'provided.',
|
||||
)
|
||||
return default
|
||||
|
||||
|
|
@ -428,7 +444,7 @@ def collate(*iterables, **kwargs):
|
|||
|
||||
"""
|
||||
warnings.warn(
|
||||
"collate is no longer part of more_itertools, use heapq.merge",
|
||||
'collate is no longer part of more_itertools, use heapq.merge',
|
||||
DeprecationWarning,
|
||||
)
|
||||
return merge(*iterables, **kwargs)
|
||||
|
|
@ -624,7 +640,7 @@ def distinct_permutations(iterable, r=None):
|
|||
# Swap the value of A[i] with that of A[j], then reverse the
|
||||
# sequence from A[i + 1] to form the new permutation
|
||||
A[i], A[j] = A[j], A[i]
|
||||
A[i + 1 :] = A[: i - size : -1] # A[i + 1:][::-1]
|
||||
A[i + 1:] = A[: i - size: -1] # A[i + 1:][::-1]
|
||||
|
||||
# Algorithm: modified from the above
|
||||
def _partial(A, r):
|
||||
|
|
@ -662,9 +678,9 @@ def distinct_permutations(iterable, r=None):
|
|||
break
|
||||
|
||||
# Reverse head[i + 1:] and swap it with tail[:r - (i + 1)]
|
||||
tail += head[: i - r : -1] # head[i + 1:][::-1]
|
||||
tail += head[: i - r: -1] # head[i + 1:][::-1]
|
||||
i += 1
|
||||
head[i:], tail[:] = tail[: r - i], tail[r - i :]
|
||||
head[i:], tail[:] = tail[: r - i], tail[r - i:]
|
||||
|
||||
items = sorted(iterable)
|
||||
|
||||
|
|
@ -811,7 +827,7 @@ def substrings(iterable):
|
|||
# And the rest
|
||||
for n in range(2, item_count + 1):
|
||||
for i in range(item_count - n + 1):
|
||||
yield seq[i : i + n]
|
||||
yield seq[i: i + n]
|
||||
|
||||
|
||||
def substrings_indexes(seq, reverse=False):
|
||||
|
|
@ -844,7 +860,7 @@ def substrings_indexes(seq, reverse=False):
|
|||
if reverse:
|
||||
r = reversed(r)
|
||||
return (
|
||||
(seq[i : i + L], i, i + L) for L in r for i in range(len(seq) - L + 1)
|
||||
(seq[i: i + L], i, i + L) for L in r for i in range(len(seq) - L + 1)
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1046,9 +1062,9 @@ def collapse(iterable, base_type=None, levels=None):
|
|||
|
||||
def walk(node, level):
|
||||
if (
|
||||
((levels is not None) and (level > levels))
|
||||
or isinstance(node, (str, bytes))
|
||||
or ((base_type is not None) and isinstance(node, base_type))
|
||||
((levels is not None) and (level > levels)) or
|
||||
isinstance(node, (str, bytes)) or
|
||||
((base_type is not None) and isinstance(node, base_type))
|
||||
):
|
||||
yield node
|
||||
return
|
||||
|
|
@ -1146,13 +1162,13 @@ def sliced(seq, n, strict=False):
|
|||
For non-sliceable iterables, see :func:`chunked`.
|
||||
|
||||
"""
|
||||
iterator = takewhile(len, (seq[i : i + n] for i in count(0, n)))
|
||||
iterator = takewhile(len, (seq[i: i + n] for i in count(0, n)))
|
||||
if strict:
|
||||
|
||||
def ret():
|
||||
for _slice in iterator:
|
||||
if len(_slice) != n:
|
||||
raise ValueError("seq is not divisible by n.")
|
||||
raise ValueError('seq is not divisible by n.')
|
||||
yield _slice
|
||||
|
||||
return iter(ret())
|
||||
|
|
@ -1475,7 +1491,7 @@ def stagger(iterable, offsets=(-1, 0, 1), longest=False, fillvalue=None):
|
|||
children = tee(iterable, len(offsets))
|
||||
|
||||
return zip_offset(
|
||||
*children, offsets=offsets, longest=longest, fillvalue=fillvalue
|
||||
*children, offsets=offsets, longest=longest, fillvalue=fillvalue,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1484,7 +1500,7 @@ class UnequalIterablesError(ValueError):
|
|||
msg = 'Iterables have different lengths'
|
||||
if details is not None:
|
||||
msg += (': index 0 has length {}; index {} has length {}').format(
|
||||
*details
|
||||
*details,
|
||||
)
|
||||
|
||||
super().__init__(msg)
|
||||
|
|
@ -1635,17 +1651,18 @@ def sort_together(iterables, key_list=(0,), key=None, reverse=False):
|
|||
# if key_list contains a single item, pass the item at that offset
|
||||
# as the only argument to the key function
|
||||
key_offset = key_list[0]
|
||||
key_argument = lambda zipped_items: key(zipped_items[key_offset])
|
||||
def key_argument(zipped_items): return key(zipped_items[key_offset])
|
||||
else:
|
||||
# if key_list contains multiple items, use itemgetter to return a
|
||||
# tuple of items, which we pass as *args to the key function
|
||||
get_key_items = itemgetter(*key_list)
|
||||
key_argument = lambda zipped_items: key(
|
||||
*get_key_items(zipped_items)
|
||||
|
||||
def key_argument(zipped_items): return key(
|
||||
*get_key_items(zipped_items),
|
||||
)
|
||||
|
||||
return list(
|
||||
zip(*sorted(zip(*iterables), key=key_argument, reverse=reverse))
|
||||
zip(*sorted(zip(*iterables), key=key_argument, reverse=reverse)),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1954,12 +1971,12 @@ class numeric_range(abc.Sequence, abc.Hashable):
|
|||
elif argc == 0:
|
||||
raise TypeError(
|
||||
'numeric_range expected at least '
|
||||
'1 argument, got {}'.format(argc)
|
||||
'1 argument, got {}'.format(argc),
|
||||
)
|
||||
else:
|
||||
raise TypeError(
|
||||
'numeric_range expected at most '
|
||||
'3 arguments, got {}'.format(argc)
|
||||
'3 arguments, got {}'.format(argc),
|
||||
)
|
||||
|
||||
self._zero = type(self._step)(0)
|
||||
|
|
@ -1992,9 +2009,9 @@ class numeric_range(abc.Sequence, abc.Hashable):
|
|||
return empty_self and empty_other # True if both empty
|
||||
else:
|
||||
return (
|
||||
self._start == other._start
|
||||
and self._step == other._step
|
||||
and self._get_by_index(-1) == other._get_by_index(-1)
|
||||
self._start == other._start and
|
||||
self._step == other._step and
|
||||
self._get_by_index(-1) == other._get_by_index(-1)
|
||||
)
|
||||
else:
|
||||
return False
|
||||
|
|
@ -2023,7 +2040,7 @@ class numeric_range(abc.Sequence, abc.Hashable):
|
|||
else:
|
||||
raise TypeError(
|
||||
'numeric range indices must be '
|
||||
'integers or slices, not {}'.format(type(key).__name__)
|
||||
'integers or slices, not {}'.format(type(key).__name__),
|
||||
)
|
||||
|
||||
def __hash__(self):
|
||||
|
|
@ -2063,19 +2080,19 @@ class numeric_range(abc.Sequence, abc.Hashable):
|
|||
|
||||
def __repr__(self):
|
||||
if self._step == 1:
|
||||
return "numeric_range({}, {})".format(
|
||||
repr(self._start), repr(self._stop)
|
||||
return 'numeric_range({}, {})'.format(
|
||||
repr(self._start), repr(self._stop),
|
||||
)
|
||||
else:
|
||||
return "numeric_range({}, {}, {})".format(
|
||||
repr(self._start), repr(self._stop), repr(self._step)
|
||||
return 'numeric_range({}, {}, {})'.format(
|
||||
repr(self._start), repr(self._stop), repr(self._step),
|
||||
)
|
||||
|
||||
def __reversed__(self):
|
||||
return iter(
|
||||
numeric_range(
|
||||
self._get_by_index(-1), self._start - self._step, -self._step
|
||||
)
|
||||
self._get_by_index(-1), self._start - self._step, -self._step,
|
||||
),
|
||||
)
|
||||
|
||||
def count(self, value):
|
||||
|
|
@ -2093,13 +2110,13 @@ class numeric_range(abc.Sequence, abc.Hashable):
|
|||
if r == self._zero:
|
||||
return int(q)
|
||||
|
||||
raise ValueError("{} is not in numeric range".format(value))
|
||||
raise ValueError(f'{value} is not in numeric range')
|
||||
|
||||
def _get_by_index(self, i):
|
||||
if i < 0:
|
||||
i += self._len
|
||||
if i < 0 or i >= self._len:
|
||||
raise IndexError("numeric range object index out of range")
|
||||
raise IndexError('numeric range object index out of range')
|
||||
return self._start + i * self._step
|
||||
|
||||
|
||||
|
|
@ -2468,7 +2485,7 @@ def consecutive_groups(iterable, ordering=lambda x: x):
|
|||
|
||||
"""
|
||||
for k, g in groupby(
|
||||
enumerate(iterable), key=lambda x: x[0] - ordering(x[1])
|
||||
enumerate(iterable), key=lambda x: x[0] - ordering(x[1]),
|
||||
):
|
||||
yield map(itemgetter(1), g)
|
||||
|
||||
|
|
@ -2557,7 +2574,7 @@ class SequenceView(Sequence):
|
|||
return len(self._target)
|
||||
|
||||
def __repr__(self):
|
||||
return '{}({})'.format(self.__class__.__name__, repr(self._target))
|
||||
return f'{self.__class__.__name__}({repr(self._target)})'
|
||||
|
||||
|
||||
class seekable:
|
||||
|
|
@ -3043,7 +3060,7 @@ def set_partitions(iterable, k=None):
|
|||
if k is not None:
|
||||
if k < 1:
|
||||
raise ValueError(
|
||||
"Can't partition in a negative or zero number of groups"
|
||||
"Can't partition in a negative or zero number of groups",
|
||||
)
|
||||
elif k > n:
|
||||
return
|
||||
|
|
@ -3060,7 +3077,7 @@ def set_partitions(iterable, k=None):
|
|||
yield [[e], *p]
|
||||
for p in set_partitions_helper(M, k):
|
||||
for i in range(len(p)):
|
||||
yield p[:i] + [[e] + p[i]] + p[i + 1 :]
|
||||
yield p[:i] + [[e] + p[i]] + p[i + 1:]
|
||||
|
||||
if k is None:
|
||||
for k in range(1, n + 1):
|
||||
|
|
@ -3225,9 +3242,9 @@ def distinct_combinations(iterable, r):
|
|||
else:
|
||||
generators.append(
|
||||
unique_everseen(
|
||||
enumerate(pool[cur_idx + 1 :], cur_idx + 1),
|
||||
enumerate(pool[cur_idx + 1:], cur_idx + 1),
|
||||
key=itemgetter(1),
|
||||
)
|
||||
),
|
||||
)
|
||||
level += 1
|
||||
|
||||
|
|
@ -3493,7 +3510,7 @@ class callback_iter:
|
|||
q.put((args, kwargs))
|
||||
|
||||
self._future = self._executor.submit(
|
||||
self._func, **{self._callback_kwd: callback}
|
||||
self._func, **{self._callback_kwd: callback},
|
||||
)
|
||||
|
||||
while True:
|
||||
|
|
@ -3556,8 +3573,8 @@ def windowed_complete(iterable, n):
|
|||
|
||||
for i in range(size - n + 1):
|
||||
beginning = seq[:i]
|
||||
middle = seq[i : i + n]
|
||||
end = seq[i + n :]
|
||||
middle = seq[i: i + n]
|
||||
end = seq[i + n:]
|
||||
yield beginning, middle, end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,22 +7,24 @@ Some backward-compatible usability improvements have been made.
|
|||
.. [1] http://docs.python.org/library/itertools.html#recipes
|
||||
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import operator
|
||||
import warnings
|
||||
from collections import deque
|
||||
from itertools import (
|
||||
chain,
|
||||
combinations,
|
||||
count,
|
||||
cycle,
|
||||
groupby,
|
||||
islice,
|
||||
repeat,
|
||||
starmap,
|
||||
tee,
|
||||
zip_longest,
|
||||
)
|
||||
import operator
|
||||
from random import randrange, sample, choice
|
||||
from itertools import chain
|
||||
from itertools import combinations
|
||||
from itertools import count
|
||||
from itertools import cycle
|
||||
from itertools import groupby
|
||||
from itertools import islice
|
||||
from itertools import repeat
|
||||
from itertools import starmap
|
||||
from itertools import tee
|
||||
from itertools import zip_longest
|
||||
from random import choice
|
||||
from random import randrange
|
||||
from random import sample
|
||||
|
||||
__all__ = [
|
||||
'all_equal',
|
||||
|
|
@ -290,7 +292,7 @@ def grouper(iterable, n, fillvalue=None):
|
|||
"""
|
||||
if isinstance(iterable, int):
|
||||
warnings.warn(
|
||||
"grouper expects iterable as first parameter", DeprecationWarning
|
||||
'grouper expects iterable as first parameter', DeprecationWarning,
|
||||
)
|
||||
n, iterable = iterable, n
|
||||
args = [iter(iterable)] * n
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ entry has an index that can be looked up.
|
|||
Based on a recipe originally posted to ActiveState Recipes by Raymond Hettiger,
|
||||
and released under the MIT license.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import itertools as it
|
||||
from collections import deque
|
||||
|
||||
|
|
@ -13,10 +15,10 @@ try:
|
|||
from collections.abc import MutableSet, Sequence
|
||||
except ImportError:
|
||||
# Python 2.7
|
||||
from collections import MutableSet, Sequence
|
||||
from collections.abc import MutableSet, Sequence
|
||||
|
||||
SLICE_ALL = slice(None)
|
||||
__version__ = "3.1"
|
||||
__version__ = '3.1'
|
||||
|
||||
|
||||
def is_iterable(obj):
|
||||
|
|
@ -33,9 +35,9 @@ def is_iterable(obj):
|
|||
have an `__iter__` attribute anyway.
|
||||
"""
|
||||
return (
|
||||
hasattr(obj, "__iter__")
|
||||
and not isinstance(obj, str)
|
||||
and not isinstance(obj, tuple)
|
||||
hasattr(obj, '__iter__') and
|
||||
not isinstance(obj, str) and
|
||||
not isinstance(obj, tuple)
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -89,7 +91,7 @@ class OrderedSet(MutableSet, Sequence):
|
|||
return self.copy()
|
||||
elif is_iterable(index):
|
||||
return [self.items[i] for i in index]
|
||||
elif hasattr(index, "__index__") or isinstance(index, slice):
|
||||
elif hasattr(index, '__index__') or isinstance(index, slice):
|
||||
result = self.items[index]
|
||||
if isinstance(result, list):
|
||||
return self.__class__(result)
|
||||
|
|
@ -181,7 +183,7 @@ class OrderedSet(MutableSet, Sequence):
|
|||
item_index = self.add(item)
|
||||
except TypeError:
|
||||
raise ValueError(
|
||||
"Argument needs to be an iterable, got %s" % type(sequence)
|
||||
'Argument needs to be an iterable, got %s' % type(sequence),
|
||||
)
|
||||
return item_index
|
||||
|
||||
|
|
@ -218,7 +220,7 @@ class OrderedSet(MutableSet, Sequence):
|
|||
3
|
||||
"""
|
||||
if not self.items:
|
||||
raise KeyError("Set is empty")
|
||||
raise KeyError('Set is empty')
|
||||
|
||||
elem = self.items[-1]
|
||||
del self.items[-1]
|
||||
|
|
@ -274,8 +276,8 @@ class OrderedSet(MutableSet, Sequence):
|
|||
|
||||
def __repr__(self):
|
||||
if not self:
|
||||
return "%s()" % (self.__class__.__name__,)
|
||||
return "%s(%r)" % (self.__class__.__name__, list(self))
|
||||
return '{}()'.format(self.__class__.__name__)
|
||||
return '{}({!r})'.format(self.__class__.__name__, list(self))
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
|
|
@ -484,5 +486,5 @@ class OrderedSet(MutableSet, Sequence):
|
|||
items_to_add = [item for item in other if item not in self]
|
||||
items_to_remove = set(other)
|
||||
self._update_items(
|
||||
[item for item in self.items if item not in items_to_remove] + items_to_add
|
||||
[item for item in self.items if item not in items_to_remove] + items_to_add,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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 setuptools.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd
|
||||
from setuptools.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString
|
||||
from setuptools.extern.pyparsing import Forward
|
||||
from setuptools.extern.pyparsing import Group
|
||||
from setuptools.extern.pyparsing import Literal as L # noqa
|
||||
from setuptools.extern.pyparsing import ParseException
|
||||
from setuptools.extern.pyparsing import ParseResults
|
||||
from setuptools.extern.pyparsing import QuotedString
|
||||
from setuptools.extern.pyparsing import stringEnd
|
||||
from setuptools.extern.pyparsing import stringStart
|
||||
from setuptools.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 setuptools.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException
|
||||
from setuptools.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine
|
||||
from setuptools.extern.pyparsing import Literal as L # noqa
|
||||
import string
|
||||
from urllib import parse as urlparse
|
||||
|
||||
from setuptools.extern.pyparsing import Combine
|
||||
from setuptools.extern.pyparsing import Literal as L # noqa
|
||||
from setuptools.extern.pyparsing import Optional
|
||||
from setuptools.extern.pyparsing import originalTextFor
|
||||
from setuptools.extern.pyparsing import ParseException
|
||||
from setuptools.extern.pyparsing import Regex
|
||||
from setuptools.extern.pyparsing import stringEnd
|
||||
from setuptools.extern.pyparsing import stringStart
|
||||
from setuptools.extern.pyparsing import Word
|
||||
from setuptools.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
|
||||
# setuptools.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
Loading…
Add table
Add a link
Reference in a new issue