Skip to content

Commit 63d3f5b

Browse files
MarkDaoustcopybara-github
authored andcommitted
Standardize the use of inspect.getsource
PiperOrigin-RevId: 438269328
1 parent 8aea6cc commit 63d3f5b

File tree

5 files changed

+61
-29
lines changed

5 files changed

+61
-29
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
# ==============================================================================
15+
"""Simple get_source."""
16+
import inspect
17+
import textwrap
18+
19+
from typing import Any, Optional, Sequence, Tuple
20+
21+
22+
def get_source(py_object: Any) -> Optional[str]:
23+
if py_object is not None:
24+
try:
25+
return textwrap.dedent(inspect.getsource(py_object))
26+
except Exception: # pylint: disable=broad-except
27+
# A wide-variety of errors can be thrown here.
28+
pass
29+
return None
30+
31+
32+
def get_source_lines(
33+
py_object: Any) -> Tuple[Optional[Sequence[str]], Optional[int]]:
34+
if py_object is not None:
35+
try:
36+
return inspect.getsourcelines(py_object)
37+
except Exception: # pylint: disable=broad-except
38+
# A wide-variety of errors can be thrown here.
39+
pass
40+
return None, None

tools/tensorflow_docs/api_generator/parser.py

Lines changed: 5 additions & 5 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_generator_visitor
31+
from tensorflow_docs.api_generator import get_source
3132
from tensorflow_docs.api_generator import obj_type as obj_type_lib
3233
from tensorflow_docs.api_generator import signature as signature_lib
3334

@@ -653,15 +654,14 @@ def get_defined_in(
653654
if code_url_prefix is None:
654655
return None
655656

656-
try:
657-
lines, start_line = inspect.getsourcelines(py_object)
657+
lines, start_line = get_source.get_source_lines(py_object)
658+
if start_line is None:
659+
end_line = None
660+
else:
658661
end_line = start_line + len(lines) - 1
659662
if 'MACHINE GENERATED' in lines[0]:
660663
# don't link to files generated by tf_export
661664
return None
662-
except (IOError, TypeError, IndexError):
663-
start_line = None
664-
end_line = None
665665

666666
# In case this is compiled, point to the original
667667
if posix_rel_path_str.endswith('.pyc'):

tools/tensorflow_docs/api_generator/public_api.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from tensorflow_docs.api_generator import doc_controls
2525
from tensorflow_docs.api_generator import doc_generator_visitor
26+
from tensorflow_docs.api_generator import get_source
2627

2728
_TYPING_IDS = frozenset(
2829
id(obj)
@@ -184,11 +185,10 @@ def visit_Import(self, node): # pylint: disable=invalid-name
184185
def visit_ImportFrom(self, node): # pylint: disable=invalid-name
185186
self._add_imported_symbol(node)
186187

187-
try:
188-
source = inspect.getsource(obj)
189-
except OSError:
190-
# inspect raises an OSError for empty module files.
188+
source = get_source.get_source(obj)
189+
if source is None:
191190
return []
191+
192192
tree = ast.parse(source)
193193
visitor = ImportNodeVisitor()
194194
visitor.visit(tree)

tools/tensorflow_docs/api_generator/report/linter.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,12 @@
2323

2424
import astor
2525

26+
from tensorflow_docs.api_generator import get_source
2627
from tensorflow_docs.api_generator import parser
2728
from tensorflow_docs.api_generator.pretty_docs import base_page
2829
from tensorflow_docs.api_generator.report.schema import api_report_generated_pb2 as api_report_pb2
2930

3031

31-
def _get_source(py_object: Any) -> Optional[str]:
32-
if py_object is not None:
33-
try:
34-
source = textwrap.dedent(inspect.getsource(py_object))
35-
return source
36-
except Exception: # pylint: disable=broad-except
37-
return None
38-
return None
3932

4033

4134
def _count_empty_param(items: List[Tuple[str, Optional[str]]]) -> int:
@@ -183,7 +176,7 @@ def lint_returns(
183176
Returns:
184177
A filled `ReturnLint` proto object.
185178
"""
186-
source = _get_source(page_info.py_object)
179+
source = get_source.get_source(page_info.py_object)
187180

188181
return_visitor = ReturnVisitor()
189182
if source is not None:
@@ -243,7 +236,7 @@ def lint_raises(page_info: base_page.PageInfo) -> api_report_pb2.RaisesLint:
243236

244237
# Extract the raises from the source code.
245238
raise_visitor = RaiseVisitor()
246-
source = _get_source(page_info.py_object)
239+
source = get_source.get_source(page_info.py_object)
247240
if source is not None:
248241
try:
249242
raise_visitor.visit(ast.parse(source))

tools/tensorflow_docs/api_generator/signature.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import astor
3131

3232
from tensorflow_docs.api_generator import config
33+
from tensorflow_docs.api_generator import get_source
3334
from tensorflow_docs.api_generator import public_api
3435

3536
EMPTY = inspect.Signature.empty
@@ -55,9 +56,10 @@ def _preprocess_default(self, val: ast.AST) -> str:
5556
return text_default_val
5657

5758
def extract(self, obj: Any):
58-
obj_source = textwrap.dedent(inspect.getsource(obj))
59-
obj_ast = ast.parse(obj_source)
60-
self.visit(obj_ast)
59+
obj_source = get_source.get_source(obj)
60+
if obj_source is not None:
61+
obj_ast = ast.parse(obj_source)
62+
self.visit(obj_ast)
6163

6264

6365
class _ArgDefaultAndAnnotationExtractor(_BaseDefaultAndAnnotationExtractor):
@@ -672,14 +674,11 @@ def visit_FunctionDef(self, node): # pylint: disable=invalid-name
672674

673675
visitor = ASTDecoratorExtractor()
674676

675-
try:
676-
# Note: inspect.getsource doesn't include the decorator lines on classes,
677-
# this won't work for classes until that's fixed.
678-
func_source = textwrap.dedent(inspect.getsource(func))
677+
# Note: inspect.getsource doesn't include the decorator lines on classes,
678+
# this won't work for classes until that's fixed.
679+
func_source = get_source.get_source(func)
680+
if func_source is not None:
679681
func_ast = ast.parse(func_source)
680682
visitor.visit(func_ast)
681-
except Exception: # pylint: disable=broad-except
682-
# A wide-variety of errors can be thrown here.
683-
pass
684683

685684
return visitor.decorator_list

0 commit comments

Comments
 (0)