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

Move *.trait_defs.ui.qt4 to *.trait_defs.ui.qt #1028

Merged
merged 23 commits into from
May 2, 2023
Merged

Conversation

homosapien-lcy
Copy link
Contributor

@homosapien-lcy homosapien-lcy commented Apr 11, 2023

Recently a decision to move pyface.ui.qt4 to pyface.ui.qt has been made in pyface (enthought/pyface#1223) since versions newer than qt4 have become increasingly popular. However, this move can lead to import errors in other packages that are utilizing pyface when they try to import from qt4. For instance, in issue #1026 , we found that the example cannot find the enable.savage.trait_defs.ui.qt module since the default ETS_TOOLKIT is qt while the folder for qt is still enable.savage.trait_defs.ui.qt.

The first way I proposed to solve this is by adapting the similar ShadowedModuleFinder approach in pyface (https://github.com/enthought/pyface/blob/main/pyface/ui/qt4/__init__.py).

Now, Corran also proposed a simpler solution in the comment which is to use a simple check on import. This may be a simpler solution than using ShadowedModuleFinder.
Closes issue #1026

@homosapien-lcy homosapien-lcy changed the title [WIP] FEAT: add ShadowedModuleFinder FEAT: add ShadowedModuleFinder Apr 11, 2023
@@ -0,0 +1,93 @@
# Import hooks for loading enable.savage.trait_defs.ui.qt.* in place of
Copy link
Member

Choose a reason for hiding this comment

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

@homosapien-lcy this feels like a lot of duplicated code. enable depends on pyface, no? I suspect we could make sure it depends on pyface 8.x and just import the code from there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, currently the issue is, if the pyface version the user need is not 8.x, we would still need the ShadowedModuleFinder in Enable since we cannot import it (This folder renaming does not happen only in pyface, but in other packages as well). Do you want the code to first try to import from the ShadowModuleFinder like this?:

try:
    from pyface.ui import ShadowedModuleFinder
except ImportError:
    from enable.savage.trait_defs.ui import ShadowedModuleFinder

Copy link
Member

Choose a reason for hiding this comment

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

It's good to think of backward compatibility. The current enable version has a requirement of pyface >= 7.2 (see https://github.com/enthought/enable/blob/main/enable/__init__.py#L19). You can bump the requirement for this release to be >= 8.0.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, we did this for the upcoming TraitsUI release - simply require Pyface >= 8

@corranwebster
Copy link
Contributor

I think the sys.meta_path stuff is overkill for this situation, unless there is a lot of code that is directly importing enable.savage.trait_defs.ui.qt4 in 3rd-party libraries. A simpler solution is to just have some logic that if ETSConfig.toolkit is qt4 then the toolkit should import from enable.savage.trait_defs.ui.qt instead: ie. replace this:

backend = "enable.savage.trait_defs.ui.%s" % ETSConfig.toolkit

with

if ETSConfig.toolkit == "qt4":
    backend = "enable.savage.trait_defs.ui.qt"
else:
    backend = "enable.savage.trait_defs.ui.%s" % ETSConfig.toolkit

and that should likely fix everything.

@homosapien-lcy
Copy link
Contributor Author

The online tests seem failed due to installing pyface7.4.4 for the tests.

@homosapien-lcy
Copy link
Contributor Author

enable.savage.trait_defs.ui

I think the sys.meta_path stuff is overkill for this situation, unless there is a lot of code that is directly importing enable.savage.trait_defs.ui.qt4 in 3rd-party libraries. A simpler solution is to just have some logic that if ETSConfig.toolkit is qt4 then the toolkit should import from enable.savage.trait_defs.ui.qt instead: ie. replace this:

backend = "enable.savage.trait_defs.ui.%s" % ETSConfig.toolkit

with

if ETSConfig.toolkit == "qt4":
    backend = "enable.savage.trait_defs.ui.qt"
else:
    backend = "enable.savage.trait_defs.ui.%s" % ETSConfig.toolkit

and that should likely fix everything.

This solution actually may make sense, since there seems not to be other places where we need to use the qt import (for instance, "enable.trait_defs.ui.qt doesn't have the same problem). Also, this can avoid the git test failure problem due to pyface version requirement. What do you think @dpinte

@homosapien-lcy homosapien-lcy changed the title FEAT: add ShadowedModuleFinder Move *.trait_defs.ui.qt4 to *.trait_defs.ui.qt Apr 14, 2023
Chengyu Liu added 3 commits April 19, 2023 15:29
…nce the import for enable.savage.trait_defs.ui.qt is not widely imported in third party package
@homosapien-lcy homosapien-lcy changed the title Move *.trait_defs.ui.qt4 to *.trait_defs.ui.qt [WIP] Move *.trait_defs.ui.qt4 to *.trait_defs.ui.qt Apr 19, 2023
@homosapien-lcy homosapien-lcy changed the title [WIP] Move *.trait_defs.ui.qt4 to *.trait_defs.ui.qt Move *.trait_defs.ui.qt4 to *.trait_defs.ui.qt Apr 20, 2023
corranwebster added a commit that referenced this pull request Apr 20, 2023
Rename *.qt4.* modules as *.qt.* and adapt imports to account for changes in Pyface 8.0 and TraitsUI 8.0 while keeping backwards compatibility.

It also removes some lingering PyQt4 support code.

This has some overlap with #1028 but doesn't fix everything that that PR does, so we still need that, or need to merge it into this.

As best I can tell, this change will break one test in an internal downstream project so we don't need to do any magic backwards compatibility mapping like we did in Pyface or TraitsUI.
@@ -42,7 +42,6 @@
DRAG_RESULTS_MAP,
)


Copy link
Member

Choose a reason for hiding this comment

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

this should be removed

@@ -26,6 +26,7 @@
class ScrollBarTest(unittest.TestCase):
def setUp(self):
from pyface.qt.QtGui import QApplication

Copy link
Member

Choose a reason for hiding this comment

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

this can be removed

setup.py Outdated
@@ -422,7 +422,6 @@ def macos_extensions():
'enable.toolkits': [
'null = enable.null.toolkit:toolkit',
'qt = enable.qt.toolkit:toolkit',
'qt4 = enable.qt.toolkit:toolkit',
Copy link
Member

Choose a reason for hiding this comment

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

this needs to stay for backward compatibility!

@homosapien-lcy
Copy link
Contributor Author

In the latest commits, unneccessary spaces are removed, backward compatibility is added back

@mdickinson
Copy link
Member

What's the reason for the existence of both enable.savage.trait_defs.ui.qt.svg_editor and enable.savage.trait_defs.qt.svg_editor?

@mdickinson
Copy link
Member

mdickinson commented Apr 27, 2023

I have the same question for svg_button_editor: at this point, enable/savage/trait_defs/qt/svg_button_editor.py and enable/savage/trait_defs/ui/qt/svg_button_editor.py seem to be near duplicates of one another. Should the qt/ versions have been removed, or are both needed? If we need both modules, is there a way to fix the duplication?

@dpinte
Copy link
Member

dpinte commented Apr 27, 2023

Good question, @mdickinson ! I'll let @homosapien-lcy investigate.

@homosapien-lcy
Copy link
Contributor Author

I have the same question for svg_button_editor: at this point, enable/savage/trait_defs/qt/svg_button_editor.py and enable/savage/trait_defs/ui/qt/svg_button_editor.py seem to be near duplicates of one another. Should the qt/ versions have been removed, or are both needed? If we need both modules, is there a way to fix the duplication?

Hi Mark:

They are actually different, enable.savage.trait_defs.ui.svg_editor and enable/savage/trait_defs/ui/svg_button_editor.py also inherits BasicEditorFactory (https://github.com/enthought/traitsui/blob/main/traitsui/basic_editor_factory.py) from traitsui class, which allows them to create editors of different styles with the same class as foundation.

If the duplicated names can cause confusion, there are two ways we can solve it:

1 make these class doubly inherited both Editor and BasicEditorFactory and merge into 1 class (For instance SVGEditor(Editor) -> SVGEditor(Editor, BasicEditorFactory)). But the caveat is this will make the class content very long and less readable

2 change the class name of the qt version to **Foundation to avoid confusion

what do you think @mdickinson @dpinte

@mdickinson
Copy link
Member

@homosapien-lcy As of commit 5f076f3 in this PR, we have:

These two files are almost identical; one of them already existed in the main branch prior to this PR, and one of them was introduced in this PR. I'm asking why it was necessary to introduce a new module that's almost identical to an existing one.

I'm not asking about the editor factory file at https://github.com/enthought/enable/blob/5f076f3b29f9a3f5a757c6be080faa332faacbad/enable/savage/trait_defs/ui/svg_editor.py. As you correctly say, that's something different.

A similar situation exists for svg_button_editor. I was hoping that since you introduced these near-duplicate modules in this PR, you could explain why the duplication was necessary.

@dpinte
Copy link
Member

dpinte commented Apr 28, 2023

@mdickinson @homosapien-lcy looking at the enable.savage.traits_def.ui.toolkit, the toolkit directories should in the enable/savage/traits_def/ui. This where the old qt4 directory was. I think the issues come from PR #1043 that moved the qt4 directory to enable/savage/traits_def. The solution is to remove enable/savage/traits_def/qt and keep enable/savage/traits_def/ui/qt.

@mdickinson
Copy link
Member

@dpinte Yep, that sounds plausible.

@@ -16,7 +16,7 @@
__version__ = "not-built"

__requires__ = [
"numpy", "pillow", "traits>=6.2.0", "traitsui", "pyface>=7.2.0", "fonttools"
Copy link
Member

Choose a reason for hiding this comment

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

Do we still need this change to the Pyface requirement?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me check on that, whether any issues will be raised in pyface < 8

Copy link
Member

Choose a reason for hiding this comment

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

Since many of the changes are depending on pyface 8.00 which renamed all qt4 to qt, I think we need pyface 8.00

Please could you point to some examples? I'm not seeing anything in this PR which would require us to use Pyface 8.0.

Copy link
Member

Choose a reason for hiding this comment

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

(Note that EDM doesn't have Pyface 8.0 yet.)

Copy link
Member

Choose a reason for hiding this comment

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

@homosapien-lcy Ah, you edited your comment after I replied to it. Please don't do that! (Now my replies don't make sense out of context.)

try:
from pyface.qt import QtGui
except ImportError:
raise Exception("PyQt4 needs to be installed to run this example")
Copy link
Member

Choose a reason for hiding this comment

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

Is this accurate? We stopped supporting PyQt4 some time ago, so I'm not sure there's much value in introducing a new example that requires PyQt4.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see; this isn't a new example - it's a duplicate of kiva/examples/kiva/qpainter_simple.py, with only this one line changed. I suggest removing this addition to the PR.

@mdickinson
Copy link
Member

mdickinson commented Apr 28, 2023

@homosapien-lcy It seems that the file qt_simple.py introduced in this PR is also essentially a duplicate of qpainter_simple.py in the same directory - only the exception message has been changed, in a way that doesn't make sense to me.

Should qt_simple.py be deleted? If not, what's the reason for introducing it?

@homosapien-lcy
Copy link
Contributor Author

I have push a change to remove the pyface 8.0.0 requirement and remove the qt_simple.py example

Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

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

Thanks for the changes. LGTM.

@corranwebster corranwebster merged commit 92196ef into main May 2, 2023
35 checks passed
@corranwebster corranwebster deleted the fix_qt_import branch May 2, 2023 12:53
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

4 participants