Skip to content

Commit 5b02a84

Browse files
MarkDaoustcopybara-github
authored andcommitted
Pure refactor: Give the PageInfo access to the parser_config and api_node.
I prefer api_nodes compared to passing around (py_object, full_name) everywhere. PiperOrigin-RevId: 444817172
1 parent b46ed63 commit 5b02a84

File tree

14 files changed

+211
-205
lines changed

14 files changed

+211
-205
lines changed

tools/tensorflow_docs/api_generator/doc_generator_visitor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class PathTreeNode(object):
7373
"""
7474
path: ApiPath
7575
py_object: Any
76-
parent: Optional['PathTreeNode']
76+
parent: Optional['PathTreeNode'] = None
7777
children: Dict[str, 'PathTreeNode'] = dataclasses.field(default_factory=dict)
7878

7979
def __hash__(self):

tools/tensorflow_docs/api_generator/generate_lib.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,17 @@ def write_docs(
120120

121121
# Parse and write Markdown pages, resolving cross-links (`tf.symbol`).
122122
num_docs_output = 0
123-
for node in parser_config.api_tree.iter_nodes():
124-
full_name = node.full_name
125-
py_object = node.py_object
123+
for api_node in parser_config.api_tree.iter_nodes():
124+
full_name = api_node.full_name
125+
py_object = api_node.py_object
126126

127-
if node.output_type() is node.OutputType.FRAGMENT:
127+
if api_node.output_type() is api_node.OutputType.FRAGMENT:
128128
continue
129129

130130
# Generate docs for `py_object`, resolving references.
131131
try:
132132
page_info = docs_for_object.docs_for_object(
133-
full_name=full_name,
134-
py_object=py_object,
133+
api_node=api_node,
135134
parser_config=parser_config,
136135
extra_docs=extra_docs,
137136
search_hints=search_hints,

tools/tensorflow_docs/api_generator/parser.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,6 @@
3333
from tensorflow_docs.api_generator import signature as signature_lib
3434

3535

36-
@dataclasses.dataclass
37-
class FileLocation(object):
38-
"""This class indicates that the object is defined in a regular file.
39-
40-
This can be used for the `defined_in` slot of the `PageInfo` objects.
41-
"""
42-
43-
base_url: Optional[str] = None
44-
start_line: Optional[int] = None
45-
end_line: Optional[int] = None
46-
47-
@property
48-
def url(self) -> Optional[str]:
49-
if self.start_line and self.end_line:
50-
if 'github.com' in self.base_url:
51-
return f'{self.base_url}#L{self.start_line}-L{self.end_line}'
52-
return self.base_url
53-
54-
5536
def is_class_attr(full_name, index):
5637
"""Check if the object's parent is a class.
5738
@@ -614,6 +595,24 @@ def _unwrap_obj(obj):
614595
return obj
615596

616597

598+
@dataclasses.dataclass
599+
class FileLocation(object):
600+
"""This class indicates that the object is defined in a regular file.
601+
602+
This can be used for the `defined_in` slot of the `PageInfo` objects.
603+
"""
604+
605+
base_url: Optional[str] = None
606+
start_line: Optional[int] = None
607+
end_line: Optional[int] = None
608+
609+
@property
610+
def url(self) -> Optional[str]:
611+
if self.start_line and self.end_line:
612+
if 'github.com' in self.base_url:
613+
return f'{self.base_url}#L{self.start_line}-L{self.end_line}'
614+
return self.base_url
615+
617616
def get_defined_in(
618617
py_object: Any,
619618
parser_config: config.ParserConfig) -> Optional[FileLocation]:

tools/tensorflow_docs/api_generator/parser_test.py

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
from tensorflow_docs.api_generator import config
3030
from tensorflow_docs.api_generator import doc_controls
31+
from tensorflow_docs.api_generator import doc_generator_visitor
3132
from tensorflow_docs.api_generator import generate_lib
3233
from tensorflow_docs.api_generator import parser
3334
from tensorflow_docs.api_generator import reference_resolver as reference_resolver_lib
@@ -198,10 +199,13 @@ def test_docs_for_class(self):
198199

199200
parser_config = generator.run_extraction()
200201

202+
api_node = doc_generator_visitor.ApiTreeNode(
203+
path=(
204+
'm',
205+
'TestClass',
206+
), py_object=TestClass)
201207
page_info = docs_for_object.docs_for_object(
202-
full_name='m.TestClass',
203-
py_object=TestClass,
204-
parser_config=parser_config)
208+
api_node=api_node, parser_config=parser_config)
205209

206210
# Make sure the brief docstring is present
207211
self.assertEqual(
@@ -241,10 +245,10 @@ def test_dataclass_attributes_table(self):
241245

242246
parser_config = generator.run_extraction()
243247

248+
api_node = doc_generator_visitor.ApiTreeNode(
249+
path=('m', 'ExampleDataclass'), py_object=ExampleDataclass)
244250
page_info = docs_for_object.docs_for_object(
245-
full_name='m.ExampleDataclass',
246-
py_object=ExampleDataclass,
247-
parser_config=parser_config)
251+
api_node=api_node, parser_config=parser_config)
248252

249253
self.assertCountEqual(['a', 'b', 'c', 'x', 'y', 'z'],
250254
[name for name, value in page_info.attr_block.items])
@@ -268,10 +272,10 @@ def hide(path, parent, children):
268272

269273
parser_config = generator.run_extraction()
270274

275+
api_node = doc_generator_visitor.ApiTreeNode(
276+
path=('m', 'namedtupleclass'), py_object=namedtupleclass)
271277
page_info = docs_for_object.docs_for_object(
272-
full_name='m.namedtupleclass',
273-
py_object=namedtupleclass,
274-
parser_config=parser_config)
278+
api_node=api_node, parser_config=parser_config)
275279

276280
self.assertIsNone(page_info._namedtuplefields['hidden'])
277281

@@ -308,8 +312,13 @@ def a_method(self, arg='default'):
308312

309313
parser_config = generator.run_extraction()
310314

315+
api_node = doc_generator_visitor.ApiTreeNode(
316+
path=(
317+
'm',
318+
'Child',
319+
), py_object=Child)
311320
page_info = docs_for_object.docs_for_object(
312-
full_name='m.Child', py_object=Child, parser_config=parser_config)
321+
api_node=api_node, parser_config=parser_config)
313322

314323
# Make sure the `a_method` is not present
315324
self.assertEmpty(page_info.methods)
@@ -347,10 +356,10 @@ def my_method(self):
347356

348357
parser_config = generator.run_extraction()
349358

359+
api_node = doc_generator_visitor.ApiTreeNode(
360+
path=('m', 'ChildMessage'), py_object=ChildMessage)
350361
page_info = docs_for_object.docs_for_object(
351-
full_name='m.ChildMessage',
352-
py_object=ChildMessage,
353-
parser_config=parser_config)
362+
api_node=api_node, parser_config=parser_config)
354363

355364
self.assertLen(page_info.methods, 1)
356365
self.assertEqual('my_method', page_info.methods[0].short_name)
@@ -369,8 +378,10 @@ def test_docs_for_module(self):
369378

370379
parser_config = generator.run_extraction()
371380

381+
api_node = doc_generator_visitor.ApiTreeNode(
382+
path=('m',), py_object=test_module)
372383
page_info = docs_for_object.docs_for_object(
373-
full_name='m', py_object=test_module, parser_config=parser_config)
384+
api_node=api_node, parser_config=parser_config)
374385

375386
# Make sure the brief docstring is present
376387
self.assertEqual(
@@ -395,10 +406,10 @@ def test_docs_for_function(self):
395406

396407
parser_config = generator.run_extraction()
397408

409+
api_node = doc_generator_visitor.ApiTreeNode(
410+
path=('test_function',), py_object=test_function)
398411
page_info = docs_for_object.docs_for_object(
399-
full_name='test_function',
400-
py_object=test_function,
401-
parser_config=parser_config)
412+
api_node=api_node, parser_config=parser_config)
402413

403414
# Make sure the brief docstring is present
404415
self.assertEqual(
@@ -420,10 +431,11 @@ def test_docs_for_function_with_kwargs(self):
420431

421432
parser_config = generator.run_extraction()
422433

434+
api_node = doc_generator_visitor.ApiTreeNode(
435+
path=('test_function_with_args_kwargs',),
436+
py_object=test_function_with_args_kwargs)
423437
page_info = docs_for_object.docs_for_object(
424-
full_name='test_function_with_args_kwargs',
425-
py_object=test_function_with_args_kwargs,
426-
parser_config=parser_config)
438+
api_node=api_node, parser_config=parser_config)
427439

428440
# Make sure the brief docstring is present
429441
self.assertEqual(
@@ -594,10 +606,10 @@ def test_getsource_indexerror_resilience(self):
594606

595607
parser_config = generator.run_extraction()
596608

609+
api_node = doc_generator_visitor.ApiTreeNode(
610+
path=('m', 'ConcreteMutableMapping'), py_object=ConcreteMutableMapping)
597611
page_info = docs_for_object.docs_for_object(
598-
full_name='m.ConcreteMutableMapping',
599-
py_object=ConcreteMutableMapping,
600-
parser_config=parser_config)
612+
api_node=api_node, parser_config=parser_config)
601613

602614
self.assertIn(ConcreteMutableMapping.get,
603615
[m.py_object for m in page_info.methods])
@@ -621,8 +633,10 @@ def test_strips_default_arg_memory_address(self):
621633

622634
parser_config = generator.run_extraction()
623635

636+
api_node = doc_generator_visitor.ApiTreeNode(
637+
path=('m', 'fun'), py_object=m.fun)
624638
page_info = docs_for_object.docs_for_object(
625-
full_name='m.fun', py_object=m.fun, parser_config=parser_config)
639+
api_node=api_node, parser_config=parser_config)
626640

627641
output = str(page_info.signature)
628642
self.assertNotIn('object at 0x', output)
@@ -669,10 +683,10 @@ def test_empty_defined_in(self, cls, method, py_object):
669683

670684
parser_config = generator.run_extraction()
671685

686+
api_node = doc_generator_visitor.ApiTreeNode(
687+
path=(cls, method), py_object=py_object)
672688
function_info = docs_for_object.docs_for_object(
673-
full_name='%s.%s' % (cls, method),
674-
py_object=py_object,
675-
parser_config=parser_config)
689+
api_node=api_node, parser_config=parser_config)
676690

677691
self.assertIsNone(function_info.defined_in)
678692

tools/tensorflow_docs/api_generator/pretty_docs/base_page.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ class PageInfo:
110110

111111
def __init__(
112112
self,
113-
full_name: str,
114-
py_object: Any,
113+
api_node,
115114
extra_docs: Optional[Dict[int, str]] = None,
116115
search_hints: bool = True,
116+
parser_config=None,
117117
):
118118
"""Initialize a PageInfo.
119119
@@ -126,46 +126,48 @@ def __init__(
126126
"robots: noindex"
127127
128128
"""
129-
self.full_name = full_name
130-
self.py_object = py_object
129+
self.api_node = api_node
130+
self.full_name = api_node.full_name
131+
self.py_object = api_node.py_object
131132
self._extra_docs = extra_docs
132133
self.search_hints = search_hints
134+
self.parser_config = parser_config
133135

134136
self._defined_in = None
135137
self._aliases = None
136138
self._doc = None
137139
self._page_text = None
138140

139-
def collect_docs(self, parser_config: config.ParserConfig):
141+
def collect_docs(self):
140142
"""Collects additional information from the `config.ParserConfig`."""
141143
pass
142144

143-
def docs_for_object(self, parser_config):
144-
duplicate_names = parser_config.duplicates.get(self.full_name, [])
145-
if self.full_name in duplicate_names:
146-
duplicate_names.remove(self.full_name)
147-
145+
def docs_for_object(self):
148146
relative_path = os.path.relpath(
149147
path='.',
150148
start=os.path.dirname(parser.documentation_path(self.full_name)) or '.')
151149

152150
# Convert from OS-specific path to URL/POSIX path.
153151
relative_path = posixpath.join(*relative_path.split(os.path.sep))
154152

155-
with parser_config.reference_resolver.temp_prefix(relative_path):
153+
with self.parser_config.reference_resolver.temp_prefix(relative_path):
156154
self.set_doc(
157155
parser.parse_md_docstring(
158156
self.py_object,
159157
self.full_name,
160-
parser_config,
158+
self.parser_config,
161159
self._extra_docs,
162160
))
163161

164-
self.collect_docs(parser_config)
162+
self.collect_docs()
165163

166-
self.set_aliases(duplicate_names)
164+
aliases = ['.'.join(alias) for alias in self.api_node.aliases]
165+
if self.full_name in aliases:
166+
aliases.remove(self.full_name)
167+
self.set_aliases(aliases)
167168

168-
self.set_defined_in(parser.get_defined_in(self.py_object, parser_config))
169+
self.set_defined_in(
170+
parser.get_defined_in(self.py_object, self.parser_config))
169171

170172
self._page_text = self.build()
171173

0 commit comments

Comments
 (0)