Skip to content

TypeError in backend_qt5.py #16821

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

Closed
rayosborn opened this issue Mar 18, 2020 · 3 comments
Closed

TypeError in backend_qt5.py #16821

rayosborn opened this issue Mar 18, 2020 · 3 comments

Comments

@rayosborn
Copy link

Bug report

Bug summary

In NeXpy, a PyQt application that subclasses NavigationToolbar2QT in backends/backend_qt5.py, a call to _init_toolbar fails because of a TypeError, which is generated by an internal conflict between positional and keyword arguments within the Matplotlib code. This affects Matplotlib v3.2.0, but not v3.1.2.

The issue is caused by a call to _icon in _init_toolbar, i.e., self._icon(image_file + '.png', icon_color), which has the color defined as a positional argument. However, the _icon function is defined as def _icon(self, name, color=None):

I don't understand why this is a problem. I thought that Python is tolerant of keyword arguments being defined as positional arguments when there is no ambiguity. I also have no idea why it doesn't appear to affect the toolbar initialization when opening a PyQt window in pyplot, e.g., within a Jupyter qtconsole client, which presumably calls the same function. I would be grateful if anyone else does understand it and can suggest a work-around. Nevertheless, I presume that the Matplotlib code should respect the use of keyword arguments.

Traceback

~/miniconda3/lib/python3.7/site-packages/nexpy/gui/plotview.py in _init_toolbar(self)
   3385             ('Add', 'Add plot data to tree', 'hand', 'add_data')
   3386                 )
-> 3387         super(NXNavigationToolbar, self)._init_toolbar()
   3388         self._actions['set_aspect'].setCheckable(True)
   3389         for action in self.findChildren(QtWidgets.QAction):

~/miniconda3/lib/python3.7/site-packages/matplotlib/backends/backend_qt5.py in _init_toolbar(self)
    698                 self.addSeparator()
    699             else:
--> 700                 a = self.addAction(self._icon(image_file + '.png', icon_color),
    701                                    text, getattr(self, callback))
    702                 self._actions[callback] = a

TypeError: _icon() takes 2 positional arguments but 3 were given

Matplotlib version

  • Operating system: Mac OS X
  • Matplotlib version: 3.2.0
  • Matplotlib backend: Qt5Agg
  • Python version: 3.7 and 3.8

I tested this with Matplotlib v3.2.0 installed by pip and conda.

@tacaswell
Copy link
Member

What I think happened is that in #14810 we added an (optional) keyword argument to NavigationToolbar2QT._icon and make use of of the keyword internally.

However, in nexpy you are over-loading _icon (https://github.com/nexpy/nexpy/blob/1b0adabbdabe0ace5cd9131577e3ba8c2b96c3f5/src/nexpy/gui/plotview.py#L3367-L3369) matching the old signature so when initializing nexpy's custom toolbar the self._icon call (in Matplotlib's code) finds the _icon definition from nexpy's code that then complains about there being too many positional arguments.

Given that this is a private method I think the best fix is for nexpy to add the colors param to he signature of _icon (or add *args, **kwargs) and ignore it which should get nexpy working with all versions of Matplotlib again.

@rayosborn
Copy link
Author

Thanks for the quick response. That's embarrassing. I had forgotten that I had overridden the _icon function as well. I was thrown off by assuming it was a positional vs keyword issue. I agree then that this is not really a Matplotlib issue. Unless you think there are other ramifications, please feel free to close this.

@anntzer
Copy link
Contributor

anntzer commented Mar 18, 2020

I'll close, as I don't think there's anything to change on our side? Except perhaps "let's try to avoid APIs where third parties may want to subclass private methods".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants