diff --git a/CHANGELOG.md b/CHANGELOG.md index 94b4c5f..a75a2e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ - Changed - Command line message about loading config file is now hidden with config option `--quiet` +- Fixed + - Fixed a bug where assigning a value to an attribute caused pydoclint to + crash ## [0.5.9] - 2024-09-29 diff --git a/pydoclint/utils/arg.py b/pydoclint/utils/arg.py index c74b2c9..a021e07 100644 --- a/pydoclint/utils/arg.py +++ b/pydoclint/utils/arg.py @@ -92,7 +92,7 @@ def fromAstArg(cls, astArg: ast.arg) -> 'Arg': def fromAstAnnAssign(cls, astAnnAssign: ast.AnnAssign) -> 'Arg': """Construct an Arg object from a Python ast.AnnAssign object""" return Arg( - name=astAnnAssign.target.id, + name=unparseAnnotation(astAnnAssign.target), typeHint=unparseAnnotation(astAnnAssign.annotation), ) @@ -220,6 +220,10 @@ def fromAstAssign(cls, astAssign: ast.Assign) -> 'ArgList': infoList.append(Arg(name=item.id, typeHint='')) elif isinstance(target, ast.Name): # such as `a = 1` or `a = b = 2` infoList.append(Arg(name=target.id, typeHint='')) + elif isinstance(target, ast.Attribute): # e.g., uvw.xyz = 1 + infoList.append( + Arg(name=unparseAnnotation(target), typeHint='') + ) else: raise InternalError( f'astAssign.targets[{i}] is of type {type(target)}' diff --git a/tests/data/edge_cases/16_assign_to_attr/cases.py b/tests/data/edge_cases/16_assign_to_attr/cases.py new file mode 100644 index 0000000..5737de3 --- /dev/null +++ b/tests/data/edge_cases/16_assign_to_attr/cases.py @@ -0,0 +1,12 @@ +# From https://github.com/jsh9/pydoclint/issues/180 + + +class MyClass: + def large_drawing(self, obj): + return self.drawing(obj, size=500, center=False) + + large_drawing.descr_1: str = 'Drawing' + + # Non-self attribute should not be type hinted, because this could lead to + # potential ambiguities. See more: https://stackoverflow.com/a/77831273 + large_drawing.descr_2: str = 'Drawing' diff --git a/tests/test_main.py b/tests/test_main.py index 0a68f60..d319a48 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1459,6 +1459,9 @@ def testNonAscii() -> None: ('15_very_long_annotations/sphinx.py', {'style': 'sphinx'}, []), ('15_very_long_annotations/google.py', {'style': 'google'}, []), ('15_very_long_annotations/numpy.py', {'style': 'numpy'}, []), + ('16_assign_to_attr/cases.py', {'style': 'sphinx'}, []), + ('16_assign_to_attr/cases.py', {'style': 'google'}, []), + ('16_assign_to_attr/cases.py', {'style': 'numpy'}, []), ], ) def testEdgeCases(