in tools/tensorflow_docs/api_generator/parser.py [0:0]
def get_defined_in(
py_object: Any,
parser_config: config.ParserConfig) -> Optional[FileLocation]:
"""Returns a description of where the passed in python object was defined.
Args:
py_object: The Python object.
parser_config: A config.ParserConfig object.
Returns:
A `FileLocation`
"""
# Every page gets a note about where this object is defined
base_dirs_and_prefixes = zip(parser_config.base_dir,
parser_config.code_url_prefix)
try:
obj_path = inspect.getfile(_unwrap_obj(py_object))
except TypeError: # getfile throws TypeError if py_object is a builtin.
return None
if not obj_path.endswith(('.py', '.pyc')):
return None
code_url_prefix = None
for base_dir, temp_prefix in base_dirs_and_prefixes:
rel_path = os.path.relpath(path=obj_path, start=base_dir)
# A leading ".." indicates that the file is not inside `base_dir`, and
# the search should continue.
if rel_path.startswith('..'):
continue
else:
code_url_prefix = temp_prefix
# rel_path is currently a platform-specific path, so we need to convert
# it to a posix path (for lack of a URL path).
rel_path = posixpath.join(*rel_path.split(os.path.sep))
break
# No link if the file was not found in a `base_dir`, or the prefix is None.
if code_url_prefix is None:
return None
try:
lines, start_line = inspect.getsourcelines(py_object)
end_line = start_line + len(lines) - 1
if 'MACHINE GENERATED' in lines[0]:
# don't link to files generated by tf_export
return None
except (IOError, TypeError, IndexError):
start_line = None
end_line = None
# In case this is compiled, point to the original
if rel_path.endswith('.pyc'):
# If a PY3 __pycache__/ subdir is being used, omit it.
rel_path = rel_path.replace('__pycache__' + os.sep, '')
# Strip everything after the first . so that variants such as .pyc and
# .cpython-3x.pyc or similar are all handled.
rel_path = rel_path.partition('.')[0] + '.py'
if re.search(r'<[\w\s]+>', rel_path):
# Built-ins emit paths like <embedded stdlib>, <string>, etc.
return None
if '<attrs generated' in rel_path:
return None
if re.match(r'.*/gen_[^/]*\.py$', rel_path):
return FileLocation()
if 'genfiles' in rel_path:
return FileLocation()
elif re.match(r'.*_pb2\.py$', rel_path):
# The _pb2.py files all appear right next to their defining .proto file.
rel_path = rel_path[:-7] + '.proto'
return FileLocation(base_url=posixpath.join(code_url_prefix, rel_path))
else:
return FileLocation(
base_url=posixpath.join(code_url_prefix, rel_path),
start_line=start_line,
end_line=end_line)