Skip to content

Commit

Permalink
Merge pull request #5457 from ccordoba12/remove-permissionerror
Browse files Browse the repository at this point in the history
PR: Make consoles to start without an stderr file
  • Loading branch information
ccordoba12 committed Oct 17, 2017
2 parents 7b8042c + 30bab3e commit 51a2bc3
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 25 deletions.
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Expand Up @@ -9,7 +9,7 @@ pycodestyle
pylint
psutil
qtawesome>=0.4.1
qtpy>=1.1.0
qtpy>=1.2.0
pickleshare
pyzmq
chardet>=2.0.0
Expand Down
22 changes: 14 additions & 8 deletions spyder/plugins/ipythonconsole.py
Expand Up @@ -602,7 +602,8 @@ class IPythonConsole(SpyderPluginWidget):
"required to create IPython consoles. Please "
"make it writable.")

def __init__(self, parent, testing=False, test_dir=TEMPDIR):
def __init__(self, parent, testing=False, test_dir=TEMPDIR,
test_no_stderr=False):
"""Ipython Console constructor."""
if PYQT5:
SpyderPluginWidget.__init__(self, parent, main = parent)
Expand All @@ -623,8 +624,11 @@ def __init__(self, parent, testing=False, test_dir=TEMPDIR):
self.filenames = []
self.mainwindow_close = False
self.create_new_client_if_empty = True

# Attrs for testing
self.testing = testing
self.test_dir = test_dir
self.test_no_stderr = test_no_stderr

# Initialize plugin
if not self.testing:
Expand Down Expand Up @@ -1021,12 +1025,11 @@ def create_client_for_kernel(self):
def connect_client_to_kernel(self, client):
"""Connect a client to its kernel"""
connection_file = client.connection_file
try:

if self.test_no_stderr:
stderr_file = None
else:
stderr_file = client.stderr_file
except PermissionError:
error_msg = self.permission_error_msg.format(TEMPDIR)
client.show_kernel_error(error_msg)
return

km, kc = self.create_kernel_manager_and_kernel_client(connection_file,
stderr_file)
Expand Down Expand Up @@ -1430,7 +1433,10 @@ def create_kernel_manager_and_kernel_client(self, connection_file,
kernel_manager._kernel_spec = kernel_spec

# Save stderr in a file to read it later in case of errors
stderr = codecs.open(stderr_file, 'w', encoding='utf-8')
if stderr_file is not None:
stderr = codecs.open(stderr_file, 'w', encoding='utf-8')
else:
stderr = None
kernel_manager.start_kernel(stderr=stderr)

# Kernel client
Expand Down Expand Up @@ -1559,7 +1565,7 @@ def _new_connection_file(self):
if not osp.isdir(jupyter_runtime_dir()):
try:
os.makedirs(jupyter_runtime_dir())
except PermissionError:
except (IOError, OSError):
return None
cf = ''
while not cf:
Expand Down
59 changes: 47 additions & 12 deletions spyder/plugins/tests/test_ipythonconsole.py
Expand Up @@ -26,6 +26,7 @@
KernelConnectionDialog)
from spyder.utils.environ import listdict2envdict
from spyder.utils.ipython.style import create_style_class
from spyder.utils.programs import TEMPDIR
from spyder.utils.test import close_message_box
from spyder.widgets.variableexplorer.collectionseditor import CollectionsEditor

Expand All @@ -36,6 +37,7 @@
SHELL_TIMEOUT = 20000
PYQT_WHEEL = PYQT_VERSION > '5.6'
TEMP_DIRECTORY = tempfile.gettempdir()
NON_ASCII_DIR = osp.join(TEMP_DIRECTORY, u'測試', u'اختبار')


#==============================================================================
Expand Down Expand Up @@ -64,41 +66,74 @@ def get_console_background_color(style_sheet):
#==============================================================================
@pytest.fixture
def ipyconsole(request):
try:
console = IPythonConsole(None, testing=True, test_dir=request.param)
except AttributeError:
console = IPythonConsole(None, testing=True)
"""IPython console fixture."""

# Test the console with a non-ascii temp dir
non_ascii_dir = request.node.get_marker('non_ascii_dir')
if non_ascii_dir:
test_dir = NON_ASCII_DIR
else:
test_dir = TEMPDIR

# Instruct the console to not use a stderr file
no_stderr_file = request.node.get_marker('no_stderr_file')
if no_stderr_file:
test_no_stderr = True
else:
test_no_stderr = False

# Create the console and a new client
console = IPythonConsole(parent=None,
testing=True,
test_dir=test_dir,
test_no_stderr=test_no_stderr)
console.create_new_client()

def close_console():
console.closing_plugin()
console.close()
request.addfinalizer(close_console)
console.show()

return console


#==============================================================================
# Tests
#==============================================================================
@pytest.mark.parametrize('ipyconsole', [osp.join(TEMP_DIRECTORY, u'測試',
u'اختبار')], indirect=True)
@flaky(max_runs=3)
@pytest.mark.skipif(os.name == 'nt', reason="It times out sometimes on Windows")
def test_console_stderr_file(ipyconsole, qtbot):
"""Test a the creation of a console with a stderr file in ascii dir."""
@pytest.mark.no_stderr_file
def test_no_stderr_file(ipyconsole, qtbot):
"""Test that consoles can run without an stderr."""
# Wait until the window is fully up
shell = ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None,
timeout=SHELL_TIMEOUT)

# Create a new client with s stderr file in a non-ascii dir
ipyconsole.create_new_client()
# Execute a simple assignment
with qtbot.waitSignal(shell.executed):
shell.execute('a = 1')

# Assert we get the assigned value correctly
assert shell.get_value('a') == 1


@flaky(max_runs=3)
@pytest.mark.skipif(os.name == 'nt', reason="It times out sometimes on Windows")
@pytest.mark.non_ascii_dir
def test_non_ascii_stderr_file(ipyconsole, qtbot):
"""Test the creation of a console with a stderr file in a non-ascii dir."""
# Wait until the window is fully up
shell = ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None,
timeout=SHELL_TIMEOUT)

# Execute a simple assignment
with qtbot.waitSignal(shell.executed):
shell.execute('a = 1')

# Assert we get the a value correctly
# Assert we get the assigned value
assert shell.get_value('a') == 1


Expand Down Expand Up @@ -531,7 +566,7 @@ def test_restart_kernel(ipyconsole, qtbot):
client = ipyconsole.get_current_client()
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT)

# Do an assigment to verify that it's not there after restarting
# Do an assignment to verify that it's not there after restarting
with qtbot.waitSignal(shell.executed):
shell.execute('a = 10')

Expand Down
12 changes: 8 additions & 4 deletions spyder/widgets/ipythonconsole/client.py
Expand Up @@ -156,15 +156,19 @@ def kernel_id(self):
@property
def stderr_file(self):
"""Filename to save kernel stderr output."""
stderr_file = None
if self.connection_file is not None:
stderr_file = self.kernel_id + '.stderr'
if self.stderr_dir is not None:
stderr_file = osp.join(self.stderr_dir, stderr_file)
else:
if not osp.isdir(TEMPDIR):
os.makedirs(TEMPDIR)
stderr_file = osp.join(TEMPDIR, stderr_file)
return stderr_file
try:
if not osp.isdir(TEMPDIR):
os.makedirs(TEMPDIR)
stderr_file = osp.join(TEMPDIR, stderr_file)
except (IOError, OSError):
stderr_file = None
return stderr_file

def configure_shellwidget(self, give_focus=True):
"""Configure shellwidget after kernel is started"""
Expand Down

0 comments on commit 51a2bc3

Please sign in to comment.