@@ -4,21 +4,55 @@ load("//python/private:version.bzl", "version")
4
4
load (":parse_whl_name.bzl" , "parse_whl_name" )
5
5
load (":python_tag.bzl" , "PY_TAG_GENERIC" , "python_tag" )
6
6
7
- def _get_priority (* , tag , values , allow_wildcard = True ):
7
+ def _get_priority (* , tags , values , allow_wildcard = True ):
8
+ keys = []
8
9
for priority , wp in enumerate (values ):
9
- head , sep , tail = wp .partition ("*" )
10
- if "*" in tail :
11
- fail ("only a single '*' can be present in the matcher" )
12
- if not allow_wildcard and sep :
13
- fail ("'*' is not allowed in the matcher" )
10
+ for tag in tags .split ("." ):
11
+ head , sep , tail = wp .partition ("*" )
12
+ if "*" in tail :
13
+ fail ("only a single '*' can be present in the matcher" )
14
+ if not allow_wildcard and sep :
15
+ fail ("'*' is not allowed in the matcher" )
16
+
17
+ if not sep and tag == head :
18
+ keys .append (priority )
19
+ elif sep and tag .startswith (head ) and tag .endswith (tail ):
20
+ keys .append (priority )
21
+
22
+ if not keys :
23
+ return None
24
+
25
+ return max (keys )
26
+
27
+ def _get_py_priority (* , tags , implementation , py_version ):
28
+ keys = []
29
+ for tag in tags .split ("." ):
30
+ if tag .startswith (PY_TAG_GENERIC ):
31
+ ver_str = tag [len (PY_TAG_GENERIC ):]
32
+ elif tag .startswith (implementation ):
33
+ ver_str = tag [len (implementation ):]
34
+ else :
35
+ continue
36
+
37
+ # Add a 0 at the end in case it is a single digit
38
+ ver_str = "{}.{}" .format (ver_str [0 ], ver_str [1 :] or "0" )
39
+
40
+ ver = version .parse (ver_str )
41
+ if not version .is_compatible (py_version , ver ):
42
+ continue
43
+
44
+ keys .append ((
45
+ tag .startswith (implementation ),
46
+ version .key (ver ),
47
+ # Prefer shorter py_tags, which will yield more specialized matches,
48
+ # like preferring py3 over py2.py3
49
+ - len (tags ),
50
+ ))
14
51
15
- for p in tag .split ("." ):
16
- if not sep and p == head :
17
- return priority
18
- elif sep and p .startswith (head ) and p .endswith (tail ):
19
- return priority
52
+ if not keys :
53
+ return None
20
54
21
- return None
55
+ return max ( keys )
22
56
23
57
def select_whl (* , whls , python_version , platforms , whl_abi_tags , implementation_name = "cpython" , limit = 1 , logger = None ):
24
58
"""Select a whl that is the most suitable for the given platform.
@@ -56,26 +90,22 @@ def select_whl(*, whls, python_version, platforms, whl_abi_tags, implementation_
56
90
))
57
91
continue
58
92
59
- if parsed .python_tag == "py2.py3" :
60
- min_version = "2"
61
- else :
62
- min_version = parsed .python_tag [len (implementation ):]
63
-
64
- if len (min_version ) > 1 :
65
- min_version = "{}.{}" .format (min_version [0 ], min_version [1 :])
66
-
67
- min_whl_py_version = version .parse (min_version , strict = True )
68
- if not version .is_ge (py_version , min_whl_py_version ):
93
+ py_priority = _get_py_priority (
94
+ tags = parsed .python_tag ,
95
+ implementation = implementation ,
96
+ py_version = py_version ,
97
+ )
98
+ if py_priority == None :
69
99
if logger :
70
- logger .debug (lambda : "Discarding the wheel because the min version supported based on the wheel ABI tag '{}' ({}) is not compatible with the provided target Python version '{}' " .format (
71
- parsed .abi_tag ,
72
- min_whl_py_version . string ,
100
+ logger .debug (lambda : "The py_tag '{}' does not match implementation version: {} {} " .format (
101
+ parsed .py_tag ,
102
+ implementation ,
73
103
py_version .string ,
74
104
))
75
105
continue
76
106
77
107
abi_priority = _get_priority (
78
- tag = parsed .abi_tag ,
108
+ tags = parsed .abi_tag ,
79
109
values = whl_abi_tags ,
80
110
allow_wildcard = False ,
81
111
)
@@ -86,8 +116,9 @@ def select_whl(*, whls, python_version, platforms, whl_abi_tags, implementation_
86
116
whl_abi_tags ,
87
117
))
88
118
continue
119
+
89
120
platform_priority = _get_priority (
90
- tag = parsed .platform_tag ,
121
+ tags = parsed .platform_tag ,
91
122
values = platforms ,
92
123
)
93
124
if platform_priority == None :
@@ -100,10 +131,8 @@ def select_whl(*, whls, python_version, platforms, whl_abi_tags, implementation_
100
131
101
132
key = (
102
133
# Ensure that we chose the highest compatible version
103
- parsed . python_tag . startswith ( implementation ) ,
134
+ py_priority ,
104
135
platform_priority ,
105
- # prefer abi_tags in this order
106
- version .key (min_whl_py_version ),
107
136
abi_priority ,
108
137
)
109
138
candidates .setdefault (key , whl )
0 commit comments