def _AddMember(member_name, member_obj, proto):
   """Add the child object to the object being constructed."""
   _, member_obj = tf_decorator.unwrap(member_obj)
   if member_name == '__init__' or not member_name.startswith('_'):
     if tf_inspect.isroutine(member_obj):
       new_method = proto.member_method.add()
       new_method.name = member_name
       # If member_obj is a python builtin, there is no way to get its
       # argspec, because it is implemented on the C side. It also has no
       # func_code.
       if getattr(member_obj, 'func_code', None):
         new_method.argspec = _SanitizedArgSpec(member_obj)
     else:
       new_member = proto.member.add()
       new_member.name = member_name
       new_member.mtype = str(type(member_obj))
Exemple #2
0
 def _AddMember(member_name, member_obj, proto):
     """Add the child object to the object being constructed."""
     _, member_obj = tf_decorator.unwrap(member_obj)
     if member_name == '__init__' or not member_name.startswith('_'):
         if tf_inspect.isroutine(member_obj):
             new_method = proto.member_method.add()
             new_method.name = member_name
             # If member_obj is a python builtin, there is no way to get its
             # argspec, because it is implemented on the C side. It also has no
             # func_code.
             if getattr(member_obj, 'func_code', None):
                 new_method.argspec = _SanitizedArgSpec(member_obj)
         else:
             new_member = proto.member.add()
             new_member.name = member_name
             new_member.mtype = str(type(member_obj))
 def _AddMember(member_name, member_obj, proto):
   """Add the child object to the object being constructed."""
   _, member_obj = tf_decorator.unwrap(member_obj)
   if (_SkipMember(parent, member_name)
       or member_obj == deprecation.HIDDEN_ATTRIBUTE):
     return
   if member_name == '__init__' or not member_name.startswith('_'):
     if tf_inspect.isroutine(member_obj):
       new_method = proto.member_method.add()
       new_method.name = member_name
       # If member_obj is a python builtin, there is no way to get its
       # argspec, because it is implemented on the C side. It also has no
       # func_code.
       if hasattr(member_obj, '__code__'):
         new_method.argspec = _SanitizedArgSpec(member_obj)
     else:
       new_member = proto.member.add()
       new_member.name = member_name
       new_member.mtype = _NormalizeType(str(type(member_obj)))
 def _AddMember(member_name, member_obj, proto):
     """Add the child object to the object being constructed."""
     _, member_obj = tf_decorator.unwrap(member_obj)
     if (_SkipMember(parent, member_name)
             or member_obj == deprecation.HIDDEN_ATTRIBUTE):
         return
     if member_name == '__init__' or not member_name.startswith('_'):
         if tf_inspect.isroutine(member_obj):
             new_method = proto.member_method.add()
             new_method.name = member_name
             # If member_obj is a python builtin, there is no way to get its
             # argspec, because it is implemented on the C side. It also has no
             # func_code.
             if hasattr(member_obj, '__code__'):
                 new_method.argspec = _SanitizedArgSpec(member_obj)
         else:
             new_member = proto.member.add()
             new_member.name = member_name
             new_member.mtype = _NormalizeType(str(type(member_obj)))
 def testIsRoutine(self):
     self.assertTrue(tf_inspect.isroutine(len))
     self.assertFalse(tf_inspect.isroutine(TestDecoratedClass))
 def testIsRoutine(self):
   self.assertTrue(tf_inspect.isroutine(len))
   self.assertFalse(tf_inspect.isroutine(TestDecoratedClass))
Exemple #7
0
  def collect_docs_for_class(self, py_class, parser_config):
    """Collect information necessary specifically for a class's doc page.

    Mainly, this is details about information about the class's members.

    Args:
      py_class: the class object being documented
      parser_config: An instance of ParserConfig.
    """
    doc_path = documentation_path(self.full_name)
    relative_path = os.path.relpath(
        path='.', start=os.path.dirname(doc_path) or '.')

    for short_name in parser_config.tree[self.full_name]:
      # Remove builtin members that we never want to document.
      if short_name in ['__class__', '__base__', '__weakref__', '__doc__',
                        '__module__', '__dict__', '__abstractmethods__',
                        '__slots__', '__getnewargs__']:
        continue

      child_name = '.'.join([self.full_name, short_name])
      child = parser_config.py_name_to_object(child_name)

      # Don't document anything that is defined in object or by protobuf.
      defining_class = _get_defining_class(py_class, short_name)
      if (defining_class is object or
          defining_class is type or defining_class is tuple or
          defining_class is BaseException or defining_class is Exception or
          # The following condition excludes most protobuf-defined symbols.
          defining_class and defining_class.__name__ in ['CMessage', 'Message',
                                                         'MessageMeta']):
        continue
      # TODO(markdaoust): Add a note in child docs showing the defining class.

      child_doc = _parse_md_docstring(child, relative_path,
                                      parser_config.reference_resolver)

      if isinstance(child, property):
        self._add_property(short_name, child_name, child, child_doc)

      elif tf_inspect.isclass(child):
        if defining_class is None:
          continue
        url = parser_config.reference_resolver.reference_to_url(
            child_name, relative_path)
        self._add_class(short_name, child_name, child, child_doc, url)

      elif (tf_inspect.ismethod(child) or tf_inspect.isfunction(child) or
            tf_inspect.isroutine(child)):
        if defining_class is None:
          continue

        # Omit methods defined by namedtuple.
        original_method = defining_class.__dict__[short_name]
        if (hasattr(original_method, '__module__') and
            (original_method.__module__ or '').startswith('namedtuple')):
          continue

        # Some methods are often overridden without documentation. Because it's
        # obvious what they do, don't include them in the docs if there's no
        # docstring.
        if not child_doc.brief.strip() and short_name in [
            '__str__', '__repr__', '__hash__', '__del__', '__copy__']:
          print('Skipping %s, defined in %s, no docstring.' % (child_name,
                                                               defining_class))
          continue

        try:
          child_signature = _generate_signature(child,
                                                parser_config.reverse_index)
        except TypeError:
          # If this is a (dynamically created) slot wrapper, tf_inspect will
          # raise typeerror when trying to get to the code. Ignore such
          # functions.
          continue

        self._add_method(short_name, child_name, child, child_doc,
                         child_signature)
      else:
        # Exclude members defined by protobuf that are useless
        if issubclass(py_class, ProtoMessage):
          if (short_name.endswith('_FIELD_NUMBER') or
              short_name in ['__slots__', 'DESCRIPTOR']):
            continue

        # TODO(wicke): We may want to also remember the object itself.
        self._add_other_member(short_name, child_name, child, child_doc)
Exemple #8
0
def docs_for_object(full_name, py_object, parser_config):
  """Return a PageInfo object describing a given object from the TF API.

  This function uses _parse_md_docstring to parse the docs pertaining to
  `object`.

  This function resolves '@{symbol}' references in the docstrings into links to
  the appropriate location. It also adds a list of alternative names for the
  symbol automatically.

  It assumes that the docs for each object live in a file given by
  `documentation_path`, and that relative links to files within the
  documentation are resolvable.

  Args:
    full_name: The fully qualified name of the symbol to be
      documented.
    py_object: The Python object to be documented. Its documentation is sourced
      from `py_object`'s docstring.
    parser_config: A ParserConfig object.

  Returns:
    Either a `_FunctionPageInfo`, `_ClassPageInfo`, or a `_ModulePageInfo`
    depending on the type of the python object being documented.

  Raises:
    RuntimeError: If an object is encountered for which we don't know how
      to make docs.
  """

  # Which other aliases exist for the object referenced by full_name?
  master_name = parser_config.reference_resolver.py_master_name(full_name)
  duplicate_names = parser_config.duplicates.get(master_name, [full_name])

  # TODO(wicke): Once other pieces are ready, enable this also for partials.
  if (tf_inspect.ismethod(py_object) or tf_inspect.isfunction(py_object) or
      # Some methods in classes from extensions come in as routines.
      tf_inspect.isroutine(py_object)):
    page_info = _FunctionPageInfo(master_name)
    page_info.set_signature(py_object, parser_config.reverse_index)

  elif tf_inspect.isclass(py_object):
    page_info = _ClassPageInfo(master_name)
    page_info.collect_docs_for_class(py_object, parser_config)

  elif tf_inspect.ismodule(py_object):
    page_info = _ModulePageInfo(master_name)
    page_info.collect_docs_for_module(parser_config)

  else:
    raise RuntimeError('Cannot make docs for object %s: %r' % (full_name,
                                                               py_object))

  relative_path = os.path.relpath(
      path='.', start=os.path.dirname(documentation_path(full_name)) or '.')

  page_info.set_doc(_parse_md_docstring(
      py_object, relative_path, parser_config.reference_resolver))

  page_info.set_aliases(duplicate_names)

  page_info.set_guides(_get_guides_markdown(
      duplicate_names, parser_config.guide_index, relative_path))

  page_info.set_defined_in(_get_defined_in(py_object, parser_config))

  return page_info
Exemple #9
0
    def collect_docs_for_class(self, py_class, parser_config):
        """Collect information necessary specifically for a class's doc page.

    Mainly, this is details about information about the class's members.

    Args:
      py_class: the class object being documented
      parser_config: An instance of ParserConfig.
    """
        doc_path = documentation_path(self.full_name)
        relative_path = os.path.relpath(path='.',
                                        start=os.path.dirname(doc_path) or '.')

        for short_name in parser_config.tree[self.full_name]:
            # Remove builtin members that we never want to document.
            if short_name in [
                    '__class__', '__base__', '__weakref__', '__doc__',
                    '__module__', '__dict__', '__abstractmethods__',
                    '__slots__', '__getnewargs__'
            ]:
                continue

            child_name = '.'.join([self.full_name, short_name])
            child = parser_config.py_name_to_object(child_name)

            # Don't document anything that is defined in object or by protobuf.
            defining_class = _get_defining_class(py_class, short_name)
            if (defining_class is object or defining_class is type
                    or defining_class is tuple
                    or defining_class is BaseException
                    or defining_class is Exception or
                    # The following condition excludes most protobuf-defined symbols.
                    defining_class and defining_class.__name__
                    in ['CMessage', 'Message', 'MessageMeta']):
                continue
            # TODO(markdaoust): Add a note in child docs showing the defining class.

            child_doc = _parse_md_docstring(child, relative_path,
                                            parser_config.reference_resolver)

            if isinstance(child, property):
                self._add_property(short_name, child_name, child, child_doc)

            elif tf_inspect.isclass(child):
                if defining_class is None:
                    continue
                url = parser_config.reference_resolver.reference_to_url(
                    child_name, relative_path)
                self._add_class(short_name, child_name, child, child_doc, url)

            elif (tf_inspect.ismethod(child) or tf_inspect.isfunction(child)
                  or tf_inspect.isroutine(child)):
                if defining_class is None:
                    continue

                # Omit methods defined by namedtuple.
                original_method = defining_class.__dict__[short_name]
                if (hasattr(original_method, '__module__')
                        and (original_method.__module__
                             or '').startswith('namedtuple')):
                    continue

                # Some methods are often overridden without documentation. Because it's
                # obvious what they do, don't include them in the docs if there's no
                # docstring.
                if not child_doc.brief.strip() and short_name in [
                        '__str__', '__repr__', '__hash__', '__del__',
                        '__copy__'
                ]:
                    print('Skipping %s, defined in %s, no docstring.' %
                          (child_name, defining_class))
                    continue

                try:
                    child_signature = _generate_signature(
                        child, parser_config.reverse_index)
                except TypeError:
                    # If this is a (dynamically created) slot wrapper, tf_inspect will
                    # raise typeerror when trying to get to the code. Ignore such
                    # functions.
                    continue

                self._add_method(short_name, child_name, child, child_doc,
                                 child_signature)
            else:
                # Exclude members defined by protobuf that are useless
                if issubclass(py_class, ProtoMessage):
                    if (short_name.endswith('_FIELD_NUMBER')
                            or short_name in ['__slots__', 'DESCRIPTOR']):
                        continue

                # TODO(wicke): We may want to also remember the object itself.
                self._add_other_member(short_name, child_name, child,
                                       child_doc)
Exemple #10
0
def docs_for_object(full_name, py_object, parser_config):
    """Return a PageInfo object describing a given object from the TF API.

  This function uses _parse_md_docstring to parse the docs pertaining to
  `object`.

  This function resolves '@{symbol}' references in the docstrings into links to
  the appropriate location. It also adds a list of alternative names for the
  symbol automatically.

  It assumes that the docs for each object live in a file given by
  `documentation_path`, and that relative links to files within the
  documentation are resolvable.

  Args:
    full_name: The fully qualified name of the symbol to be
      documented.
    py_object: The Python object to be documented. Its documentation is sourced
      from `py_object`'s docstring.
    parser_config: A ParserConfig object.

  Returns:
    Either a `_FunctionPageInfo`, `_ClassPageInfo`, or a `_ModulePageInfo`
    depending on the type of the python object being documented.

  Raises:
    RuntimeError: If an object is encountered for which we don't know how
      to make docs.
  """

    # Which other aliases exist for the object referenced by full_name?
    master_name = parser_config.reference_resolver.py_master_name(full_name)
    duplicate_names = parser_config.duplicates.get(master_name, [full_name])

    # TODO(wicke): Once other pieces are ready, enable this also for partials.
    if (tf_inspect.ismethod(py_object) or tf_inspect.isfunction(py_object) or
            # Some methods in classes from extensions come in as routines.
            tf_inspect.isroutine(py_object)):
        page_info = _FunctionPageInfo(master_name)
        page_info.set_signature(py_object, parser_config.reverse_index)

    elif tf_inspect.isclass(py_object):
        page_info = _ClassPageInfo(master_name)
        page_info.collect_docs_for_class(py_object, parser_config)

    elif tf_inspect.ismodule(py_object):
        page_info = _ModulePageInfo(master_name)
        page_info.collect_docs_for_module(parser_config)

    else:
        raise RuntimeError('Cannot make docs for object %s: %r' %
                           (full_name, py_object))

    relative_path = os.path.relpath(
        path='.', start=os.path.dirname(documentation_path(full_name)) or '.')

    page_info.set_doc(
        _parse_md_docstring(py_object, relative_path,
                            parser_config.reference_resolver))

    page_info.set_aliases(duplicate_names)

    page_info.set_guides(
        _get_guides_markdown(duplicate_names, parser_config.guide_index,
                             relative_path))

    page_info.set_defined_in(_get_defined_in(py_object, parser_config))

    return page_info