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
Make pylab import all configurable #622
Conversation
This looks good, but I have a couple of comments:
with ip.magic('pylab') self.assertTrue('plot' in ip.user_ns) which is clearer, faster and fully equivalent.
In summary, I think if we work a bit on this one, not only will we get the import_all situation fixed, but more generally where we handle pylab for all ipython shells. |
There is only ever one config object in the entire application, and get_ipython().config will return it. There is no store of defaults other than the classes themselves, so the only 'merged' value is in the actual traits of configured instances. |
Got it, thanks @minrk. So indeed, @jenshnielsen, the way to go is to clean things out and put the pylab flags only in the From looking around, I get the feeling that we need to do a little cleanup of all the classes, but you don't need to worry about that quite now. |
I changed the test and moved pylab_import_all to The test is still potentially problematic because pylab is activated in the testing env. and I guess that this |
Thanks much. I won't have time to finish this in the next couple of days, but hopefully on Wednesday at the mini-sprint prior to euroscipy I can finish it up. |
self.shell.enable_pylab(s) | ||
|
||
try: | ||
ip = get_ipython() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be the same object as self.shell
in this context, so you needn't use get_ipython
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes thats simpler, thanks. The try except AttributeError: construction
still seems to be necessary as pylab_import_all has doesn't have any
value if it hasn't been customized in a config file. Is there a simple way to get the default value
so that true doesn't have to be hard coded here?.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I think you're currently using a reference to the config itself. What we'd need is a reference to the application object itself, but I don't know if it's possible to get one from the shell object.
@fperez, @minrk : Is there a way to get a reference to the application from inside a magic method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current Application can always be retrieved with:
from IPython.config.application import Application
app = Application.instance()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works except in the test. The test returns an instance of the basic application without pylab_import_all.
In the IPython shell it returns a TerminalIPythonApp instance that has pylab_import_all
defined. I worked around this by falling back to self.shell.config.TerminalIPythonApp.pylab_import_all
that works in the test. But is not defined in the IPython shell when it hasn't been customized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I prefer to avoid having code in the core just for compatibility with the test suite. Two possible ways round it:
- The test calls
Application.instance()
before the code, and sets apylab_import_all
attribute. - The test runs a separate IPython process and gets it to print some output indicating whether or not names from pylab have been imported.
Thanks for this work - I hope it doesn't feel like a wild goose chase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks for working on this. The configuration stuff is definitely going through some growing pains, as it's brand new and not the most convenient for everything. The test suite should presumably start an Application, so its environment is more like that seen by a real IPython, but that's out of scope for this.
For now, I would create the Application in your tests, rather than writing to the config object itself. Add:
app = Application.instance()
app.pylab_import_all = True/False
in your tests,
and then check in the magic should not go directly to the config object, but straight to a default in the application doesn't have the right attribute:
if Application.initialized():
app = Application.instance()
try:
import_all_status = app.pylab_import_all
except AttributeError:
import_all_status = True # (or False, whatever the default is)
else:
import_all_status = True
That way you can have a test that includes the case where the Application does not even have the trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks I have implemented this exactly as you suggested and it works.
I am still a bit worried about the test. I think we need a way to avoid that the pylab magic activates the gui
in order to avoid problems in subsequent tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are concerned about polluting the environment, @takluyver is right, performing the test via an IPython subprocess is safer. There are various irunner tests already in the test suite that give examples of this.
New version of the test using now irunner. I copied and modified the test_irunner.py a bit. Note that one of the tests fails when running it from virtualenv. The virualenv irunner seems to use the system wide |
@decorators.skipif_not_matplotlib | ||
def test_pylab_import_all_disabled(self): | ||
"Verify that plot is not available when pylab_import_all = False" | ||
runner = irunner.PythonRunner(out=self.out) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this line supposed to do anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a duplicate line in the other test. Presumably leftovers from the copy/paste.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I have removed the useless line.
The real code looks great to me. I'm not sure why the irunner would not spawn the same IPython it's being run from - it does inherit the path/env as I understand, but virtualenv can fail at such things. It is possible that the path/env does not get set up or inherited properly, but this has not been my experience. |
I submitted a new issue #779 for the irunner problem. It is independent of both this pull request and the general testing |
Okay, I think this looks good. Thanks for opening the virtualenv-test Issue. It now conflicts with a big recent py3compat merge, so if you rebase again on master, I will do the merge. If you'd rather not do that, I can to a rebased merge myself. |
Thanks. I have already another local branch with the changes squashed into 4 logical commits and |
Rebased |
Thanks! Looks good to me, passes tests. Merged. |
New version of pull request #551 This should of cause not be merged until after 0.11
I have added a test and changed the magic function to use the import_all setting.
I few issues remain:
I don't like the way that the magic function works as the default value True is hard coded when
get_ipython().TerminalIPythonApp.pylab_import_all
is not set. Is there a simple way to get the default value here?The test uses the magic function. It results in 2 warnings because of problems with the gtk hook and because matplotlib.use. It would be better with a test that creates a new instance of IPython only for the test. I tried creating a new instance with code similar to the TerminalIPythonApp launch_new_instance. However this seems to lock the test framework. Any hints for making a better test are welcome.