I am trying embed wx.py.shell.Shell into my wxPython application as a
new tab of the main notebook widget.
The application works fine till the moment I use pyshell, eg. after typing
import sys
sys.path
the application is unusable, one traceback as an example
page: 1
self.notebook: <wx.lib.agw.flatnotebook.FlatNotebook; proxy of <Swig
Object of type 'wxPyPanel *' at 0xa1f94d0> >
Traceback (most recent call last):
self.notebook.SetPageText(page, _("Command console"))
TypeError: 'list' object is not callable
Variables seems to be OK ("page" and "notebook"), anyway the statement
fails with TypeError ('list' because `sys.path` returns a list). It
seems that pyshell modifies app variables stack?
Please make a runnable, small as possible, sample application that demonstrates the problem and let us know the platform and wx version. MakingSampleApps - wxPyWiki
···
On 6/1/11 9:10 AM, Martin Landa wrote:
Hi,
I am trying embed wx.py.shell.Shell into my wxPython application as a
new tab of the main notebook widget.
The application works fine till the moment I use pyshell, eg. after typing
import sys
sys.path
the application is unusable, one traceback as an example
page: 1
self.notebook:<wx.lib.agw.flatnotebook.FlatNotebook; proxy of<Swig
Object of type 'wxPyPanel *' at 0xa1f94d0> >
Traceback (most recent call last):
self.notebook.SetPageText(page, _("Command console"))
TypeError: 'list' object is not callable
Variables seems to be OK ("page" and "notebook"), anyway the statement
fails with TypeError ('list' because `sys.path` returns a list). It
seems that pyshell modifies app variables stack?
Please make a runnable, small as possible, sample application that
demonstrates the problem and let us know the platform and wx version. MakingSampleApps - wxPyWiki
till now I was not able to reproduce it with a simple app. Just some
more notes:
* everything works when I type `print` statement in the pyshell tab, ie.
`print sys.path` -> OK
`sys.path` -> app starts to be broken, after that every function which
takes string as a argument produces this strange traceback, eg.
self.notebook.SetPageText(page, _("Command console"))
TypeError: 'list' object is not callable
or
ctrl.SetToolTipString(_("Click to edit layer settings"))
TypeError: 'list' object is not callable
or
label=_(" List of %s layers ") % self.importType.upper())
TypeError: 'list' object is not callable
Please make a runnable, small as possible, sample application that
demonstrates the problem and let us know the platform and wx version. MakingSampleApps - wxPyWiki
till now I was not able to reproduce it with a simple app. Just some
more notes:
* everything works when I type `print` statement in the pyshell tab, ie.
`print sys.path` -> OK
`sys.path` -> app starts to be broken, after that every function which
takes string as a argument produces this strange traceback, eg.
PyShell runs in process so it can modify variables in your app at
runtime. Calling something that produces a return value in the shell
with out assigning it to something will cause it to be implicitly
assigned to the temporary variable '_'.
self.notebook.SetPageText(page, _("Command console"))
TypeError: 'list' object is not callable
or
ctrl.SetToolTipString(_("Click to edit layer settings"))
TypeError: 'list' object is not callable
or
label=_(" List of %s layers ") % self.importType.upper())
TypeError: 'list' object is not callable
_ has now become a list() instance since it sys.path was assigned to
it in your shell session, hence the error given above.
Cody
···
On Wed, Jun 1, 2011 at 1:46 PM, Martin Landa <landa.martin@gmail.com> wrote:
* everything works when I type `print` statement in the pyshell tab, ie.
`print sys.path` -> OK
`sys.path` -> app starts to be broken, after that every function which
takes string as a argument produces this strange traceback, eg.
self.notebook.SetPageText(page, _("Command console"))
TypeError: 'list' object is not callable
or
ctrl.SetToolTipString(_("Click to edit layer settings"))
TypeError: 'list' object is not callable
or
label=_(" List of %s layers ") % self.importType.upper())
TypeError: 'list' object is not callable
I discovered that the source of problems is i18n. Try attached app.
* go to second tab, type
import sys
sys.path
* go to first tab, you should get an error
page: 0
self.notebook: <wx.lib.agw.flatnotebook.FlatNotebook; proxy of <Swig
Object of type 'wxPyPanel *' at 0xa17f1a0> >
Traceback (most recent call last):
File "app.py", line 49, in OnPageChanged
self.notebook.SetPageText(page, _("Tab %d") % page)
TypeError: 'list' object is not callable
Tested on Debian GNU/Linux with '2.8.10.1 (gtk2-unicode)'.
PyShell runs in process so it can modify variables in your app at
runtime. Calling something that produces a return value in the shell
with out assigning it to something will cause it to be implicitly
assigned to the temporary variable '_'.
it explains the mystery perfectly. Thanks! Do yo know to change this
temp variable to something less harmless. I cannot control what the
user will type in the shell...
I discovered that the source of problems is i18n. Try attached app.
Yes, because one commonly uses _ as a shortcut for the i18n
gettext.gettext() function. One can argue about whether or not modules
should re-import the _ function, but in the meantime, the solution is to
do all of your PyShell console printing with the "print" statement,
instead of relying on the "lone expression gets printed" mechanism,
which has this side effect.
···
2011/6/1 Martin Landa <landa.martin@gmail.com>:
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
should re-import the _ function, but in the meantime, the solution is to
do all of your PyShell console printing with the "print" statement,
instead of relying on the "lone expression gets printed" mechanism,
which has this side effect.
well, this app will be used by different users. I am afraid that the
most of them will "rely on the lone expression gets printed
mechanism". I need to make this app more error-prone. This lone
expression mechanism cannot break the whole app.
IIRC this behavior can be changed by setting sys.displayhook to a function that just prints the value and does not set __builtin__._ like the default function does.
···
On 6/1/11 11:57 AM, Martin Landa wrote:
Hi,
2011/6/1 Cody Precord<codyprecord@gmail.com>:
PyShell runs in process so it can modify variables in your app at
runtime. Calling something that produces a return value in the shell
with out assigning it to something will cause it to be implicitly
assigned to the temporary variable '_'.
it explains the mystery perfectly. Thanks! Do yo know to change this
temp variable to something less harmless. I cannot control what the
user will type in the shell...
IIRC this behavior can be changed by setting sys.displayhook to a function
that just prints the value and does not set __builtin__._ like the default
function does.
PyShell runs in process so it can modify variables in your app at
runtime. Calling something that produces a return value in the shell
with out assigning it to something will cause it to be implicitly
assigned to the temporary variable '_'.
it explains the mystery perfectly. Thanks! Do yo know to change this
temp variable to something less harmless. I cannot control what the
user will type in the shell...
There is always an inherent risk in embedding PyShell in your
application since it runs with in the same instance of Python as your
application does. A user can do any number of things that can cause
problems in your app.
The only real solution would be to have pyshell run and evaluate code
in a separate instance of python and just have the widget communicate
back and forth with it.
Cody
···
On Wed, Jun 1, 2011 at 1:57 PM, Martin Landa <landa.martin@gmail.com> wrote:
Sure, but some behaviors are more or less likely. I’d wager most times you want to provide a shell in your program, it’s so your users can access functionality that exists in the program but hasn’t been exposed in the UI yet, or so they can easily do math. If they set out to break the program, then obviously they have that capability, but the program shouldn’t break on its own when they’re staying within the expected use cases.
Of course, if it’s important that the program never break, then an embedded pyshell probably isn’t the way to go.