Python source code parser to pick up variable comments.
| 237 | |
| 238 | |
| 239 | class VariableCommentPicker(ast.NodeVisitor): |
| 240 | """Python source code parser to pick up variable comments.""" |
| 241 | |
| 242 | def __init__(self, buffers: list[str], encoding: str) -> None: |
| 243 | self.counter = itertools.count() |
| 244 | self.buffers = buffers |
| 245 | self.encoding = encoding |
| 246 | self.context: list[str] = [] |
| 247 | self.current_classes: list[str] = [] |
| 248 | self.current_function: ast.FunctionDef | None = None |
| 249 | self.comments: dict[tuple[str, str], str] = {} |
| 250 | self.annotations: dict[tuple[str, str], str] = {} |
| 251 | self.previous: ast.AST | None = None |
| 252 | self.deforders: dict[str, int] = {} |
| 253 | self.finals: list[str] = [] |
| 254 | self.overloads: dict[str, list[Signature]] = {} |
| 255 | self.typing_mods: set[str] = set() |
| 256 | self.typing_final_names: set[str] = set() |
| 257 | self.typing_overload_names: set[str] = set() |
| 258 | super().__init__() |
| 259 | |
| 260 | def get_qualname_for(self, name: str) -> list[str] | None: |
| 261 | """Get qualified name for given object as a list of string(s).""" |
| 262 | if self.current_function: |
| 263 | if self.current_classes and self.context[-1] == '__init__': |
| 264 | # store variable comments inside __init__ method of classes |
| 265 | return [*self.context[:-1], name] |
| 266 | else: |
| 267 | return None |
| 268 | else: |
| 269 | return [*self.context, name] |
| 270 | |
| 271 | def add_entry(self, name: str) -> None: |
| 272 | qualname = self.get_qualname_for(name) |
| 273 | if qualname: |
| 274 | self.deforders['.'.join(qualname)] = next(self.counter) |
| 275 | |
| 276 | def add_final_entry(self, name: str) -> None: |
| 277 | qualname = self.get_qualname_for(name) |
| 278 | if qualname: |
| 279 | self.finals.append('.'.join(qualname)) |
| 280 | |
| 281 | def add_overload_entry(self, func: ast.FunctionDef) -> None: |
| 282 | # avoid circular import problem |
| 283 | from sphinx.util.inspect import signature_from_ast |
| 284 | |
| 285 | qualname = self.get_qualname_for(func.name) |
| 286 | if qualname: |
| 287 | overloads = self.overloads.setdefault('.'.join(qualname), []) |
| 288 | overloads.append(signature_from_ast(func)) |
| 289 | |
| 290 | def add_variable_comment(self, name: str, comment: str) -> None: |
| 291 | qualname = self.get_qualname_for(name) |
| 292 | if qualname: |
| 293 | basename = '.'.join(qualname[:-1]) |
| 294 | self.comments[basename, name] = comment |
| 295 | |
| 296 | def add_variable_annotation(self, name: str, annotation: ast.AST) -> None: |
no outgoing calls
no test coverage detected
searching dependent graphs…