| 453 | |
| 454 | |
| 455 | class GettextVisitor(ast.NodeVisitor): |
| 456 | def __init__(self, options): |
| 457 | super().__init__() |
| 458 | self.options = options |
| 459 | self.filename = None |
| 460 | self.messages = {} |
| 461 | self.comments = {} |
| 462 | |
| 463 | def visit_file(self, source, filename): |
| 464 | try: |
| 465 | module_tree = ast.parse(source) |
| 466 | except SyntaxError: |
| 467 | return |
| 468 | |
| 469 | self.filename = filename |
| 470 | if self.options.comment_tags: |
| 471 | self.comments = get_source_comments(source) |
| 472 | self.visit(module_tree) |
| 473 | |
| 474 | def visit_Module(self, node): |
| 475 | self._extract_docstring(node) |
| 476 | self.generic_visit(node) |
| 477 | |
| 478 | visit_ClassDef = visit_FunctionDef = visit_AsyncFunctionDef = visit_Module |
| 479 | |
| 480 | def visit_Call(self, node): |
| 481 | self._extract_message(node) |
| 482 | self.generic_visit(node) |
| 483 | |
| 484 | def _extract_docstring(self, node): |
| 485 | if (not self.options.docstrings or |
| 486 | self.options.nodocstrings.get(self.filename)): |
| 487 | return |
| 488 | |
| 489 | docstring = ast.get_docstring(node) |
| 490 | if docstring is not None: |
| 491 | lineno = node.body[0].lineno # The first statement is the docstring |
| 492 | self._add_message(lineno, docstring, is_docstring=True) |
| 493 | |
| 494 | def _extract_message(self, node): |
| 495 | func_name = self._get_func_name(node) |
| 496 | errors = [] |
| 497 | specs = self.options.keywords.get(func_name, []) |
| 498 | for spec in specs: |
| 499 | err = self._extract_message_with_spec(node, spec) |
| 500 | if err is None: |
| 501 | return |
| 502 | errors.append(err) |
| 503 | |
| 504 | if not errors: |
| 505 | return |
| 506 | if len(errors) == 1: |
| 507 | print(f'*** {self.filename}:{node.lineno}: {errors[0]}', |
| 508 | file=sys.stderr) |
| 509 | else: |
| 510 | # There are multiple keyword specs for the function name and |
| 511 | # none of them could be extracted. Print a general error |
| 512 | # message and list the errors for each keyword spec. |
no outgoing calls
no test coverage detected
searching dependent graphs…