##// END OF EJS Templates
Merge pull request #11593 from Carreau/ast-38...
Matthias Bussonnier -
r24935:542cc5a4 merge
parent child Browse files
Show More
@@ -67,6 +67,9 b' matrix:'
67 - python: "3.7"
67 - python: "3.7"
68 dist: xenial
68 dist: xenial
69 sudo: true
69 sudo: true
70 - python: "3.8-dev"
71 dist: xenial
72 sudo: true
70 - python: "3.7-dev"
73 - python: "3.7-dev"
71 dist: xenial
74 dist: xenial
72 sudo: true
75 sudo: true
@@ -107,6 +107,14 b' class ProvisionalWarning(DeprecationWarning):'
107 """
107 """
108 pass
108 pass
109
109
110 if sys.version_info > (3,8):
111 from ast import Module
112 else :
113 # mock the new API, ignore second argument
114 # see https://github.com/ipython/ipython/issues/11590
115 from ast import Module as OriginalModule
116 Module = lambda nodelist, type_ignores: OriginalModule(nodelist)
117
110 if sys.version_info > (3,6):
118 if sys.version_info > (3,6):
111 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
119 _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign)
112 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
120 _single_targets_nodes = (ast.AugAssign, ast.AnnAssign)
@@ -3188,15 +3196,15 b' class InteractiveShell(SingletonConfigurable):'
3188 if _async:
3196 if _async:
3189 # If interactivity is async the semantics of run_code are
3197 # If interactivity is async the semantics of run_code are
3190 # completely different Skip usual machinery.
3198 # completely different Skip usual machinery.
3191 mod = ast.Module(nodelist)
3199 mod = Module(nodelist, [])
3192 async_wrapper_code = compiler(mod, 'cell_name', 'exec')
3200 async_wrapper_code = compiler(mod, cell_name, 'exec')
3193 exec(async_wrapper_code, self.user_global_ns, self.user_ns)
3201 exec(async_wrapper_code, self.user_global_ns, self.user_ns)
3194 async_code = removed_co_newlocals(self.user_ns.pop('async-def-wrapper')).__code__
3202 async_code = removed_co_newlocals(self.user_ns.pop('async-def-wrapper')).__code__
3195 if (yield from self.run_code(async_code, result, async_=True)):
3203 if (yield from self.run_code(async_code, result, async_=True)):
3196 return True
3204 return True
3197 else:
3205 else:
3198 for i, node in enumerate(to_run_exec):
3206 for i, node in enumerate(to_run_exec):
3199 mod = ast.Module([node])
3207 mod = Module([node], [])
3200 code = compiler(mod, cell_name, "exec")
3208 code = compiler(mod, cell_name, "exec")
3201 if (yield from self.run_code(code, result)):
3209 if (yield from self.run_code(code, result)):
3202 return True
3210 return True
@@ -609,10 +609,18 b' class TestModules(tt.TempFileMixin, unittest.TestCase):'
609
609
610 class Negator(ast.NodeTransformer):
610 class Negator(ast.NodeTransformer):
611 """Negates all number literals in an AST."""
611 """Negates all number literals in an AST."""
612
613 # for python 3.7 and earlier
612 def visit_Num(self, node):
614 def visit_Num(self, node):
613 node.n = -node.n
615 node.n = -node.n
614 return node
616 return node
615
617
618 # for python 3.8+
619 def visit_Constant(self, node):
620 if isinstance(node.value, int):
621 return self.visit_Num(node)
622 return node
623
616 class TestAstTransform(unittest.TestCase):
624 class TestAstTransform(unittest.TestCase):
617 def setUp(self):
625 def setUp(self):
618 self.negator = Negator()
626 self.negator = Negator()
@@ -674,12 +682,23 b' class TestAstTransform(unittest.TestCase):'
674
682
675 class IntegerWrapper(ast.NodeTransformer):
683 class IntegerWrapper(ast.NodeTransformer):
676 """Wraps all integers in a call to Integer()"""
684 """Wraps all integers in a call to Integer()"""
685
686 # for Python 3.7 and earlier
687
688 # for Python 3.7 and earlier
677 def visit_Num(self, node):
689 def visit_Num(self, node):
678 if isinstance(node.n, int):
690 if isinstance(node.n, int):
679 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
691 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
680 args=[node], keywords=[])
692 args=[node], keywords=[])
681 return node
693 return node
682
694
695 # For Python 3.8+
696 def visit_Constant(self, node):
697 if isinstance(node.value, int):
698 return self.visit_Num(node)
699 return node
700
701
683 class TestAstTransform2(unittest.TestCase):
702 class TestAstTransform2(unittest.TestCase):
684 def setUp(self):
703 def setUp(self):
685 self.intwrapper = IntegerWrapper()
704 self.intwrapper = IntegerWrapper()
@@ -720,9 +739,18 b' class TestAstTransform2(unittest.TestCase):'
720
739
721 class ErrorTransformer(ast.NodeTransformer):
740 class ErrorTransformer(ast.NodeTransformer):
722 """Throws an error when it sees a number."""
741 """Throws an error when it sees a number."""
742
743 # for Python 3.7 and earlier
723 def visit_Num(self, node):
744 def visit_Num(self, node):
724 raise ValueError("test")
745 raise ValueError("test")
725
746
747 # for Python 3.8+
748 def visit_Constant(self, node):
749 if isinstance(node.value, int):
750 return self.visit_Num(node)
751 return node
752
753
726 class TestAstTransformError(unittest.TestCase):
754 class TestAstTransformError(unittest.TestCase):
727 def test_unregistering(self):
755 def test_unregistering(self):
728 err_transformer = ErrorTransformer()
756 err_transformer = ErrorTransformer()
@@ -741,10 +769,17 b' class StringRejector(ast.NodeTransformer):'
741 Used to verify that NodeTransformers can signal that a piece of code should
769 Used to verify that NodeTransformers can signal that a piece of code should
742 not be executed by throwing an InputRejected.
770 not be executed by throwing an InputRejected.
743 """
771 """
744
772
773 #for python 3.7 and earlier
745 def visit_Str(self, node):
774 def visit_Str(self, node):
746 raise InputRejected("test")
775 raise InputRejected("test")
747
776
777 # 3.8 only
778 def visit_Constant(self, node):
779 if isinstance(node.value, str):
780 raise InputRejected("test")
781 return node
782
748
783
749 class TestAstTransformInputRejection(unittest.TestCase):
784 class TestAstTransformInputRejection(unittest.TestCase):
750
785
@@ -379,10 +379,16 b' def test_handlers():'
379 handler(*sys.exc_info())
379 handler(*sys.exc_info())
380 buff.write('')
380 buff.write('')
381
381
382 from IPython.testing.decorators import skipif
382
383
383 class TokenizeFailureTest(unittest.TestCase):
384 class TokenizeFailureTest(unittest.TestCase):
384 """Tests related to https://github.com/ipython/ipython/issues/6864."""
385 """Tests related to https://github.com/ipython/ipython/issues/6864."""
385
386
387 # that appear to test that we are handling an exception that can be thrown
388 # by the tokenizer due to a bug that seem to have been fixed in 3.8, though
389 # I'm unsure if other sequences can make it raise this error. Let's just
390 # skip in 3.8 for now
391 @skipif(sys.version_info > (3,8))
386 def testLogging(self):
392 def testLogging(self):
387 message = "An unexpected error occurred while tokenizing input"
393 message = "An unexpected error occurred while tokenizing input"
388 cell = 'raise ValueError("""a\nb""")'
394 cell = 'raise ValueError("""a\nb""")'
@@ -53,7 +53,7 b' def _elide(string, *, min_elide=30):'
53
53
54
54
55 def _adjust_completion_text_based_on_context(text, body, offset):
55 def _adjust_completion_text_based_on_context(text, body, offset):
56 if text.endswith('=') and len(body) > offset and body[offset] is '=':
56 if text.endswith('=') and len(body) > offset and body[offset] == '=':
57 return text[:-1]
57 return text[:-1]
58 else:
58 else:
59 return text
59 return text
General Comments 0
You need to be logged in to leave comments. Login now