From b9bfb192d1335fa619d1bf89e64e89443ebaa01a 2020-07-23 22:11:14 From: Matthias Bussonnier Date: 2020-07-23 22:11:14 Subject: [PATCH] Allow to mark transformers as having side effects We then unly run them when actually running the code. --- diff --git a/IPython/core/inputtransformer2.py b/IPython/core/inputtransformer2.py index 097dd88..afbce23 100644 --- a/IPython/core/inputtransformer2.py +++ b/IPython/core/inputtransformer2.py @@ -637,7 +637,8 @@ class TransformerManager: try: for transform in self.cleanup_transforms: - lines = transform(lines) + if not getattr(transform, 'has_side_effects', False): + lines = transform(lines) except SyntaxError: return 'invalid', None @@ -650,7 +651,8 @@ class TransformerManager: try: for transform in self.line_transforms: - lines = transform(lines) + if not getattr(transform, 'has_side_effects', False): + lines = transform(lines) lines = self.do_token_transforms(lines) except SyntaxError: return 'invalid', None diff --git a/IPython/core/tests/test_inputtransformer2.py b/IPython/core/tests/test_inputtransformer2.py index b29a019..1ff0fd8 100644 --- a/IPython/core/tests/test_inputtransformer2.py +++ b/IPython/core/tests/test_inputtransformer2.py @@ -289,4 +289,38 @@ def test_check_complete_II(): def test_null_cleanup_transformer(): manager = ipt2.TransformerManager() manager.cleanup_transforms.insert(0, null_cleanup_transformer) - nt.assert_is(manager.transform_cell(""), "") + assert manager.transform_cell("") == "" + + + + +def test_side_effects_I(): + count = 0 + def counter(lines): + nonlocal count + count += 1 + return lines + + counter.has_side_effects = True + + manager = ipt2.TransformerManager() + manager.cleanup_transforms.insert(0, counter) + assert manager.check_complete("a=1\n") == ('complete', None) + assert count == 0 + + + + +def test_side_effects_II(): + count = 0 + def counter(lines): + nonlocal count + count += 1 + return lines + + counter.has_side_effects = True + + manager = ipt2.TransformerManager() + manager.line_transforms.insert(0, counter) + assert manager.check_complete("b=1\n") == ('complete', None) + assert count == 0 diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index 496e3bd..951b843 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -689,6 +689,30 @@ class TestAstTransform(unittest.TestCase): with tt.AssertPrints("8"): ip.run_cell("amacro") +class TestMiscTransform(unittest.TestCase): + + + def test_transform_only_once(self): + cleanup = 0 + line_t = 0 + def count_cleanup(lines): + nonlocal cleanup + cleanup += 1 + return lines + + def count_line_t(lines): + nonlocal line_t + line_t += 1 + return lines + + ip.input_transformer_manager.cleanup_transforms.append(count_cleanup) + ip.input_transformer_manager.line_transforms.append(count_line_t) + + ip.run_cell('1') + + assert cleanup == 1 + assert line_t == 1 + class IntegerWrapper(ast.NodeTransformer): """Wraps all integers in a call to Integer()"""