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

Fixes, cleanups and type annotations for zope.interface support #336

Merged
merged 16 commits into from
Dec 29, 2020

Conversation

mthuurne
Copy link
Contributor

@mthuurne mthuurne commented Dec 17, 2020

After I added annotations, mypy flagged several cases where pydoctor made invalid assumptions about types. These could lead to crashes when analyzing invalid code. Since projects don't tend to keep invalid code around, this is unlikely to occur often in practice, but of course it shouldn't happen at all. In one case, the method (allImplementations property) was broken but it was never called, so it couldn't lead to problems.

@mthuurne
Copy link
Contributor Author

CI seems to be broken because of actions/setup-python#171.

Inner methods are difficult for mypy. In this particular case, mypy
doesn't know that 'expr' is a Call instance, because it doesn't know
that the assert that establishes that will always run before the
inner method is called and 'expr' won't be modified afterward.
The visit_Call_zope_interface_classImplements() method assumes that
if the first argument can be resolved to an object, that object will
be a class. Since that is the correct way to use classImplements(),
this assumption is usually true, but it doesn't have to hold when
analyzing broken code or mis-analyzing complex code.
The old warning didn't print a source location and didn't have unit
test coverage.
This default was inactive because we override 'exclude_lines'.
If we don't have a name for the decorator, we can't do anything useful
with it, so there is no point in storing it. Not storing it means that
the code analyzing decorators later doesn't have to deal with 'base'
being None.

Note that analysis can fail in theory, but in practice I was unable
to find any decorators for which this happens: CPython's parser for
decorators seems to be quite strict and every attempt I made to
use a nonsensical decorator resulted in SyntaxError being raised.
This decorator requires arguments, but in broken code it can occur
without being called.
This property was used by the pydoctor.html module, which was removed
over a year ago, in commit 8040e1d. Since it did have test coverage,
it wasn't obvious that it was dead code.

After I added annotations, mypy reported that 'c' could be an instance
of ZopeInterfaceModule, which doesn't have a 'subclasses' attribute.
When I tried to find any use cases that could trigger this bug, I found
out that nothing uses this property.
Now that the whole package is annotated, we no longer need to exempt
this package from the `disallow_untyped_defs` setting.
If we can return an existing list under a read-only type, do so.

I don't expect this to make much of a difference though: in
Twisted, there are zero uses of implementsOnly() and one use
of moduleProvides().
@codecov
Copy link

codecov bot commented Dec 18, 2020

Codecov Report

Merging #336 (7ce9227) into master (d9e91cc) will increase coverage by 0.15%.
The diff coverage is 94.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #336      +/-   ##
==========================================
+ Coverage   85.73%   85.89%   +0.15%     
==========================================
  Files          22       22              
  Lines        3927     3914      -13     
  Branches      817      812       -5     
==========================================
- Hits         3367     3362       -5     
+ Misses        359      355       -4     
+ Partials      201      197       -4     
Impacted Files Coverage Δ
pydoctor/zopeinterface.py 87.74% <94.11%> (+3.38%) ⬆️
pydoctor/astbuilder.py 91.73% <100.00%> (-0.10%) ⬇️
pydoctor/model.py 89.22% <100.00%> (+0.02%) ⬆️

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 d9e91cc...7ce9227. Read the comment docs.

The other two elements of the tuple were not used anywhere.
The other two elements of the tuple were not used anywhere.
Previously, self.builder.current was used as the scope, but this will
contain the class being decorated at time of evaluation, which is not
the right context for the class decorators.
There are only strings in the 'bases' attribute. I guess the other
types were present at some point during the port to the 'ast' module,
but they didn't stick around.
This is more efficient than looking up the name. And more reliable,
if for example the name was altered because it was a duplicate.
@mthuurne mthuurne marked this pull request as ready for review December 18, 2020 22:47
@mthuurne mthuurne requested a review from a team December 28, 2020 09:39
Copy link
Member

@adiroiban adiroiban left a comment

Choose a reason for hiding this comment

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

Wonderful work. Thanks!
This can be merged.

pydoctor/test/test_astbuilder.py Show resolved Hide resolved
@mthuurne mthuurne merged commit f64d1de into twisted:master Dec 29, 2020
@mthuurne mthuurne deleted the annotate-zopeinterface branch December 29, 2020 03:27
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.

None yet

2 participants