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 = |
|
3199 | mod = Module(nodelist, []) | |
3192 |
async_wrapper_code = compiler(mod, |
|
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 = |
|
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] |
|
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