Skip to content

Contribute examples to etsdemo#494

Merged
aaronayres35 merged 20 commits into
masterfrom
contribute-examples-to-etsdemo
Dec 18, 2020
Merged

Contribute examples to etsdemo#494
aaronayres35 merged 20 commits into
masterfrom
contribute-examples-to-etsdemo

Conversation

@aaronayres35
Copy link
Copy Markdown
Contributor

@aaronayres35 aaronayres35 commented Dec 14, 2020

fixes #436

This PR contributes the kiva and enable examples to etsdemo.

It is currently flagged as a WIP, as some examples are broken / have strange behaviors. However, some of these problems may best be solved in a separate PR.
EDIT: I have opened issues for any broken demos, and have added comments to this PR for any demos that work when run independently, but not as we want them to when run through etsdemo.

To run the etsdemo app:

pip install -e .[demo]
pip install etsdemo[pyside2]  # or a different gui toolkit
etsdemo

Additionally, some of the kiva examples simply save a file, rather than having a showcased demo. e,g. dummy, pdf_arcs, star_path. Not sure what is best approach for these.

I removed the WIP marker, as I think the lingering issues are likely best handled in separate PRs.

Comment thread enable/__init__.py Outdated

__extras_require__ = {
'demo': ['chaco', 'mayavi', 'scipy', 'traitsui[demo]'],
'demo': ['chaco', 'mayavi', 'scipy', 'traitsui[demo]', 'kiwisolver'],
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is a bit orthogonal to this PR, but so many examples depend on ConstraintsContainer that it felt appropriate to add. If one does pip install enable[demo] and pip install etsdemo[pyside2] and they launch the demo app, they would expect to have what they need to see all the demos.

I believe there are other dependencies as well (e.g. pyglet for pyglet_gl.py), but they are much less common. I may end up adding to them to this PR as well?

@aaronayres35
Copy link
Copy Markdown
Contributor Author

kiva_explorer is a great example, but it does not work with the etsdemo application.
I am not sure what to do with it, as it is a bit special

@aaronayres35
Copy link
Copy Markdown
Contributor Author

CI is failing on the enable added test, but I can't reproduce locally

@aaronayres35
Copy link
Copy Markdown
Contributor Author

CI is failing on the enable added test, but I can't reproduce locally

I recreated the environment and I can now reproduce the test failure, however if I run pip install -e . I no longer see the error

Comment thread ci/edmtool.py Outdated
Copy link
Copy Markdown
Member

@jwiggins jwiggins left a comment

Choose a reason for hiding this comment

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

Just some minor comments. I didn't look into the testing problems at all.

Comment thread enable/examples/_etsdemo_info.py Outdated
Comment thread MANIFEST.in Outdated
Comment thread kiva/examples/_etsdemo_info.py Outdated
Comment thread MANIFEST.in Outdated
Comment thread setup.py Outdated
Comment thread setup.py

if __name__ == '__main__':
demo = ScriptedComponentView()
demo.configure_traits()
Copy link
Copy Markdown
Contributor Author

@aaronayres35 aaronayres35 Dec 15, 2020

Choose a reason for hiding this comment

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

I left original kiva_explorer.py sitting in examples as it is currently still best run outside of etsdemo. Further, in the etsdemo application the demo is still not shown here, all that is visible is the code at the moment.
Edit: this is now fixed, the full view is now shown in the demo but it is still a bit awkward looking as it is all condensed into the lower right panel

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the current status is about the best we are going to get with kiva_explorer in etsdemo for now. Eventually, we may want to rework things so that maybe when you click run the explorer application pops up separately or something like that.

I think I will delete the kiva_explorer.py that is still sitting in the original examples directory (actually I will delete examples entirely) as it can still be run the same way independent of etsdemo where it sits now.

On that note though, I am not a huge fan of where it sits now because it comes off as just another kiva example, but it is inherently a bit different, and would be nice if that distinction were clearer

Comment thread ci/edmtool.py
install_local = (
"edm run -e {environment} -- "
"pip install --force-reinstall --no-dependencies -e ."
"pip install --force-reinstall --no-dependencies " + ROOT
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not exactly sure why, but I'm not seeing the test failure anymore

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Previously the test failure reflects the issue that I ran into 😅 : the examples files are moved inside demo subdirectory but the package_data has not been updated to say demo/enable/* etc.
Using pip install -e . "fixes" the test failure because it actually makes the package available from source: the package_data is not really relevant in that setup.

After 7cecefb, the package_data is fixed to reference the demo subdirectory, and that truly fixes the test.

This is in fact one instance where it is valuable to have a CI job where we don't install the source with editable mode. It tests the installed environment more truthfully.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ahhh I see, that makes sense now, thank you!

@codecov-io
Copy link
Copy Markdown

codecov-io commented Dec 15, 2020

Codecov Report

Merging #494 (189f22c) into master (622249e) will increase coverage by 0.03%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #494      +/-   ##
==========================================
+ Coverage   30.63%   30.66%   +0.03%     
==========================================
  Files         208      210       +2     
  Lines       17832    17840       +8     
  Branches     2454     2454              
==========================================
+ Hits         5463     5471       +8     
  Misses      12036    12036              
  Partials      333      333              
Impacted Files Coverage Δ
enable/__init__.py 75.00% <ø> (ø)
enable/examples/_etsdemo_info.py 100.00% <100.00%> (ø)
kiva/examples/_etsdemo_info.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 622249e...189f22c. Read the comment docs.

@aaronayres35
Copy link
Copy Markdown
Contributor Author

aaronayres35 commented Dec 15, 2020

The vtk_example.py now sitting in enable/examples/demo/enable does not work with etsdemo currently.
For one thing it imports from another example from basic_move import Box, but it also is using

if __name__=="__main__":
    main()

and using mlab.show() to show the example.

EDIT: As a sanity check I copy pasted the code for basic_move.Box into this file and changed __main__ to ___main___. With those changes the demo can be run from etsdemo. The ___main___ issue I am leaving untouched by this PR (I am not going to add a workaround if __name__ == "__main__" or __name__ == "___main___":). The other issue has effectively already been resolved in envisage, see enthought/envisage#377. I was thinking though that this may be a common problem, and that the context manager used by envisage is more general and should maybe sit in traitsui itself? I am not sure about this, but again I think I will leave this PR as is and that issue can be addressed separately.

@aaronayres35
Copy link
Copy Markdown
Contributor Author

aaronayres35 commented Dec 15, 2020

https://github.com/enthought/enable/blob/7b56e5275c707e7ee5749ce4ba141240729f5a26/examples/enable/tools/apptools/undoable_move_tool.py
Is also not working in etsdemo but works when run on its own

related to enthought/traitsui#1428

EDIT: I changed if __name__ == "__main__": to be if __name__ == "__main__" or __name__ == "___main___": as a work around so that this example could run both stand alone and from within etsdemo and it works as expected. However, as soon one selects the file, the demo pops up, rather than waiting until run is clicked. This is not the ideal behavior so I think I will leave this and some of the similar examples that aren't currently working as is for now in this PR.

@aaronayres35
Copy link
Copy Markdown
Contributor Author

@aaronayres35
Copy link
Copy Markdown
Contributor Author

aaronayres35 commented Dec 15, 2020

Note that https://github.com/enthought/enable/blob/7b56e5275c707e7ee5749ce4ba141240729f5a26/examples/kiva/qt4_simple.py fails with pyside2 with this error:

$ python qt4_simple.py 
Traceback (most recent call last):
  File "qt4_simple.py", line 56, in <module>
    app = QtGui.QApplication(sys.argv)
RuntimeError: Please destroy the QApplication singleton before creating a new QApplication instance.

But runs fine with pyqt5. However, etsdemo can not be run with pyqt5 because of the QtWebKit issue.

Details
 $ etsdemo
Traceback (most recent call last):
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/pyface/qt/QtWebKit.py", line 19, in <module>
    from PyQt5.QtWebEngine import *
ModuleNotFoundError: No module named 'PyQt5.QtWebEngine'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/tree_editor.py", line 944, in _on_tree_sel_changed
    parent=editor, view=view, kind="subpanel"
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traits/has_traits.py", line 1678, in edit_traits
    args,
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/view.py", line 462, in ui
    ui.ui(parent, kind)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/ui.py", line 244, in ui
    self.rebuild(self, parent)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/toolkit.py", line 147, in ui_subpanel
    ui_panel.ui_subpanel(ui, parent)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 62, in ui_subpanel
    _ui_panel_for(ui, parent, True)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 68, in _ui_panel_for
    ui.control = control = _Panel(ui, parent, is_subpanel).control
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 130, in __init__
    self.control = panel(ui)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 259, in panel
    panel = _GroupPanel(content[0], ui).control
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 617, in __init__
    layout = self._add_items(content, inner)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/ui_panel.py", line 883, in _add_items
    ui, object, name, item.tooltip, None
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/editor_factory.py", line 168, in readonly_editor
    description=description,
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/editors/html_editor.py", line 34, in html_editor
    return toolkit_object("html_editor:SimpleEditor")(*args, **traits)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/toolkit.py", line 71, in toolkit_object
    obj = _toolkit(name)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/pyface/base_toolkit.py", line 152, in __call__
    module = import_module(mname, package)
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/traitsui/qt4/html_editor.py", line 23, in <module>
    from pyface.qt import QtCore, QtGui, QtWebKit
  File "/Users/aayres/.edm/envs/enable-test-3.6-null-pillow/lib/python3.6/site-packages/pyface/qt/QtWebKit.py", line 28, in <module>
    from PyQt5.QtWebKit import *
ModuleNotFoundError: No module named 'PyQt5.QtWebKit'
Abort trap: 6

@aaronayres35 aaronayres35 requested a review from kitchoi December 15, 2020 18:19
Copy link
Copy Markdown
Contributor

@kitchoi kitchoi left a comment

Choose a reason for hiding this comment

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

Some preliminary review comments. I understand this is still a work-in-progress. Happy to review this again.

Comment thread enable/__init__.py
Comment thread enable/examples/_etsdemo_info.py
Comment thread kiva/examples/tests/test_etsdemo_info.py Outdated
@aaronayres35 aaronayres35 changed the title [WIP] Contribute examples to etsdemo Contribute examples to etsdemo Dec 16, 2020
kitchoi
kitchoi previously approved these changes Dec 17, 2020
Copy link
Copy Markdown
Contributor

@kitchoi kitchoi left a comment

Choose a reason for hiding this comment

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

For the ones that don't work well, since we are exposing them anyway, what do you think about adding docstrings to warn about that instead of letting the user finding it out for themselves and getting disappointed?
e.g. https://github.com/enthought/traitsui/blob/98b6593d4e8eabb010982861ae977cc8a9d66f79/traitsui/examples/demo/Standard_Editors/TableEditor_demo.py#L5
It is also useful to add a comment referencing the issue you opened. https://github.com/enthought/traitsui/blob/98b6593d4e8eabb010982861ae977cc8a9d66f79/traitsui/examples/demo/Standard_Editors/TableEditor_demo.py#L17

Not only this will set the user's expectation upfront, later we can track down the issue and determine if the warning can be removed. e.g. I was able to remove one warning entirely when the sole issue is resolved: enthought/traitsui@1b7de78#diff-c79f163118f7b6def1f8f0f3fbff5736f8c1679f9d387c6dc4a411a8d437c887

It that sounds good to you, please feel free to do so in a separate PR as it is slightly broader scope.

@aaronayres35
Copy link
Copy Markdown
Contributor Author

For the ones that don't work well, since we are exposing them anyway, what do you think about adding docstrings to warn about that instead of letting the user finding it out for themselves and getting disappointed?
e.g. https://github.com/enthought/traitsui/blob/98b6593d4e8eabb010982861ae977cc8a9d66f79/traitsui/examples/demo/Standard_Editors/TableEditor_demo.py#L5
It is also useful to add a comment referencing the issue you opened. https://github.com/enthought/traitsui/blob/98b6593d4e8eabb010982861ae977cc8a9d66f79/traitsui/examples/demo/Standard_Editors/TableEditor_demo.py#L17

Not only this will set the user's expectation upfront, later we can track down the issue and determine if the warning can be removed. e.g. I was able to remove one warning entirely when the sole issue is resolved: enthought/traitsui@1b7de78#diff-c79f163118f7b6def1f8f0f3fbff5736f8c1679f9d387c6dc4a411a8d437c887

It that sounds good to you, please feel free to do so in a separate PR as it is slightly broader scope.

SGTM! I might also mention on the ones that work stand-alone but not in etsdemo that changing __main__ to ___main___ in the code editor will work, and add a reference to the issue enthought/traitsui#1428. Does that make sense?

@kitchoi
Copy link
Copy Markdown
Contributor

kitchoi commented Dec 17, 2020

add a reference to the issue enthought/traitsui#1428.

Adding reference to ___main___ (enthought/traitsui#1428) is a bit tricky, because then when enthought/traitsui#1428 is fixed and released, you have to make releases for all the demo files that have that reference, otherwise the reference would be extremely unhelpful and misleading. So probably not...
We should just fix the issue. Now that we have seen examples in different context, it is a good place to be to decide how we want to fix it.

@kitchoi kitchoi dismissed their stale review December 17, 2020 17:46

Apologies. We agreed to resolve the issue noted in #494 (comment) here. Dismissing the review so we don't accidentally merge this. I will come back to review new changes.

class Demo(DemoFrame):

def create_component(self):
def _create_component(self):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

part of #500
All this required to fix was this leading underscore so I figured it was fine to add with this PR.

The issue name is misleading, as the other examples in the comments of the issue are still independently broken. they need to overwrite the _create_component method. I will update issue and try to fix those in a later PR

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This makes sense. Thank you!

def _create_component(self):
canvas = Canvas(bgcolor="lightsteelblue", draw_axes=True)
from basic_move import Box
from enable.examples.demo.enable.basic_move import Box
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@kitchoi I was googling namespace packages in python, and was trying to understand but still am a bit confused. It seems that doing this, without adding any __init__.py files works as we want it to, but I want to confirm I am not missing anything.

Copy link
Copy Markdown
Member

@jwiggins jwiggins Dec 18, 2020

Choose a reason for hiding this comment

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

Does from .basic_move import Box not work?

I don't think namespace packages are relevant in this situation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The context while running the example in the etsdemo GUI application is a little different.The Python path there is the Python path used for running the GUI application, which is not necessarily the same as the Python path used for running the script from the command line. The absolute import removes assumption on the Python path.

This is the block of code relevant while this file is run from the GUI application, the triple-underscore-main thing can be found here:
https://github.com/enthought/traitsui/blob/e913f98d10e96624245c603d856b33ded665d565/ets-demo/etsdemo/app.py#L462-L487

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems that doing this, without adding any init.py files works as we want it to

This was what I expected as well.

Copy link
Copy Markdown
Contributor

@kitchoi kitchoi Dec 18, 2020

Choose a reason for hiding this comment

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

@jwiggins comment is valid as in it shows the cognitive load required to maintain these examples.

Should enthought/traitsui#1455 be fixed, from .basic_move import Box should work (I think).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should enthought/traitsui#1455 be fixed, from .basic_move import Box should work (I think).

That seems like the better solution here

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry, I was wrong... I should never guess but try for myself... :(

from .basic_move import Box does not work, if I try to run the script from the command line (I am using master with the create_component -> _create_component fix:

 $ pwd
/Users/kchoi/Work/ETS/enable/examples/enable
$ python canvas_demo.py
...
  File "/Users/kchoi/Work/ETS/enable/enable/example_support.py", line 40, in _component_default
    return self._create_component()
  File "canvas_demo.py", line 10, in _create_component
    from .basic_move import Box
ModuleNotFoundError: No module named '__main__.basic_move'; '__main__' is not a package

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The absolute import here does work on both the etsdemo application and from the command line.
from basic_move import Box does not work on etsdemo but will work if enthought/traitsui#1455 is fixed.

@jwiggins Is it okay for us to proceed with the absolute import here to decouple this import from the pending issue?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

From offline discussion: John says yes. :D

Copy link
Copy Markdown
Contributor

@kitchoi kitchoi left a comment

Choose a reason for hiding this comment

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

LGTM

@aaronayres35 aaronayres35 merged commit 24b534d into master Dec 18, 2020
@jwiggins jwiggins deleted the contribute-examples-to-etsdemo branch December 18, 2020 17:12
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.

Contribute examples to the etsdemo application

4 participants