Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ebd2ed7

Browse files
[3.13] gh-125331: Allow the parser to activate future imports on the fly (GH-125482) (#131062)
gh-125331: Allow the parser to activate future imports on the fly (GH-125482) (cherry picked from commit 3bd3e09) Co-authored-by: Pablo Galindo Salgado <[email protected]>
1 parent 977af3a commit ebd2ed7

File tree

6 files changed

+50
-2
lines changed

6 files changed

+50
-2
lines changed

Grammar/python.gram

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ import_name[stmt_ty]: 'import' a=dotted_as_names { _PyAST_Import(a, EXTRA) }
207207
# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
208208
import_from[stmt_ty]:
209209
| 'from' a=('.' | '...')* b=dotted_name 'import' c=import_from_targets {
210-
_PyAST_ImportFrom(b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) }
210+
_PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) }
211211
| 'from' a=('.' | '...')+ 'import' b=import_from_targets {
212212
_PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) }
213213
import_from_targets[asdl_alias_seq*]:

Lib/test/test_flufl.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,32 @@ def test_guido_as_bdfl(self):
3434
# parser reports the start of the token
3535
self.assertEqual(cm.exception.offset, 3)
3636

37+
def test_barry_as_bdfl_look_ma_with_no_compiler_flags(self):
38+
# Check that the future import is handled by the parser
39+
# even if the compiler flags are not passed.
40+
code = "from __future__ import barry_as_FLUFL;2 {0} 3"
41+
compile(code.format('<>'), '<BDFL test>', 'exec')
42+
with self.assertRaises(SyntaxError) as cm:
43+
compile(code.format('!='), '<FLUFL test>', 'exec')
44+
self.assertRegex(str(cm.exception), "with Barry as BDFL, use '<>' instead of '!='")
45+
self.assertIn('2 != 3', cm.exception.text)
46+
self.assertEqual(cm.exception.filename, '<FLUFL test>')
47+
self.assertEqual(cm.exception.lineno, 1)
48+
self.assertEqual(cm.exception.offset, len(code) - 4)
49+
50+
def test_barry_as_bdfl_relative_import(self):
51+
code = "from .__future__ import barry_as_FLUFL;2 {0} 3"
52+
compile(code.format('!='), '<FLUFL test>', 'exec')
53+
with self.assertRaises(SyntaxError) as cm:
54+
compile(code.format('<>'), '<BDFL test>', 'exec')
55+
self.assertRegex(str(cm.exception), "<BDFL test>")
56+
self.assertIn('2 <> 3', cm.exception.text)
57+
self.assertEqual(cm.exception.filename, '<BDFL test>')
58+
self.assertEqual(cm.exception.lineno, 1)
59+
self.assertEqual(cm.exception.offset, len(code) - 4)
60+
61+
62+
3763

3864
if __name__ == '__main__':
3965
unittest.main()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
``from __future__ import barry_as_FLUFL`` now works in more contexts,
2+
including when it is used in files, with the ``-c`` flag, and in the REPL
3+
when there are multiple statements on the same line. Previously, it worked
4+
only on subsequent lines in the REPL, and when the appropriate flags were
5+
passed directly to :func:`compile`. Patch by Pablo Galindo.

Parser/action_helpers.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,3 +1685,18 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
16851685
assert(current_pos == n_elements);
16861686
return _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, end_col_offset, p->arena);
16871687
}
1688+
1689+
stmt_ty
1690+
_PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq * names, int level,
1691+
int lineno, int col_offset, int end_lineno, int end_col_offset,
1692+
PyArena *arena) {
1693+
if (level == 0 && PyUnicode_CompareWithASCIIString(module, "__future__") == 0) {
1694+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(names); i++) {
1695+
alias_ty alias = asdl_seq_GET(names, i);
1696+
if (PyUnicode_CompareWithASCIIString(alias->name, "barry_as_FLUFL") == 0) {
1697+
p->flags |= PyPARSE_BARRY_AS_BDFL;
1698+
}
1699+
}
1700+
}
1701+
return _PyAST_ImportFrom(module, names, level, lineno, col_offset, end_lineno, end_col_offset, arena);
1702+
}

Parser/parser.c

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Parser/pegen.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ mod_ty _PyPegen_make_module(Parser *, asdl_stmt_seq *);
346346
void *_PyPegen_arguments_parsing_error(Parser *, expr_ty);
347347
expr_ty _PyPegen_get_last_comprehension_item(comprehension_ty comprehension);
348348
void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions);
349+
stmt_ty _PyPegen_checked_future_import(Parser *p, identifier module, asdl_alias_seq *,
350+
int , int, int , int , int , PyArena *);
349351

350352
// Parser API
351353

0 commit comments

Comments
 (0)