summaryrefslogtreecommitdiff
path: root/sphinx/pycode
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/pycode')
-rw-r--r--sphinx/pycode/__init__.py27
-rw-r--r--sphinx/pycode/ast.py24
-rw-r--r--sphinx/pycode/parser.py7
3 files changed, 27 insertions, 31 deletions
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index 4879fb349..6505f8dbb 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -10,14 +10,12 @@
import re
import tokenize
-import warnings
from importlib import import_module
from io import StringIO
from os import path
from typing import Any, Dict, IO, List, Tuple, Optional
from zipfile import ZipFile
-from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.errors import PycodeError
from sphinx.pycode.parser import Parser
@@ -77,7 +75,7 @@ class ModuleAnalyzer:
@classmethod
def for_string(cls, string: str, modname: str, srcname: str = '<string>'
) -> "ModuleAnalyzer":
- return cls(StringIO(string), modname, srcname, decoded=True)
+ return cls(StringIO(string), modname, srcname)
@classmethod
def for_file(cls, filename: str, modname: str) -> "ModuleAnalyzer":
@@ -85,7 +83,7 @@ class ModuleAnalyzer:
return cls.cache['file', filename]
try:
with tokenize.open(filename) as f:
- obj = cls(f, modname, filename, decoded=True)
+ obj = cls(f, modname, filename)
cls.cache['file', filename] = obj
except Exception as err:
if '.egg' + path.sep in filename:
@@ -125,21 +123,12 @@ class ModuleAnalyzer:
cls.cache['module', modname] = obj
return obj
- def __init__(self, source: IO, modname: str, srcname: str, decoded: bool = False) -> None:
+ def __init__(self, source: IO, modname: str, srcname: str) -> None:
self.modname = modname # name of the module
self.srcname = srcname # name of the source file
# cache the source code as well
- pos = source.tell()
- if not decoded:
- warnings.warn('decode option for ModuleAnalyzer is deprecated.',
- RemovedInSphinx40Warning, stacklevel=2)
- self._encoding, _ = tokenize.detect_encoding(source.readline)
- source.seek(pos)
- self.code = source.read().decode(self._encoding)
- else:
- self._encoding = None
- self.code = source.read()
+ self.code = source.read()
# will be filled by parse()
self.annotations = None # type: Dict[Tuple[str, str], str]
@@ -151,7 +140,7 @@ class ModuleAnalyzer:
def parse(self) -> None:
"""Parse the source code."""
try:
- parser = Parser(self.code, self._encoding)
+ parser = Parser(self.code)
parser.parse()
self.attr_docs = {}
@@ -181,9 +170,3 @@ class ModuleAnalyzer:
self.parse()
return self.tags
-
- @property
- def encoding(self) -> str:
- warnings.warn('ModuleAnalyzer.encoding is deprecated.',
- RemovedInSphinx40Warning, stacklevel=2)
- return self._encoding
diff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py
index 9bafff11c..9734cb476 100644
--- a/sphinx/pycode/ast.py
+++ b/sphinx/pycode/ast.py
@@ -10,6 +10,7 @@
import sys
from typing import Dict, List, Type, Optional
+from typing import overload
if sys.version_info > (3, 8):
import ast
@@ -58,6 +59,16 @@ def parse(code: str, mode: str = 'exec') -> "ast.AST":
return ast.parse(code, mode=mode)
+@overload
+def unparse(node: None) -> None:
+ ...
+
+
+@overload
+def unparse(node: ast.AST) -> str:
+ ...
+
+
def unparse(node: Optional[ast.AST]) -> Optional[str]:
"""Unparse an AST to string."""
if node is None:
@@ -144,6 +155,12 @@ class _UnparseVisitor(ast.NodeVisitor):
["%s=%s" % (k.arg, self.visit(k.value)) for k in node.keywords])
return "%s(%s)" % (self.visit(node.func), ", ".join(args))
+ def visit_Constant(self, node: ast.Constant) -> str: # type: ignore
+ if node.value is Ellipsis:
+ return "..."
+ else:
+ return repr(node.value)
+
def visit_Dict(self, node: ast.Dict) -> str:
keys = (self.visit(k) for k in node.keys)
values = (self.visit(v) for v in node.values)
@@ -177,13 +194,6 @@ class _UnparseVisitor(ast.NodeVisitor):
else:
return "()"
- if sys.version_info >= (3, 6):
- def visit_Constant(self, node: ast.Constant) -> str:
- if node.value is Ellipsis:
- return "..."
- else:
- return repr(node.value)
-
if sys.version_info < (3, 8):
# these ast nodes were deprecated in python 3.8
def visit_Bytes(self, node: ast.Bytes) -> str:
diff --git a/sphinx/pycode/parser.py b/sphinx/pycode/parser.py
index 3762c72cc..7eb2419c0 100644
--- a/sphinx/pycode/parser.py
+++ b/sphinx/pycode/parser.py
@@ -93,7 +93,10 @@ def dedent_docstring(s: str) -> str:
dummy.__doc__ = s
docstring = inspect.getdoc(dummy)
- return docstring.lstrip("\r\n").rstrip("\r\n")
+ if docstring:
+ return docstring.lstrip("\r\n").rstrip("\r\n")
+ else:
+ return ""
class Token:
@@ -367,7 +370,7 @@ class VariableCommentPicker(ast.NodeVisitor):
for varname in varnames:
self.add_entry(varname)
- def visit_AnnAssign(self, node: ast.AST) -> None: # Note: ast.AnnAssign not found in py35
+ def visit_AnnAssign(self, node: ast.AnnAssign) -> None:
"""Handles AnnAssign node and pick up a variable comment."""
self.visit_Assign(node) # type: ignore