|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 | 3 | import ast
|
| 4 | +from typing import Any |
4 | 5 |
|
5 | 6 | from docstring_parser.common import DocstringAttr, DocstringParam
|
6 | 7 |
|
@@ -217,34 +218,56 @@ def fromAstAssign(cls, astAssign: ast.Assign) -> 'ArgList':
|
217 | 218 | for i, target in enumerate(astAssign.targets):
|
218 | 219 | if isinstance(target, ast.Tuple): # such as `a, b = c, d = 1, 2`
|
219 | 220 | for j, item in enumerate(target.elts):
|
220 |
| - if not isinstance(item, ast.Name): |
221 |
| - raise EdgeCaseError( |
222 |
| - f'astAssign.targets[{i}].elts[{j}] is of' |
223 |
| - f' type {type(item)} instead of ast.Name' |
224 |
| - ) |
225 |
| - |
226 |
| - infoList.append(Arg(name=item.id, typeHint='')) |
227 |
| - elif isinstance(target, ast.Name): # such as `a = 1` or `a = b = 2` |
228 |
| - infoList.append(Arg(name=target.id, typeHint='')) |
229 |
| - else: |
230 |
| - try: # we may not know all potential cases, so we use try/catch |
231 |
| - unparsedTarget: str | None = unparseName(target) |
232 |
| - assert unparsedTarget is not None # to help mypy understand type |
233 |
| - infoList.append(Arg(name=unparsedTarget, typeHint='')) |
234 |
| - except Exception as ex: |
235 |
| - lineRange: str = ( |
236 |
| - f'in Line {astAssign.lineno}' |
237 |
| - if astAssign.lineno == astAssign.end_lineno |
238 |
| - else f'in Lines {astAssign.lineno}-{astAssign.end_lineno}' |
239 |
| - ) |
240 |
| - msg: str = ( |
241 |
| - f'Edge case encountered {lineRange}.' |
242 |
| - f' astAssign.targets[{i}] is of type {type(target)}.' |
| 221 | + cls._unparseTargetAndAppendToInfoList( |
| 222 | + target=item, |
| 223 | + infoList=infoList, |
| 224 | + lineNum=astAssign.lineno, |
| 225 | + endLineNum=astAssign.end_lineno, |
| 226 | + i=i, |
| 227 | + j=j, |
243 | 228 | )
|
244 |
| - raise EdgeCaseError(msg) from ex |
| 229 | + else: # a single element |
| 230 | + cls._unparseTargetAndAppendToInfoList( |
| 231 | + target=target, |
| 232 | + infoList=infoList, |
| 233 | + lineNum=astAssign.lineno, |
| 234 | + endLineNum=astAssign.end_lineno, |
| 235 | + i=i, |
| 236 | + j=None, |
| 237 | + ) |
245 | 238 |
|
246 | 239 | return ArgList(infoList=infoList)
|
247 | 240 |
|
| 241 | + @classmethod |
| 242 | + def _unparseTargetAndAppendToInfoList( |
| 243 | + cls, |
| 244 | + *, |
| 245 | + target: Any, |
| 246 | + infoList: list[Arg], |
| 247 | + lineNum: int | None, |
| 248 | + endLineNum: int | None, |
| 249 | + i: int, |
| 250 | + j: int | None = None, |
| 251 | + ) -> None: |
| 252 | + try: # we may not know all potential cases, so we use try/catch |
| 253 | + unparsedTarget: str | None = unparseName(target) |
| 254 | + assert unparsedTarget is not None # to help mypy understand type |
| 255 | + infoList.append(Arg(name=unparsedTarget, typeHint='')) |
| 256 | + except Exception as ex: |
| 257 | + lineRange: str = ( |
| 258 | + f'in Line {lineNum}' |
| 259 | + if lineNum == endLineNum |
| 260 | + else f'in Lines {lineNum}-{endLineNum}' |
| 261 | + ) |
| 262 | + msg1: str = f'Edge case encountered {lineRange}.' |
| 263 | + msg2: str = ( |
| 264 | + f' astAssign.targets[{i}] is of type {type(target)}.' |
| 265 | + if j is None |
| 266 | + else f' astAssign.targets[{i}].elts[{j}] is of type {type(target)}.' |
| 267 | + ) |
| 268 | + msg: str = msg1 + msg2 |
| 269 | + raise EdgeCaseError(msg) from ex |
| 270 | + |
248 | 271 | def contains(self, arg: Arg) -> bool:
|
249 | 272 | """Whether a given `Arg` object exists in the list"""
|
250 | 273 | return arg.name in self.lookup
|
|
0 commit comments