7
7
8
8
from hatchling .version .source .plugin .interface import VersionSourceInterface
9
9
10
+ PRE_PATTERN = r"""
11
+ (?P<{prefix}pre_l>(a|b|c|rc|alpha|beta|pre|preview))
12
+ [-.]?
13
+ (?P<{prefix}pre_n>[0-9]+)?
14
+
15
+ """
16
+ DEV_PATTERN = r"""
17
+ dev
18
+ [-.]?
19
+ (?P<{prefix}dev_n>[0-9]+)?
20
+ """
21
+
10
22
# The Python-aware NodeJS version regex
11
23
# This is very similar to `packaging.version.VERSION_PATTERN`, with a few changes:
12
24
# - Don't accept underscores
13
25
# - Only support four-component release, prerelease, and build segments
14
26
# - Require - to indicate prerelease
15
- NODE_VERSION_PATTERN = r """
27
+ NODE_VERSION_PATTERN = rf """
16
28
(?P<major>[0-9]+) # major
17
29
\.
18
30
(?P<minor>[0-9]+) # minor
19
31
\.
20
32
(?P<patch>[0-9]+) # patch
21
- (?P<pre> # pre-release
33
+ (?:
34
+ (?P<pre_only> # pre-release
22
35
-
23
- (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
24
- [-\.]?
25
- (?P<pre_n>[0-9]+)?
36
+ { PRE_PATTERN .format (prefix = "pre_only_" )}
37
+ ) |
38
+ (?P<dev_only> # dev
39
+ -
40
+ { DEV_PATTERN .format (prefix = "dev_only_" )}
41
+ ) |
42
+ (?P<pre_dev> # pre-release and dev
43
+ -
44
+ { PRE_PATTERN .format (prefix = "pre_dev_" )}
45
+ \.
46
+ { DEV_PATTERN .format (prefix = "pre_dev_" )}
47
+ )
26
48
)?
27
49
(?:
28
50
\+
40
62
41
63
# The NodeJS-aware Python version regex
42
64
# This is very similar to `packaging.version.VERSION_PATTERN`, with a few changes:
43
- # - Only support four -component release, prerelease, and build segments
65
+ # - Only support five -component release, prerelease, dev , and build segments
44
66
PYTHON_VERSION_PATTERN = r"""
45
67
v?
46
68
(?:
50
72
\.
51
73
(?P<patch>[0-9]+) # patch
52
74
(?P<pre> # pre-release
53
- [-_\ .]?
75
+ [-_.]?
54
76
(?P<pre_l>(alpha|beta|preview|a|b|c|rc|pre))
55
- [-_\ .]?
77
+ [-_.]?
56
78
(?P<pre_n>[0-9]+)?
57
79
)?
58
- (?:
80
+ (?P<dev>
81
+ [-_.]?
82
+ dev
83
+ (?P<dev_n>[0-9]+)
84
+ )?
85
+ (?: # local version number
59
86
\+
60
87
(?P<local>
61
88
[0-9A-Za-z][0-9A-Za-z-_]* # non-hyphen/dash leading identifier
@@ -105,16 +132,31 @@ def node_version_to_python(version: str) -> str:
105
132
if match is None :
106
133
raise ValueError (f"Version { version !r} did not match regex" )
107
134
108
- parts = ["{major}.{minor}.{patch}" .format_map (match )]
135
+ groups = {}
136
+ for key , value in match .groupdict ().items ():
137
+ key = re .sub ("pre_dev_|pre_only_|dev_only_" , "" , key )
138
+ if key not in groups :
139
+ groups [key ] = value
140
+ elif value is not None :
141
+ groups [key ] = value
109
142
110
- if match ["pre" ]:
111
- if match ["pre_n" ] is None :
112
- parts .append ("{pre_l}" .format_map (match ))
143
+ del match
144
+ parts = ["{major}.{minor}.{patch}" .format_map (groups )]
145
+
146
+ if groups ["pre_only" ] or groups ["pre_dev" ]:
147
+ if groups ["pre_n" ] is None :
148
+ parts .append ("{pre_l}" .format_map (groups ))
113
149
else :
114
- parts .append ("{pre_l}{pre_n}" .format_map (match ))
150
+ parts .append ("{pre_l}{pre_n}" .format_map (groups ))
115
151
116
- if match ["build" ]:
117
- parts .append ("+{build}" .format_map (match ))
152
+ if groups ["dev_only" ] or groups ["pre_dev" ]:
153
+ if groups ["dev_n" ] is None :
154
+ parts .append ("dev0" )
155
+ else :
156
+ parts .append ("dev{dev_n}" .format_map (groups ))
157
+
158
+ if groups ["build" ]:
159
+ parts .append ("+{build}" .format_map (groups ))
118
160
119
161
return "" .join (parts )
120
162
@@ -137,6 +179,12 @@ def python_version_to_node(version: str) -> str:
137
179
else :
138
180
parts .append ("-{pre_l}{pre_n}" .format_map (match ))
139
181
182
+ if match ["dev" ]:
183
+ if match ["pre" ]:
184
+ parts .append (".dev{dev_n}" .format_map (match ))
185
+ else :
186
+ parts .append ("-dev{dev_n}" .format_map (match ))
187
+
140
188
if match ["local" ]:
141
189
parts .append ("+{local}" .format_map (match ))
142
190
return "" .join (parts )
0 commit comments