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

Visit Try 'orelse', 'finalbody' and 'handlers' and If 'orelse' #589

Open
wants to merge 32 commits into
base: master
Choose a base branch
from

Conversation

tristanlatr
Copy link
Contributor

@tristanlatr tristanlatr commented May 24, 2022

…re. The older visitor relied on generic_visit() to be recursive. Where the provided generic_visit() is not recursive anymore, and moreover not called automatically when visiting unknow nodes! So what I'm saying here is that since #576 have been merged, we're not visiting the statements inside the 'orelse' field of Try and If nodes, same goes for 'finalbody' and 'handlers'.

This commit fixes that issue. The rationale is now the following: All statements in the 'orelse' block of IF nodes and statements in the except handlers of TRY nodes that would override a name already defined in the main 'body' (or TRY 'orelse' or 'finalbody') are ignored.

Meaning that in the context of the code below, 'ssl' would resolve to 'twisted.internet.ssl':

try:
    from twisted.internet import ssl as _ssl
except ImportError:
    ssl = None
else:
    ssl = _ssl
@codecov
Copy link

codecov bot commented May 24, 2022

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 92.85%. Comparing base (f835fb4) to head (2dd25e1).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #589      +/-   ##
==========================================
+ Coverage   92.68%   92.85%   +0.17%     
==========================================
  Files          47       47              
  Lines        8279     8310      +31     
  Branches     1828     1842      +14     
==========================================
+ Hits         7673     7716      +43     
+ Misses        347      337      -10     
+ Partials      259      257       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@tristanlatr
Copy link
Contributor Author

tristanlatr commented May 24, 2022

Tell me if you think the rationale is good @glyph @adiroiban. Also, this needs to be documented in the codedoc.rst file.

I think that we could introduce options to choose how to evaluate a specific name in a module, for instance TYPE_CHECKING, in some complex module, it could more easy fo pydoctor to visit the 'orelse' field only if the If.test can be evaluated to something we passed in as an option. See #590

@tristanlatr tristanlatr changed the title Visit try orelse finalbody and if orelse Visit Try 'orelse', 'finalbody' and 'handlers' and If 'orelse' May 24, 2022
@tristanlatr tristanlatr requested a review from glyph May 24, 2022 01:13
pydoctor/astbuilder.py Outdated Show resolved Hide resolved
pydoctor/astbuilder.py Outdated Show resolved Hide resolved
pydoctor/astbuilder.py Outdated Show resolved Hide resolved
pydoctor/astbuilder.py Outdated Show resolved Hide resolved
pydoctor/test/test_astbuilder.py Outdated Show resolved Hide resolved
@tristanlatr
Copy link
Contributor Author

This PR is somewhat liked to #17 and #33 in the sense that a duplicate name defined in except handlers or a If else block will not override the name previously defined.

So in the case of class 'Arena' from https://github.com/python/cpython/blob/d2ef66a10be1250b13c32fbf3c0f9a9d2d98b124/Lib/multiprocessing/heap.py#L31
Only the first class will be documented.

Copy link
Member

@glyph glyph left a comment

Choose a reason for hiding this comment

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

LGTM with the caveat that the specific semantics of the priorities should be better explained in terms of specific order, rather than things not-getting-overridden which is a sort of a double negative.

docs/source/codedoc.rst Outdated Show resolved Hide resolved
Comment on lines 325 to 326
When pydoctor deals with try/except/else or if/else block, it makes sure that the names defined in
the "principal" branch do not get overriden by names defined in the except hanlders or ifs' else block.
Copy link
Member

Choose a reason for hiding this comment

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

This strikes me as a bit awkward. I think you want to be saying something about the priority of the binding of the name in the last branch? Or the else branch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No it's not about whether the branch is last or not. It's only the except hanlders and ifs' else blocks where we enable the override name guard.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please advise on another wording you would have used :)

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 else branch of try: blocks have the priority over the except: block. Similarly, the main body of if: blocks have priority over what's defined in the else: block.

So the thing that might be confusing here if that Try.orelse and If.orelse are NOT handled with the same override priority. Because the main branches in case of a if: is the body uniquely and in case of a try: it's the body, the orelse and the finalbody, in this order. So just saying else: block can be confusing if we don't know if it's the else block of a IF statement or a TRY statement.

@contextlib.contextmanager
def override_guard(self) -> Iterator[None]:
"""
Returns a context manager that will make the builder ignore any extraneous
Copy link
Member

Choose a reason for hiding this comment

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

A clearer explanation of the definition of "extraneous" would be interesting here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

extraneous meaning assignments to name that already exist

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can read: "Returns a context manager that will make the builder ignore any new assignments to names that already existed in the same context"

@@ -227,6 +294,9 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None:
parent = self.builder.current
if isinstance(parent, model.Function):
raise self.SkipNode()
# Ignore in override guard
if self._name_in_override_guard(parent, node.name):
raise self.SkipNode()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder why this code is required, a module under an if branch is not possible. I also wonder how this code is not marked as unreached by the tests…

@contextlib.contextmanager
def override_guard(self) -> Iterator[None]:
"""
Returns a context manager that will make the builder ignore any extraneous
Copy link
Contributor Author

Choose a reason for hiding this comment

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

extraneous meaning assignments to name that already exist

except ImportError:
ssl = None
else:
ssl = _ssl
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here the else branch have the priority over what defined in the except handler. Because it's the "principal" flow.

Comment on lines 325 to 326
When pydoctor deals with try/except/else or if/else block, it makes sure that the names defined in
the "principal" branch do not get overriden by names defined in the except hanlders or ifs' else block.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No it's not about whether the branch is last or not. It's only the except hanlders and ifs' else blocks where we enable the override name guard.

Comment on lines 247 to 249
return self._override_guard_state[0] is True \
and self._override_guard_state[1] is ob \
and name in self._override_guard_state[2]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@glyph please see this method for the implementation of the override guard.

The override guard is a re-entrant context manager that ensures that follow-up assignments to names that already existed before in the same frame context are simply ignored.

Co-authored-by: Glyph <glyph@twistedmatrix.com>
docs/source/codedoc.rst Outdated Show resolved Hide resolved
docs/source/codedoc.rst Show resolved Hide resolved
@contextlib.contextmanager
def override_guard(self) -> Iterator[None]:
"""
Returns a context manager that will make the builder ignore any extraneous
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
Returns a context manager that will make the builder ignore any extraneous
Returns a context manager that will make the builder ignore any new

@tristanlatr
Copy link
Contributor Author

tristanlatr commented Jun 12, 2022

I see this in the code:

   def handleDuplicate(self, obj: Documentable) -> None:
        """
        This is called when we see two objects with the same
        .fullName(), for example::

            class C:
                if something:
                    def meth(self):
                        implementation 1
                else:
                    def meth(self):
                        implementation 2

        The default is that the second definition "wins".
        """

But clearly, that was never tested, so never officially supported.
I'm wondering if we should stick to that or to what I'm proposing, which seems better IMO.

but would be a breaking change. (Anyway it's broken right now and the CI is still green ^^')

@tristanlatr tristanlatr requested a review from glyph June 12, 2022 04:39
Copy link
Member

@glyph glyph left a comment

Choose a reason for hiding this comment

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

I do not want to block on my quibbles about documentation. If a brief reflection does not yield a satisfactorily improved phrasing, let's deal with that later, since these semantics make more sense.

I'm wondering if we should stick to that or to what I'm proposing, which seems better IMO, but would be a breaking change

If you wouldn't mind doing a few spot-checks to make sure that Twisted's generated docs don't have any major reliance on this pattern, I'd definitely just merge this; my suspicion would be that it will improve the docs in a bunch of places where we didn't realize we had broken references and not break anything elsewhere.

@tristanlatr
Copy link
Contributor Author

tristanlatr commented Jul 13, 2022

Ok i believe this PR is a mess.

I’ll first port all these tests to the 22.5.x branch, then we’ll see them pass (so I’ll adjust them for the older behaviors), then we’ll merge these tests to master and the CI will fail.

Then I’ll submit a patch that fixes pydoctor and keep the breaking change for later.

Then I’ll think of a better way of implementing this feature.

@tristanlatr
Copy link
Contributor Author

tristanlatr commented Jul 13, 2022

Ok, it might not be a total mess... Since it actually adds a new feature and NOT fixes a bug.

Also this means that there is no rush in merging this PR, we can release a new version of pydoctor now.

@tristanlatr
Copy link
Contributor Author

Need to investigate what happen with visitor extensions if we run into something like:

if sys.version_info>(3.8):
    def foo():
        ...
else:
    @twisted.python.deprecate.deprecated(...)
    def foo():
        ...

I believe foo should not be documented as deprecated.

raise self.SkipChildren()

def depart_If(self, node: ast.If) -> None:
# At this point the body of the Try node has already been visited
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
# At this point the body of the Try node has already been visited
# At this point the body of the If node has already been visited

@@ -180,6 +231,9 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None:
parent = self.builder.current
if isinstance(parent, model.Function):
raise self.SkipNode()
# Ignore in override guard
if self._ignore_name(parent, node.name):
raise self.SkipNode(skip_extensions=True)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
raise self.SkipNode(skip_extensions=True)
raise self.SkipNode()

Makes more sens to have a visit_extensions parameter that default to false. Actually we should not call extension for inner functions or classes in functions, because there will not be part of the docs anyway and we make some assumptions regarding the fact that they don’t exist in the documentable tree.

This comment has been minimized.

@tristanlatr
Copy link
Contributor Author

The diff shows that this change will fix issues. So I’ll look at merging this contribution sonner rather than later.

This comment has been minimized.

The visitors still needs a refactor.

This comment has been minimized.

Copy link

Diff from pydoctor_primer, showing the effect of this PR on open source code:

pycma (https://github.com/CMA-ES/pycma)
+ /projects/pycma/cma/wrapper.py:41: bad docstring: Unexpected indentation.
+ /projects/pycma/cma/wrapper.py:42: bad docstring: Block quote ends without a blank line; unexpected unindent.
- /projects/pycma/cma/__init__.py:20: Cannot find link target for "cma.CMAEvolutionStrategy"
- /projects/pycma/cma/__init__.py:27: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/__init__.py:27: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/__init__.py:27: Cannot find link target for "fmin"
- /projects/pycma/cma/__init__.py:90: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/__init__.py:90: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/__init__.py:90: Cannot find link target for "fmin"
- /projects/pycma/cma/constraints_handler.py:317: Cannot find link target for "cma.fmin"
- /projects/pycma/cma/constraints_handler.py:318: Cannot find link target for "cma.CMAEvolutionStrategy"
- /projects/pycma/cma/constraints_handler.py:337: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/constraints_handler.py:337: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/constraints_handler.py:337: Cannot find link target for "fmin"
- /projects/pycma/cma/constraints_handler.py:784: Cannot find link target for "cma.ConstrainedFitnessAL"
- /projects/pycma/cma/constraints_handler.py:1269: Cannot find link target for "cma.fmin2"
- /projects/pycma/cma/evolution_strategy.py:522: Cannot find link target for "cma.CMAOptions"
- /projects/pycma/cma/evolution_strategy.py:4624: Cannot find link target for "cma.CMAEvolutionStrategy"
- /projects/pycma/cma/evolution_strategy.py:4656: Cannot find link target for "objective_function"
- /projects/pycma/cma/evolution_strategy.py:4517: Cannot find link target for "cma.fmin"
- /projects/pycma/cma/evolution_strategy.py:5122: Cannot find link target for "cma.ConstrainedFitnessAL"
- /projects/pycma/cma/evolution_strategy.py:5122: Cannot find link target for "cma.fmin_con2"
- /projects/pycma/cma/evolution_strategy.py:5127: Cannot find link target for "objective_function"
- /projects/pycma/cma/evolution_strategy.py:5162: Cannot find link target for "cma.fmin"
- /projects/pycma/cma/evolution_strategy.py:5322: Cannot find link target for "objective_function"
- /projects/pycma/cma/evolution_strategy.py:5326: Cannot find link target for "cma.fmin2"
- /projects/pycma/cma/evolution_strategy.py:4320: Cannot find link target for "objective_function"
- /projects/pycma/cma/evolution_strategy.py:4357: Cannot find link target for "cma.fmin"
- /projects/pycma/cma/evolution_strategy.py:4398: Cannot find link target for "objective_function"
- /projects/pycma/cma/evolution_strategy.py:4439: Cannot find link target for "objective_function"
- /projects/pycma/cma/evolution_strategy.py:1143: Cannot find link target for "cma.ff.rosen"
+ /projects/pycma/cma/evolution_strategy.py:1143: Cannot find link target for "cma.fitness_functions.ff.rosen", resolved from "cma.ff.rosen"
- /projects/pycma/cma/evolution_strategy.py:1144: Cannot find link target for "cma.ff"
- /projects/pycma/cma/fitness_models.py:135: Cannot find link target for "cma.fmin"
- /projects/pycma/cma/fitness_transformations.py:642: Cannot find link target for "cma.CMAOptions"
- /projects/pycma/cma/logger.py:1852: Cannot find link target for "cma.plot"
- /projects/pycma/cma/logger.py:1855: Cannot find link target for "cma.plot"
- /projects/pycma/cma/optimization_tools.py:531: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:531: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:531: Cannot find link target for "fmin"
- /projects/pycma/cma/optimization_tools.py:536: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:536: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:536: Cannot find link target for "fmin"
- /projects/pycma/cma/optimization_tools.py:603: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:603: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:603: Cannot find link target for "fmin"
- /projects/pycma/cma/optimization_tools.py:627: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:627: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:627: Cannot find link target for "fmin"
- /projects/pycma/cma/optimization_tools.py:641: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:641: ambiguous ref to fmin, could be cma.evolution_strategy.fmin, cma.purecma.fmin
- /projects/pycma/cma/optimization_tools.py:641: Cannot find link target for "fmin"
- /projects/pycma/cma/purecma.py:26: Cannot find link target for "cma.fmin"
- /projects/pycma/cma/purecma.py:26: Cannot find link target for "cma.CMAEvolutionStrategy"
- /projects/pycma/cma/restricted_gaussian_sampler.py:78: Cannot find link target for "cma.fmin"
- /projects/pycma/cma/restricted_gaussian_sampler.py:79: Cannot find link target for "cma.CMAEvolutionStrategy"
- /projects/pycma/cma/restricted_gaussian_sampler.py:344: Cannot find link target for "cma.fmin"
- /projects/pycma/cma/restricted_gaussian_sampler.py:345: Cannot find link target for "cma.CMAEvolutionStrategy"
- /projects/pycma/cma/sigma_adaptation.py:21: Cannot find link target for "cma.CMAEvolutionStrategy"
- /projects/pycma/cma/wrapper.py:4: Cannot find link target for "SkoptCMAoptimizer"
+ /projects/pycma/cma/wrapper.py:38: Cannot find link target for "func"
+ /projects/pycma/cma/wrapper.py:45: Cannot find link target for "res"
+ /projects/pycma/cma/wrapper.py:48: Cannot find link target for "x"
+ /projects/pycma/cma/wrapper.py:49: Cannot find link target for "fun"
+ /projects/pycma/cma/wrapper.py:50: Cannot find link target for "x_iters"
+ /projects/pycma/cma/wrapper.py:52: Cannot find link target for "func_vals"
+ /projects/pycma/cma/wrapper.py:53: Cannot find link target for "space"
+ these 1 objects' docstrings contain syntax errors:
+     cma.wrapper.SkoptCMAoptimizer

numpy (https://github.com/numpy/numpy)
- /projects/numpy/numpy/_core/_type_aliases.py:3: Cannot find link target for "numpy.generic"
+ /projects/numpy/numpy/_core/_type_aliases.py:3: Cannot find link target for "numpy._core.generic", resolved from "numpy.generic"
- /projects/numpy/numpy/_core/_ufunc_config.py:164: Cannot find link target for "numpy.errstate"
+ /projects/numpy/numpy/_core/_ufunc_config.py:164: Cannot find link target for "numpy._core.errstate", resolved from "numpy.errstate"
- /projects/numpy/numpy/_core/arrayprint.py:628: Cannot find link target for "numpy.timedelta64"
+ /projects/numpy/numpy/_core/arrayprint.py:628: Cannot find link target for "numpy._core.timedelta64", resolved from "numpy.timedelta64"
- /projects/numpy/numpy/_core/arrayprint.py:629: Cannot find link target for "numpy.datetime64"
+ /projects/numpy/numpy/_core/arrayprint.py:629: Cannot find link target for "numpy._core.datetime64", resolved from "numpy.datetime64"
- /projects/numpy/numpy/_core/arrayprint.py:634: Cannot find link target for "numpy.void"
+ /projects/numpy/numpy/_core/arrayprint.py:634: Cannot find link target for "numpy._core.void", resolved from "numpy.void"
- /projects/numpy/numpy/_core/arrayprint.py:635: Cannot find link target for "numpy.bytes_"
+ /projects/numpy/numpy/_core/arrayprint.py:635: Cannot find link target for "numpy._core.bytes_", resolved from "numpy.bytes_"
- /projects/numpy/numpy/_core/arrayprint.py:635: Cannot find link target for "numpy.str_"
+ /projects/numpy/numpy/_core/arrayprint.py:635: Cannot find link target for "numpy._core.str_", resolved from "numpy.str_"
- /projects/numpy/numpy/_core/arrayprint.py:174: Cannot find link target for "numpy.timedelta64"
+ /projects/numpy/numpy/_core/arrayprint.py:174: Cannot find link target for "numpy._core.timedelta64", resolved from "numpy.timedelta64"
- /projects/numpy/numpy/_core/arrayprint.py:175: Cannot find link target for "numpy.datetime64"
+ /projects/numpy/numpy/_core/arrayprint.py:175: Cannot find link target for "numpy._core.datetime64", resolved from "numpy.datetime64"
- /projects/numpy/numpy/_core/arrayprint.py:180: Cannot find link target for "numpy.bytes_"
+ /projects/numpy/numpy/_core/arrayprint.py:180: Cannot find link target for "numpy._core.bytes_", resolved from "numpy.bytes_"
- /projects/numpy/numpy/_core/arrayprint.py:180: Cannot find link target for "numpy.str_"
+ /projects/numpy/numpy/_core/arrayprint.py:180: Cannot find link target for "numpy._core.str_", resolved from "numpy.str_"
- /projects/numpy/numpy/_core/arrayprint.py:181: Cannot find link target for "numpy.object_", resolved from "np.object_"
+ /projects/numpy/numpy/_core/arrayprint.py:181: Cannot find link target for "numpy._core.object_", resolved from "np.object_"
- /projects/numpy/numpy/_core/arrayprint.py:1727: Cannot find link target for "numpy.set_printoptions", resolved from "np.set_printoptions"
+ /projects/numpy/numpy/_core/arrayprint.py:1727: Cannot find link target for "numpy._core.set_printoptions", resolved from "np.set_printoptions"
- /projects/numpy/numpy/_core/defchararray.py:62: Cannot find link target for "numpy.equal"
+ /projects/numpy/numpy/_core/defchararray.py:62: Cannot find link target for "numpy._core.equal", resolved from "numpy.equal"
- /projects/numpy/numpy/_core/defchararray.py:195: Cannot find link target for "numpy.greater"
+ /projects/numpy/numpy/_core/defchararray.py:195: Cannot find link target for "numpy._core.greater", resolved from "numpy.greater"
- /projects/numpy/numpy/_core/defchararray.py:128: Cannot find link target for "numpy.greater_equal"
+ /projects/numpy/numpy/_core/defchararray.py:128: Cannot find link target for "numpy._core.greater_equal", resolved from "numpy.greater_equal"
- /projects/numpy/numpy/_core/defchararray.py:228: Cannot find link target for "numpy.greater"
+ /projects/numpy/numpy/_core/defchararray.py:228: Cannot find link target for "numpy._core.greater", resolved from "numpy.greater"
- /projects/numpy/numpy/_core/defchararray.py:162: Cannot find link target for "numpy.less_equal"
+ /projects/numpy/numpy/_core/defchararray.py:162: Cannot find link target for "numpy._core.less_equal", resolved from "numpy.less_equal"
- /projects/numpy/numpy/_core/defchararray.py:95: Cannot find link target for "numpy.not_equal"
+ /projects/numpy/numpy/_core/defchararray.py:95: Cannot find link target for "numpy._core.not_equal", resolved from "numpy.not_equal"
- /projects/numpy/numpy/_core/defchararray.py:349: ambiguous ref to copy, could be numpy.lib._function_base_impl.copy, numpy.ma.core.copy
- /projects/numpy/numpy/_core/defchararray.py:349: Cannot find link target for "copy"
- /projects/numpy/numpy/_core/defchararray.py:633: Cannot find link target for "numpy.argsort"
+ /projects/numpy/numpy/_core/defchararray.py:633: Cannot find link target for "numpy._core.argsort", resolved from "numpy.argsort"
- /projects/numpy/numpy/_core/einsumfunc.py:1135: Cannot find link target for "numpy.trace"
+ /projects/numpy/numpy/_core/einsumfunc.py:1135: Cannot find link target for "numpy._core.trace", resolved from "numpy.trace"
- /projects/numpy/numpy/_core/einsumfunc.py:1136: Cannot find link target for "numpy.diag"
- /projects/numpy/numpy/_core/einsumfunc.py:1137: Cannot find link target for "numpy.sum"
+ /projects/numpy/numpy/_core/einsumfunc.py:1137: Cannot find link target for "numpy._core.sum", resolved from "numpy.sum"
- /projects/numpy/numpy/_core/einsumfunc.py:1138: Cannot find link target for "numpy.transpose"
+ /projects/numpy/numpy/_core/einsumfunc.py:1138: Cannot find link target for "numpy._core.transpose", resolved from "numpy.transpose"
- /projects/numpy/numpy/_core/einsumfunc.py:1139: Cannot find link target for "numpy.matmul"
+ /projects/numpy/numpy/_core/einsumfunc.py:1139: Cannot find link target for "numpy._core.matmul", resolved from "numpy.matmul"
- /projects/numpy/numpy/_core/einsumfunc.py:1140: Cannot find link target for "numpy.dot"
+ /projects/numpy/numpy/_core/einsumfunc.py:1140: Cannot find link target for "numpy._core.dot", resolved from "numpy.dot"
- /projects/numpy/numpy/_core/einsumfunc.py:1141: Cannot find link target for "numpy.inner"
+ /projects/numpy/numpy/_core/einsumfunc.py:1141: Cannot find link target for "numpy._core.inner", resolved from "numpy.inner"
- /projects/numpy/numpy/_core/einsumfunc.py:1142: Cannot find link target for "numpy.outer"
+ /projects/numpy/numpy/_core/einsumfunc.py:1142: Cannot find link target for "numpy._core.outer", resolved from "numpy.outer"
- /projects/numpy/numpy/_core/einsumfunc.py:1144: Cannot find link target for "numpy.multiply"
+ /projects/numpy/numpy/_core/einsumfunc.py:1144: Cannot find link target for "numpy._core.multiply", resolved from "numpy.multiply"
- /projects/numpy/numpy/_core/einsumfunc.py:1145: Cannot find link target for "numpy.tensordot"
+ /projects/numpy/numpy/_core/einsumfunc.py:1145: Cannot find link target for "numpy._core.tensordot", resolved from "numpy.tensordot"
- /projects/numpy/numpy/_core/einsumfunc.py:1147: Cannot find link target for "numpy.einsum_path"
+ /projects/numpy/numpy/_core/einsumfunc.py:1147: Cannot find link target for "numpy._core.einsum_path", resolved from "numpy.einsum_path"
- /projects/numpy/numpy/_core/einsumfunc.py:1152: Cannot find link target for "numpy.inner"
+ /projects/numpy/numpy/_core/einsumfunc.py:1152: Cannot find link target for "numpy._core.inner", resolved from "numpy.inner"
- /projects/numpy/numpy/_core/einsumfunc.py:1156: Cannot find link target for "numpy.matmul"
+ /projects/numpy/numpy/_core/einsumfunc.py:1156: Cannot find link target for "numpy._core.matmul", resolved from "numpy.matmul"
- /projects/numpy/numpy/_core/einsumfunc.py:1159: Cannot find link target for "numpy.trace"
+ /projects/numpy/numpy/_core/einsumfunc.py:1159: Cannot find link target for "numpy._core.trace", resolved from "numpy.trace"
- /projects/numpy/numpy/_core/einsumfunc.py:1174: Cannot find link target for "numpy.sum"
+ /projects/numpy/numpy/_core/einsumfunc.py:1174: Cannot find link target for "numpy._core.sum", resolved from "numpy.sum"
- /projects/numpy/numpy/_core/einsumfunc.py:1176: Cannot find link target for "numpy.diag"
- /projects/numpy/numpy/_core/einsumfunc.py:1186: Cannot find link target for "numpy.sum"
+ /projects/numpy/numpy/_core/einsumfunc.py:1186: Cannot find link target for "numpy._core.sum", resolved from "numpy.sum"
- /projects/numpy/numpy/_core/einsumfunc.py:1208: Cannot find link target for "numpy.swapaxes"
+ /projects/numpy/numpy/_core/einsumfunc.py:1208: Cannot find link target for "numpy._core.swapaxes", resolved from "numpy.swapaxes"
- /projects/numpy/numpy/_core/einsumfunc.py:1226: Cannot find link target for "numpy.einsum_path"
+ /projects/numpy/numpy/_core/einsumfunc.py:1226: Cannot find link target for "numpy._core.einsum_path", resolved from "numpy.einsum_path"
- /projects/numpy/numpy/_core/fromnumeric.py:375: Cannot find link target for "numpy.take_along_axis"
- /projects/numpy/numpy/_core/fromnumeric.py:2138: ambiguous ref to diag, could be numpy.lib._twodim_base_impl.diag, numpy.ma.core.diag
- /projects/numpy/numpy/_core/fromnumeric.py:2138: Cannot find link target for "diag"
- /projects/numpy/numpy/_core/fromnumeric.py:2642: ambiguous ref to diff, could be numpy.lib._function_base_impl.diff, numpy.ma.core.diff
- /projects/numpy/numpy/_core/fromnumeric.py:2642: Cannot find link target for "diff"
- /projects/numpy/numpy/_core/fromnumeric.py:1701: ambiguous ref to diag, could be numpy.lib._twodim_base_impl.diag, numpy.ma.core.diag
- /projects/numpy/numpy/_core/fromnumeric.py:1701: Cannot find link target for "diag"
- /projects/numpy/numpy/_core/fromnumeric.py:1704: ambiguous ref to diagflat, could be numpy.lib._twodim_base_impl.diagflat, numpy.ma.extras.diagflat
- /projects/numpy/numpy/_core/fromnumeric.py:1704: Cannot find link target for "diagflat"
- /projects/numpy/numpy/_core/fromnumeric.py:1745: Cannot find link target for "numpy.flipud"

... (truncated 549 lines) ...

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