| 260 | |
| 261 | |
| 262 | class ReplaceCodeTransformer(NodeTransformer): |
| 263 | enabled: bool = True |
| 264 | debug: bool = False |
| 265 | mangler: Mangler |
| 266 | |
| 267 | def __init__( |
| 268 | self, template: Module, mapping: Optional[Dict] = None, mangling_predicate=None |
| 269 | ): |
| 270 | assert isinstance(mapping, (dict, type(None))) |
| 271 | assert isinstance(mangling_predicate, (type(None), type(lambda: None))) |
| 272 | assert isinstance(template, ast.Module) |
| 273 | self.template = template |
| 274 | self.mangler = Mangler(predicate=mangling_predicate) |
| 275 | if mapping is None: |
| 276 | mapping = {} |
| 277 | self.mapping = mapping |
| 278 | |
| 279 | @classmethod |
| 280 | def from_string( |
| 281 | cls, template: str, mapping: Optional[Dict] = None, mangling_predicate=None |
| 282 | ): |
| 283 | return cls( |
| 284 | ast.parse(template), mapping=mapping, mangling_predicate=mangling_predicate |
| 285 | ) |
| 286 | |
| 287 | def visit_Module(self, code): |
| 288 | if not self.enabled: |
| 289 | return code |
| 290 | # if not isinstance(code, ast.Module): |
| 291 | # recursively called... |
| 292 | # return generic_visit(self, code) |
| 293 | last = code.body[-1] |
| 294 | if isinstance(last, Expr): |
| 295 | code.body.pop() |
| 296 | code.body.append(Assign([Name("ret-tmp", ctx=Store())], value=last.value)) |
| 297 | ast.fix_missing_locations(code) |
| 298 | ret = Expr(value=Name("ret-tmp", ctx=Load())) |
| 299 | ret = ast.fix_missing_locations(ret) |
| 300 | self.mapping["__ret__"] = ret |
| 301 | else: |
| 302 | self.mapping["__ret__"] = ast.parse("None").body[0] |
| 303 | self.mapping["__code__"] = code.body |
| 304 | tpl = ast.fix_missing_locations(self.template) |
| 305 | |
| 306 | tx = copy.deepcopy(tpl) |
| 307 | tx = self.mangler.visit(tx) |
| 308 | node = self.generic_visit(tx) |
| 309 | node_2 = ast.fix_missing_locations(node) |
| 310 | if self.debug: |
| 311 | print("---- Transformed code ----") |
| 312 | print(ast.unparse(node_2)) |
| 313 | print("---- ---------------- ----") |
| 314 | return node_2 |
| 315 | |
| 316 | # this does not work as the name might be in a list and one might want to extend the list. |
| 317 | # def visit_Name(self, name): |
| 318 | # if name.id in self.mapping and name.id == "__ret__": |
| 319 | # print(name, "in mapping") |
no outgoing calls
no test coverage detected
searching dependent graphs…