Source code for pyfileconf.io.file.load.parsers.assign

import ast
from typing import Union, TYPE_CHECKING
if TYPE_CHECKING:
    from pyfileconf.assignments.models.statement import AssignmentStatement
    from pyfileconf.assignments.models.container import AssignmentStatementContainer

AssignmentStatementOrNone = Union['AssignmentStatement', None]

[docs]class AssignmentExtractor(ast.NodeVisitor):
[docs] def __init__(self): from pyfileconf.assignments.models.container import AssignmentStatementContainer self.assigns = AssignmentStatementContainer([])
[docs] def visit_Assign(self, node): from pyfileconf.assignments.models.statement import AssignmentStatement self.assigns.append( AssignmentStatement.from_ast_assign(node) )
[docs] def visit_AnnAssign(self, node): from pyfileconf.assignments.models.statement import AssignmentStatement self.assigns.append( AssignmentStatement.from_ast_assign(node) )
[docs]def extract_assignments_from_ast(module: ast.Module) -> 'AssignmentStatementContainer': ae = AssignmentExtractor() ae.visit(module) return ae.assigns
[docs]def extract_assignment_from_ast(module: ast.Module) -> AssignmentStatementOrNone: assign_container = extract_assignments_from_ast(module) if len(assign_container) == 0: return None if len(assign_container) > 1: raise ValueError(f'expected to extract one assignment from ast. got {len(assign_container)} ' f'assigns: {assign_container.items}') return assign_container[0]
[docs]class AssignmentByVarnameExtractor(AssignmentExtractor):
[docs] def __init__(self, varname: str): self.varname = varname super().__init__()
[docs] def visit_Assign(self, node): varnames = [target.id for target in node.targets] if self.varname in varnames: super().visit_Assign(node)
[docs] def visit_AnnAssign(self, node): if node.target.id == self.varname: super().visit_AnnAssign(node)
[docs]def extract_assignments_from_ast_by_name(module: ast.Module, name: str) -> 'AssignmentStatementContainer': ae = AssignmentByVarnameExtractor(name) ae.visit(module) return ae.assigns
[docs]def extract_assignment_from_ast_by_name(module: ast.Module, name: str) -> AssignmentStatementOrNone: assign_container = extract_assignments_from_ast_by_name(module, name) if len(assign_container) == 0: return None if len(assign_container) > 1: raise ValueError(f'expected to extract one assignment from ast. got {len(assign_container)} ' f'assigns: {assign_container.items}') return assign_container[0]