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

strategy="api" misses methods from private superclasses #177

Open
ev-br opened this issue Dec 11, 2024 · 1 comment · May be fixed by #179
Open

strategy="api" misses methods from private superclasses #177

ev-br opened this issue Dec 11, 2024 · 1 comment · May be fixed by #179
Labels
bug Something isn't working

Comments

@ev-br
Copy link
Member

ev-br commented Dec 11, 2024

Discovered in scipy/scipy#22027 (comment)

Consider a public class, B, which inherits from a private superclass _A:

$ cat package/__init__.py 
__all__ = ["B"]

class _A:
    """A private superclass."""
    def meth(self):
        """
        >>> 2 / 3
        0.68
        """
        return 42


class B(_A):
    """A public subclass."""
    def other_meth(self):
        """
        >>> 4 // 2
        2
        """
        return 43

Instances of B have methods from both classes, and one would expect that doctesting finds docstrings of both B.meth and B.other_meth.

However, it is not the case with strategy="api"!

$ pytest --doctest-modules --doctest-collect=api package/ -v
...
rootdir: /home/br/sweethome/proj/scipy/refguide_check_2/scrtch/collection
plugins: scipy_doctest-1.5.1, anyio-4.4.0, hypothesis-6.108.2
collected 1 item                                                                       

package/__init__.py::package.B.other_meth PASSED                                 [100%]

================================== 1 passed in 0.41s ===================================

With the default strategy=None, both doctests are discovered:

$ pytest --doctest-modules  package/ -v
================================= test session starts ==================================
...
rootdir: /home/br/sweethome/proj/scipy/refguide_check_2/scrtch/collection
plugins: scipy_doctest-1.5.1, anyio-4.4.0, hypothesis-6.108.2
collected 2 items                                                                      

package/__init__.py::package.B.other_meth PASSED                                 [ 50%]
package/__init__.py::package._A.meth FAILED                                      [100%]


So, as it turns out, the standard library doctest module only inspects methods defined in the class, and skips those from parent classes.
For vanilla doctest, it's fine, because it looks everywhere, including a private superclass.

For strategy="api", it's a problem however.

Possible solutions:

  1. check if there's a hook in DoctestFinder we can use
  2. In DTFinder.find, walk the MRO of an object (in the toy example above, >>> package.B.__mro__ is
    (<class 'package.B'>, <class 'package._A'>, <class 'object'>)
@ev-br
Copy link
Member Author

ev-br commented Dec 11, 2024

From the the doctest sources: DoctestFinder.find only looks at a class __dict__ attribute, and inherited methods are not there:

(Pdb) p obj
<class 'package.B'>
(Pdb) p obj.__dict__.items()
dict_items([('__module__', 'package'), ('__doc__', 'A public subclass.'), ('other_meth', <function B.other_meth at 0x7fc45d499a80>)])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant