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

Bug: mypy cannot access QMainWindow methods from MainWindow #163

Open
adam-grant-hendry opened this issue Jun 12, 2022 · 0 comments
Open

Comments

@adam-grant-hendry
Copy link
Contributor

adam-grant-hendry commented Jun 12, 2022

__init__.py imports MainWindow from plotting. However, MainWindow is fully exported from window, not plotting. While not incorrect python, this causes mypy to not be able to see QMainWindow super class methods when creating pyvistaqt.MainWindow instances.

e.g.

from pyvistaqt import MainWindow

window = MainWindow()
window.setWindowTitle('window')  # mypy complains window has no attribute "setWindowTitle"

Also mypy<=0.961 does not yet fully support conditional imports (see Issue 1297 and 1393).

The fix for the first item is to either use a package wildcard import or import from the appropriate modules using the from ... import ... as ... notation:

Option 1: Explicit

...
else:
    from .plotting import (
        BackgroundPlotter as BackgroundPlotter,
        MultiPlotter as MultiPlotter,
        QtInteractor as QtInteractor,
    )
    from .window import MainWindow as MainWindow

Option 2: Implicit

...
else:
    from .plotting import *
    from .window import *

The fix for the second item would simply be to raise the RuntimeError directly within the except clause and use the @cjerdonek workaround:

try:
    from qtpy import QtCore as _QtCore
except Exception as exc:
    QtCore = None  # pylint: disable=invalid-name
    raise RuntimeError(f'No Qt binding was found, got: {exc}') from exc
else:
    QtCore = _QtCore
    # Do imports from ``plotting`` and ``window`` here

NOTE: PEP 484 states

  • Modules and variables imported into the stub are not considered exported from the stub unless the import uses the import ... as ... form or the equivalent from ... import ... as ... form. (UPDATE: To clarify, the intention here is that only names imported using the form X as X will be exported, i.e. the name before and after as must be the same.)
  • However, as an exception to the previous bullet, all objects imported into a stub using from ... import * are considered exported. (This makes it easier to re-export all objects from a given module that may vary by Python version.)

and Pyright indicates

If a file init.py uses the form “from .A import X”, symbol “A” is not private unless the name begins with an underscore (but “X” is still private).

A module can expose an all symbol at the module level that provides a list of names that are considered part of the interface. The all symbol indicates which symbols are included in a wildcard import.

Note also that Pyright states

  • import A as A is called a redundant module alias
  • from X import A as A is called a redundant symbol alias
adam-grant-hendry pushed a commit to adam-grant-hendry/pyvistaqt that referenced this issue Jun 28, 2022
PEP 484 requires redundant alias imports to identify modules as being re-exported. Adding these fixes the mypy error that it cannot find parent methods in child instances of `MainWindow`.

Fixes Issue pyvista#163
@adeak adeak linked a pull request Jun 28, 2022 that will close this issue
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 a pull request may close this issue.

1 participant