Dedublizierung gefixt
- lange existierender Updatecode wurde in jeder 2. Version angezeigt - UPDATEANALYSE.md ergänzt.
This commit is contained in:
+75
@@ -76,6 +76,15 @@ INTERESTING_OPS = {
|
||||
"select",
|
||||
}
|
||||
|
||||
# Aufrufe, die im "unresolved"-Log NICHT auftauchen sollen, weil sie entweder
|
||||
# an anderer Stelle bereits sinnvoll aufgelöst werden (__table__,
|
||||
# __table_handler__, pool.get) oder nachweislich nie eine DB-Operation sind
|
||||
# (Listen-.append, Logging). Erste Fassung nach Sichtung von echten
|
||||
# Tryton-Modulen (product.json) - bei Bedarf einfach erweitern.
|
||||
IGNORED_UNRESOLVED_OPERATIONS = {"__table__", "__table_handler__", "append"}
|
||||
IGNORED_UNRESOLVED_OBJECTS = {"logger"}
|
||||
IGNORED_UNRESOLVED_CALLS = {("pool", "get")}
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# AST-Visitor
|
||||
@@ -433,10 +442,76 @@ class RegisterExtractor(ast.NodeVisitor):
|
||||
self.walk_into_helper(
|
||||
method_name, func_node, node.lineno, operations, phase, condition
|
||||
)
|
||||
else:
|
||||
unresolved = self.extract_unresolved_call(node)
|
||||
if unresolved:
|
||||
unresolved["phase"] = phase
|
||||
if condition:
|
||||
unresolved["condition"] = condition
|
||||
if self.call_chain:
|
||||
unresolved["via"] = [dict(entry) for entry in self.call_chain]
|
||||
operations.append(unresolved)
|
||||
|
||||
for child in ast.iter_child_nodes(node):
|
||||
self.walk_expression(child, operations, phase, condition)
|
||||
|
||||
def extract_unresolved_call(self, call):
|
||||
"""
|
||||
Rohmaterial-Eintrag für Aufrufe in __register__ (bzw. einem
|
||||
verfolgten Helper), die weder eine erkannte DB-Operation noch ein
|
||||
auflösbarer cls./self.-Helper sind. Über das Flag "unresolved": true
|
||||
von echten Operationen unterscheidbar. Bewusst noch ungefiltert
|
||||
gehalten - bis auf eine kleine, aus echten Modulen (siehe
|
||||
IGNORED_UNRESOLVED_*) abgeleitete Liste von Aufrufen, die
|
||||
nachweislich nie eine DB-Operation sind bzw. bereits an anderer
|
||||
Stelle sinnvoll aufgelöst werden. Gibt None zurück, wenn der Aufruf
|
||||
gefiltert werden soll.
|
||||
"""
|
||||
if isinstance(call.func, ast.Attribute):
|
||||
operation = call.func.attr
|
||||
if isinstance(call.func.value, ast.Name):
|
||||
obj = call.func.value.id
|
||||
else:
|
||||
obj = ast.unparse(call.func.value)
|
||||
elif isinstance(call.func, ast.Name):
|
||||
operation = call.func.id
|
||||
obj = ""
|
||||
else:
|
||||
operation = ast.unparse(call.func)
|
||||
obj = ""
|
||||
|
||||
if (
|
||||
operation in IGNORED_UNRESOLVED_OPERATIONS
|
||||
or obj in IGNORED_UNRESOLVED_OBJECTS
|
||||
or (obj, operation) in IGNORED_UNRESOLVED_CALLS
|
||||
):
|
||||
return None
|
||||
|
||||
args = []
|
||||
for arg in call.args:
|
||||
try:
|
||||
args.append(ast.unparse(arg))
|
||||
except Exception:
|
||||
args.append("<unknown>")
|
||||
|
||||
kwargs = {}
|
||||
for kw in call.keywords:
|
||||
try:
|
||||
kwargs[kw.arg] = ast.unparse(kw.value)
|
||||
except Exception:
|
||||
kwargs[kw.arg] = "<unknown>"
|
||||
|
||||
return {
|
||||
"object": obj,
|
||||
"operation": operation,
|
||||
"tables": self.find_tables(call),
|
||||
"line": call.lineno,
|
||||
"args": args,
|
||||
"kwargs": kwargs,
|
||||
"code": self._render_code(call),
|
||||
"unresolved": True,
|
||||
}
|
||||
|
||||
def resolve_helper_call(self, node):
|
||||
"""
|
||||
Erkennt Aufrufe der Form `cls.<method>(...)` / `self.<method>(...)`
|
||||
|
||||
Reference in New Issue
Block a user