Skip to content

Commit 060458b

Browse files
authored
Merge branch '3.13' into backport-a931a8b-3.13
2 parents 5d63142 + ebd2ed7 commit 060458b

File tree

10 files changed

+62
-3
lines changed

10 files changed

+62
-3
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/_pyrepl/reader.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def disp_str(buffer: str) -> tuple[str, list[int]]:
6262
elif unicodedata.category(c).startswith("C"):
6363
c = r"\u%04x" % ord(c)
6464
s.append(c)
65-
b.extend([0] * (len(c) - 1))
65+
b.append(len(c))
6666
else:
6767
s.append(c)
6868
b.append(str_width(c))
@@ -577,6 +577,7 @@ def setpos_from_xy(self, x: int, y: int) -> None:
577577
cur_x = self.screeninfo[i][0]
578578
while cur_x < x:
579579
if self.screeninfo[i][1][j] == 0:
580+
j += 1 # prevent potential future infinite loop
580581
continue
581582
cur_x += self.screeninfo[i][1][j]
582583
j += 1

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()

Lib/test/test_pyrepl/test_reader.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,11 @@ def test_pos2xy_with_no_columns(self):
319319
# Simulate a resize to 0 columns
320320
reader.screeninfo = []
321321
self.assertEqual(reader.pos2xy(), (0, 0))
322+
323+
def test_setpos_from_xy_for_non_printing_char(self):
324+
code = "# non \u200c printing character"
325+
events = code_to_events(code)
326+
327+
reader, _ = handle_all_events(events)
328+
reader.setpos_from_xy(8, 0)
329+
self.assertEqual(reader.pos, 7)

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ Laurent De Buyst
277277
Zach Byrne
278278
Vedran Čačić
279279
Nicolas Cadou
280+
Zhikai Cai
280281
Jp Calderone
281282
Ben Caller
282283
Arnaud Calmettes
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.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Non-printing characters are now properly handled in the new REPL.

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)