Skip to content

Commit 3f77543

Browse files
committed
Decorate class directly with _log_error_with_line_context
instead of each method manually. Also makes it possibly to wrap the _docstub_comment_directives decorator and catch errors raised inside it.
1 parent 6323e9d commit 3f77543

1 file changed

Lines changed: 37 additions & 29 deletions

File tree

src/docstub/_stubs.py

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -178,38 +178,46 @@ def _get_docstring_node(node):
178178
return docstring_node
179179

180180

181-
def _log_error_with_line_context(func):
181+
def _log_error_with_line_context(cls):
182182
"""Log unexpected errors in Py2StubTransformer` with line context.
183183
184184
Parameters
185185
----------
186-
func : callable
187-
A `leave_*` method of `Py2StubTransformer`.
186+
cls : Py2StubTransformer
187+
The class whose methods will be decorated.
188188
189189
Returns
190190
-------
191-
wrapped : callable
191+
updated_cls : Py2StubTransformer
192+
The modified class.
192193
"""
193194

194-
@wraps(func)
195-
def wrapped(self: "Py2StubTransformer", original_node, updated_node):
196-
try:
197-
return func(self, original_node, updated_node)
198-
except (SystemError, KeyboardInterrupt):
199-
raise
200-
except Exception:
201-
position = self.get_metadata(
202-
cst.metadata.PositionProvider, original_node
203-
).start
204-
logger.exception(
205-
"unexpected exception at %s:%s", self.current_source, position.line
206-
)
207-
return updated_node
195+
def wrap(func):
196+
@wraps(func)
197+
def wrapped(self, original_node, updated_node):
198+
try:
199+
return func(self, original_node, updated_node)
200+
except (SystemError, KeyboardInterrupt):
201+
raise
202+
except Exception:
203+
position = self.get_metadata(
204+
cst.metadata.PositionProvider, original_node
205+
).start
206+
logger.exception(
207+
"unexpected exception at %s:%s", self.current_source, position.line
208+
)
209+
return updated_node
210+
211+
return wrapped
208212

209-
return wrapped
213+
for attr_name, attr_value in cls.__dict__.items():
214+
if attr_name.startswith("leave_"):
215+
setattr(cls, attr_name, wrap(attr_value))
210216

217+
return cls
211218

212-
def _docstub_comment_directives(transformer_cls):
219+
220+
def _docstub_comment_directives(cls):
213221
"""Handle `Py2StubTransformer` docstub directives.
214222
215223
This handles the comment directives ``# docstub: off`` and``# docstub: on``.
@@ -218,12 +226,12 @@ def _docstub_comment_directives(transformer_cls):
218226
219227
Parameters
220228
----------
221-
transformer_cls : Py2StubTransformer
229+
cls : Py2StubTransformer
222230
The class whose methods will be decorated.
223231
224232
Returns
225233
-------
226-
wrapped_cls : Py2StubTransformer
234+
updated_cls : Py2StubTransformer
227235
The modified class.
228236
229237
Notes
@@ -265,15 +273,18 @@ def wrapped(self, original_node, updated_node):
265273

266274
return wrapped
267275

268-
for attr_name, attr_value in transformer_cls.__dict__.items():
276+
assert hasattr(cls, "leave_Comment")
277+
278+
for attr_name, attr_value in cls.__dict__.items():
269279
if attr_name == "leave_Comment":
270-
setattr(transformer_cls, attr_name, wrap_leave_Comment(attr_value))
280+
setattr(cls, attr_name, wrap_leave_Comment(attr_value))
271281
elif attr_name.startswith("leave_"):
272-
setattr(transformer_cls, attr_name, wrap_leave(attr_value))
282+
setattr(cls, attr_name, wrap_leave(attr_value))
273283

274-
return transformer_cls
284+
return cls
275285

276286

287+
@_log_error_with_line_context
277288
@_docstub_comment_directives
278289
class Py2StubTransformer(cst.CSTTransformer):
279290
"""Transform syntax tree of a Python file into the tree of a stub file [1]_.
@@ -511,7 +522,6 @@ def leave_FunctionDef(self, original_node, updated_node):
511522
self._scope_stack.pop()
512523
return updated_node
513524

514-
@_log_error_with_line_context
515525
def leave_Param(self, original_node, updated_node):
516526
"""Add type annotation to parameter.
517527
@@ -594,7 +604,6 @@ def leave_Comment(self, original_node, updated_node):
594604
return updated_node
595605
return cst.RemovalSentinel.REMOVE
596606

597-
@_log_error_with_line_context
598607
def leave_Assign(self, original_node, updated_node):
599608
"""Handle assignment statements without annotations.
600609
@@ -638,7 +647,6 @@ def leave_Assign(self, original_node, updated_node):
638647

639648
return updated_node
640649

641-
@_log_error_with_line_context
642650
def leave_AnnAssign(self, original_node, updated_node):
643651
"""Handle annotated assignment statements.
644652

0 commit comments

Comments
 (0)