@@ -56,6 +56,16 @@ _NON_VERSION_VAR_NAMES = [
56
56
_AND = "and"
57
57
_OR = "or"
58
58
_NOT = "not"
59
+ _VALUE_ALIASES = {
60
+ "platform_machine" : {
61
+ # These pairs mean the same hardware, but different values may be used
62
+ # on different host platforms.
63
+ "amd64" : "x86_64" ,
64
+ "arm64" : "aarch64" ,
65
+ "i386" : "x86_32" ,
66
+ "i686" : "x86_32" ,
67
+ },
68
+ }
59
69
60
70
def tokenize (marker ):
61
71
"""Tokenize the input string.
@@ -123,13 +133,17 @@ def tokenize(marker):
123
133
124
134
return fail ("BUG: failed to process the marker in allocated cycles: {}" .format (marker ))
125
135
126
- def evaluate (marker , * , env , strict = True , ** kwargs ):
136
+ def evaluate (marker , * , env , strict = True , value_aliases = _VALUE_ALIASES , ** kwargs ):
127
137
"""Evaluate the marker against a given env.
128
138
129
139
Args:
130
- marker: {type}`str`: The string marker to evaluate.
131
- env: {type}`dict`: The environment to evaluate the marker against.
132
- strict: {type}`bool`: A setting to not fail on missing values in the env.
140
+ marker: {type}`str` The string marker to evaluate.
141
+ env: {type}`dict` The environment to evaluate the marker against.
142
+ strict: {type}`bool` A setting to not fail on missing values in the env.
143
+ value_aliases: {type}`dict` The value normalization to do for certain
144
+ fields to ensure that `aarch64` evaluation in the `platform_machine`
145
+ works the same way irrespective if the marker uses `arm64` or
146
+ `aarch64` value in the expression.
133
147
**kwargs: Extra kwargs to be passed to the expression evaluator.
134
148
135
149
Returns:
@@ -142,7 +156,7 @@ def evaluate(marker, *, env, strict = True, **kwargs):
142
156
if not tokens :
143
157
break
144
158
145
- tokens = ast .parse (env = env , tokens = tokens , strict = strict )
159
+ tokens = ast .parse (env = env , tokens = tokens , strict = strict , value_aliases = value_aliases )
146
160
147
161
if not tokens :
148
162
return ast .value ()
@@ -236,7 +250,7 @@ def _new_expr(
236
250
)
237
251
return self
238
252
239
- def _parse (self , * , env , tokens , strict = False ):
253
+ def _parse (self , * , env , tokens , strict = False , value_aliases = {} ):
240
254
"""The parse function takes the consumed tokens and returns the remaining."""
241
255
token , remaining = tokens [0 ], tokens [1 :]
242
256
@@ -251,7 +265,7 @@ def _parse(self, *, env, tokens, strict = False):
251
265
elif token == _NOT :
252
266
expr = _not_expr (self )
253
267
else :
254
- expr = marker_expr (env = env , strict = strict , * tokens [:3 ])
268
+ expr = marker_expr (env = env , strict = strict , value_aliases = value_aliases , * tokens [:3 ])
255
269
remaining = tokens [3 :]
256
270
257
271
_append (self , expr )
@@ -277,7 +291,7 @@ def _value(self):
277
291
278
292
fail ("BUG: invalid state: {}" .format (self .tree ))
279
293
280
- def marker_expr (left , op , right , * , env , strict = True ):
294
+ def marker_expr (left , op , right , * , env , strict = True , value_aliases = {} ):
281
295
"""Evaluate a marker expression
282
296
283
297
Args:
@@ -288,6 +302,7 @@ def marker_expr(left, op, right, *, env, strict = True):
288
302
in the environment, otherwise returns the original expression.
289
303
env: {type}`dict[str, str]` the `env` to substitute `env` identifiers in
290
304
the `<left> <op> <right>` expression.
305
+ value_aliases: the value normalization used for certain fields.
291
306
292
307
Returns:
293
308
{type}`bool` if the expression evaluation result or {type}`str` if the expression
@@ -300,11 +315,21 @@ def marker_expr(left, op, right, *, env, strict = True):
300
315
var_name = right
301
316
right = env [right ]
302
317
left = left .strip ("\" " )
318
+
319
+ # On Windows, Linux, OSX different values may mean the same hardware,
320
+ # e.g. Python on Windows returns arm64, but on Linux returns aarch64.
321
+ # e.g. Python on Windows returns amd64, but on Linux returns x86_64.
322
+ #
323
+ # The following normalizes the values
324
+ left = value_aliases .get (var_name , {}).get (left , left )
303
325
else :
304
326
var_name = left
305
327
left = env [left ]
306
328
right = right .strip ("\" " )
307
329
330
+ # See the note above on normalization
331
+ right = value_aliases .get (var_name , {}).get (right , right )
332
+
308
333
if var_name in _NON_VERSION_VAR_NAMES :
309
334
return _env_expr (left , op , right )
310
335
elif var_name .endswith ("_version" ):
0 commit comments