Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/autograph/pyct/loader.py: 32%
37 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
1# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""Converting AST to code and Python entities.
17Adapted from Tangent.
18"""
20import atexit
21import errno
22import importlib
23import os
24import sys
25import tempfile
27from tensorflow.python.autograph.pyct import origin_info
28from tensorflow.python.autograph.pyct import parser
31def _remove_file(file_name):
32 """Remove a file, if it exists."""
33 try:
34 os.remove(file_name)
35 except OSError as e:
36 if e.errno == errno.ENOENT:
37 # The file disappeared. Ignore this. Temporary files might get
38 # cleaned up, especially if they reside in /tmp.
39 pass
40 else:
41 raise
44def load_source(source, delete_on_exit):
45 """Loads the given source code as a Python module."""
46 with tempfile.NamedTemporaryFile(
47 mode='w',
48 suffix='.py',
49 prefix='__autograph_generated_file',
50 delete=False,
51 encoding='utf-8') as f:
52 module_name = os.path.basename(f.name[:-3])
53 file_name = f.name
54 f.write(source)
56 if delete_on_exit:
57 atexit.register(lambda: _remove_file(file_name))
59 spec = importlib.util.spec_from_file_location(module_name, file_name)
60 module = importlib.util.module_from_spec(spec)
61 spec.loader.exec_module(module)
62 # TODO(mdan): Use our own garbage-collected cache instead of sys.modules.
63 sys.modules[module_name] = module
64 return module, file_name
67def load_ast(nodes,
68 indentation=' ',
69 include_source_map=False,
70 delete_on_exit=True):
71 """Loads the given AST as a Python module.
73 Compiling the AST code this way ensures that the source code is readable by
74 e.g. `pdb` or `inspect`.
76 Args:
77 nodes: Union[ast.AST, Iterable[ast.AST]], the code to compile, as an AST
78 object.
79 indentation: Text, the string to use for indentation.
80 include_source_map: bool, whether return a source map.
81 delete_on_exit: bool, whether to delete the temporary file used for
82 compilation on exit.
84 Returns:
85 Tuple[module, Text, Dict[LineLocation, OriginInfo]], containing:
86 the module containing the unparsed nodes, the source code corresponding to
87 nodes, and the source map. Is include_source_map is False, the source map
88 will be None.
89 """
90 if not isinstance(nodes, (list, tuple)):
91 nodes = (nodes,)
93 source = parser.unparse(nodes, indentation=indentation)
94 module, _ = load_source(source, delete_on_exit)
96 if include_source_map:
97 source_map = origin_info.create_source_map(nodes, source, module.__file__)
98 else:
99 source_map = None
101 # TODO(mdan): Return a structured object.
102 return module, source, source_map