From 6a90b3afa67416a79d036a11880da4d33aad8e30 Mon Sep 17 00:00:00 2001 From: Osher De Paz Date: Sat, 1 Oct 2022 11:46:26 +0300 Subject: [PATCH 1/4] raise an error when user tries to open a standard stream Fixes #13718 --- IPython/core/interactiveshell.py | 9 +++++++++ IPython/core/tests/test_interactiveshell.py | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 6d04846081a..e9cc89a0881 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1255,6 +1255,15 @@ def prepare_user_module(self, user_module=None, user_ns=None): if user_ns is None: user_ns = user_module.__dict__ + @functools.wraps(io_open) + def modified_open(file, *args, **kwargs): + if file in {0, 1, 2}: + raise ValueError(f"IPython won't let you open fd={file} by default") + + return io_open(file, *args, **kwargs) + + user_ns["open"] = modified_open + return user_module, user_ns def init_sys_modules(self): diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index 10827b5fa0f..b5efe98b85b 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -103,6 +103,21 @@ def test_syntax_error(self): res = ip.run_cell("raise = 3") self.assertIsInstance(res.error_before_exec, SyntaxError) + def test_open_standard_input_stream(self): + ip.init_create_namespaces() + res = ip.run_cell("open(0)") + self.assertIsInstance(res.error_in_exec, ValueError) + + def test_open_standard_output_stream(self): + ip.init_create_namespaces() + res = ip.run_cell("open(1)") + self.assertIsInstance(res.error_in_exec, ValueError) + + def test_open_standard_error_stream(self): + ip.init_create_namespaces() + res = ip.run_cell("open(2)") + self.assertIsInstance(res.error_in_exec, ValueError) + def test_In_variable(self): "Verify that In variable grows with user input (GH-284)" oldlen = len(ip.user_ns['In']) From 467f4a49105b74a1e55a2ab070f947b7b82fbecb Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Wed, 19 Oct 2022 06:37:22 -0700 Subject: [PATCH 2/4] Update IPython/core/interactiveshell.py --- IPython/core/interactiveshell.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index e9cc89a0881..c6950453bf7 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1258,7 +1258,10 @@ def prepare_user_module(self, user_module=None, user_ns=None): @functools.wraps(io_open) def modified_open(file, *args, **kwargs): if file in {0, 1, 2}: - raise ValueError(f"IPython won't let you open fd={file} by default") + raise ValueError(f"IPython won't let you open fd={file} by default " + "as it is likely to crash IPython. If you know what you are doing, " + "you can use builtins' open." + ) return io_open(file, *args, **kwargs) From 17ac9ea417bd1c308af4f01691159a83efa376a4 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sat, 29 Oct 2022 12:28:12 +0200 Subject: [PATCH 3/4] please formatter --- IPython/core/display.py | 1 + IPython/core/interactiveshell.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/IPython/core/display.py b/IPython/core/display.py index a095f3cb5e0..25b340fc8eb 100644 --- a/IPython/core/display.py +++ b/IPython/core/display.py @@ -625,6 +625,7 @@ def _data_and_metadata(self): def _repr_json_(self): return self._data_and_metadata() + _css_t = """var link = document.createElement("link"); link.ref = "stylesheet"; link.type = "text/css"; diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index c6950453bf7..54e5d547beb 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1258,9 +1258,10 @@ def prepare_user_module(self, user_module=None, user_ns=None): @functools.wraps(io_open) def modified_open(file, *args, **kwargs): if file in {0, 1, 2}: - raise ValueError(f"IPython won't let you open fd={file} by default " - "as it is likely to crash IPython. If you know what you are doing, " - "you can use builtins' open." + raise ValueError( + f"IPython won't let you open fd={file} by default " + "as it is likely to crash IPython. If you know what you are doing, " + "you can use builtins' open." ) return io_open(file, *args, **kwargs) From f44e27095fd647cc22bf37874f183ec4db85949f Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sat, 29 Oct 2022 14:40:25 +0200 Subject: [PATCH 4/4] Refactor a bit of uniformity. Not-reiniting user_ns may also help fix issues on windows. --- IPython/core/interactiveshell.py | 24 ++++++++++----------- IPython/core/tests/test_interactiveshell.py | 3 --- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 54e5d547beb..214493b324c 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -270,6 +270,16 @@ def __repr__(self): return '<%s object at %x, execution_count=%s error_before_exec=%s error_in_exec=%s info=%s result=%s>' %\ (name, id(self), self.execution_count, self.error_before_exec, self.error_in_exec, repr(self.info), repr(self.result)) +@functools.wraps(io_open) +def _modified_open(file, *args, **kwargs): + if file in {0, 1, 2}: + raise ValueError( + f"IPython won't let you open fd={file} by default " + "as it is likely to crash IPython. If you know what you are doing, " + "you can use builtins' open." + ) + + return io_open(file, *args, **kwargs) class InteractiveShell(SingletonConfigurable): """An enhanced, interactive shell for Python.""" @@ -1255,19 +1265,6 @@ def prepare_user_module(self, user_module=None, user_ns=None): if user_ns is None: user_ns = user_module.__dict__ - @functools.wraps(io_open) - def modified_open(file, *args, **kwargs): - if file in {0, 1, 2}: - raise ValueError( - f"IPython won't let you open fd={file} by default " - "as it is likely to crash IPython. If you know what you are doing, " - "you can use builtins' open." - ) - - return io_open(file, *args, **kwargs) - - user_ns["open"] = modified_open - return user_module, user_ns def init_sys_modules(self): @@ -1336,6 +1333,7 @@ def init_user_ns(self): ns['exit'] = self.exiter ns['quit'] = self.exiter + ns["open"] = _modified_open # Sync what we've added so far to user_ns_hidden so these aren't seen # by %who diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index b5efe98b85b..982bd5a3b22 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -104,17 +104,14 @@ def test_syntax_error(self): self.assertIsInstance(res.error_before_exec, SyntaxError) def test_open_standard_input_stream(self): - ip.init_create_namespaces() res = ip.run_cell("open(0)") self.assertIsInstance(res.error_in_exec, ValueError) def test_open_standard_output_stream(self): - ip.init_create_namespaces() res = ip.run_cell("open(1)") self.assertIsInstance(res.error_in_exec, ValueError) def test_open_standard_error_stream(self): - ip.init_create_namespaces() res = ip.run_cell("open(2)") self.assertIsInstance(res.error_in_exec, ValueError)