5
5
# https://www.python.org/dev/peps/pep-0503/#normalized-names.
6
6
7
7
import re
8
+ from enum import Enum
8
9
from functools import partial
9
10
from typing import Dict , Iterable , Match , Tuple
10
11
11
12
12
- def all_hyphen_to_dot (m : Match [str ]) -> str :
13
- """Convert all hyphens to dots e.g. azure-foo-bar -> azure.foo.bar.
13
+ class PackageSeparator (Enum ):
14
+ DOT = "."
15
+ UNDERSCORE = "_"
16
+ NONE = ""
14
17
15
- >>> all_hyphen_to_dot(re.match(r"^azure-.+", "azure-foo-bar"))
18
+
19
+ def all_hyphen_to_separator (m : Match [str ], separator : PackageSeparator ) -> str :
20
+ """Convert all hyphens to a package separator e.g. azure-foo-bar -> azure.foo.bar or
21
+ azure_foo_bar.
22
+
23
+ >>> all_hyphen_to_separator(re.match(r"^azure-.+", "azure-foo-bar"), PackageSeparator.DOT)
16
24
'azure.foo.bar'
25
+ >>> all_hyphen_to_separator(re.match(r"^azure-.+", "azure-foo-bar"), PackageSeparator.UNDERSCORE)
26
+ 'azure_foo_bar'
27
+ >>> all_hyphen_to_separator(re.match(r"^azure-.+", "azure-foo-bar"), PackageSeparator.NONE)
28
+ 'azurefoobar'
17
29
"""
18
- return m .string .replace ("-" , "." )
30
+ return m .string .replace ("-" , separator . value )
19
31
20
32
21
- def first_group_hyphen_to_underscore (m : Match [str ]) -> str :
33
+ def first_group_hyphen_to_separator (m : Match [str ], separator : PackageSeparator ) -> str :
22
34
"""Convert the first group(regex match group) of hyphens to underscores. Only returns the first
23
35
group and must contain at least one group.
24
36
25
- >>> first_group_hyphen_to_underscore (re.match(r"^django-((.+(-.+)?))", "django-admin-cursor-paginator"))
37
+ >>> first_group_hyphen_to_separator (re.match(r"^django-((.+(-.+)?))", "django-admin-cursor-paginator"), separator=PackageSeparator.UNDERSCORE )
26
38
'admin_cursor_paginator'
39
+ >>> first_group_hyphen_to_separator(re.match(r"^django-((.+(-.+)?))", "django-admin-cursor-paginator"), separator=PackageSeparator.DOT)
40
+ 'admin.cursor.paginator'
41
+ >>> first_group_hyphen_to_separator(re.match(r"^django-((.+(-.+)?))", "django-admin-cursor-paginator"), separator=PackageSeparator.NONE)
42
+ 'admincursorpaginator'
27
43
"""
28
44
if m .re .groups == 0 or not m .groups ():
29
45
raise ValueError (f"expected at least one group in the pattern{ m .re .pattern } but got none." )
30
- return str (m .groups ()[0 ]).replace ("-" , "_" )
46
+ return str (m .groups ()[0 ]).replace ("-" , separator . value )
31
47
32
48
33
49
def two_groups_hyphens_two_replacements_with_suffix (
34
50
m : Match [str ],
35
- first_group_replacement : str = "." ,
36
- second_group_replacement : str = "" ,
51
+ first_group_replacement : PackageSeparator = PackageSeparator . DOT ,
52
+ second_group_replacement : PackageSeparator = PackageSeparator . NONE ,
37
53
custom_suffix : str = "" ,
38
54
) -> str :
39
55
"""take two groups, and by default, the first will have '-' replaced with '.', the second will
40
56
have '-' replaced with '' e.g. google-cloud-foo-bar -> group1(google.cloud.)group2(foobar)
41
57
42
58
>>> two_groups_hyphens_two_replacements_with_suffix(re.match(r"^(google-cloud-)([^.]+)", "google-cloud-foo-bar"))
43
59
'google.cloud.foobar'
60
+ >>> two_groups_hyphens_two_replacements_with_suffix(re.match(r"^(google-cloud-)([^.]+)", "google-cloud-foo-bar"), first_group_replacement=PackageSeparator.UNDERSCORE, second_group_replacement=PackageSeparator.DOT)
61
+ 'google_cloud_foo.bar'
44
62
"""
45
63
if m .re .groups < 2 or not m .groups ():
46
64
raise ValueError (f"expected at least two groups in the pattern{ m .re .pattern } ." )
47
- prefix = m .string [m .start (1 ) : m .end (1 )].replace ("-" , first_group_replacement )
48
- suffix = m .string [m .start (2 ) : m .end (2 )].replace ("-" , second_group_replacement )
65
+ prefix = m .string [m .start (1 ) : m .end (1 )].replace ("-" , first_group_replacement . value )
66
+ suffix = m .string [m .start (2 ) : m .end (2 )].replace ("-" , second_group_replacement . value )
49
67
return f"{ prefix } { suffix } { custom_suffix } "
50
68
51
69
70
+ def only_preserve_group (m : Match [str ]) -> str :
71
+ """Preseve the first and only group.
72
+
73
+ >>> only_preserve_group(re.match(r"^prefix_(.+)", "prefix_foo"))
74
+ 'foo'
75
+ >>> only_preserve_group(re.match(r"^(.+)_suffix", "bar_suffix"))
76
+ 'bar'
77
+ """
78
+ if m .re .groups != 1 or not m .groups ():
79
+ raise ValueError (f"expected exactly one group in the pattern{ m .re .pattern } ." )
80
+ return m .group (1 )
81
+
82
+
83
+ # common replacement methods
84
+ all_hyphen_to_dot = partial (all_hyphen_to_separator , separator = PackageSeparator .DOT )
85
+ all_hyphen_to_underscore = partial (all_hyphen_to_separator , separator = PackageSeparator .UNDERSCORE )
86
+ first_group_hyphen_to_dot = partial (first_group_hyphen_to_separator , separator = PackageSeparator .DOT )
87
+ first_group_hyphen_to_underscore = partial (
88
+ first_group_hyphen_to_separator , separator = PackageSeparator .UNDERSCORE
89
+ )
90
+
52
91
"""
53
92
A mapping of Patterns and their replacements. will be used with `re.sub`.
54
93
The match is either a string or a function`(str) -> str`; that takes a re.Match and returns
@@ -67,9 +106,13 @@ def two_groups_hyphens_two_replacements_with_suffix(
67
106
for custom_suffix in ("" , "_v1" , "_v2" , "_v3" )
68
107
],
69
108
re .compile (r"""^(opentelemetry-instrumentation-)([^.]+)""" ): [
70
- partial (two_groups_hyphens_two_replacements_with_suffix , second_group_replacement = "_" ),
109
+ partial (
110
+ two_groups_hyphens_two_replacements_with_suffix ,
111
+ second_group_replacement = "_" ,
112
+ ),
71
113
],
72
- re .compile (r"""^(oslo-.+)""" ): [first_group_hyphen_to_underscore ],
114
+ re .compile (r"""^oslo-.+""" ): [all_hyphen_to_underscore ],
115
+ re .compile (r"""^python-(.+)""" ): [first_group_hyphen_to_underscore ],
73
116
re .compile (r"""^python-(.+)""" ): [first_group_hyphen_to_underscore ],
74
117
}
75
118
@@ -159,6 +202,14 @@ def two_groups_hyphens_two_replacements_with_suffix(
159
202
"websocket-client" : ("websocket" ,),
160
203
}
161
204
205
+ DEFAULT_TYPE_STUB_MODULE_PATTERN_MAPPING : Dict [re .Pattern , Iterable ] = {
206
+ re .compile (r"""^mypy-boto3-.+""" ): [all_hyphen_to_underscore ],
207
+ re .compile (r"""^stubs_(.+)""" ): [only_preserve_group ],
208
+ re .compile (r"""^types_(.+)""" ): [only_preserve_group ],
209
+ re .compile (r"""^(.+)_stubs""" ): [only_preserve_group ],
210
+ re .compile (r"""^(.+)_types""" ): [only_preserve_group ],
211
+ }
212
+
162
213
DEFAULT_TYPE_STUB_MODULE_MAPPING = {
163
214
"djangorestframework-types" : ("rest_framework" ,),
164
215
"lark-stubs" : ("lark" ,),
0 commit comments