From cc370d7c16f02def4c6636bb07e259f4ea03878d Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sat, 25 Nov 2023 20:44:36 +0000 Subject: [PATCH 1/4] gh-99606: Make code generated for an empty f-string identical to that of a normal empty string --- Lib/importlib/_bootstrap_external.py | 3 ++- Lib/test/test_fstring.py | 10 ++++++++++ .../2023-11-25-20-36-38.gh-issue-99606.fDY5hK.rst | 2 ++ Python/compile.c | 8 ++++++-- 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-11-25-20-36-38.gh-issue-99606.fDY5hK.rst diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 4e96a916324824..685d84f56ea05f 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -461,6 +461,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.13a1 3563 (Add CALL_KW and remove KW_NAMES) # Python 3.13a1 3564 (Removed oparg from YIELD_VALUE, changed oparg values of RESUME) # Python 3.13a1 3565 (Oparg of YIELD_VALUE indicates whether it is in a yield-from) +# Python 3.13a1 3566 (Code for empty f-string matches empty normal string) # Python 3.14 will start with 3600 @@ -477,7 +478,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3565).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3578).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index da0160d2382cc6..27c7f70cef32e3 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -8,6 +8,7 @@ # Unicode identifiers in tests is allowed by PEP 3131. import ast +import dis import os import re import types @@ -1738,5 +1739,14 @@ def test_syntax_warning_infinite_recursion_in_file(self): self.assertIn(rb'\1', stdout) self.assertEqual(len(stderr.strip().splitlines()), 2) + def test_fstring_without_formatting_bytecode(self): + # f-string without any formatting should emit the same bytecode + # as a normal string. See gh-99606. + def get_code(s): + return [(i.opname, i.oparg) for i in dis.get_instructions(s)] + + for s in ["", "some string"]: + self.assertEqual(get_code(f"'{s}'"), get_code(f"f'{s}'")) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-25-20-36-38.gh-issue-99606.fDY5hK.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-25-20-36-38.gh-issue-99606.fDY5hK.rst new file mode 100644 index 00000000000000..adc0e3a6bbc89a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-25-20-36-38.gh-issue-99606.fDY5hK.rst @@ -0,0 +1,2 @@ +Make code generated for an empty f-string identical to the code of an empty +normal string. diff --git a/Python/compile.c b/Python/compile.c index 8b1eef79a79eae..8b9e2f02048f11 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -5042,8 +5042,12 @@ compiler_joined_str(struct compiler *c, expr_ty e) } else { VISIT_SEQ(c, expr, e->v.JoinedStr.values); - if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) { - ADDOP_I(c, loc, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); + if (value_count > 1) { + ADDOP_I(c, loc, BUILD_STRING, value_count); + } + else if (value_count == 0) { + _Py_DECLARE_STR(empty, ""); + ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty))); } } return SUCCESS; From 8e15f08219ea00d8a2befd9141a6b3392460ddd2 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sat, 25 Nov 2023 20:47:21 +0000 Subject: [PATCH 2/4] fix magic number --- Lib/importlib/_bootstrap_external.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 685d84f56ea05f..6f9715a8e1a475 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -478,7 +478,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3578).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3566).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c From 21eedf4d78b9a483c7e727a17457a75f81f8ae48 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:16:53 +0000 Subject: [PATCH 3/4] Update _bootstrap_external.py --- Lib/importlib/_bootstrap_external.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 6f9715a8e1a475..035013430cd344 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -461,7 +461,6 @@ def _write_atomic(path, data, mode=0o666): # Python 3.13a1 3563 (Add CALL_KW and remove KW_NAMES) # Python 3.13a1 3564 (Removed oparg from YIELD_VALUE, changed oparg values of RESUME) # Python 3.13a1 3565 (Oparg of YIELD_VALUE indicates whether it is in a yield-from) -# Python 3.13a1 3566 (Code for empty f-string matches empty normal string) # Python 3.14 will start with 3600 From c5c1d968d8673b567b0d6e16002a7ca4a945715f Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:16:59 +0000 Subject: [PATCH 4/4] Update _bootstrap_external.py --- Lib/importlib/_bootstrap_external.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 035013430cd344..4e96a916324824 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -477,7 +477,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3566).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3565).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy