# -*- coding: utf-8 -*- # # Copyright (C) 2012-2023 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # """
Parser for the environment markers micro-language defined in PEP 508. """
# Note: In PEP 345, the micro-language was Python compatible, so the ast # module could be used to parse it. However, PEP 508 introduced operators such # as ~= and === which aren't in Python, necessitating a different approach.
import os import re import sys import platform
from .compat import string_types from .util import in_venv, parse_marker from .version import LegacyVersion as LV
def _get_versions(s): return {LV(m.groups()[0]) for m in _VERSION_PATTERN.finditer(s)}
class Evaluator(object): """
This classis used to evaluate marker expressions. """
operations = { '==': lambda x, y: x == y, '===': lambda x, y: x == y, '~=': lambda x, y: x == y or x > y, '!=': lambda x, y: x != y, '<': lambda x, y: x < y, '<=': lambda x, y: x == y or x < y, '>': lambda x, y: x > y, '>=': lambda x, y: x == y or x > y, 'and': lambda x, y: x and y, 'or': lambda x, y: x or y, 'in': lambda x, y: x in y, 'not in': lambda x, y: x notin y,
}
def evaluate(self, expr, context): """
Evaluate a marker expression returned by the :func:`parse_requirement`
function in the specified context. """ if isinstance(expr, string_types): if expr[0] in'\'"':
result = expr[1:-1] else: if expr notin context: raise SyntaxError('unknown variable: %s' % expr)
result = context[expr] else: assert isinstance(expr, dict)
op = expr['op'] if op notin self.operations: raise NotImplementedError('op not implemented: %s' % op)
elhs = expr['lhs']
erhs = expr['rhs'] if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): raise SyntaxError('invalid comparison: %s %s %s' %
(elhs, op, erhs))
lhs = self.evaluate(elhs, context)
rhs = self.evaluate(erhs, context) if ((_is_version_marker(elhs) or _is_version_marker(erhs)) and op in ('<', '<=', '>', '>=', '===', '==', '!=', '~=')):
lhs = LV(lhs)
rhs = LV(rhs) elif _is_version_marker(elhs) and op in ('in', 'not in'):
lhs = LV(lhs)
rhs = _get_versions(rhs)
result = self.operations[op](lhs, rhs) return result
_DIGITS = re.compile(r'\d+\.\d+')
def default_context():
def format_full_version(info):
version = '%s.%s.%s' % (info.major, info.minor, info.micro)
kind = info.releaselevel if kind != 'final':
version += kind[0] + str(info.serial) return version
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.