dp_wizard_templates 0.3.0__py2.py3-none-any.whl → 0.4.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dp_wizard_templates might be problematic. Click here for more details.
- dp_wizard_templates/VERSION +1 -1
- dp_wizard_templates/code_template.py +52 -22
- {dp_wizard_templates-0.3.0.dist-info → dp_wizard_templates-0.4.0.dist-info}/METADATA +1 -1
- dp_wizard_templates-0.4.0.dist-info/RECORD +9 -0
- dp_wizard_templates-0.3.0.dist-info/RECORD +0 -9
- {dp_wizard_templates-0.3.0.dist-info → dp_wizard_templates-0.4.0.dist-info}/WHEEL +0 -0
- {dp_wizard_templates-0.3.0.dist-info → dp_wizard_templates-0.4.0.dist-info}/licenses/LICENSE +0 -0
dp_wizard_templates/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.4.0
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
from typing import Optional, Callable
|
|
1
|
+
from typing import Optional, Callable, Iterable
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
import inspect
|
|
4
4
|
import re
|
|
5
5
|
import black
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TemplateException(Exception):
|
|
10
|
+
pass
|
|
6
11
|
|
|
7
12
|
|
|
8
13
|
def _get_body(func):
|
|
@@ -12,46 +17,71 @@ def _get_body(func):
|
|
|
12
17
|
if not re.match(r"def \w+\((\w+(, \w+)*)?\):", first_line.strip()):
|
|
13
18
|
# Parsing to AST and unparsing is a more robust option,
|
|
14
19
|
# but more complicated.
|
|
15
|
-
raise
|
|
20
|
+
raise TemplateException(
|
|
21
|
+
f"def and parameters should fit on one line: {first_line}"
|
|
22
|
+
)
|
|
16
23
|
|
|
17
24
|
# The "def" should not be in the output,
|
|
18
25
|
# and cleandoc handles the first line differently.
|
|
19
26
|
source_lines[0] = ""
|
|
20
27
|
body = inspect.cleandoc("\n".join(source_lines))
|
|
21
|
-
|
|
22
|
-
r"\s
|
|
23
|
-
"\
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
comments_to_strip = [
|
|
29
|
+
r"\s+#\s+type:\s+ignore\s*",
|
|
30
|
+
r"\s+#\s+noqa:.+\s*",
|
|
31
|
+
r"\s+#\s+pragma:\s+no cover\s*",
|
|
32
|
+
]
|
|
33
|
+
for comment_re in comments_to_strip:
|
|
34
|
+
body = re.sub(
|
|
35
|
+
comment_re,
|
|
36
|
+
"\n",
|
|
37
|
+
body,
|
|
38
|
+
)
|
|
39
|
+
|
|
31
40
|
return body
|
|
32
41
|
|
|
33
42
|
|
|
43
|
+
def _check_repr(value):
|
|
44
|
+
"""
|
|
45
|
+
Confirms that the string returned by repr()
|
|
46
|
+
can be evaluated to recreate the original value.
|
|
47
|
+
Takes a conservative approach by checking
|
|
48
|
+
if the value can be serialized to JSON.
|
|
49
|
+
"""
|
|
50
|
+
try:
|
|
51
|
+
json.dumps(value)
|
|
52
|
+
except TypeError as e:
|
|
53
|
+
raise TemplateException(e)
|
|
54
|
+
return repr(value)
|
|
55
|
+
|
|
56
|
+
|
|
34
57
|
class Template:
|
|
35
58
|
def __init__(
|
|
36
59
|
self,
|
|
37
60
|
template: str | Callable,
|
|
38
61
|
root: Optional[Path] = None,
|
|
62
|
+
ignore: Iterable[str] = ("TODO",),
|
|
39
63
|
):
|
|
40
|
-
if root is
|
|
41
|
-
template_name = f"_{template}.py"
|
|
42
|
-
template_path = root / template_name
|
|
43
|
-
self._source = f"'{template_name}'"
|
|
44
|
-
self._template = template_path.read_text()
|
|
45
|
-
else:
|
|
64
|
+
if root is None:
|
|
46
65
|
if callable(template):
|
|
47
66
|
self._source = "function template"
|
|
48
67
|
self._template = _get_body(template)
|
|
49
68
|
else:
|
|
50
69
|
self._source = "string template"
|
|
51
70
|
self._template = template
|
|
71
|
+
else:
|
|
72
|
+
if callable(template):
|
|
73
|
+
raise TemplateException(
|
|
74
|
+
"If template is function, root kwarg not allowed"
|
|
75
|
+
)
|
|
76
|
+
else:
|
|
77
|
+
template_name = f"_{template}.py"
|
|
78
|
+
template_path = root / template_name
|
|
79
|
+
self._source = f"'{template_name}'"
|
|
80
|
+
self._template = template_path.read_text()
|
|
52
81
|
# We want a list of the initial slots, because substitutions
|
|
53
82
|
# can produce sequences of upper case letters that could be mistaken for slots.
|
|
54
83
|
self._initial_slots = self._find_slots()
|
|
84
|
+
self._ignore = ignore
|
|
55
85
|
|
|
56
86
|
def _find_slots(self) -> set[str]:
|
|
57
87
|
# Slots:
|
|
@@ -75,7 +105,7 @@ class Template:
|
|
|
75
105
|
for k, v in kwargs.items():
|
|
76
106
|
function(k, v, errors)
|
|
77
107
|
if errors:
|
|
78
|
-
raise
|
|
108
|
+
raise TemplateException(self._make_message(errors))
|
|
79
109
|
|
|
80
110
|
def _fill_inline_slots(
|
|
81
111
|
self,
|
|
@@ -141,7 +171,7 @@ class Template:
|
|
|
141
171
|
"""
|
|
142
172
|
Fill in string or numeric values. `repr` is called before filling.
|
|
143
173
|
"""
|
|
144
|
-
self._fill_inline_slots(stringifier=
|
|
174
|
+
self._fill_inline_slots(stringifier=_check_repr, **kwargs)
|
|
145
175
|
return self
|
|
146
176
|
|
|
147
177
|
def fill_code_blocks(self, **kwargs) -> "Template":
|
|
@@ -168,10 +198,10 @@ class Template:
|
|
|
168
198
|
return self
|
|
169
199
|
|
|
170
200
|
def finish(self, reformat: bool = False) -> str:
|
|
171
|
-
unfilled_slots = self._initial_slots & self._find_slots()
|
|
201
|
+
unfilled_slots = (self._initial_slots & self._find_slots()) - set(self._ignore)
|
|
172
202
|
if unfilled_slots:
|
|
173
203
|
errors = [f"'{slot}' slot not filled" for slot in unfilled_slots]
|
|
174
|
-
raise
|
|
204
|
+
raise TemplateException(self._make_message(errors))
|
|
175
205
|
|
|
176
206
|
if reformat:
|
|
177
207
|
self._template = black.format_str(self._template, mode=black.Mode())
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
dp_wizard_templates/VERSION,sha256=zXhTTtFa1GkStxM50UF9DQQ9gwnCuUQV8-0bnR_frtA,5
|
|
2
|
+
dp_wizard_templates/__init__.py,sha256=E2xrnvZGY24pU3PCryH4TmvhNYsLmxXCtfvIcYNbTYw,126
|
|
3
|
+
dp_wizard_templates/code_template.py,sha256=mHJKN0pzPHIGSF3K_ffwM1m1VPAjQ-zdwQawzPgKoQk,6606
|
|
4
|
+
dp_wizard_templates/converters.py,sha256=0Ml_V71Z6zce2SaxDQMzYXg-5jQw2-NWChrY_9SCGIo,4359
|
|
5
|
+
dp_wizard_templates/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
dp_wizard_templates-0.4.0.dist-info/licenses/LICENSE,sha256=FDrIMeZPiT4g_4w0i1Ec4Bc8h9wfNytroheQN4508yU,1063
|
|
7
|
+
dp_wizard_templates-0.4.0.dist-info/WHEEL,sha256=Dyt6SBfaasWElUrURkknVFAZDHSTwxg3PaTza7RSbkY,100
|
|
8
|
+
dp_wizard_templates-0.4.0.dist-info/METADATA,sha256=zXPD9TDjoYP-T3kIO_yJMARkU3L50Qte8zyEVLwbQYs,1881
|
|
9
|
+
dp_wizard_templates-0.4.0.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
dp_wizard_templates/VERSION,sha256=VQYTU3_EiPOzcq90pAAYefASyEZbgW8bhcbTRGss-0k,5
|
|
2
|
-
dp_wizard_templates/__init__.py,sha256=E2xrnvZGY24pU3PCryH4TmvhNYsLmxXCtfvIcYNbTYw,126
|
|
3
|
-
dp_wizard_templates/code_template.py,sha256=BAt9vsvrusqR3mETsUE4HfsPgF3D0yPHgL8Q0no01h4,5735
|
|
4
|
-
dp_wizard_templates/converters.py,sha256=0Ml_V71Z6zce2SaxDQMzYXg-5jQw2-NWChrY_9SCGIo,4359
|
|
5
|
-
dp_wizard_templates/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
dp_wizard_templates-0.3.0.dist-info/licenses/LICENSE,sha256=FDrIMeZPiT4g_4w0i1Ec4Bc8h9wfNytroheQN4508yU,1063
|
|
7
|
-
dp_wizard_templates-0.3.0.dist-info/WHEEL,sha256=Dyt6SBfaasWElUrURkknVFAZDHSTwxg3PaTza7RSbkY,100
|
|
8
|
-
dp_wizard_templates-0.3.0.dist-info/METADATA,sha256=uBCyEVM3KWsLChzbFCYT8nxjwdxvQeWMsGAKSKCiEYA,1881
|
|
9
|
-
dp_wizard_templates-0.3.0.dist-info/RECORD,,
|
|
File without changes
|
{dp_wizard_templates-0.3.0.dist-info → dp_wizard_templates-0.4.0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|