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 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]