comparison env/lib/python3.7/site-packages/distlib/markers.py @ 5:9b1c78e6ba9c draft default tip

"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author shellac
date Mon, 01 Jun 2020 08:59:25 -0400
parents 79f47841a781
children
comparison
equal deleted inserted replaced
4:79f47841a781 5:9b1c78e6ba9c
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2012-2017 Vinay Sajip.
4 # Licensed to the Python Software Foundation under a contributor agreement.
5 # See LICENSE.txt and CONTRIBUTORS.txt.
6 #
7 """
8 Parser for the environment markers micro-language defined in PEP 508.
9 """
10
11 # Note: In PEP 345, the micro-language was Python compatible, so the ast
12 # module could be used to parse it. However, PEP 508 introduced operators such
13 # as ~= and === which aren't in Python, necessitating a different approach.
14
15 import os
16 import sys
17 import platform
18 import re
19
20 from .compat import python_implementation, urlparse, string_types
21 from .util import in_venv, parse_marker
22
23 __all__ = ['interpret']
24
25 def _is_literal(o):
26 if not isinstance(o, string_types) or not o:
27 return False
28 return o[0] in '\'"'
29
30 class Evaluator(object):
31 """
32 This class is used to evaluate marker expessions.
33 """
34
35 operations = {
36 '==': lambda x, y: x == y,
37 '===': lambda x, y: x == y,
38 '~=': lambda x, y: x == y or x > y,
39 '!=': lambda x, y: x != y,
40 '<': lambda x, y: x < y,
41 '<=': lambda x, y: x == y or x < y,
42 '>': lambda x, y: x > y,
43 '>=': lambda x, y: x == y or x > y,
44 'and': lambda x, y: x and y,
45 'or': lambda x, y: x or y,
46 'in': lambda x, y: x in y,
47 'not in': lambda x, y: x not in y,
48 }
49
50 def evaluate(self, expr, context):
51 """
52 Evaluate a marker expression returned by the :func:`parse_requirement`
53 function in the specified context.
54 """
55 if isinstance(expr, string_types):
56 if expr[0] in '\'"':
57 result = expr[1:-1]
58 else:
59 if expr not in context:
60 raise SyntaxError('unknown variable: %s' % expr)
61 result = context[expr]
62 else:
63 assert isinstance(expr, dict)
64 op = expr['op']
65 if op not in self.operations:
66 raise NotImplementedError('op not implemented: %s' % op)
67 elhs = expr['lhs']
68 erhs = expr['rhs']
69 if _is_literal(expr['lhs']) and _is_literal(expr['rhs']):
70 raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs))
71
72 lhs = self.evaluate(elhs, context)
73 rhs = self.evaluate(erhs, context)
74 result = self.operations[op](lhs, rhs)
75 return result
76
77 def default_context():
78 def format_full_version(info):
79 version = '%s.%s.%s' % (info.major, info.minor, info.micro)
80 kind = info.releaselevel
81 if kind != 'final':
82 version += kind[0] + str(info.serial)
83 return version
84
85 if hasattr(sys, 'implementation'):
86 implementation_version = format_full_version(sys.implementation.version)
87 implementation_name = sys.implementation.name
88 else:
89 implementation_version = '0'
90 implementation_name = ''
91
92 result = {
93 'implementation_name': implementation_name,
94 'implementation_version': implementation_version,
95 'os_name': os.name,
96 'platform_machine': platform.machine(),
97 'platform_python_implementation': platform.python_implementation(),
98 'platform_release': platform.release(),
99 'platform_system': platform.system(),
100 'platform_version': platform.version(),
101 'platform_in_venv': str(in_venv()),
102 'python_full_version': platform.python_version(),
103 'python_version': platform.python_version()[:3],
104 'sys_platform': sys.platform,
105 }
106 return result
107
108 DEFAULT_CONTEXT = default_context()
109 del default_context
110
111 evaluator = Evaluator()
112
113 def interpret(marker, execution_context=None):
114 """
115 Interpret a marker and return a result depending on environment.
116
117 :param marker: The marker to interpret.
118 :type marker: str
119 :param execution_context: The context used for name lookup.
120 :type execution_context: mapping
121 """
122 try:
123 expr, rest = parse_marker(marker)
124 except Exception as e:
125 raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e))
126 if rest and rest[0] != '#':
127 raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest))
128 context = dict(DEFAULT_CONTEXT)
129 if execution_context:
130 context.update(execution_context)
131 return evaluator.evaluate(expr, context)