Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add return type information only for functions #220

Merged
merged 6 commits into from
Oct 19, 2020

Conversation

mthuurne
Copy link
Contributor

@mthuurne mthuurne commented Oct 6, 2020

I noticed a stray "Returns" at the end of module descriptions when using pydoctor's master branch, but not with the 20.7.1 release. So this is a regression, probably introduced as part of #209.

The problem is that an empty FieldDesc is assigned to return_desc, which ends up in the HTML output as a return value because it evaluates to True even when empty. Rather than trying to define exactly how empty a FieldDesc must be to be considered False, I decided it was clearer to leave return_desc on its default value of None for Documentables other than functions.

@codecov
Copy link

codecov bot commented Oct 6, 2020

Codecov Report

Merging #220 into master will increase coverage by 0.09%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #220      +/-   ##
==========================================
+ Coverage   79.56%   79.66%   +0.09%     
==========================================
  Files          23       23              
  Lines        3616     3619       +3     
  Branches      786      788       +2     
==========================================
+ Hits         2877     2883       +6     
+ Misses        512      511       -1     
+ Partials      227      225       -2     
Impacted Files Coverage Δ
pydoctor/epydoc/markup/__init__.py 76.47% <100.00%> (+0.71%) ⬆️
pydoctor/epydoc2stan.py 76.33% <100.00%> (+0.75%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4b51a4a...97b554b. Read the comment docs.

pydoctor/epydoc2stan.py Outdated Show resolved Hide resolved
Comment on lines 14 to 22
class CapLog:
records: Sequence[LogRecord]

class CaptureResult(NamedTuple):
out: str
err: str

class CapSys:
def readouterr(self) -> CaptureResult: ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be better to use Protocols here, rather than concrete types - as that's what the pytest fixture types in pytest. will be.

otherwise you can use the exported types in _pytest.logging.LogCaptureFixture

Suggested change
class CapLog:
records: Sequence[LogRecord]
class CaptureResult(NamedTuple):
out: str
err: str
class CapSys:
def readouterr(self) -> CaptureResult: ...
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing_extensions import Protocol
class CapLog(Protocol):
records: Sequence[LogRecord]
class CaptureResult(Protocol):
out: str
err: str
class CapSys(Protocol):
def readouterr(self) -> CaptureResult: ...
else:
CapLog = CaptureResult = CapSys = None

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's probably a good idea, for #219 though.

There were 3 copies of this function already, as inner functions named
format(), and I'm planning to add more test cases that use it.
Currently this test fails because too much output is produced.
The return type information was added for all Documentables, which
is both unnecessary and leads to incorrect output.

Also do not redefine 'annotations' with a different type; use
a separate name instead.
The HTML5 spec specifies that a <table> element must contain "either
zero or more <tbody> elements or one or more <tr> elements".

Besides spec compliance, the HTML output is just smaller and cleaner
without the empty table.
Copy link
Contributor

@moshez moshez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One stylistic comment: either modify or not as you think right, and merge.

}
ret_type = formatted_annotations.pop('return', None)
ret_value = cls(obj, formatted_annotations)
if ret_type is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing a None sentinel, couldn't we do it with exceptions?

try:
    ret_type = formatted_annotations.pop("return")
except KeyError:
    pass
else:
        return_type = FieldDesc()
        return_type.body = ret_type
        ret_value.handle_returntype(return_type)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since ret_value is needed whether the return annotation exists or not, its creation must happen on both flows. But if it is moved before the pop(), then the return annotation will be mixed into the parameter annotations, which isn't how FieldHandler is designed. So we'd either have to duplicate the ret_value initialization or put ret_type = None in the except: clause and keep the if ret_type is not None:, neither of which is appealing.

Actually ret_value is a poorly chosen name here: it's the return value of the method, but has nothing to do with the return statement, unlike ret_type. I'll rename it to handler.

The name `ret_value` is confusing next to `ret_type`, since the former
is the return value of from_ast_annotations(), while the latter is the
type annotation for the return type of the introspected function.
@mthuurne mthuurne merged commit 15d62f6 into twisted:master Oct 19, 2020
@mthuurne mthuurne deleted the rettype-only-functions branch October 21, 2020 03:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants