Specialization of `convert_entity_to_ast` for callable functions.
(f, program_ctx, do_rename=True)
| 626 | |
| 627 | |
| 628 | def convert_func_to_ast(f, program_ctx, do_rename=True): |
| 629 | """Specialization of `convert_entity_to_ast` for callable functions.""" |
| 630 | |
| 631 | future_features = inspect_utils.getfutureimports(f) |
| 632 | node, source = parser.parse_entity(f, future_features=future_features) |
| 633 | logging.log(3, 'Source code of %s:\n\n%s\n', f, source) |
| 634 | # Parsed AST should contain future imports and one function def node. |
| 635 | |
| 636 | # In general, the output of inspect.getsource is inexact for lambdas because |
| 637 | # it uses regex matching to adjust the exact location around the line number |
| 638 | # that CPython records. Then, the entire containing line is returned, which |
| 639 | # we may have trouble disambiguating. For example: |
| 640 | # x, y = lambda: 1, lambda: 2 |
| 641 | if f.__name__ == '<lambda>': |
| 642 | nodes = ast_util.find_matching_definitions(node, f) |
| 643 | if len(nodes) != 1: |
| 644 | raise ValueError( |
| 645 | 'Unable to identify source code of lambda function {}. It was' |
| 646 | ' defined on this line: {}, which must contain a single lambda with' |
| 647 | ' matching signature. To avoid ambiguity, define each lambda' |
| 648 | ' in a separate expression.'.format(f, source)) |
| 649 | node, = nodes |
| 650 | |
| 651 | # TODO(znado): Place inside standard_analysis. |
| 652 | origin_info.resolve_entity(node, source, f) |
| 653 | |
| 654 | namespace = inspect_utils.getnamespace(f) |
| 655 | _add_self_references(namespace, program_ctx.autograph_module) |
| 656 | namer = naming.Namer(namespace) |
| 657 | |
| 658 | if isinstance(node, gast.Lambda): |
| 659 | new_name = namer.new_symbol('tf__lambda', ()) |
| 660 | elif do_rename: |
| 661 | new_name = namer.function_name(f.__name__) |
| 662 | else: |
| 663 | new_name = f.__name__ |
| 664 | |
| 665 | entity_info = transformer.EntityInfo( |
| 666 | source_code=source, |
| 667 | source_file='<fragment>', |
| 668 | future_features=future_features, |
| 669 | namespace=namespace) |
| 670 | context = converter.EntityContext(namer, entity_info, program_ctx, new_name) |
| 671 | node = node_to_graph(node, context) |
| 672 | |
| 673 | if isinstance(node, gast.Lambda): |
| 674 | node = gast.Assign( |
| 675 | targets=[ |
| 676 | gast.Name( |
| 677 | new_name, ctx=gast.Store(), annotation=None, type_comment=None) |
| 678 | ], |
| 679 | value=node) |
| 680 | elif do_rename: |
| 681 | node.name = new_name |
| 682 | else: |
| 683 | assert node.name == new_name |
| 684 | |
| 685 | return (node,), new_name, entity_info |
no test coverage detected