def get_defined_in()

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)