]>
jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/pip/_vendor/packaging/markers.py
1 # This file is dual licensed under the terms of the Apache License, Version
2 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3 # for complete details.
9 from typing
import Any
, Callable
, Dict
, List
, Optional
, Tuple
, Union
11 from pip
._vendor
.pyparsing
import ( # noqa: N817
23 from .specifiers
import InvalidSpecifier
, Specifier
27 "UndefinedComparison",
28 "UndefinedEnvironmentName",
30 "default_environment",
33 Operator
= Callable
[[str, str], bool]
36 class InvalidMarker(ValueError):
38 An invalid marker was found, users should refer to PEP 508.
42 class UndefinedComparison(ValueError):
44 An invalid operation was attempted on a value that doesn't support it.
48 class UndefinedEnvironmentName(ValueError):
50 A name was attempted to be used that does not exist inside of the
56 def __init__(self
, value
: Any
) -> None:
59 def __str__(self
) -> str:
60 return str(self
.value
)
62 def __repr__(self
) -> str:
63 return f
"<{self.__class__.__name__}('{self}')>"
65 def serialize(self
) -> str:
66 raise NotImplementedError
70 def serialize(self
) -> str:
75 def serialize(self
) -> str:
80 def serialize(self
) -> str:
85 L("implementation_version")
86 |
L("platform_python_implementation")
87 |
L("implementation_name")
88 |
L("python_full_version")
89 |
L("platform_release")
90 |
L("platform_version")
91 |
L("platform_machine")
92 |
L("platform_system")
96 |
L("os.name") # PEP-345
97 |
L("sys.platform") # PEP-345
98 |
L("platform.version") # PEP-345
99 |
L("platform.machine") # PEP-345
100 |
L("platform.python_implementation") # PEP-345
101 |
L("python_implementation") # undocumented setuptools legacy
102 |
L("extra") # PEP-508
105 "os.name": "os_name",
106 "sys.platform": "sys_platform",
107 "platform.version": "platform_version",
108 "platform.machine": "platform_machine",
109 "platform.python_implementation": "platform_python_implementation",
110 "python_implementation": "platform_python_implementation",
112 VARIABLE
.setParseAction(lambda s
, l
, t
: Variable(ALIASES
.get(t
[0], t
[0])))
115 L("===") |
L("==") |
L(">=") |
L("<=") |
L("!=") |
L("~=") |
L(">") |
L("<")
118 MARKER_OP
= VERSION_CMP |
L("not in") |
L("in")
119 MARKER_OP
.setParseAction(lambda s
, l
, t
: Op(t
[0]))
121 MARKER_VALUE
= QuotedString("'") |
QuotedString('"')
122 MARKER_VALUE
.setParseAction(lambda s
, l
, t
: Value(t
[0]))
124 BOOLOP
= L("and") |
L("or")
126 MARKER_VAR
= VARIABLE | MARKER_VALUE
128 MARKER_ITEM
= Group(MARKER_VAR
+ MARKER_OP
+ MARKER_VAR
)
129 MARKER_ITEM
.setParseAction(lambda s
, l
, t
: tuple(t
[0]))
131 LPAREN
= L("(").suppress()
132 RPAREN
= L(")").suppress()
134 MARKER_EXPR
= Forward()
135 MARKER_ATOM
= MARKER_ITEM |
Group(LPAREN
+ MARKER_EXPR
+ RPAREN
)
136 MARKER_EXPR
<< MARKER_ATOM
+ ZeroOrMore(BOOLOP
+ MARKER_EXPR
)
138 MARKER
= stringStart
+ MARKER_EXPR
+ stringEnd
141 def _coerce_parse_result(results
: Union
[ParseResults
, List
[Any
]]) -> List
[Any
]:
142 if isinstance(results
, ParseResults
):
143 return [_coerce_parse_result(i
) for i
in results
]
149 marker
: Union
[List
[str], Tuple
[Node
, ...], str], first
: Optional
[bool] = True
152 assert isinstance(marker
, (list, tuple, str))
154 # Sometimes we have a structure like [[...]] which is a single item list
155 # where the single item is itself it's own list. In that case we want skip
156 # the rest of this function so that we don't get extraneous () on the
159 isinstance(marker
, list)
161 and isinstance(marker
[0], (list, tuple))
163 return _format_marker(marker
[0])
165 if isinstance(marker
, list):
166 inner
= (_format_marker(m
, first
=False) for m
in marker
)
168 return " ".join(inner
)
170 return "(" + " ".join(inner
) + ")"
171 elif isinstance(marker
, tuple):
172 return " ".join([m
.serialize() for m
in marker
])
177 _operators
: Dict
[str, Operator
] = {
178 "in": lambda lhs
, rhs
: lhs
in rhs
,
179 "not in": lambda lhs
, rhs
: lhs
not in rhs
,
189 def _eval_op(lhs
: str, op
: Op
, rhs
: str) -> bool:
191 spec
= Specifier("".join([op
.serialize(), rhs
]))
192 except InvalidSpecifier
:
195 return spec
.contains(lhs
)
197 oper
: Optional
[Operator
] = _operators
.get(op
.serialize())
199 raise UndefinedComparison(f
"Undefined {op!r} on {lhs!r} and {rhs!r}.")
201 return oper(lhs
, rhs
)
208 _undefined
= Undefined()
211 def _get_env(environment
: Dict
[str, str], name
: str) -> str:
212 value
: Union
[str, Undefined
] = environment
.get(name
, _undefined
)
214 if isinstance(value
, Undefined
):
215 raise UndefinedEnvironmentName(
216 f
"{name!r} does not exist in evaluation environment."
222 def _evaluate_markers(markers
: List
[Any
], environment
: Dict
[str, str]) -> bool:
223 groups
: List
[List
[bool]] = [[]]
225 for marker
in markers
:
226 assert isinstance(marker
, (list, tuple, str))
228 if isinstance(marker
, list):
229 groups
[-1].append(_evaluate_markers(marker
, environment
))
230 elif isinstance(marker
, tuple):
231 lhs
, op
, rhs
= marker
233 if isinstance(lhs
, Variable
):
234 lhs_value
= _get_env(environment
, lhs
.value
)
235 rhs_value
= rhs
.value
237 lhs_value
= lhs
.value
238 rhs_value
= _get_env(environment
, rhs
.value
)
240 groups
[-1].append(_eval_op(lhs_value
, op
, rhs_value
))
242 assert marker
in ["and", "or"]
246 return any(all(item
) for item
in groups
)
249 def format_full_version(info
: "sys._version_info") -> str:
250 version
= "{0.major}.{0.minor}.{0.micro}".format(info
)
251 kind
= info
.releaselevel
253 version
+= kind
[0] + str(info
.serial
)
257 def default_environment() -> Dict
[str, str]:
258 iver
= format_full_version(sys
.implementation
.version
)
259 implementation_name
= sys
.implementation
.name
261 "implementation_name": implementation_name
,
262 "implementation_version": iver
,
264 "platform_machine": platform
.machine(),
265 "platform_release": platform
.release(),
266 "platform_system": platform
.system(),
267 "platform_version": platform
.version(),
268 "python_full_version": platform
.python_version(),
269 "platform_python_implementation": platform
.python_implementation(),
270 "python_version": ".".join(platform
.python_version_tuple()[:2]),
271 "sys_platform": sys
.platform
,
276 def __init__(self
, marker
: str) -> None:
278 self
._markers
= _coerce_parse_result(MARKER
.parseString(marker
))
279 except ParseException
as e
:
281 f
"Invalid marker: {marker!r}, parse error at "
282 f
"{marker[e.loc : e.loc + 8]!r}"
285 def __str__(self
) -> str:
286 return _format_marker(self
._markers
)
288 def __repr__(self
) -> str:
289 return f
"<Marker('{self}')>"
291 def evaluate(self
, environment
: Optional
[Dict
[str, str]] = None) -> bool:
292 """Evaluate a marker.
294 Return the boolean from evaluating the given marker against the
295 environment. environment is an optional argument to override all or
296 part of the determined environment.
298 The environment is determined from the current Python process.
300 current_environment
= default_environment()
301 if environment
is not None:
302 current_environment
.update(environment
)
304 return _evaluate_markers(self
._markers
, current_environment
)