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

Push variables to console when instantiated #5210

Merged
merged 33 commits into from
Jun 15, 2023

Conversation

davidpross
Copy link
Contributor

Description

Currently, if update_console is called on viewer object before the console is instantiated the function does nothing. With this PR instead references to the requested variables are added to a console_backlog list attribute on qt_viewer. If and when console is instantiated these variables are pushed.

Unsure if this related PR is moving forward and whether it would solve this case.

Type of change

  • Bug-fix (non-breaking change which fixes an issue)

References

Closes #4098

How has this been tested?

  • Ran unit tests for napari/_qt. There were some errors but looked unrelated to my changes.
  • Added unit test based on existing test_update_console

Final checklist:

  • My PR is the minimum possible work for the desired functionality
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works

@github-actions github-actions bot added qt Relates to qt tests Something related to our tests labels Oct 12, 2022
@codecov
Copy link

codecov bot commented Oct 12, 2022

Codecov Report

Merging #5210 (7eeb664) into main (49fee1d) will increase coverage by 0.18%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main    #5210      +/-   ##
==========================================
+ Coverage   89.82%   90.01%   +0.18%     
==========================================
  Files         610      618       +8     
  Lines       52131    52769     +638     
==========================================
+ Hits        46825    47498     +673     
+ Misses       5306     5271      -35     
Impacted Files Coverage Δ
napari/_qt/qt_viewer.py 75.80% <100.00%> (+2.12%) ⬆️
napari/_tests/test_advanced.py 100.00% <100.00%> (ø)
napari/viewer.py 88.46% <100.00%> (+0.22%) ⬆️

... and 89 files with indirect coverage changes

@psobolewskiPhD
Copy link
Member

This works quite nicely for me locally!
While you have this PR open, can you also fix the example that the issue refers to?
It's making two viewers, in a rather nonsensical fashion, as noted in the original issue:
#4098 (comment)
Worse yet, it means using the example to test your fix doesn't work!

Just change:

image_layer = napari.view_image(photographer, name='photographer')

from napari.view_image to viewer.add_image
(Also, I'm not sure what the deal is with printing in the doc string, it doesn't print anything, but with your fix one can access polygons. You could delete that I guess.)

I think fixing this is useful, even if I personally think the console should inherit from scripts automagically. That's what napari/napari-console#18 is trying to do, which would make this obsolete, but it's still WIP, so in the meantime this is nice.

@davidpross
Copy link
Contributor Author

This works quite nicely for me locally!
While you have this PR open, can you also fix the example that the issue refers to?

Thanks for checking it out, I added a fix for the example to not open two viewers and also printed the updated shapes coordinates after the window closes.

@Czaki
Copy link
Collaborator

Czaki commented Oct 20, 2022

Aaybe it will be also nice to always push np to the console to not require type import numpy as np

@psobolewskiPhD
Copy link
Member

Aaybe it will be also nice to always push np to the console to not require type import numpy as np

On one hand I agree, it's handy, saves keystrokes. On the other it seems potentially dangerous because some snippets will work as if by magic without an explicit import and a new python user may then be confused when in ipython/jupyter they don't. I've found the console very nice to learn and explore, as well as show python to people, so I think i'd prefer that such behavior not be included.
Perhaps it's a new PR to make some sort of console init preference to import on open?

@brisvag
Copy link
Contributor

brisvag commented Nov 2, 2022

On the other it seems potentially dangerous because some snippets will work as if by magic without an explicit import and a new python user may then be confused when in ipython/jupyter they don't.

In the past I dealt with similar issue by having the console print a header where it informs that some things have been imported for the user, something like:

--- napari console ---
The napari viewer is accessible from the `viewer` variable.
Additionally, numpy was imported as `np` and ...
---

@psobolewskiPhD
Copy link
Member

I like that a lot. Maybe 2nd PR though? Could be some discussion as to what should be auto-imported and how the message should look.

@hanjinliu
Copy link

I think the safer but more useful way is to execute the ipython startup files on launching the napari console (see here as an example if you are not familiar with).

@brisvag
Copy link
Contributor

brisvag commented Nov 4, 2022

Yes, that's also great, though not really equivalent (we still have the viewer variable, for example, which is a napari-only thing)

@jni
Copy link
Member

jni commented Dec 13, 2022

I think napari/napari-console#18 would indeed solve this. I'd be in favour of pushing on that one but I'm not sure whether @Carreau is around to push it over the line... I'm not opposed to merging this though because the implementation is so simple. I only have a minor question which is that it seems a bit pointless to reset the blank value to None instead of always using the empty list? ie you would save an if clause if you just set it to the empty list?

@@ -180,6 +180,34 @@ def test_update_console(make_napari_viewer):
del viewer.window._qt_viewer.console.shell.user_ns[k]


@pytest.mark.filterwarnings("ignore::DeprecationWarning:jupyter_client")
def test_update_lazy_console(make_napari_viewer):
Copy link
Contributor

Choose a reason for hiding this comment

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

I am trying to understand if this test will still do its job if the startup time for console is decreased to the point that it is loaded when update_console is called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With the lazy instantiation the console shouldn't begin starting up until the assertion on L196 below.

@davidpross
Copy link
Contributor Author

I only have a minor question which is that it seems a bit pointless to reset the blank value to None instead of always using the empty list? ie you would save an if clause if you just set it to the empty list?

I think my last commit implemented your suggestion but let me know if I misinterpreted it.

@Carreau
Copy link
Contributor

Carreau commented Dec 21, 2022

I think napari/napari-console#18 would indeed solve this. I'd be in favor of pushing on that one but I'm not sure whether @Carreau is around to push it over the line...

Yeah, sorry I'm been a bit under the wether over the past two weeks.

Seeing that napari console is not super active, have considered having a mono-repo under napari, that has both napari and napari console, it would make it a bit easier to manage all in the same place ?

@davidpross
Copy link
Contributor Author

Added description for when creating a weakref fails, also made suggested updates. In addition on further reflection removed special handling for list objects because if a list or tuple is passed it is supposed to only contain strings of variable names. So weakrefs are created if possible for the values of any dictionary passed to update_console when console hasn't been instantiated. A weakref will be created for something like a numpy array but not a Python list. So there could still be some strong references if you passed something like update_console({'obj_list': [obj1, obj2, obj3]})

Comment on lines 511 to 515
Args:
value (Object|weakref): Can be a weakref

Returns:
Object|None: Returns object or None if weakref is dead.
Copy link
Member

Choose a reason for hiding this comment

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

@davidpross can you use numpydoc formatting here? 🙏 (and above). Otherwise, nice, thanks! 😊

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated docstrings, thanks for all the help with these changes.

@kephale
Copy link
Contributor

kephale commented Apr 17, 2023

@Carreau just a gently nudge for review on this one. Thank you!

@Carreau
Copy link
Contributor

Carreau commented Apr 17, 2023

@Carreau just a gently nudge for review on this one. Thank you!

That looks good to me, there will always be edge case we can refine later.

}
)
else:
self.console.push(i)
Copy link
Member

Choose a reason for hiding this comment

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

@davidpross I think this line isn't covered by tests? Ditto for line 508. tbh I don't understand the usage that would get us there. Could you elaborate on that and maybe add a test? I think this is very close to merging otherwise! 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch on the test coverage. It turns out that passing a variable name as a string or list of variable names was not working in the context of a console that is not yet instantiated. I added code from here to handle these cases and updated the unit tests accordingly. Also the console_backlog will now always be a list of dicts.

@jni
Copy link
Member

jni commented Apr 27, 2023

btw I've pushed some minor formatting fixes so please git pull before making further changes!

@jni jni added the ready to merge Last chance for comments! Will be merged in ~24h label May 26, 2023
@Czaki Czaki added this to the 0.4.18 milestone Jun 15, 2023
@Czaki Czaki merged commit bea22f5 into napari:main Jun 15, 2023
35 checks passed
@Czaki Czaki removed the ready to merge Last chance for comments! Will be merged in ~24h label Jun 15, 2023
Czaki added a commit that referenced this pull request Jun 19, 2023
Currently, if
[`update_console`](https://github.com/napari/napari/blob/7117d22e4baa740864762454911dc5ed09764ccc/napari/viewer.py#L88)
is called on viewer object before the console is instantiated the
function does nothing. With this PR instead references to the requested
variables are added to a `console_backlog` list attribute on qt_viewer.
If and when console is instantiated these variables are pushed.

Unsure if [this related
PR](napari/napari-console#18) is moving forward
and whether it would solve this case.

- [x] Enhancment

Closes #4098

- [x] Ran unit tests for `napari/_qt`. There were some errors but looked
unrelated to my changes.
- [x] Added unit test based on existing `test_update_console`

- [x] My PR is the minimum possible work for the desired functionality
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my
feature works

---------

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>
Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
@davidpross davidpross deleted the update-console branch June 20, 2023 18:46
Czaki added a commit that referenced this pull request Jun 21, 2023
Currently, if
[`update_console`](https://github.com/napari/napari/blob/7117d22e4baa740864762454911dc5ed09764ccc/napari/viewer.py#L88)
is called on viewer object before the console is instantiated the
function does nothing. With this PR instead references to the requested
variables are added to a `console_backlog` list attribute on qt_viewer.
If and when console is instantiated these variables are pushed.

Unsure if [this related
PR](napari/napari-console#18) is moving forward
and whether it would solve this case.

- [x] Enhancment

Closes #4098

- [x] Ran unit tests for `napari/_qt`. There were some errors but looked
unrelated to my changes.
- [x] Added unit test based on existing `test_update_console`

- [x] My PR is the minimum possible work for the desired functionality
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my
feature works

---------

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>
Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
Czaki added a commit that referenced this pull request Jun 21, 2023
Currently, if
[`update_console`](https://github.com/napari/napari/blob/7117d22e4baa740864762454911dc5ed09764ccc/napari/viewer.py#L88)
is called on viewer object before the console is instantiated the
function does nothing. With this PR instead references to the requested
variables are added to a `console_backlog` list attribute on qt_viewer.
If and when console is instantiated these variables are pushed.

Unsure if [this related
PR](napari/napari-console#18) is moving forward
and whether it would solve this case.

- [x] Enhancment

Closes #4098

- [x] Ran unit tests for `napari/_qt`. There were some errors but looked
unrelated to my changes.
- [x] Added unit test based on existing `test_update_console`

- [x] My PR is the minimum possible work for the desired functionality
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my
feature works

---------

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>
Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
Czaki added a commit that referenced this pull request Jun 21, 2023
Currently, if
[`update_console`](https://github.com/napari/napari/blob/7117d22e4baa740864762454911dc5ed09764ccc/napari/viewer.py#L88)
is called on viewer object before the console is instantiated the
function does nothing. With this PR instead references to the requested
variables are added to a `console_backlog` list attribute on qt_viewer.
If and when console is instantiated these variables are pushed.

Unsure if [this related
PR](napari/napari-console#18) is moving forward
and whether it would solve this case.

- [x] Enhancment

Closes #4098

- [x] Ran unit tests for `napari/_qt`. There were some errors but looked
unrelated to my changes.
- [x] Added unit test based on existing `test_update_console`

- [x] My PR is the minimum possible work for the desired functionality
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my
feature works

---------

Co-authored-by: Peter Sobolewski <76622105+psobolewskiPhD@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>
Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement qt Relates to qt tests Something related to our tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

update_console example is broken
8 participants