Skip to content

Commit

Permalink
Fixes for PythonEditor and Python Widget (#980)
Browse files Browse the repository at this point in the history
This mainly kicks off the deprecation of automatic creation of the widgets
in the __init__ method.  This also deprecates the very old wx IPython widget.
  • Loading branch information
corranwebster authored Jul 13, 2021
1 parent 131a3ce commit 7db0298
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 32 deletions.
41 changes: 37 additions & 4 deletions pyface/tests/test_python_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,26 @@ def tearDown(self):
def test_lifecycle(self):
# test that destroy works
with self.event_loop():
self.widget = PythonEditor(self.window.control)
with self.assertWarns(PendingDeprecationWarning):
self.widget = PythonEditor(self.window.control)

self.assertIsNotNone(self.widget.control)
self.assertFalse(self.widget.dirty)

with self.event_loop():
self.widget.destroy()

def test_two_stage_create(self):
# test that create and destroy work
self.widget = PythonEditor(create=False)

self.assertIsNone(self.widget.control)

with self.event_loop():
self.widget.parent = self.window.control
self.widget.create()

self.assertIsNotNone(self.widget.control)
self.assertFalse(self.widget.dirty)

with self.event_loop():
Expand All @@ -56,19 +74,29 @@ def test_show_line_numbers(self):
# test that destroy works
with self.event_loop():
self.widget = PythonEditor(
self.window.control, show_line_numbers=False
parent=self.window.control,
show_line_numbers=False,
create=False,
)
self.widget.create()

with self.event_loop():
self.widget.show_line_numbers = True

with self.event_loop():
self.widget.show_line_numbers = False

with self.event_loop():
self.widget.destroy()

def test_load(self):
# test that destroy works
with self.event_loop():
self.widget = PythonEditor(self.window.control)
self.widget = PythonEditor(
parent=self.window.control,
create=False,
)
self.widget.create()

with self.assertTraitChanges(self.widget, "changed", count=1):
with self.event_loop():
Expand All @@ -81,7 +109,12 @@ def test_load(self):
def test_select_line(self):
# test that destroy works
with self.event_loop():
self.widget = PythonEditor(self.window.control, path=PYTHON_SCRIPT)
self.widget = PythonEditor(
parent=self.window.control,
path=PYTHON_SCRIPT,
create=False,
)
self.widget.create()

with self.event_loop():
self.widget.select_line(3)
Expand Down
46 changes: 36 additions & 10 deletions pyface/tests/test_python_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,34 @@ def tearDown(self):
def test_lifecycle(self):
# test that destroy works
with self.event_loop():
self.widget = PythonShell(self.window.control)
with self.assertWarns(PendingDeprecationWarning):
self.widget = PythonShell(self.window.control)

self.assertIsNotNone(self.widget.control)

with self.event_loop():
self.widget.destroy()

def test_two_stage_create(self):
# test that create=False works
self.widget = PythonShell(create=False)

self.assertIsNone(self.widget.control)

with self.event_loop():
self.widget.parent = self.window.control
self.widget.create()

self.assertIsNotNone(self.widget.control)

with self.event_loop():
self.widget.destroy()

def test_bind(self):
# test that binding a variable works
self.widget = PythonShell(parent=self.window.control, create=False)
with self.event_loop():
self.widget = PythonShell(self.window.control)
self.widget.create()
with self.event_loop():
self.widget.bind("x", 1)

Expand All @@ -64,8 +84,9 @@ def test_bind(self):

def test_execute_command(self):
# test that executing a command works
self.widget = PythonShell(parent=self.window.control, create=False)
with self.event_loop():
self.widget = PythonShell(self.window.control)
self.widget.create()

with self.assertTraitChanges(self.widget, "command_executed", count=1):
with self.event_loop():
Expand All @@ -78,8 +99,9 @@ def test_execute_command(self):

def test_execute_command_not_hidden(self):
# test that executing a non-hidden command works
self.widget = PythonShell(parent=self.window.control, create=False)
with self.event_loop():
self.widget = PythonShell(self.window.control)
self.widget.create()

with self.assertTraitChanges(self.widget, "command_executed", count=1):
with self.event_loop():
Expand All @@ -92,8 +114,9 @@ def test_execute_command_not_hidden(self):

def test_execute_file(self):
# test that executing a file works
self.widget = PythonShell(parent=self.window.control, create=False)
with self.event_loop():
self.widget = PythonShell(self.window.control)
self.widget.create()

# XXX inconsistent behaviour between backends
# with self.assertTraitChanges(self.widget, 'command_executed', count=1):
Expand All @@ -108,8 +131,9 @@ def test_execute_file(self):

def test_execute_file_not_hidden(self):
# test that executing a file works
self.widget = PythonShell(parent=self.window.control, create=False)
with self.event_loop():
self.widget = PythonShell(self.window.control)
self.widget.create()

# XXX inconsistent behaviour between backends
# with self.assertTraitChanges(self.widget, 'command_executed', count=1):
Expand All @@ -123,9 +147,10 @@ def test_execute_file_not_hidden(self):
self.widget.destroy()

def test_get_history(self):
# test that executing a command works
# test that command history can be extracted
self.widget = PythonShell(parent=self.window.control, create=False)
with self.event_loop():
self.widget = PythonShell(self.window.control)
self.widget.create()

with self.event_loop():
self.widget.execute_command("x = 1", hidden=False)
Expand All @@ -139,9 +164,10 @@ def test_get_history(self):
self.widget.destroy()

def test_set_history(self):
# test that executing a command works
# test that command history can be updated
self.widget = PythonShell(parent=self.window.control, create=False)
with self.event_loop():
self.widget = PythonShell(self.window.control)
self.widget.create()

with self.event_loop():
self.widget.set_history(["x = 1", "y = x + 1"], 1)
Expand Down
16 changes: 14 additions & 2 deletions pyface/ui/qt4/python_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#
# Thanks for using Enthought open source!

import warnings

from pyface.qt import QtCore, QtGui

Expand Down Expand Up @@ -46,9 +47,20 @@ class PythonEditor(MPythonEditor, Widget):
# 'object' interface.
# ------------------------------------------------------------------------

def __init__(self, parent, **traits):
def __init__(self, parent=None, **traits):

create = traits.pop("create", True)

super().__init__(parent=parent, **traits)
self._create()

if create:
self.create()
warnings.warn(
"automatic widget creation is deprecated and will be removed "
"in a future Pyface version, use create=False and explicitly "
"call create() for future behaviour",
PendingDeprecationWarning,
)

# ------------------------------------------------------------------------
# 'PythonEditor' interface.
Expand Down
17 changes: 14 additions & 3 deletions pyface/ui/qt4/python_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from io import StringIO
import sys
from time import time
import warnings


from pyface.qt import QtCore, QtGui
Expand Down Expand Up @@ -56,11 +57,21 @@ class PythonShell(MPythonShell, Widget):

# FIXME v3: Either make this API consistent with other Widget sub-classes
# or make it a sub-class of HasTraits.
def __init__(self, parent, **traits):
def __init__(self, parent=None, **traits):

create = traits.pop("create", True)

super().__init__(parent=parent, **traits)

# Create the toolkit-specific control that represents the widget.
self._create()
if create:
# Create the toolkit-specific control that represents the widget.
self.create()
warnings.warn(
"automatic widget creation is deprecated and will be removed "
"in a future Pyface version, use create=False and explicitly "
"call create() for future behaviour",
PendingDeprecationWarning,
)

# --------------------------------------------------------------------------
# 'IPythonShell' interface
Expand Down
7 changes: 7 additions & 0 deletions pyface/ui/wx/ipython_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import codeop
import re
import sys
import warnings


import IPython
Expand Down Expand Up @@ -345,6 +346,12 @@ class IPythonWidget(Widget):
def __init__(self, parent, **traits):
""" Creates a new pager. """

warnings.warn(
"the Wx IPython widget us deprecated and will be removed in a "
"future Pyface version",
PendingDeprecationWarning,
)

# Base class constructor.
super().__init__(**traits)

Expand Down
20 changes: 15 additions & 5 deletions pyface/ui/wx/python_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
""" Enthought pyface package component
"""

import warnings

import wx.stc

Expand Down Expand Up @@ -49,14 +50,23 @@ class PythonEditor(MPythonEditor, Widget):
# 'object' interface.
# ------------------------------------------------------------------------

def __init__(self, parent, **traits):
def __init__(self, parent=None, **traits):
""" Creates a new pager. """

# Base class constructor.
super().__init__(**traits)
create = traits.pop("create", True)

# Create the toolkit-specific control that represents the widget.
self.control = self._create_control(parent)
# Base class constructor.
super().__init__(parent=parent, **traits)

if create:
# Create the widget's toolkit-specific control.
self.create()
warnings.warn(
"automatic widget creation is deprecated and will be removed "
"in a future Pyface version, use create=False and explicitly "
"call create() for future behaviour",
PendingDeprecationWarning,
)

return

Expand Down
26 changes: 18 additions & 8 deletions pyface/ui/wx/python_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import os
import sys
import types
import warnings


from wx.py.shell import Shell as PyShellBase
Expand Down Expand Up @@ -52,17 +53,23 @@ class PythonShell(MPythonShell, Widget):

# FIXME v3: Either make this API consistent with other Widget sub-classes
# or make it a sub-class of HasTraits.
def __init__(self, parent, **traits):
def __init__(self, parent=None, **traits):
""" Creates a new pager. """

# Base class constructor.
super().__init__(**traits)

# Create the toolkit-specific control that represents the widget.
self.control = self._create_control(parent)
create = traits.pop("create", True)

# Set up to be notified whenever a Python statement is executed:
self.control.handlers.append(self._on_command_executed)
# Base class constructor.
super().__init__(parent=parent, **traits)

if create:
# Create the toolkit-specific control that represents the widget.
self.control = self.create()
warnings.warn(
"automatic widget creation is deprecated and will be removed "
"in a future Pyface version, use create=False and explicitly "
"call create() for future behaviour",
PendingDeprecationWarning,
)

# ------------------------------------------------------------------------
# 'IPythonShell' interface.
Expand Down Expand Up @@ -172,6 +179,9 @@ def _create_control(self, parent):
# Enable the shell as a drag and drop target.
shell.SetDropTarget(PythonDropTarget(self))

# Set up to be notified whenever a Python statement is executed:
shell.handlers.append(self._on_command_executed)

return shell

# ------------------------------------------------------------------------
Expand Down

0 comments on commit 7db0298

Please sign in to comment.