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

Provides caching for the linker #498

Merged
merged 27 commits into from
Mar 6, 2022
Merged

Conversation

tristanlatr
Copy link
Contributor

@tristanlatr tristanlatr commented Feb 18, 2022

This PR tries to solve #497, it partially succeeds but we also need to cache the whole Documentable summary stan.

It does fixes #478

@tristanlatr tristanlatr marked this pull request as draft February 18, 2022 06:01
@codecov
Copy link

codecov bot commented Feb 18, 2022

Codecov Report

Merging #498 (411ae79) into master (c367d21) will increase coverage by 0.16%.
The diff coverage is 96.79%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #498      +/-   ##
==========================================
+ Coverage   89.90%   90.06%   +0.16%     
==========================================
  Files          35       35              
  Lines        6369     6504     +135     
  Branches     1436     1463      +27     
==========================================
+ Hits         5726     5858     +132     
- Misses        391      392       +1     
- Partials      252      254       +2     
Impacted Files Coverage Δ
pydoctor/epydoc2stan.py 90.72% <96.55%> (+1.59%) ⬆️
pydoctor/astbuilder.py 95.10% <100.00%> (ø)
pydoctor/model.py 92.58% <100.00%> (+0.10%) ⬆️
pydoctor/templatewriter/pages/__init__.py 84.16% <100.00%> (ø)

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 c367d21...411ae79. Read the comment docs.

@tristanlatr
Copy link
Contributor Author

Note: It does not seem to influence the performance of pydoctor, but many warnings are now displayed only once and not many times! so that's good.

@tristanlatr tristanlatr marked this pull request as ready for review February 18, 2022 17:45
@tristanlatr tristanlatr marked this pull request as draft February 18, 2022 19:27
@tristanlatr tristanlatr marked this pull request as ready for review February 18, 2022 23:29
@adiroiban
Copy link
Member

Thanks for the update.

I am a bit busy these days. if @not-my-profile can review this, that would be great :)

Comment on lines 378 to 388
@property
def docstringlinker(self) -> 'epydoc2stan.DocstringLinker':
"""
Returns an instance of L{epydoc2stan.DocstringLinker} suitable for resolving names
in the context of the object scope.
"""
if self._linker is not None:
return self._linker
from pydoctor.epydoc2stan import _CachedEpydocLinker
self._linker = _CachedEpydocLinker(self)
return self._linker
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The best would be to avoid this workaround cyclic imports.
In order to do that, we should move all code related to the concrete docstring linkers in a new module: docstringlinker.py. I wonder if this change should happen in this PR though ?

Copy link
Member

Choose a reason for hiding this comment

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

Better for a separate PR, but also add all this info in a code comment :)

Use string annotation in the linker code when possible and add even more docs to the cached linker.

Correct english.
@tristanlatr
Copy link
Contributor Author

@adiroiban, I don't think @not-my-profile wants to be involved in pydoctor development. He manifested interest into creating a new doc generator based on mypy internals. So I don't think we should wait for his review.

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.

Hi,Thanks for the update.

If there is no speedup, I am not sure if it's worth it.

Also by not having repeated errors, it might be ok when you run locally, but for CI, I prefer to see all the errors so that I can fix them in one run.

So.. I am now +1 for this change, but you are the maintainer and if you want to have this code, I am ok with that.

Thanks again!

@@ -119,31 +134,46 @@ def look_for_intersphinx(self, name: str) -> Optional[str]:
return self.obj.system.intersphinx.getLink(name)

def link_to(self, identifier: str, label: "Flattenable") -> Tag:
# :Raises _EpydocLinker.LookupFailed: If the identifier cannot be resolved and self.strict is True.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe have this as docstrig instead of comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do

Copy link
Contributor Author

@tristanlatr tristanlatr Feb 24, 2022

Choose a reason for hiding this comment

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

Actually, I remember. I did not do that not to override the docstirng inherited by ParsedDocstring.
Since this an implementation detail because we're always using the _CachedEpydocLinker, and I did not want to change the pretty well documented docstring that we already have for link_to and link_xref.


def link_xref(self, target: str, label: "Flattenable", lineno: int) -> Tag:
# :Raises _EpydocLinker.LookupFailed: If the identifier cannot be resolved and self.strict is True.
Copy link
Member

Choose a reason for hiding this comment

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

Can we have it as docstring?

Comment on lines 378 to 388
@property
def docstringlinker(self) -> 'epydoc2stan.DocstringLinker':
"""
Returns an instance of L{epydoc2stan.DocstringLinker} suitable for resolving names
in the context of the object scope.
"""
if self._linker is not None:
return self._linker
from pydoctor.epydoc2stan import _CachedEpydocLinker
self._linker = _CachedEpydocLinker(self)
return self._linker
Copy link
Member

Choose a reason for hiding this comment

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

Better for a separate PR, but also add all this info in a code comment :)

@tristanlatr
Copy link
Contributor Author

Also by not having repeated errors, it might be ok when you run locally, but for CI, I prefer to see all the errors so that I can fix them in one run.

We are talking about the same errors again and again for the summary table generation, not different errors. Just run

$ wget -O nodes.py https://sourceforge.net/p/docutils/code/HEAD/tree/tags/docutils-0.17.1/docutils/nodes.py?format=raw
$ time pydoctor nodes.py

And you'll see what I mean. See #497

@tristanlatr
Copy link
Contributor Author

If there is no speedup, I am not sure if it's worth it.

@adiroiban,

I've thought to give up this change and instead implement caching for summaries and docstring stan. But here's the deal: there is not way to simply ignore xref warnings when we call parse_docstring, so warnings are getting reported when we generate stan for the summary, so at least invalid links present in the fist three lines of docstrings will be reported twice even if we cache the docstring and summary stan (and even if we fix #86. Actually we'de need to have both #86 and #421 fixed and compute the summary document from a version with already resolved links in it). So maybe this patch is just the wrong way of dealing with this problem.

I'm unsure what's the best way forward. The class _CachedEpydocLinker is 200 lines of codes and the same in tests. But tests can be recycled anyway. Yes it's a bit of complexity (and multiple invalid link on the same line are reported only once, but it's better than reporting warnings X times the number of summaries we generate for that object. Also if you fix one link in one line in the docstring it's likely that you'll notice the other invalid link that is using the same target on the same line). What I mean is this code can be used until we have fixed #421, #86 and implemented docstring stan caching, then we can remove the _CachedEpydocLinker and simply replace all occurences with _EpydocLinker.

Please tell me what you think, ok I'm maintainer but I do want to fix issue this the right way.

Thanks.

@tristanlatr
Copy link
Contributor Author

Do you have comments @adiroiban ?
Otherwise we would proceed with the proposed plan.

@adiroiban
Copy link
Member

I am not -1 on this.
And reducing noise in the output is +1.
So I think that this can be merge.

Thanks!


Sorry... I didn't had time to look into pydoctor for twisted usage and why CI doesn't fail an warnings.

@tristanlatr
Copy link
Contributor Author

Great, thanks!

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.

Links in docstring summary break when the summary is included on another page
2 participants