Mercurial > repos > shellac > guppy_basecaller
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) |