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

Passing a class to a decorator factory now fails to import for mocked decorators #8134

Closed
andyneff opened this issue Aug 17, 2020 · 0 comments

Comments

@andyneff
Copy link

Describe the bug

It looks like while #6719 added support for decorators from mocked modules.

Unfortunately, when you using a decorator factory, (a function that returns a decorator or a decorator that takes arguments), if a class is an argument to the decorator factory, it attempts to instantiate the class, and fails to import the file.

To Reproduce

Example:

import mocked_module

class SomeClass:
  def __init__(self): # If this init takes two arguments, it won't "fail", but is still technically wrong
    pass

@mocked_module.decorator2(SomeClass)
class MyClass:
  ''' This is a class '''
  pass

Somehow mocked_module.decorator2 appears to be calling SomeClass's __init__ with two arguments

Error when building docs:

WARNING: autodoc: failed to import module 'bar' from module 'foo'; the following exception was raised:
Traceback (most recent call last):
  File "/home/andy/.local/share/virtualenvs/sphinx_decorator_bug-0V71t1Ku/lib/python3.7/site-packages/sphinx/ext/autodoc/importer.py", line 66, in import_module
    return importlib.import_module(modname)
  File "/home/andy/.local/share/virtualenvs/sphinx_decorator_bug-0V71t1Ku/lib64/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/opt/projects/sphinx_decorator_bug/foo/bar.py", line 29, in <module>
    @mocked_module.decorator2(BaseClass)
TypeError: __init__() takes 1 positional argument but 2 were given

Expected behavior

At the very least, it should not be trying to instantiate SomeClass at all and it should not fail to import. Ideally, it would work and document MyClass, the decorated class.

Work around

Not mocking the particular class works. If I added the third party library to the sphinx environment, and use it directly instead of mocking, it seems to work.

Your project

https://github.com/andyneff/sphinx_decorator_bug

Environment info

  • OS: Fedora 31
  • Python version: 3.7.8
  • Sphinx version: 2.3.0 - 3.2.1
  • Sphinx extensions: [sphinx.ext.autodoc, sphinx.ext.napoleon]
  • Also reproduced in the python:3.7.0 docker image
@tk0miya tk0miya added this to the 3.5.0 milestone Jan 24, 2021
tk0miya added a commit that referenced this issue Jan 25, 2021
Fix #8134: autodoc: crashes when mocked decorator takes arguments
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants