mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	gh-124960: Fixed `barry_as_FLUFL` future flag does not work in new REPL (#124999)
Co-authored-by: Wulian <xiguawulian@gmail.com>
Co-authored-by: Nice Zombies <nineteendo19d0@gmail.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
(cherry picked from commit 6a08a753b7)
			
			
This commit is contained in:
		
							parent
							
								
									cbcdf34a4b
								
							
						
					
					
						commit
						d54dbd62cc
					
				
					 4 changed files with 40 additions and 5 deletions
				
			
		|  | @ -174,7 +174,13 @@ def _excepthook(self, typ, value, tb): | |||
| 
 | ||||
|     def runsource(self, source, filename="<input>", symbol="single"): | ||||
|         try: | ||||
|             tree = ast.parse(source) | ||||
|             tree = self.compile.compiler( | ||||
|                 source, | ||||
|                 filename, | ||||
|                 "exec", | ||||
|                 ast.PyCF_ONLY_AST, | ||||
|                 incomplete_input=False, | ||||
|             ) | ||||
|         except (SyntaxError, OverflowError, ValueError): | ||||
|             self.showsyntaxerror(filename, source=source) | ||||
|             return False | ||||
|  | @ -185,7 +191,7 @@ def runsource(self, source, filename="<input>", symbol="single"): | |||
|             the_symbol = symbol if stmt is last_stmt else "exec" | ||||
|             item = wrapper([stmt]) | ||||
|             try: | ||||
|                 code = self.compile.compiler(item, filename, the_symbol, dont_inherit=True) | ||||
|                 code = self.compile.compiler(item, filename, the_symbol) | ||||
|             except SyntaxError as e: | ||||
|                 if e.args[0] == "'await' outside function": | ||||
|                     python = os.path.basename(sys.executable) | ||||
|  |  | |||
|  | @ -44,6 +44,7 @@ | |||
| # Caveat emptor: These flags are undocumented on purpose and depending | ||||
| # on their effect outside the standard library is **unsupported**. | ||||
| PyCF_DONT_IMPLY_DEDENT = 0x200 | ||||
| PyCF_ONLY_AST = 0x400 | ||||
| PyCF_ALLOW_INCOMPLETE_INPUT = 0x4000 | ||||
| 
 | ||||
| def _maybe_compile(compiler, source, filename, symbol): | ||||
|  | @ -109,12 +110,14 @@ class Compile: | |||
|     def __init__(self): | ||||
|         self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT | ||||
| 
 | ||||
|     def __call__(self, source, filename, symbol, **kwargs): | ||||
|         flags = self.flags | ||||
|     def __call__(self, source, filename, symbol, flags=0, **kwargs): | ||||
|         flags |= self.flags | ||||
|         if kwargs.get('incomplete_input', True) is False: | ||||
|             flags &= ~PyCF_DONT_IMPLY_DEDENT | ||||
|             flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT | ||||
|         codeob = compile(source, filename, symbol, flags, True) | ||||
|         if flags & PyCF_ONLY_AST: | ||||
|             return codeob  # this is an ast.Module in this case | ||||
|         for feature in _features: | ||||
|             if codeob.co_flags & feature.compiler_flag: | ||||
|                 self.flags |= feature.compiler_flag | ||||
|  |  | |||
|  | @ -119,13 +119,38 @@ def test_runsource_shows_syntax_error_for_failed_compilation(self): | |||
| 
 | ||||
|     def test_no_active_future(self): | ||||
|         console = InteractiveColoredConsole() | ||||
|         source = "x: int = 1; print(__annotations__)" | ||||
|         source = dedent("""\ | ||||
|         x: int = 1 | ||||
|         print(__annotations__) | ||||
|         """) | ||||
|         f = io.StringIO() | ||||
|         with contextlib.redirect_stdout(f): | ||||
|             result = console.runsource(source) | ||||
|         self.assertFalse(result) | ||||
|         self.assertEqual(f.getvalue(), "{'x': <class 'int'>}\n") | ||||
| 
 | ||||
|     def test_future_annotations(self): | ||||
|         console = InteractiveColoredConsole() | ||||
|         source = dedent("""\ | ||||
|         from __future__ import annotations | ||||
|         def g(x: int): ... | ||||
|         print(g.__annotations__) | ||||
|         """) | ||||
|         f = io.StringIO() | ||||
|         with contextlib.redirect_stdout(f): | ||||
|             result = console.runsource(source) | ||||
|         self.assertFalse(result) | ||||
|         self.assertEqual(f.getvalue(), "{'x': 'int'}\n") | ||||
| 
 | ||||
|     def test_future_barry_as_flufl(self): | ||||
|         console = InteractiveColoredConsole() | ||||
|         f = io.StringIO() | ||||
|         with contextlib.redirect_stdout(f): | ||||
|             result = console.runsource("from __future__ import barry_as_FLUFL\n") | ||||
|             result = console.runsource("""print("black" <> 'blue')\n""") | ||||
|         self.assertFalse(result) | ||||
|         self.assertEqual(f.getvalue(), "True\n") | ||||
| 
 | ||||
| 
 | ||||
| class TestMoreLines(unittest.TestCase): | ||||
|     def test_invalid_syntax_single_line(self): | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| Fix support for the ``barry_as_FLUFL`` future flag in the new REPL. | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nice Zombies
						Nice Zombies