Format docstrings in a consistent style
This commit is contained in:
@@ -71,9 +71,8 @@ class Code:
|
||||
|
||||
@property
|
||||
def path(self) -> Union[py.path.local, str]:
|
||||
"""Return a path object pointing to source code (or a str in case
|
||||
of OSError / non-existing file).
|
||||
"""
|
||||
"""Return a path object pointing to source code, or an ``str`` in
|
||||
case of ``OSError`` / non-existing file."""
|
||||
if not self.raw.co_filename:
|
||||
return ""
|
||||
try:
|
||||
@@ -420,15 +419,16 @@ class ExceptionInfo(Generic[_E]):
|
||||
exc_info: Tuple["Type[_E]", "_E", TracebackType],
|
||||
exprinfo: Optional[str] = None,
|
||||
) -> "ExceptionInfo[_E]":
|
||||
"""Returns an ExceptionInfo for an existing exc_info tuple.
|
||||
"""Return an ExceptionInfo for an existing exc_info tuple.
|
||||
|
||||
.. warning::
|
||||
|
||||
Experimental API
|
||||
|
||||
:param exprinfo: a text string helping to determine if we should
|
||||
strip ``AssertionError`` from the output, defaults
|
||||
to the exception message/``__str__()``
|
||||
:param exprinfo:
|
||||
A text string helping to determine if we should strip
|
||||
``AssertionError`` from the output. Defaults to the exception
|
||||
message/``__str__()``.
|
||||
"""
|
||||
_striptext = ""
|
||||
if exprinfo is None and isinstance(exc_info[1], AssertionError):
|
||||
@@ -444,15 +444,16 @@ class ExceptionInfo(Generic[_E]):
|
||||
def from_current(
|
||||
cls, exprinfo: Optional[str] = None
|
||||
) -> "ExceptionInfo[BaseException]":
|
||||
"""Returns an ExceptionInfo matching the current traceback.
|
||||
"""Return an ExceptionInfo matching the current traceback.
|
||||
|
||||
.. warning::
|
||||
|
||||
Experimental API
|
||||
|
||||
:param exprinfo: a text string helping to determine if we should
|
||||
strip ``AssertionError`` from the output, defaults
|
||||
to the exception message/``__str__()``
|
||||
:param exprinfo:
|
||||
A text string helping to determine if we should strip
|
||||
``AssertionError`` from the output. Defaults to the exception
|
||||
message/``__str__()``.
|
||||
"""
|
||||
tup = sys.exc_info()
|
||||
assert tup[0] is not None, "no current exception"
|
||||
@@ -467,7 +468,7 @@ class ExceptionInfo(Generic[_E]):
|
||||
return cls(None)
|
||||
|
||||
def fill_unfilled(self, exc_info: Tuple["Type[_E]", _E, TracebackType]) -> None:
|
||||
"""fill an unfilled ExceptionInfo created with for_later()"""
|
||||
"""Fill an unfilled ExceptionInfo created with ``for_later()``."""
|
||||
assert self._excinfo is None, "ExceptionInfo was already filled"
|
||||
self._excinfo = exc_info
|
||||
|
||||
@@ -568,7 +569,8 @@ class ExceptionInfo(Generic[_E]):
|
||||
Show locals per traceback entry.
|
||||
Ignored if ``style=="native"``.
|
||||
|
||||
:param str style: long|short|no|native|value traceback style
|
||||
:param str style:
|
||||
long|short|no|native|value traceback style.
|
||||
|
||||
:param bool abspath:
|
||||
If paths should be changed to absolute or left unchanged.
|
||||
@@ -583,7 +585,8 @@ class ExceptionInfo(Generic[_E]):
|
||||
:param bool truncate_locals:
|
||||
With ``showlocals==True``, make sure locals can be safely represented as strings.
|
||||
|
||||
:param bool chain: if chained exceptions in Python 3 should be shown.
|
||||
:param bool chain:
|
||||
If chained exceptions in Python 3 should be shown.
|
||||
|
||||
.. versionchanged:: 3.9
|
||||
|
||||
@@ -643,7 +646,7 @@ class FormattedExcinfo:
|
||||
astcache = attr.ib(default=attr.Factory(dict), init=False, repr=False)
|
||||
|
||||
def _getindent(self, source: "Source") -> int:
|
||||
# figure out indent for given source
|
||||
# Figure out indent for the given source.
|
||||
try:
|
||||
s = str(source.getstatement(len(source) - 1))
|
||||
except KeyboardInterrupt:
|
||||
@@ -704,7 +707,7 @@ class FormattedExcinfo:
|
||||
) -> List[str]:
|
||||
lines = []
|
||||
indentstr = " " * indent
|
||||
# get the real exception information out
|
||||
# Get the real exception information out.
|
||||
exlines = excinfo.exconly(tryshort=True).split("\n")
|
||||
failindent = self.fail_marker + indentstr[1:]
|
||||
for line in exlines:
|
||||
@@ -730,8 +733,7 @@ class FormattedExcinfo:
|
||||
str_repr = saferepr(value)
|
||||
else:
|
||||
str_repr = safeformat(value)
|
||||
# if len(str_repr) < 70 or not isinstance(value,
|
||||
# (list, tuple, dict)):
|
||||
# if len(str_repr) < 70 or not isinstance(value, (list, tuple, dict)):
|
||||
lines.append("{:<10} = {}".format(name, str_repr))
|
||||
# else:
|
||||
# self._line("%-10s =\\" % (name,))
|
||||
@@ -809,16 +811,17 @@ class FormattedExcinfo:
|
||||
def _truncate_recursive_traceback(
|
||||
self, traceback: Traceback
|
||||
) -> Tuple[Traceback, Optional[str]]:
|
||||
"""
|
||||
Truncate the given recursive traceback trying to find the starting point
|
||||
of the recursion.
|
||||
"""Truncate the given recursive traceback trying to find the starting
|
||||
point of the recursion.
|
||||
|
||||
The detection is done by going through each traceback entry and finding the
|
||||
point in which the locals of the frame are equal to the locals of a previous frame (see ``recursionindex()``.
|
||||
The detection is done by going through each traceback entry and
|
||||
finding the point in which the locals of the frame are equal to the
|
||||
locals of a previous frame (see ``recursionindex()``).
|
||||
|
||||
Handle the situation where the recursion process might raise an exception (for example
|
||||
comparing numpy arrays using equality raises a TypeError), in which case we do our best to
|
||||
warn the user of the error and show a limited traceback.
|
||||
Handle the situation where the recursion process might raise an
|
||||
exception (for example comparing numpy arrays using equality raises a
|
||||
TypeError), in which case we do our best to warn the user of the
|
||||
error and show a limited traceback.
|
||||
"""
|
||||
try:
|
||||
recursionindex = traceback.recursionindex()
|
||||
@@ -863,8 +866,8 @@ class FormattedExcinfo:
|
||||
excinfo_._getreprcrash() if self.style != "value" else None
|
||||
) # type: Optional[ReprFileLocation]
|
||||
else:
|
||||
# fallback to native repr if the exception doesn't have a traceback:
|
||||
# ExceptionInfo objects require a full traceback to work
|
||||
# Fallback to native repr if the exception doesn't have a traceback:
|
||||
# ExceptionInfo objects require a full traceback to work.
|
||||
reprtraceback = ReprTracebackNative(
|
||||
traceback.format_exception(type(e), e, None)
|
||||
)
|
||||
@@ -915,7 +918,7 @@ class TerminalRepr:
|
||||
# This class is abstract -- only subclasses are instantiated.
|
||||
@attr.s(**{ATTRS_EQ_FIELD: False}) # type: ignore
|
||||
class ExceptionRepr(TerminalRepr):
|
||||
# Provided by in subclasses.
|
||||
# Provided by subclasses.
|
||||
reprcrash = None # type: Optional[ReprFileLocation]
|
||||
reprtraceback = None # type: ReprTraceback
|
||||
|
||||
@@ -942,7 +945,7 @@ class ExceptionChainRepr(ExceptionRepr):
|
||||
def __attrs_post_init__(self) -> None:
|
||||
super().__attrs_post_init__()
|
||||
# reprcrash and reprtraceback of the outermost (the newest) exception
|
||||
# in the chain
|
||||
# in the chain.
|
||||
self.reprtraceback = self.chain[-1][0]
|
||||
self.reprcrash = self.chain[-1][1]
|
||||
|
||||
@@ -974,7 +977,7 @@ class ReprTraceback(TerminalRepr):
|
||||
entrysep = "_ "
|
||||
|
||||
def toterminal(self, tw: TerminalWriter) -> None:
|
||||
# the entries might have different styles
|
||||
# The entries might have different styles.
|
||||
for i, entry in enumerate(self.reprentries):
|
||||
if entry.style == "long":
|
||||
tw.line("")
|
||||
@@ -1017,7 +1020,7 @@ class ReprEntry(TerminalRepr):
|
||||
style = attr.ib(type="_TracebackStyle")
|
||||
|
||||
def _write_entry_lines(self, tw: TerminalWriter) -> None:
|
||||
"""Writes the source code portions of a list of traceback entries with syntax highlighting.
|
||||
"""Write the source code portions of a list of traceback entries with syntax highlighting.
|
||||
|
||||
Usually entries are lines like these:
|
||||
|
||||
@@ -1099,8 +1102,8 @@ class ReprFileLocation(TerminalRepr):
|
||||
message = attr.ib(type=str)
|
||||
|
||||
def toterminal(self, tw: TerminalWriter) -> None:
|
||||
# filename and lineno output for each entry,
|
||||
# using an output format that most editors understand
|
||||
# Filename and lineno output for each entry, using an output format
|
||||
# that most editors understand.
|
||||
msg = self.message
|
||||
i = msg.find("\n")
|
||||
if i != -1:
|
||||
@@ -1175,10 +1178,10 @@ def getfslineno(obj: object) -> Tuple[Union[str, py.path.local], int]:
|
||||
return code.path, code.firstlineno
|
||||
|
||||
|
||||
# relative paths that we use to filter traceback entries from appearing to the user;
|
||||
# see filter_traceback
|
||||
# Relative paths that we use to filter traceback entries from appearing to the user;
|
||||
# see filter_traceback.
|
||||
# note: if we need to add more paths than what we have now we should probably use a list
|
||||
# for better maintenance
|
||||
# for better maintenance.
|
||||
|
||||
_PLUGGY_DIR = py.path.local(pluggy.__file__.rstrip("oc"))
|
||||
# pluggy is either a package or a single module depending on the version
|
||||
@@ -1197,14 +1200,14 @@ def filter_traceback(entry: TracebackEntry) -> bool:
|
||||
* internal traceback from pytest or its internal libraries, py and pluggy.
|
||||
"""
|
||||
# entry.path might sometimes return a str object when the entry
|
||||
# points to dynamically generated code
|
||||
# see https://bitbucket.org/pytest-dev/py/issues/71
|
||||
# points to dynamically generated code.
|
||||
# See https://bitbucket.org/pytest-dev/py/issues/71.
|
||||
raw_filename = entry.frame.code.raw.co_filename
|
||||
is_generated = "<" in raw_filename and ">" in raw_filename
|
||||
if is_generated:
|
||||
return False
|
||||
# entry.path might point to a non-existing file, in which case it will
|
||||
# also return a str object. see #1133
|
||||
# also return a str object. See #1133.
|
||||
p = py.path.local(entry.path)
|
||||
return (
|
||||
not p.relto(_PLUGGY_DIR) and not p.relto(_PYTEST_DIR) and not p.relto(_PY_DIR)
|
||||
|
||||
@@ -67,9 +67,7 @@ class Source:
|
||||
return len(self.lines)
|
||||
|
||||
def strip(self) -> "Source":
|
||||
""" return new source object with trailing
|
||||
and leading blank lines removed.
|
||||
"""
|
||||
"""Return new Source object with trailing and leading blank lines removed."""
|
||||
start, end = 0, len(self)
|
||||
while start < end and not self.lines[start].strip():
|
||||
start += 1
|
||||
@@ -80,31 +78,28 @@ class Source:
|
||||
return source
|
||||
|
||||
def indent(self, indent: str = " " * 4) -> "Source":
|
||||
""" return a copy of the source object with
|
||||
all lines indented by the given indent-string.
|
||||
"""
|
||||
"""Return a copy of the source object with all lines indented by the
|
||||
given indent-string."""
|
||||
newsource = Source()
|
||||
newsource.lines = [(indent + line) for line in self.lines]
|
||||
return newsource
|
||||
|
||||
def getstatement(self, lineno: int) -> "Source":
|
||||
""" return Source statement which contains the
|
||||
given linenumber (counted from 0).
|
||||
"""
|
||||
"""Return Source statement which contains the given linenumber
|
||||
(counted from 0)."""
|
||||
start, end = self.getstatementrange(lineno)
|
||||
return self[start:end]
|
||||
|
||||
def getstatementrange(self, lineno: int) -> Tuple[int, int]:
|
||||
""" return (start, end) tuple which spans the minimal
|
||||
statement region which containing the given lineno.
|
||||
"""
|
||||
"""Return (start, end) tuple which spans the minimal statement region
|
||||
which containing the given lineno."""
|
||||
if not (0 <= lineno < len(self)):
|
||||
raise IndexError("lineno out of range")
|
||||
ast, start, end = getstatementrange_ast(lineno, self)
|
||||
return start, end
|
||||
|
||||
def deindent(self) -> "Source":
|
||||
"""return a new source object deindented."""
|
||||
"""Return a new Source object deindented."""
|
||||
newsource = Source()
|
||||
newsource.lines[:] = deindent(self.lines)
|
||||
return newsource
|
||||
@@ -129,7 +124,7 @@ def findsource(obj) -> Tuple[Optional[Source], int]:
|
||||
|
||||
|
||||
def getrawcode(obj, trycall: bool = True):
|
||||
""" return code object for given function. """
|
||||
"""Return code object for given function."""
|
||||
try:
|
||||
return obj.__code__
|
||||
except AttributeError:
|
||||
@@ -148,8 +143,8 @@ def deindent(lines: Iterable[str]) -> List[str]:
|
||||
|
||||
|
||||
def get_statement_startend2(lineno: int, node: ast.AST) -> Tuple[int, Optional[int]]:
|
||||
# flatten all statements and except handlers into one lineno-list
|
||||
# AST's line numbers start indexing at 1
|
||||
# Flatten all statements and except handlers into one lineno-list.
|
||||
# AST's line numbers start indexing at 1.
|
||||
values = [] # type: List[int]
|
||||
for x in ast.walk(node):
|
||||
if isinstance(x, (ast.stmt, ast.ExceptHandler)):
|
||||
@@ -157,7 +152,7 @@ def get_statement_startend2(lineno: int, node: ast.AST) -> Tuple[int, Optional[i
|
||||
for name in ("finalbody", "orelse"):
|
||||
val = getattr(x, name, None) # type: Optional[List[ast.stmt]]
|
||||
if val:
|
||||
# treat the finally/orelse part as its own statement
|
||||
# Treat the finally/orelse part as its own statement.
|
||||
values.append(val[0].lineno - 1 - 1)
|
||||
values.sort()
|
||||
insert_index = bisect_right(values, lineno)
|
||||
@@ -178,13 +173,13 @@ def getstatementrange_ast(
|
||||
if astnode is None:
|
||||
content = str(source)
|
||||
# See #4260:
|
||||
# don't produce duplicate warnings when compiling source to find ast
|
||||
# Don't produce duplicate warnings when compiling source to find AST.
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
astnode = ast.parse(content, "source", "exec")
|
||||
|
||||
start, end = get_statement_startend2(lineno, astnode)
|
||||
# we need to correct the end:
|
||||
# We need to correct the end:
|
||||
# - ast-parsing strips comments
|
||||
# - there might be empty lines
|
||||
# - we might have lesser indented code blocks at the end
|
||||
@@ -192,10 +187,10 @@ def getstatementrange_ast(
|
||||
end = len(source.lines)
|
||||
|
||||
if end > start + 1:
|
||||
# make sure we don't span differently indented code blocks
|
||||
# by using the BlockFinder helper used which inspect.getsource() uses itself
|
||||
# Make sure we don't span differently indented code blocks
|
||||
# by using the BlockFinder helper used which inspect.getsource() uses itself.
|
||||
block_finder = inspect.BlockFinder()
|
||||
# if we start with an indented line, put blockfinder to "started" mode
|
||||
# If we start with an indented line, put blockfinder to "started" mode.
|
||||
block_finder.started = source.lines[start][0].isspace()
|
||||
it = ((x + "\n") for x in source.lines[start:end])
|
||||
try:
|
||||
@@ -206,7 +201,7 @@ def getstatementrange_ast(
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# the end might still point to a comment or empty line, correct it
|
||||
# The end might still point to a comment or empty line, correct it.
|
||||
while end:
|
||||
line = source.lines[end - 1].lstrip()
|
||||
if line.startswith("#") or not line:
|
||||
|
||||
Reference in New Issue
Block a user