Sort namedtuple fields
PiperOrigin-RevId: 211535930
This commit is contained in:
parent
5b576291e3
commit
5cb997a353
@ -947,6 +947,7 @@ class _ClassPageInfo(object):
|
||||
self._aliases = None
|
||||
self._doc = None
|
||||
self._guides = None
|
||||
self._namedtuplefields = None
|
||||
|
||||
self._bases = None
|
||||
self._properties = []
|
||||
@ -1029,6 +1030,17 @@ class _ClassPageInfo(object):
|
||||
assert self.guides is None
|
||||
self._guides = guides
|
||||
|
||||
@property
|
||||
def namedtuplefields(self):
|
||||
return self._namedtuplefields
|
||||
|
||||
def set_namedtuplefields(self, py_class):
|
||||
if issubclass(py_class, tuple):
|
||||
if all(
|
||||
hasattr(py_class, attr)
|
||||
for attr in ('_asdict', '_fields', '_make', '_replace')):
|
||||
self._namedtuplefields = py_class._fields
|
||||
|
||||
@property
|
||||
def bases(self):
|
||||
"""Returns a list of `_LinkInfo` objects pointing to the class' parents."""
|
||||
@ -1066,7 +1078,15 @@ class _ClassPageInfo(object):
|
||||
@property
|
||||
def properties(self):
|
||||
"""Returns a list of `_PropertyInfo` describing the class' properties."""
|
||||
return self._properties
|
||||
props_dict = {prop.short_name: prop for prop in self._properties}
|
||||
props = []
|
||||
if self.namedtuplefields:
|
||||
for field in self.namedtuplefields:
|
||||
props.append(props_dict.pop(field))
|
||||
|
||||
props.extend(sorted(props_dict.values()))
|
||||
|
||||
return props
|
||||
|
||||
def _add_property(self, short_name, full_name, obj, doc):
|
||||
"""Adds a `_PropertyInfo` entry to the `properties` list.
|
||||
@ -1077,6 +1097,9 @@ class _ClassPageInfo(object):
|
||||
obj: The property object itself
|
||||
doc: The property's parsed docstring, a `_DocstringInfo`.
|
||||
"""
|
||||
# Hide useless namedtuple docs-trings
|
||||
if re.match('Alias for field number [0-9]+', doc.docstring):
|
||||
doc = doc._replace(docstring='', brief='')
|
||||
property_info = _PropertyInfo(short_name, full_name, obj, doc)
|
||||
self._properties.append(property_info)
|
||||
|
||||
@ -1156,6 +1179,7 @@ class _ClassPageInfo(object):
|
||||
py_class: The class object being documented
|
||||
parser_config: An instance of ParserConfig.
|
||||
"""
|
||||
self.set_namedtuplefields(py_class)
|
||||
doc_path = documentation_path(self.full_name)
|
||||
relative_path = os.path.relpath(
|
||||
path='.', start=os.path.dirname(doc_path) or '.')
|
||||
|
@ -18,6 +18,7 @@ from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import collections
|
||||
import functools
|
||||
import os
|
||||
import sys
|
||||
@ -190,6 +191,50 @@ class ParserTest(googletest.TestCase):
|
||||
# Make sure this file is contained as the definition location.
|
||||
self.assertEqual(os.path.relpath(__file__, '/'), page_info.defined_in.path)
|
||||
|
||||
def test_namedtuple_field_order(self):
|
||||
namedtupleclass = collections.namedtuple('namedtupleclass',
|
||||
{'z', 'y', 'x', 'w', 'v', 'u'})
|
||||
|
||||
index = {
|
||||
'namedtupleclass': namedtupleclass,
|
||||
'namedtupleclass.u': namedtupleclass.u,
|
||||
'namedtupleclass.v': namedtupleclass.v,
|
||||
'namedtupleclass.w': namedtupleclass.w,
|
||||
'namedtupleclass.x': namedtupleclass.x,
|
||||
'namedtupleclass.y': namedtupleclass.y,
|
||||
'namedtupleclass.z': namedtupleclass.z,
|
||||
}
|
||||
|
||||
visitor = DummyVisitor(index=index, duplicate_of={})
|
||||
|
||||
reference_resolver = parser.ReferenceResolver.from_visitor(
|
||||
visitor=visitor, doc_index={}, py_module_names=['tf'])
|
||||
|
||||
tree = {'namedtupleclass': {'u', 'v', 'w', 'x', 'y', 'z'}}
|
||||
parser_config = parser.ParserConfig(
|
||||
reference_resolver=reference_resolver,
|
||||
duplicates={},
|
||||
duplicate_of={},
|
||||
tree=tree,
|
||||
index=index,
|
||||
reverse_index={},
|
||||
guide_index={},
|
||||
base_dir='/')
|
||||
|
||||
page_info = parser.docs_for_object(
|
||||
full_name='namedtupleclass',
|
||||
py_object=namedtupleclass,
|
||||
parser_config=parser_config)
|
||||
|
||||
# Each namedtiple field has a docstring of the form:
|
||||
# 'Alias for field number ##'. These props are returned sorted.
|
||||
|
||||
def sort_key(prop_info):
|
||||
return int(prop_info.obj.__doc__.split(' ')[-1])
|
||||
|
||||
self.assertSequenceEqual(page_info.properties,
|
||||
sorted(page_info.properties, key=sort_key))
|
||||
|
||||
def test_docs_for_class_should_skip(self):
|
||||
|
||||
class Parent(object):
|
||||
@ -736,6 +781,5 @@ class TestGenerateSignature(googletest.TestCase):
|
||||
sig = parser._generate_signature(example_fun, reverse_index={})
|
||||
self.assertEqual(sig, ['arg1=a.b.c.d', 'arg2=a.b.c.d(1, 2)', "arg3=e['f']"])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
googletest.main()
|
||||
|
@ -136,7 +136,7 @@ def _build_class_page(page_info):
|
||||
|
||||
if page_info.properties:
|
||||
parts.append('## Properties\n\n')
|
||||
for prop_info in sorted(page_info.properties):
|
||||
for prop_info in page_info.properties:
|
||||
h3 = '<h3 id="{short_name}"><code>{short_name}</code></h3>\n\n'
|
||||
parts.append(h3.format(short_name=prop_info.short_name))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user