Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
setuptools
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jérome Perrin
setuptools
Commits
c6d8c587
Commit
c6d8c587
authored
Dec 25, 2015
by
Jason R. Coombs
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #164. Fixes #122.
parents
6bdbe895
bca120fe
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
4266 additions
and
472 deletions
+4266
-472
CHANGES.txt
CHANGES.txt
+8
-0
Makefile
Makefile
+3
-0
_markerlib/__init__.py
_markerlib/__init__.py
+0
-16
_markerlib/markers.py
_markerlib/markers.py
+0
-119
pkg_resources/__init__.py
pkg_resources/__init__.py
+31
-124
pkg_resources/_vendor/packaging/__about__.py
pkg_resources/_vendor/packaging/__about__.py
+7
-17
pkg_resources/_vendor/packaging/__init__.py
pkg_resources/_vendor/packaging/__init__.py
+3
-13
pkg_resources/_vendor/packaging/_compat.py
pkg_resources/_vendor/packaging/_compat.py
+3
-13
pkg_resources/_vendor/packaging/_structures.py
pkg_resources/_vendor/packaging/_structures.py
+3
-13
pkg_resources/_vendor/packaging/markers.py
pkg_resources/_vendor/packaging/markers.py
+249
-0
pkg_resources/_vendor/packaging/requirements.py
pkg_resources/_vendor/packaging/requirements.py
+120
-0
pkg_resources/_vendor/packaging/specifiers.py
pkg_resources/_vendor/packaging/specifiers.py
+11
-27
pkg_resources/_vendor/packaging/version.py
pkg_resources/_vendor/packaging/version.py
+3
-13
pkg_resources/_vendor/pyparsing.py
pkg_resources/_vendor/pyparsing.py
+3805
-0
pkg_resources/_vendor/vendored.txt
pkg_resources/_vendor/vendored.txt
+1
-0
pkg_resources/api_tests.txt
pkg_resources/api_tests.txt
+17
-47
pkg_resources/tests/test_markers.py
pkg_resources/tests/test_markers.py
+2
-6
setuptools/tests/test_dist_info.py
setuptools/tests/test_dist_info.py
+0
-1
setuptools/tests/test_markerlib.py
setuptools/tests/test_markerlib.py
+0
-63
No files found.
CHANGES.txt
View file @
c6d8c587
...
...
@@ -3,6 +3,14 @@ CHANGES
=======
----
19.3
----
* Pull Request #164: Replace dual PEP 345 _markerlib implementation
and PEP 426 implementation of environment marker support from
packaging 15.4 and PEP-508. Fixes Issue #122.
----
19.2
----
...
...
Makefile
View file @
c6d8c587
...
...
@@ -3,5 +3,8 @@ empty:
update-vendored
:
rm
-rf
pkg_resources/_vendor/packaging
rm
-rf
pkg_resources/_vendor/pyparsing
pip
install
-r
pkg_resources/_vendor/vendored.txt
-t
pkg_resources/_vendor/
sed
-i
-e
's/ \(pyparsing\)/ pkg_resources._vendor.\1/'
\
pkg_resources/_vendor/packaging/
*
.py
rm
-rf
pkg_resources/_vendor/
*
.
{
egg,dist
}
-info
_markerlib/__init__.py
deleted
100644 → 0
View file @
6bdbe895
try
:
import
ast
from
_markerlib.markers
import
default_environment
,
compile
,
interpret
except
ImportError
:
if
'ast'
in
globals
():
raise
def
default_environment
():
return
{}
def
compile
(
marker
):
def
marker_fn
(
environment
=
None
,
override
=
None
):
# 'empty markers are True' heuristic won't install extra deps.
return
not
marker
.
strip
()
marker_fn
.
__doc__
=
marker
return
marker_fn
def
interpret
(
marker
,
environment
=
None
,
override
=
None
):
return
compile
(
marker
)()
_markerlib/markers.py
deleted
100644 → 0
View file @
6bdbe895
# -*- coding: utf-8 -*-
"""Interpret PEP 345 environment markers.
EXPR [in|==|!=|not in] EXPR [or|and] ...
where EXPR belongs to any of those:
python_version = '%s.%s' % (sys.version_info[0], sys.version_info[1])
python_full_version = sys.version.split()[0]
os.name = os.name
sys.platform = sys.platform
platform.version = platform.version()
platform.machine = platform.machine()
platform.python_implementation = platform.python_implementation()
a free string, like '2.6', or 'win32'
"""
__all__
=
[
'default_environment'
,
'compile'
,
'interpret'
]
import
ast
import
os
import
platform
import
sys
import
weakref
_builtin_compile
=
compile
try
:
from
platform
import
python_implementation
except
ImportError
:
if
os
.
name
==
"java"
:
# Jython 2.5 has ast module, but not platform.python_implementation() function.
def
python_implementation
():
return
"Jython"
else
:
raise
# restricted set of variables
_VARS
=
{
'sys.platform'
:
sys
.
platform
,
'python_version'
:
'%s.%s'
%
sys
.
version_info
[:
2
],
# FIXME parsing sys.platform is not reliable, but there is no other
# way to get e.g. 2.7.2+, and the PEP is defined with sys.version
'python_full_version'
:
sys
.
version
.
split
(
' '
,
1
)[
0
],
'os.name'
:
os
.
name
,
'platform.version'
:
platform
.
version
(),
'platform.machine'
:
platform
.
machine
(),
'platform.python_implementation'
:
python_implementation
(),
'extra'
:
None
# wheel extension
}
for
var
in
list
(
_VARS
.
keys
()):
if
'.'
in
var
:
_VARS
[
var
.
replace
(
'.'
,
'_'
)]
=
_VARS
[
var
]
def
default_environment
():
"""Return copy of default PEP 385 globals dictionary."""
return
dict
(
_VARS
)
class
ASTWhitelist
(
ast
.
NodeTransformer
):
def
__init__
(
self
,
statement
):
self
.
statement
=
statement
# for error messages
ALLOWED
=
(
ast
.
Compare
,
ast
.
BoolOp
,
ast
.
Attribute
,
ast
.
Name
,
ast
.
Load
,
ast
.
Str
)
# Bool operations
ALLOWED
+=
(
ast
.
And
,
ast
.
Or
)
# Comparison operations
ALLOWED
+=
(
ast
.
Eq
,
ast
.
Gt
,
ast
.
GtE
,
ast
.
In
,
ast
.
Is
,
ast
.
IsNot
,
ast
.
Lt
,
ast
.
LtE
,
ast
.
NotEq
,
ast
.
NotIn
)
def
visit
(
self
,
node
):
"""Ensure statement only contains allowed nodes."""
if
not
isinstance
(
node
,
self
.
ALLOWED
):
raise
SyntaxError
(
'Not allowed in environment markers.
\
n
%s
\
n
%s'
%
(
self
.
statement
,
(
' '
*
node
.
col_offset
)
+
'^'
))
return
ast
.
NodeTransformer
.
visit
(
self
,
node
)
def
visit_Attribute
(
self
,
node
):
"""Flatten one level of attribute access."""
new_node
=
ast
.
Name
(
"%s.%s"
%
(
node
.
value
.
id
,
node
.
attr
),
node
.
ctx
)
return
ast
.
copy_location
(
new_node
,
node
)
def
parse_marker
(
marker
):
tree
=
ast
.
parse
(
marker
,
mode
=
'eval'
)
new_tree
=
ASTWhitelist
(
marker
).
generic_visit
(
tree
)
return
new_tree
def
compile_marker
(
parsed_marker
):
return
_builtin_compile
(
parsed_marker
,
'<environment marker>'
,
'eval'
,
dont_inherit
=
True
)
_cache
=
weakref
.
WeakValueDictionary
()
def
compile
(
marker
):
"""Return compiled marker as a function accepting an environment dict."""
try
:
return
_cache
[
marker
]
except
KeyError
:
pass
if
not
marker
.
strip
():
def
marker_fn
(
environment
=
None
,
override
=
None
):
""""""
return
True
else
:
compiled_marker
=
compile_marker
(
parse_marker
(
marker
))
def
marker_fn
(
environment
=
None
,
override
=
None
):
"""override updates environment"""
if
override
is
None
:
override
=
{}
if
environment
is
None
:
environment
=
default_environment
()
environment
.
update
(
override
)
return
eval
(
compiled_marker
,
environment
)
marker_fn
.
__doc__
=
marker
_cache
[
marker
]
=
marker_fn
return
_cache
[
marker
]
def
interpret
(
marker
,
environment
=
None
):
return
compile
(
marker
)(
environment
)
pkg_resources/__init__.py
View file @
c6d8c587
...
...
@@ -90,6 +90,8 @@ except ImportError:
try
:
import
pkg_resources._vendor.packaging.version
import
pkg_resources._vendor.packaging.specifiers
import
pkg_resources._vendor.packaging.requirements
import
pkg_resources._vendor.packaging.markers
packaging
=
pkg_resources
.
_vendor
.
packaging
except
ImportError
:
# fallback to naturally-installed version; allows system packagers to
...
...
@@ -1420,13 +1422,15 @@ class MarkerEvaluation(object):
@classmethod
def is_invalid_marker(cls, text):
"""
Validate text as a PEP
426
environment marker; return an exception
Validate text as a PEP
508
environment marker; return an exception
if invalid or False otherwise.
"""
try:
cls.evaluate_marker(text)
except SyntaxError as e:
return cls.normalize_exception(e)
except packaging.markers.InvalidMarker as e:
e.filename = None
e.lineno = None
return e
return False
@staticmethod
...
...
@@ -1518,48 +1522,14 @@ class MarkerEvaluation(object):
@classmethod
def evaluate_marker(cls, text, extra=None):
"""
Evaluate a PEP
426
environment marker on CPython 2.4+.
Evaluate a PEP
508
environment marker on CPython 2.4+.
Return a boolean indicating the marker result in this environment.
Raise
SyntaxErro
r if marker is invalid.
Raise
InvalidMarke
r if marker is invalid.
This implementation uses the '
parser
' module, which is not implemented
on
Jython and has been superseded by the '
ast
' module in Python 2.6 and
later.
This implementation uses the '
pyparsing
' module.
"""
return cls.interpret(parser.expr(text).totuple(1)[1])
@staticmethod
def _translate_metadata2(env):
"""
Markerlib implements Metadata 1.2 (PEP 345) environment markers.
Translate the variables to Metadata 2.0 (PEP 426).
"""
return dict(
(key.replace('
.
', '
_
'), value)
for key, value in env.items()
)
@classmethod
def _markerlib_evaluate(cls, text):
"""
Evaluate a PEP 426 environment marker using markerlib.
Return a boolean indicating the marker result in this environment.
Raise SyntaxError if marker is invalid.
"""
import _markerlib
env = cls._translate_metadata2(_markerlib.default_environment())
try:
result = _markerlib.interpret(text, env)
except NameError as e:
raise SyntaxError(e.args[0])
return result
if '
parser
' not in globals():
# Fall back to less-complete _markerlib implementation if '
parser
' module
# is not available.
evaluate_marker = _markerlib_evaluate
marker = packaging.markers.Marker(text)
return marker.evaluate()
@classmethod
def interpret(cls, nodelist):
...
...
@@ -2314,18 +2284,6 @@ def yield_lines(strs):
for
s
in
yield_lines
(
ss
):
yield
s
# whitespace and comment
LINE_END
=
re
.
compile
(
r"\
s*(#.*)?$
").match
# line continuation
CONTINUE = re.compile(r"
\
s
*
\\\
s
*
(
#.*)?$").match
# Distribution or extra
DISTRO
=
re
.
compile
(
r"\
s*((
\w|[-.])+)"
).
match
# ver. info
VERSION
=
re
.
compile
(
r"\
s*(<=?|>=?|===?|!=|~=)
\s*((\
w|[-.*_!+])+)
").match
# comma between items
COMMA = re.compile(r"
\
s
*
,
").match
OBRACKET = re.compile(r"
\
s
*
\
[
").match
CBRACKET = re.compile(r"
\
s
*
\
]
").match
MODULE
=
re
.
compile
(
r"\
w+(
\.\
w+)*$
").match
EGG_NAME = re.compile(
r"""
...
...
@@ -2861,34 +2819,22 @@ class DistInfoDistribution(Distribution):
self.__dep_map = self._compute_dependencies()
return self.__dep_map
def _preparse_requirement(self, requires_dist):
"""Convert 'Foobar (1); baz' to ('Foobar ==1', 'baz')
Split environment marker, add == prefix to version specifiers as
necessary, and remove parenthesis.
"""
parts = requires_dist.split(';', 1) + ['']
distvers = parts[0].strip()
mark = parts[1].strip()
distvers = re.sub(self.EQEQ, r"
\
1
==
\
2
\
3
", distvers)
distvers = distvers.replace('(', '').replace(')', '')
return (distvers, mark)
def _compute_dependencies(self):
"""Recompute this distribution's dependencies."""
from _markerlib import compile as compile_marker
dm = self.__dep_map = {None: []}
reqs = []
# Including any condition expressions
for req in self._parsed_pkg_info.get_all('Requires-Dist') or []:
distvers, mark = self._preparse_requirement(req)
parsed = next(parse_requirements(distvers))
parsed.marker_fn = compile_marker(mark)
current_req = packaging.requirements.Requirement(req)
specs = _parse_requirement_specs(current_req)
parsed = Requirement(current_req.name, specs, current_req.extras)
parsed._marker = current_req.marker
reqs.append(parsed)
def reqs_for_extra(extra):
for req in reqs:
if
req.marker_fn(override={'extra':
extra}):
if
not req._marker or req._marker.evaluate({'extra':
extra}):
yield req
common = frozenset(reqs_for_extra(None))
...
...
@@ -2926,6 +2872,10 @@ class RequirementParseError(ValueError):
return ' '.join(self.args)
def _parse_requirement_specs(req):
return [(spec.operator, spec.version) for spec in req.specifier]
def parse_requirements(strs):
"""Yield ``Requirement`` objects for each specification in `strs`
...
...
@@ -2934,60 +2884,17 @@ def parse_requirements(strs):
# create a steppable iterator, so we can handle \
-co
ntinuations
lines = iter(yield_lines(strs))
def scan_list(ITEM, TERMINATOR, line, p, groups, item_name):
items = []
while not TERMINATOR(line, p):
if CONTINUE(line, p):
try:
line = next(lines)
p = 0
except StopIteration:
msg = "
\\
must
not
appear
on
the
last
nonblank
line
"
raise RequirementParseError(msg)
match = ITEM(line, p)
if not match:
msg = "
Expected
" + item_name + "
in
"
raise RequirementParseError(msg, line, "
at
", line[p:])
items.append(match.group(*groups))
p = match.end()
match = COMMA(line, p)
if match:
# skip the comma
p = match.end()
elif not TERMINATOR(line, p):
msg = "
Expected
','
or
end
-
of
-
list
in
"
raise RequirementParseError(msg, line, "
at
", line[p:])
match = TERMINATOR(line, p)
# skip the terminator, if any
if match:
p = match.end()
return line, p, items
for line in lines:
match = DISTRO(line)
if not match:
raise RequirementParseError("
Missing
distribution
spec
", line)
project_name = match.group(1)
p = match.end()
extras = []
match = OBRACKET(line, p)
if match:
p = match.end()
line, p, extras = scan_list(
DISTRO, CBRACKET, line, p, (1,), "'extra'
name
"
)
line, p, specs = scan_list(VERSION, LINE_END, line, p, (1, 2),
"
version
spec
")
specs = [(op, val) for op, val in specs]
yield Requirement(project_name, specs, extras)
# Drop comments -- a hash without a space may be in a URL.
if ' #' in line:
line = line[:line.find(' #')]
# If there is a line continuation, drop it, and append the next line.
if line.endswith('\\'):
line = line[:-2].strip()
line += next(lines)
req = packaging.requirements.Requirement(line)
specs = _parse_requirement_specs(req)
yield Requirement(req.name, specs, req.extras)
class Requirement:
...
...
pkg_resources/_vendor/packaging/__about__.py
View file @
c6d8c587
# Copyright 2014 Donald Stufft
#
# 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.
# 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
__all__
=
[
...
...
@@ -22,10 +12,10 @@ __title__ = "packaging"
__summary__
=
"Core utilities for Python packages"
__uri__
=
"https://github.com/pypa/packaging"
__version__
=
"15.
3
"
__version__
=
"15.
4.dev0
"
__author__
=
"Donald Stufft"
__author__
=
"Donald Stufft
and individual contributors
"
__email__
=
"donald@stufft.io"
__license__
=
"Apache License, Version 2.0"
__copyright__
=
"Copyright 2014 %s"
%
__author__
__license__
=
"
BSD or
Apache License, Version 2.0"
__copyright__
=
"Copyright 2014
-2015
%s"
%
__author__
pkg_resources/_vendor/packaging/__init__.py
View file @
c6d8c587
# Copyright 2014 Donald Stufft
#
# 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.
# 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
.__about__
import
(
...
...
pkg_resources/_vendor/packaging/_compat.py
View file @
c6d8c587
# Copyright 2014 Donald Stufft
#
# 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.
# 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
import
sys
...
...
pkg_resources/_vendor/packaging/_structures.py
View file @
c6d8c587
# Copyright 2014 Donald Stufft
#
# 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.
# 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
...
...
pkg_resources/_vendor/packaging/markers.py
0 → 100644
View file @
c6d8c587
# 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
import
operator
import
os
import
platform
import
sys
from
pkg_resources._vendor.pyparsing
import
ParseException
,
ParseResults
,
stringStart
,
stringEnd
from
pkg_resources._vendor.pyparsing
import
ZeroOrMore
,
Group
,
Forward
,
QuotedString
from
pkg_resources._vendor.pyparsing
import
Literal
as
L
# noqa
from
._compat
import
string_types
from
.specifiers
import
Specifier
,
InvalidSpecifier
__all__
=
[
"InvalidMarker"
,
"UndefinedComparison"
,
"Marker"
,
"default_environment"
,
]
class
InvalidMarker
(
ValueError
):
"""
An invalid marker was found, users should refer to PEP 508.
"""
class
UndefinedComparison
(
ValueError
):
"""
An invalid operation was attempted on a value that doesn't support it.
"""
class
Node
(
object
):
def
__init__
(
self
,
value
):
self
.
value
=
value
def
__str__
(
self
):
return
str
(
self
.
value
)
def
__repr__
(
self
):
return
"<{0}({1!r})>"
.
format
(
self
.
__class__
.
__name__
,
str
(
self
))
class
Variable
(
Node
):
pass
class
Value
(
Node
):
pass
VARIABLE
=
(
L
(
"implementation_version"
)
|
L
(
"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
(
"extra"
)
)
VARIABLE
.
setParseAction
(
lambda
s
,
l
,
t
:
Variable
(
t
[
0
]))
VERSION_CMP
=
(
L
(
"==="
)
|
L
(
"=="
)
|
L
(
">="
)
|
L
(
"<="
)
|
L
(
"!="
)
|
L
(
"~="
)
|
L
(
">"
)
|
L
(
"<"
)
)
MARKER_OP
=
VERSION_CMP
|
L
(
"not in"
)
|
L
(
"in"
)
MARKER_VALUE
=
QuotedString
(
"'"
)
|
QuotedString
(
'"'
)
MARKER_VALUE
.
setParseAction
(
lambda
s
,
l
,
t
:
Value
(
t
[
0
]))
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
()
MARKER_EXPR
=
Forward
()
MARKER_ATOM
=
MARKER_ITEM
|
Group
(
LPAREN
+
MARKER_EXPR
+
RPAREN
)
MARKER_EXPR
<<
MARKER_ATOM
+
ZeroOrMore
(
BOOLOP
+
MARKER_EXPR
)
MARKER
=
stringStart
+
MARKER_EXPR
+
stringEnd
def
_coerce_parse_result
(
results
):
if
isinstance
(
results
,
ParseResults
):
return
[
_coerce_parse_result
(
i
)
for
i
in
results
]
else
:
return
results
def
_format_marker
(
marker
,
first
=
True
):
assert
isinstance
(
marker
,
(
list
,
tuple
,
string_types
))
# Sometimes we have a structure like [[...]] which is a single item list
# where the single item is itself it's own list. In that case we want skip
# 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
))):
return
_format_marker
(
marker
[
0
])
if
isinstance
(
marker
,
list
):
inner
=
(
_format_marker
(
m
,
first
=
False
)
for
m
in
marker
)
if
first
:
return
" "
.
join
(
inner
)
else
:
return
"("
+
" "
.
join
(
inner
)
+
")"
elif
isinstance
(
marker
,
tuple
):
return
'{0} {1} "{2}"'
.
format
(
*
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
,
}
def
_eval_op
(
lhs
,
op
,
rhs
):
try
:
spec
=
Specifier
(
""
.
join
([
op
,
rhs
]))
except
InvalidSpecifier
:
pass
else
:
return
spec
.
contains
(
lhs
)
oper
=
_operators
.
get
(
op
)
if
oper
is
None
:
raise
UndefinedComparison
(
"Undefined {0!r} on {1!r} and {2!r}."
.
format
(
op
,
lhs
,
rhs
)
)
return
oper
(
lhs
,
rhs
)
def
_evaluate_markers
(
markers
,
environment
):
groups
=
[[]]
for
marker
in
markers
:
assert
isinstance
(
marker
,
(
list
,
tuple
,
string_types
))
if
isinstance
(
marker
,
list
):
groups
[
-
1
].
append
(
_evaluate_markers
(
marker
,
environment
))
elif
isinstance
(
marker
,
tuple
):
lhs
,
op
,
rhs
=
marker
if
isinstance
(
lhs
,
Variable
):
value
=
_eval_op
(
environment
[
lhs
.
value
],
op
,
rhs
.
value
)
else
:
value
=
_eval_op
(
lhs
.
value
,
op
,
environment
[
rhs
.
value
])
groups
[
-
1
].
append
(
value
)
else
:
assert
marker
in
[
"and"
,
"or"
]
if
marker
==
"or"
:
groups
.
append
([])
return
any
(
all
(
item
)
for
item
in
groups
)
def
format_full_version
(
info
):
version
=
'{0.major}.{0.minor}.{0.micro}'
.
format
(
info
)
kind
=
info
.
releaselevel
if
kind
!=
'final'
:
version
+=
kind
[
0
]
+
str
(
info
.
serial
)
return
version
def
default_environment
():
if
hasattr
(
sys
,
'implementation'
):
iver
=
format_full_version
(
sys
.
implementation
.
version
)
implementation_name
=
sys
.
implementation
.
name
else
:
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
(),
"python_implementation"
:
platform
.
python_implementation
(),
"python_version"
:
platform
.
python_version
()[:
3
],
"sys_platform"
:
sys
.
platform
,
}
class
Marker
(
object
):
def
__init__
(
self
,
marker
):
try
:
self
.
_markers
=
_coerce_parse_result
(
MARKER
.
parseString
(
marker
))
except
ParseException
:
self
.
_markers
=
None
# We do this because we can't do raise ... from None in Python 2.x
if
self
.
_markers
is
None
:
raise
InvalidMarker
(
"Invalid marker: {0!r}"
.
format
(
marker
))
def
__str__
(
self
):
return
_format_marker
(
self
.
_markers
)
def
__repr__
(
self
):
return
"<Marker({0!r})>"
.
format
(
str
(
self
))
def
evaluate
(
self
,
environment
=
None
):
"""Evaluate a marker.
Return the boolean from evaluating the given marker against the
environment. environment is an optional argument to override all or
part of the determined environment.
The environment is determined from the current Python process.
"""
current_environment
=
default_environment
()
if
environment
is
not
None
:
current_environment
.
update
(
environment
)
return
_evaluate_markers
(
self
.
_markers
,
current_environment
)
pkg_resources/_vendor/packaging/requirements.py
0 → 100644
View file @
c6d8c587
# 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
import
string
import
re
from
pkg_resources._vendor.pyparsing
import
stringStart
,
stringEnd
,
originalTextFor
,
ParseException
from
pkg_resources._vendor.pyparsing
import
ZeroOrMore
,
Word
,
Optional
,
Regex
,
Combine
from
pkg_resources._vendor.pyparsing
import
Literal
as
L
# noqa
from
six.moves.urllib
import
parse
as
urlparse
from
.markers
import
MARKER_EXPR
,
Marker
from
.specifiers
import
LegacySpecifier
,
Specifier
,
SpecifierSet
class
InvalidRequirement
(
ValueError
):
"""
An invalid requirement was found, users should refer to PEP 508.
"""
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
()
PUNCTUATION
=
Word
(
"-_."
)
IDENTIFIER_END
=
ALPHANUM
|
(
ZeroOrMore
(
PUNCTUATION
)
+
ALPHANUM
)
IDENTIFIER
=
Combine
(
ALPHANUM
+
ZeroOrMore
(
IDENTIFIER_END
))
NAME
=
IDENTIFIER
(
"name"
)
EXTRA
=
IDENTIFIER
URI
=
Regex
(
r'[^ ]+'
)(
"url"
)
URL
=
(
AT
+
URI
)
EXTRAS_LIST
=
EXTRA
+
ZeroOrMore
(
COMMA
+
EXTRA
)
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
=
","
)(
"_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
.
setParseAction
(
lambda
s
,
l
,
t
:
t
[
1
])
MARKER_EXPR
=
originalTextFor
(
MARKER_EXPR
())(
"marker"
)
MARKER_EXPR
.
setParseAction
(
lambda
s
,
l
,
t
:
Marker
(
s
[
t
.
_original_start
:
t
.
_original_end
])
)
MARKER_SEPERATOR
=
SEMICOLON
MARKER
=
MARKER_SEPERATOR
+
MARKER_EXPR
VERSION_AND_MARKER
=
VERSION_SPEC
+
Optional
(
MARKER
)
URL_AND_MARKER
=
URL
+
Optional
(
MARKER
)
NAMED_REQUIREMENT
=
\
NAME
+
Optional
(
EXTRAS
)
+
(
URL_AND_MARKER
|
VERSION_AND_MARKER
)
REQUIREMENT
=
stringStart
+
NAMED_REQUIREMENT
+
stringEnd
class
Requirement
(
object
):
# TODO: Can we test whether something is contained within a requirement?
# If so how do we do that? Do we need to test against the _name_ of
# the thing as well as the version? What about the markers?
# TODO: Can we normalize the name and extra name?
def
__init__
(
self
,
requirement_string
):
try
:
req
=
REQUIREMENT
.
parseString
(
requirement_string
)
except
ParseException
:
raise
InvalidRequirement
(
"Invalid requirement: {0!r}"
.
format
(
requirement_string
))
self
.
name
=
req
.
name
if
req
.
url
:
parsed_url
=
urlparse
.
urlparse
(
req
.
url
)
if
not
(
parsed_url
.
scheme
and
parsed_url
.
netloc
)
or
(
not
parsed_url
.
scheme
and
not
parsed_url
.
netloc
):
raise
InvalidRequirement
(
"Invalid URL given"
)
self
.
url
=
req
.
url
else
:
self
.
url
=
None
self
.
extras
=
req
.
extras
.
asList
()
if
req
.
extras
else
[]
self
.
specifier
=
SpecifierSet
(
req
.
specifier
)
self
.
marker
=
req
.
marker
if
req
.
marker
else
None
def
__str__
(
self
):
parts
=
[
self
.
name
]
if
self
.
extras
:
parts
.
append
(
"[{0}]"
.
format
(
","
.
join
(
sorted
(
self
.
extras
))))
if
self
.
specifier
:
parts
.
append
(
str
(
self
.
specifier
))
if
self
.
url
:
parts
.
append
(
"@ {0}"
.
format
(
self
.
url
))
if
self
.
marker
:
parts
.
append
(
"; {0}"
.
format
(
self
.
marker
))
return
""
.
join
(
parts
)
def
__repr__
(
self
):
return
"<Requirement({0!r})>"
.
format
(
str
(
self
))
pkg_resources/_vendor/packaging/specifiers.py
View file @
c6d8c587
# Copyright 2014 Donald Stufft
#
# 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.
# 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
import
abc
...
...
@@ -223,10 +213,8 @@ class _IndividualSpecifier(BaseSpecifier):
class
LegacySpecifier
(
_IndividualSpecifier
):
_regex
=
re
.
compile
(
_regex
_str
=
(
r"""
^
\
s*
(?P<operator>(==|!=|<=|>=|<|>))
\
s*
(?P<version>
...
...
@@ -234,12 +222,11 @@ class LegacySpecifier(_IndividualSpecifier):
# is a "legacy" specifier and the version string can be just
# about anything.
)
\
s*
$
"""
,
re
.
VERBOSE
|
re
.
IGNORECASE
,
"""
)
_regex
=
re
.
compile
(
r"^\
s*
" + _regex_str + r"
\
s
*
$
", re.X | re.I)
_operators = {
"
==
": "
equal
",
"
!=
": "
not_equal
",
...
...
@@ -284,10 +271,8 @@ def _require_version_compare(fn):
class Specifier(_IndividualSpecifier):
_regex
=
re
.
compile
(
_regex
_str =
(
r"""
^
\
s*
(?P<operator>(~=|==|!=|<=|>=|<|>|===))
(?P<version>
(?:
...
...
@@ -378,12 +363,11 @@ class Specifier(_IndividualSpecifier):
(?:[-_
\
.]?de
v
[-_
\
.]?[
0
-9]*)? # dev release
)
)
\
s*
$
"""
,
re
.
VERBOSE
|
re
.
IGNORECASE
,
"""
)
_regex = re.compile(r"
^
\
s
*
" + _regex_str + r"
\
s
*
$
", re.X | re.I)
_operators = {
"
~=
": "
compatible
",
"
==
": "
equal
",
...
...
pkg_resources/_vendor/packaging/version.py
View file @
c6d8c587
# Copyright 2014 Donald Stufft
#
# 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.
# 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
import
collections
...
...
pkg_resources/_vendor/pyparsing.py
0 → 100644
View file @
c6d8c587
This source diff could not be displayed because it is too large. You can
view the blob
instead.
pkg_resources/_vendor/vendored.txt
View file @
c6d8c587
packaging==15.3
pyparsing==2.0.6
pkg_resources/api_tests.txt
View file @
c6d8c587
...
...
@@ -338,88 +338,58 @@ Environment Markers
>>> import os
>>> print(im("sys_platform"))
Comparison or logical expression expected
Invalid marker: 'sys_platform'
>>> print(im("sys_platform=="))
invalid syntax
Invalid marker: 'sys_platform=='
>>> print(im("sys_platform=='win32'"))
False
>>> print(im("sys=='x'"))
Unknown name 'sys'
Invalid marker: "sys=='x'"
>>> print(im("(extra)"))
Comparison or logical expression expected
Invalid marker: '(extra)'
>>> print(im("(extra"))
invalid syntax
Invalid marker: '(extra'
>>> print(im("os.open('foo')=='y'"))
Language feature not supported in environment markers
Invalid marker: "os.open('foo')=='y'"
>>> print(im("'x'=='y' and os.open('foo')=='y'")) # no short-circuit!
Language feature not supported in environment markers
Invalid marker: "'x'=='y' and os.open('foo')=='y'"
>>> print(im("'x'=='x' or os.open('foo')=='y'")) # no short-circuit!
Language feature not supported in environment markers
Invalid marker: "'x'=='x' or os.open('foo')=='y'"
>>> print(im("'x' < 'y' < 'z'"))
Chained comparison not allowed in environment markers
Invalid marker: "'x' < 'y' < 'z'"
>>> print(im("r'x'=='x'"))
Only plain strings allowed in environment markers
Invalid marker: "r'x'=='x'"
>>> print(im("'''x'''=='x'"))
Only plain strings allowed in environment markers
Invalid marker: "'''x'''=='x'"
>>> print(im('"""x"""=="x"'))
Only plain strings allowed in environment markers
Invalid marker: '"""x"""=="x"'
>>> print(im(r"
'x\n'
=='x'"))
Only plain strings allowed in environment markers
>>> print(im(r"
x\n
=='x'"))
Invalid marker: "x\\n=='x'"
>>> print(im("os.open=='y'"))
Language feature not supported in environment markers
Invalid marker: "os.open=='y'"
>>> em(
'"x"=="x"'
)
>>> em(
"'linux' in sys_platform"
)
True
>>> em('"x"=="y"')
False
>>> em('"x"=="y" and "x"=="x"')
False
>>> em('"x"=="y" or "x"=="x"')
True
>>> em('"x"=="y" and "x"=="q" or "z"=="z"')
True
>>> em('"x"=="y" and ("x"=="q" or "z"=="z")')
False
>>> em('"x"=="y" and "z"=="z" or "x"=="q"')
False
>>> em('"x"=="x" and "z"=="z" or "x"=="q"')
True
>>> em("sys_platform=='win32'") == (sys.platform=='win32')
True
>>> em("'x' in 'yx'")
True
>>> em("'yx' in 'x'")
False
>>> em("python_version >= '2.6'")
True
>>> em("python_version > '2.5'")
True
>>> im("
platform_python_implementation
=='CPython'")
>>> im("
implementation_name
=='CPython'")
False
pkg_resources/tests/test_markers.py
View file @
c6d8c587
...
...
@@ -8,9 +8,5 @@ from pkg_resources import evaluate_marker
@
mock
.
patch
.
dict
(
'pkg_resources.MarkerEvaluation.values'
,
python_full_version
=
mock
.
Mock
(
return_value
=
'2.7.10'
))
def
test_lexicographic_ordering
():
"""
Although one might like 2.7.10 to be greater than 2.7.3,
the marker spec only supports lexicographic ordering.
"""
assert
evaluate_marker
(
"python_full_version > '2.7.3'"
)
is
False
def
test_ordering
():
assert
evaluate_marker
(
"python_full_version > '2.7.3'"
)
is
True
setuptools/tests/test_dist_info.py
View file @
c6d8c587
...
...
@@ -26,7 +26,6 @@ class TestDistInfo:
assert
versioned
.
version
==
'2.718'
# from filename
assert
unversioned
.
version
==
'0.3'
# from METADATA
@
pytest
.
mark
.
importorskip
(
'ast'
)
def
test_conditional_dependencies
(
self
):
specs
=
'splort==4'
,
'quux>=1.1'
requires
=
list
(
map
(
pkg_resources
.
Requirement
.
parse
,
specs
))
...
...
setuptools/tests/test_markerlib.py
deleted
100644 → 0
View file @
6bdbe895
import
os
import
pytest
class
TestMarkerlib
:
@
pytest
.
mark
.
importorskip
(
'ast'
)
def
test_markers
(
self
):
from
_markerlib
import
interpret
,
default_environment
,
compile
os_name
=
os
.
name
assert
interpret
(
""
)
assert
interpret
(
"os.name != 'buuuu'"
)
assert
interpret
(
"os_name != 'buuuu'"
)
assert
interpret
(
"python_version > '1.0'"
)
assert
interpret
(
"python_version < '5.0'"
)
assert
interpret
(
"python_version <= '5.0'"
)
assert
interpret
(
"python_version >= '1.0'"
)
assert
interpret
(
"'%s' in os.name"
%
os_name
)
assert
interpret
(
"'%s' in os_name"
%
os_name
)
assert
interpret
(
"'buuuu' not in os.name"
)
assert
not
interpret
(
"os.name == 'buuuu'"
)
assert
not
interpret
(
"os_name == 'buuuu'"
)
assert
not
interpret
(
"python_version < '1.0'"
)
assert
not
interpret
(
"python_version > '5.0'"
)
assert
not
interpret
(
"python_version >= '5.0'"
)
assert
not
interpret
(
"python_version <= '1.0'"
)
assert
not
interpret
(
"'%s' not in os.name"
%
os_name
)
assert
not
interpret
(
"'buuuu' in os.name and python_version >= '5.0'"
)
assert
not
interpret
(
"'buuuu' in os_name and python_version >= '5.0'"
)
environment
=
default_environment
()
environment
[
'extra'
]
=
'test'
assert
interpret
(
"extra == 'test'"
,
environment
)
assert
not
interpret
(
"extra == 'doc'"
,
environment
)
def
raises_nameError
():
try
:
interpret
(
"python.version == '42'"
)
except
NameError
:
pass
else
:
raise
Exception
(
"Expected NameError"
)
raises_nameError
()
def
raises_syntaxError
():
try
:
interpret
(
"(x for x in (4,))"
)
except
SyntaxError
:
pass
else
:
raise
Exception
(
"Expected SyntaxError"
)
raises_syntaxError
()
statement
=
"python_version == '5'"
assert
compile
(
statement
).
__doc__
==
statement
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment