Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-bytecode for openSUSE:Factory
checked in at 2026-08-24 12:11:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-bytecode (Old)
and /work/SRC/openSUSE:Factory/.python-bytecode.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-bytecode"
Mon Aug 24 12:11:37 2026 rev:16 rq:1373284 version:0.19.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-bytecode/python-bytecode.changes
2026-06-15 19:44:56.479179228 +0200
+++
/work/SRC/openSUSE:Factory/.python-bytecode.new.1258/python-bytecode.changes
2026-08-24 12:16:58.059422682 +0200
@@ -1,0 +2,6 @@
+Mon Aug 24 01:14:38 UTC 2026 - Steve Kowalik <[email protected]>
+
+- Update to 0.19.0:
+ * Add support for Python 3.15 (tested against Python 3.15 rc)
+
+-------------------------------------------------------------------
Old:
----
bytecode-0.18.1.tar.gz
New:
----
bytecode-0.19.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-bytecode.spec ++++++
--- /var/tmp/diff_new_pack.Jcefm2/_old 2026-08-24 12:16:58.815449608 +0200
+++ /var/tmp/diff_new_pack.Jcefm2/_new 2026-08-24 12:16:58.816449644 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-bytecode
-Version: 0.18.1
+Version: 0.19.0
Release: 0
Summary: Python module to generate and modify bytecode
License: MIT
++++++ bytecode-0.18.1.tar.gz -> bytecode-0.19.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/.github/workflows/cis.yml
new/bytecode-0.19.0/.github/workflows/cis.yml
--- old/bytecode-0.18.1/.github/workflows/cis.yml 2026-06-03
16:17:07.000000000 +0200
+++ new/bytecode-0.19.0/.github/workflows/cis.yml 2026-08-21
23:16:51.968825800 +0200
@@ -20,9 +20,9 @@
name: Lint code
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- name: Set up Python
- uses: actions/setup-python@v6
+ uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install tools
@@ -50,14 +50,16 @@
toxenv: py313
- python-version: "3.14"
toxenv: py314
+ - python-version: "3.15-dev"
+ toxenv: py315
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v6
+ uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
@@ -70,7 +72,7 @@
run: |
tox
- name: Upload coverage to Codecov
- uses: codecov/codecov-action@v6
+ uses: codecov/codecov-action@v7
if: github.event_name != 'schedule'
with:
token: ${{ secrets.CODECOV_TOKEN }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/.github/workflows/docs.yml
new/bytecode-0.19.0/.github/workflows/docs.yml
--- old/bytecode-0.18.1/.github/workflows/docs.yml 2026-06-03
16:17:07.000000000 +0200
+++ new/bytecode-0.19.0/.github/workflows/docs.yml 2026-08-21
23:16:51.969455500 +0200
@@ -19,13 +19,13 @@
name: Docs building
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Set up Python
- uses: actions/setup-python@v6
+ uses: actions/setup-python@v7
with:
python-version: '3.x'
- name: Install dependencies
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/.github/workflows/frameworks.yml
new/bytecode-0.19.0/.github/workflows/frameworks.yml
--- old/bytecode-0.18.1/.github/workflows/frameworks.yml 2026-06-03
16:17:07.000000000 +0200
+++ new/bytecode-0.19.0/.github/workflows/frameworks.yml 2026-08-21
23:16:51.969455500 +0200
@@ -21,15 +21,15 @@
strategy:
fail-fast: false
matrix:
- python-version: ["3.11", "3.12", "3.13", "3.14"]
+ python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Set up Python
- uses: actions/setup-python@v6
+ uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}-dev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/.github/workflows/release.yml
new/bytecode-0.19.0/.github/workflows/release.yml
--- old/bytecode-0.18.1/.github/workflows/release.yml 2026-06-03
16:17:07.000000000 +0200
+++ new/bytecode-0.19.0/.github/workflows/release.yml 2026-08-21
23:16:51.969455500 +0200
@@ -13,13 +13,13 @@
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Setup Python
- uses: actions/setup-python@v6
+ uses: actions/setup-python@v7
with:
python-version: '3.x'
- name: Build sdist
@@ -43,13 +43,13 @@
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Setup Python
- uses: actions/setup-python@v6
+ uses: actions/setup-python@v7
with:
python-version: '3.x'
- name: Build wheels
@@ -107,7 +107,7 @@
path: dist
merge-multiple: true
- name: Sign the dists with Sigstore
- uses: sigstore/[email protected]
+ uses: sigstore/[email protected]
with:
inputs: >-
./dist/*.tar.gz
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/PKG-INFO new/bytecode-0.19.0/PKG-INFO
--- old/bytecode-0.18.1/PKG-INFO 2026-06-03 16:17:16.556645600 +0200
+++ new/bytecode-0.19.0/PKG-INFO 2026-08-21 23:17:01.427590800 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: bytecode
-Version: 0.18.1
+Version: 0.19.0
Summary: Python module to generate and modify bytecode
Author-email: Victor Stinner <[email protected]>
Maintainer-email: "Matthieu C. Dartiailh" <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/doc/changelog.rst
new/bytecode-0.19.0/doc/changelog.rst
--- old/bytecode-0.18.1/doc/changelog.rst 2026-06-03 16:17:07.000000000
+0200
+++ new/bytecode-0.19.0/doc/changelog.rst 2026-08-21 23:16:51.970085400
+0200
@@ -1,6 +1,11 @@
ChangeLog
=========
+21-08-2026: Version 0.19.0
+--------------------------
+
+- Add support for Python 3.15 (tested against Python 3.15 rc) PR #192
+
03-06-2026: Version 0.18.1
--------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/pyproject.toml
new/bytecode-0.19.0/pyproject.toml
--- old/bytecode-0.18.1/pyproject.toml 2026-06-03 16:17:07.000000000 +0200
+++ new/bytecode-0.19.0/pyproject.toml 2026-08-21 23:16:51.970085400 +0200
@@ -47,6 +47,7 @@
]
[tool.setuptools_scm]
+ fallback_version = "0.0.0"
write_to = "src/bytecode/version.py"
write_to_template = """
# This file is auto-generated by setuptools-scm do NOT edit it.
@@ -72,12 +73,11 @@
[tool.ruff]
src = ["src"]
- extend-exclude = ["tests/instruments/hardware/nifpga/scope_based"]
line-length = 88
[tool.ruff.lint]
select = ["B", "C", "E", "F", "W", "B9", "I", "C90", "RUF"]
- extend-ignore = ["E203", "E266", "E501", "F403", "F401", "RUF012"]
+ extend-ignore = ["E203", "E266", "E501", "F403", "F401", "RUF012",
"RUF036"]
[tool.ruff.lint.isort]
combine-as-imports = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/src/bytecode/bytecode.py
new/bytecode-0.19.0/src/bytecode/bytecode.py
--- old/bytecode-0.18.1/src/bytecode/bytecode.py 2026-06-03
16:17:07.000000000 +0200
+++ new/bytecode-0.19.0/src/bytecode/bytecode.py 2026-08-21
23:16:51.971335200 +0200
@@ -40,7 +40,7 @@
self.name = "<module>"
self.qualname = self.name
self.filename = "<string>"
- self.docstring: Union[str, None, _UNSET] = UNSET
+ self.docstring: Union[str, _UNSET, None] = UNSET
# We cannot recreate cellvars/freevars from instructions because of
super()
# special-case, which involves an implicit __class__ cell/free variable
# We could try to detect it.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/src/bytecode/concrete.py
new/bytecode-0.19.0/src/bytecode/concrete.py
--- old/bytecode-0.18.1/src/bytecode/concrete.py 2026-06-03
16:17:07.000000000 +0200
+++ new/bytecode-0.19.0/src/bytecode/concrete.py 2026-08-21
23:16:51.971335200 +0200
@@ -105,7 +105,7 @@
name: str,
arg: int = UNSET,
*,
- lineno: Union[int, None, _UNSET] = UNSET,
+ lineno: Union[int, _UNSET, None] = UNSET,
location: Optional[InstrLocation] = None,
extended_args: Optional[int] = None,
):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/src/bytecode/instr.py
new/bytecode-0.19.0/src/bytecode/instr.py
--- old/bytecode-0.18.1/src/bytecode/instr.py 2026-06-03 16:17:07.000000000
+0200
+++ new/bytecode-0.19.0/src/bytecode/instr.py 2026-08-21 23:16:51.971335200
+0200
@@ -16,7 +16,7 @@
from typing_extensions import TypeGuard # type: ignore
import bytecode as _bytecode
-from bytecode.utils import PY312, PY313, PY314
+from bytecode.utils import PY312, PY313, PY314, PY315
# --- Instruction argument tools and
@@ -39,7 +39,9 @@
)
BITFLAG2_OPCODES: Final[set[int]] = (
- {_opcode.opmap["LOAD_SUPER_ATTR"]} if PY312 else set()
+ {_opcode.opmap["LOAD_SUPER_ATTR"], _opcode.opmap["IMPORT_NAME"]}
+ if PY315
+ else ({_opcode.opmap["LOAD_SUPER_ATTR"]} if PY312 else set())
)
# Binary op opcode which has a dedicated arg
@@ -53,6 +55,11 @@
# Small integer related opcode
SMALL_INT_OPS: Final[set[int]] = {_opcode.opmap["LOAD_SMALL_INT"]} if PY314
else set()
+# Opcodes that gained a cache-only argument in 3.15 (arg is always 0 and not
user-visible)
+CACHE_ONLY_ARG_OPCODES: Final[set[int]] = (
+ {_opcode.opmap["GET_ITER"]} if PY315 else set()
+)
+
# Special method loading related opcodes
SPECIAL_OPS: Final[set[int]] = {_opcode.opmap["LOAD_SPECIAL"]} if PY314 else
set()
@@ -265,6 +272,15 @@
BUILTIN_ALL = 3
BUILTIN_ANY = 4
+ if PY315:
+ BUILTIN_LIST = 5
+ BUILTIN_SET = 6
+ CONSTANT_NONE = 7
+ CONSTANT_EMPTY_STR = 8
+ CONSTANT_TRUE = 9
+ CONSTANT_FALSE = 10
+ CONSTANT_MINUS_ONE = 11
+
# This make type checking happy but means it won't catch attempt to manipulate
an unset
# statically. We would need guard on object attribute narrowed down through
methods
@@ -419,7 +435,8 @@
"DUP_TOP": (-1, 2),
"DUP_TOP_TWO": (-2, 4),
"GET_LEN": (-1, 2),
- "GET_ITER": (-1, 1),
+ "GET_ITER": (-1, 2) if PY315 else (-1, 1),
+ # removed in 3.15, filtered by if k in _opcode.opmap
"GET_YIELD_FROM_ITER": (-1, 1),
"GET_AWAITABLE": (-1, 1),
"GET_AITER": (-1, 1),
@@ -503,7 +520,14 @@
"MAP_ADD": lambda effect, arg, jump: (-arg, arg - 2),
"FORMAT_VALUE": lambda effect, arg, jump: (effect - 1, 1),
# FOR_ITER needs TOS to be an iterator, hence a prerequisite of 1 on
the stack
- "FOR_ITER": lambda effect, arg, jump: (effect, 0) if jump else (-1, 2),
+ # In 3.15, GET_ITER pushes (iter, null_or_index) as two stack slots, so
+ # FOR_ITER now requires both on the stack (-2) and always pushes them
back
+ # plus one more slot (+3): the next value when continuing, or a marker
+ # consumed by END_FOR when exhausted before POP_ITER cleans up (iter,
+ # null_or_index). Net effect is +1 in both cases, matching
dis.stack_effect.
+ "FOR_ITER": (lambda __effect, __arg, __jump: (-2, 3))
+ if PY315
+ else (lambda effect, __arg, jump: (effect, 0) if jump else (-1, 2)),
"BUILD_INTERPOLATION": lambda effect, arg, jump: (-(2 + (arg & 1)), 1),
**{
# Instr(UNPACK_* , n) pops 1 and pushes n
@@ -701,7 +725,7 @@
name: str,
arg: A = UNSET, # type: ignore
*,
- lineno: int | None | _UNSET = UNSET,
+ lineno: int | _UNSET | None = UNSET,
location: Optional[InstrLocation] = None,
) -> None:
self._set(name, arg)
@@ -914,6 +938,9 @@
"Only base opcodes are supported"
)
+ if arg is UNSET and opcode in CACHE_ONLY_ARG_OPCODES:
+ arg = 0 # type: ignore
+
self._check_arg(name, opcode, arg)
self._name = name
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/src/bytecode/utils.py
new/bytecode-0.19.0/src/bytecode/utils.py
--- old/bytecode-0.18.1/src/bytecode/utils.py 2026-06-03 16:17:07.000000000
+0200
+++ new/bytecode-0.19.0/src/bytecode/utils.py 2026-08-21 23:16:51.971335200
+0200
@@ -4,3 +4,4 @@
PY312: Final[bool] = sys.version_info >= (3, 12)
PY313: Final[bool] = sys.version_info >= (3, 13)
PY314: Final[bool] = sys.version_info >= (3, 14)
+PY315: Final[bool] = sys.version_info >= (3, 15)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/src/bytecode/version.py
new/bytecode-0.19.0/src/bytecode/version.py
--- old/bytecode-0.18.1/src/bytecode/version.py 2026-06-03 16:17:16.000000000
+0200
+++ new/bytecode-0.19.0/src/bytecode/version.py 2026-08-21 23:17:01.242860600
+0200
@@ -5,7 +5,7 @@
#: A namedtuple of the version info for the current release.
_version_info = namedtuple("_version_info", "major minor micro status")
-parts = "0.18.1".split(".", 3)
+parts = "0.19.0".split(".", 3)
version_info = _version_info(
int(parts[0]),
int(parts[1]),
@@ -16,4 +16,4 @@
# Remove everything but the 'version_info' from this module.
del namedtuple, _version_info, parts
-__version__ = "0.18.1"
+__version__ = "0.19.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/src/bytecode.egg-info/PKG-INFO
new/bytecode-0.19.0/src/bytecode.egg-info/PKG-INFO
--- old/bytecode-0.18.1/src/bytecode.egg-info/PKG-INFO 2026-06-03
16:17:16.000000000 +0200
+++ new/bytecode-0.19.0/src/bytecode.egg-info/PKG-INFO 2026-08-21
23:17:01.399017300 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: bytecode
-Version: 0.18.1
+Version: 0.19.0
Summary: Python module to generate and modify bytecode
Author-email: Victor Stinner <[email protected]>
Maintainer-email: "Matthieu C. Dartiailh" <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/src/bytecode.egg-info/SOURCES.txt
new/bytecode-0.19.0/src/bytecode.egg-info/SOURCES.txt
--- old/bytecode-0.18.1/src/bytecode.egg-info/SOURCES.txt 2026-06-03
16:17:16.000000000 +0200
+++ new/bytecode-0.19.0/src/bytecode.egg-info/SOURCES.txt 2026-08-21
23:17:01.411725500 +0200
@@ -41,6 +41,8 @@
src/bytecode.egg-info/SOURCES.txt
src/bytecode.egg-info/dependency_links.txt
src/bytecode.egg-info/requires.txt
+src/bytecode.egg-info/scm_file_list.json
+src/bytecode.egg-info/scm_version.json
src/bytecode.egg-info/top_level.txt
tests/__init__.py
tests/cell_free_vars_cases.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/bytecode-0.18.1/src/bytecode.egg-info/scm_file_list.json
new/bytecode-0.19.0/src/bytecode.egg-info/scm_file_list.json
--- old/bytecode-0.18.1/src/bytecode.egg-info/scm_file_list.json
1970-01-01 01:00:00.000000000 +0100
+++ new/bytecode-0.19.0/src/bytecode.egg-info/scm_file_list.json
2026-08-21 23:17:01.396581200 +0200
@@ -0,0 +1,57 @@
+{
+ "files": [
+ ".coveragerc",
+ ".github/FUNDING.yml",
+ ".github/dependabot.yml",
+ ".github/workflows/cis.yml",
+ ".github/workflows/docs.yml",
+ ".github/workflows/frameworks.yml",
+ ".github/workflows/release.yml",
+ ".gitignore",
+ ".pre-commit-config.yaml",
+ ".readthedocs.yaml",
+ "COPYING",
+ "MANIFEST.in",
+ "README.rst",
+ "TODO.rst",
+ "codecov.yml",
+ "doc/Makefile",
+ "doc/api.rst",
+ "doc/byteplay_codetransformer.rst",
+ "doc/cfg.rst",
+ "doc/changelog.rst",
+ "doc/conf.py",
+ "doc/index.rst",
+ "doc/make.bat",
+ "doc/requirements.txt",
+ "doc/todo.rst",
+ "doc/usage.rst",
+ "pyproject.toml",
+ "scripts/frameworks/boto3/run.sh",
+ "scripts/frameworks/boto3/setup.sh",
+ "src/bytecode/__init__.py",
+ "src/bytecode/bytecode.py",
+ "src/bytecode/cfg.py",
+ "src/bytecode/concrete.py",
+ "src/bytecode/flags.py",
+ "src/bytecode/instr.py",
+ "src/bytecode/py.typed",
+ "src/bytecode/utils.py",
+ "tests/__init__.py",
+ "tests/cell_free_vars_cases.py",
+ "tests/exception_handling_cases.py",
+ "tests/frameworks/function.py",
+ "tests/frameworks/module.py",
+ "tests/frameworks/sitecustomize.py",
+ "tests/long_lines_example.py",
+ "tests/test_bytecode.py",
+ "tests/test_cfg.py",
+ "tests/test_code.py",
+ "tests/test_concrete.py",
+ "tests/test_flags.py",
+ "tests/test_instr.py",
+ "tests/test_misc.py",
+ "tests/util_annotation.py",
+ "tox.ini"
+ ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/bytecode-0.18.1/src/bytecode.egg-info/scm_version.json
new/bytecode-0.19.0/src/bytecode.egg-info/scm_version.json
--- old/bytecode-0.18.1/src/bytecode.egg-info/scm_version.json 1970-01-01
01:00:00.000000000 +0100
+++ new/bytecode-0.19.0/src/bytecode.egg-info/scm_version.json 2026-08-21
23:17:01.268801200 +0200
@@ -0,0 +1,8 @@
+{
+ "tag": "0.19.0",
+ "distance": 0,
+ "node": "g9eea62692be09d07a454aa5244029cc5434096d7",
+ "dirty": false,
+ "branch": "HEAD",
+ "node_date": "2026-08-21"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/tests/test_bytecode.py
new/bytecode-0.19.0/tests/test_bytecode.py
--- old/bytecode-0.18.1/tests/test_bytecode.py 2026-06-03 16:17:07.000000000
+0200
+++ new/bytecode-0.19.0/tests/test_bytecode.py 2026-08-21 23:16:51.972588300
+0200
@@ -7,8 +7,8 @@
import unittest
from bytecode import Bytecode, ConcreteInstr, FreeVar, Instr, Label, SetLineno
-from bytecode.instr import BinaryOp, FormatValue, InstrLocation
-from bytecode.utils import PY312, PY313, PY314
+from bytecode.instr import BinaryOp, CommonConstant, FormatValue, InstrLocation
+from bytecode.utils import PY312, PY313, PY314, PY315
from . import TestCase, get_code
@@ -169,6 +169,18 @@
bytecode = Bytecode.from_code(code)
label_else = Label()
if PY314:
+
+ def _ret_none(lineno):
+ return (
+ Instr(
+ "LOAD_COMMON_CONSTANT",
+ CommonConstant.CONSTANT_NONE,
+ lineno=lineno,
+ )
+ if PY315
+ else Instr("LOAD_CONST", None, lineno=lineno)
+ )
+
self.assertInstructionListEqual(
bytecode,
[
@@ -179,12 +191,12 @@
Instr("NOT_TAKEN", lineno=1),
Instr("LOAD_SMALL_INT", 1, lineno=2),
Instr("STORE_NAME", "x", lineno=2),
- Instr("LOAD_CONST", None, lineno=2),
+ _ret_none(2),
Instr("RETURN_VALUE", lineno=2),
label_else,
Instr("LOAD_SMALL_INT", 2, lineno=4),
Instr("STORE_NAME", "x", lineno=4),
- Instr("LOAD_CONST", None, lineno=4),
+ _ret_none(4),
Instr("RETURN_VALUE", lineno=4),
],
)
@@ -293,7 +305,11 @@
]
+ (
[
- Instr("LOAD_CONST", None, lineno=3),
+ Instr(
+ "LOAD_COMMON_CONSTANT" if PY315 else "LOAD_CONST",
+ CommonConstant.CONSTANT_NONE if PY315 else None,
+ lineno=3,
+ ),
Instr("RETURN_VALUE", lineno=3),
]
if PY314
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/tests/test_cfg.py
new/bytecode-0.19.0/tests/test_cfg.py
--- old/bytecode-0.18.1/tests/test_cfg.py 2026-06-03 16:17:07.000000000
+0200
+++ new/bytecode-0.19.0/tests/test_cfg.py 2026-08-21 23:16:51.972588300
+0200
@@ -21,7 +21,8 @@
TryEnd,
dump_bytecode,
)
-from bytecode.utils import PY312, PY313, PY314
+from bytecode.instr import CommonConstant
+from bytecode.utils import PY312, PY313, PY314, PY315
from . import TestCase, disassemble as _disassemble
@@ -35,15 +36,20 @@
# drop LOAD_CONST+RETURN_VALUE to only keep 2 instructions,
# to make unit tests shorter
block = blocks[-1]
- test = (
- (block[-1].name == "RETURN_CONST" and block[-1].arg is None)
- if PY312 and not PY314
- else (
+ if PY315:
+ test = (
+ block[-2].name == "LOAD_COMMON_CONSTANT"
+ and block[-2].arg == CommonConstant.CONSTANT_NONE
+ and block[-1].name == "RETURN_VALUE"
+ )
+ elif PY312 and not PY314:
+ test = block[-1].name == "RETURN_CONST" and block[-1].arg is None
+ else:
+ test = (
block[-2].name == "LOAD_CONST"
and block[-2].arg is None
and block[-1].name == "RETURN_VALUE"
)
- )
if not test:
raise ValueError(
"unable to find implicit RETURN_VALUE <None>: %s" % block[-2:]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/tests/test_code.py
new/bytecode-0.19.0/tests/test_code.py
--- old/bytecode-0.18.1/tests/test_code.py 2026-06-03 16:17:07.000000000
+0200
+++ new/bytecode-0.19.0/tests/test_code.py 2026-08-21 23:16:51.972588300
+0200
@@ -84,6 +84,17 @@
function=True,
)
+ def test_import(self):
+ # In 3.15 IMPORT_NAME gained lazy/eager flag bits packed into its arg
+ # (like LOAD_SUPER_ATTR), which a naive plain-name decode misses.
+ self.check(
+ """
+ import os
+ import os.path as osp
+ from os import path
+ """
+ )
+
def test_async_gen(self):
self.check(
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/tests/test_concrete.py
new/bytecode-0.19.0/tests/test_concrete.py
--- old/bytecode-0.18.1/tests/test_concrete.py 2026-06-03 16:17:07.000000000
+0200
+++ new/bytecode-0.19.0/tests/test_concrete.py 2026-08-21 23:16:51.972825800
+0200
@@ -21,7 +21,8 @@
SetLineno,
)
from bytecode.concrete import ExceptionTableEntry
-from bytecode.utils import PY312, PY313, PY314
+from bytecode.instr import CommonConstant
+from bytecode.utils import PY312, PY313, PY314, PY315
from . import TestCase, get_code
@@ -244,30 +245,43 @@
def test_attr(self):
code_obj = get_code("x = 5")
code = ConcreteBytecode.from_code(code_obj)
- self.assertEqual(code.consts, [5, None])
+ self.assertEqual(code.consts, [5] if PY315 else [5, None])
self.assertEqual(code.names, ["x"])
self.assertEqual(code.varnames, [])
self.assertEqual(code.freevars, [])
self.assertInstructionListEqual(
list(code),
- ([ConcreteInstr("RESUME", 0, lineno=0)])
- + [
- ConcreteInstr("LOAD_CONST", 0, lineno=1),
- ConcreteInstr("STORE_NAME", 0, lineno=1),
- ]
- + (
+ (
[
- ConcreteInstr("LOAD_SMALL_INT", 1, lineno=1),
+ ConcreteInstr("RESUME", 0, lineno=0),
+ ConcreteInstr("CACHE", 0, lineno=0),
+ ConcreteInstr("LOAD_SMALL_INT", 5, lineno=1),
+ ConcreteInstr("STORE_NAME", 0, lineno=1),
+ ConcreteInstr("LOAD_COMMON_CONSTANT", 7, lineno=1),
ConcreteInstr("RETURN_VALUE", lineno=1),
]
- if PY314
+ if PY315
else (
- [ConcreteInstr("RETURN_CONST", 1, lineno=1)]
- if PY312
- else [
- ConcreteInstr("LOAD_CONST", 1, lineno=1),
- ConcreteInstr("RETURN_VALUE", lineno=1),
+ [ConcreteInstr("RESUME", 0, lineno=0)]
+ + [
+ ConcreteInstr("LOAD_CONST", 0, lineno=1),
+ ConcreteInstr("STORE_NAME", 0, lineno=1),
]
+ + (
+ [
+ ConcreteInstr("LOAD_SMALL_INT", 1, lineno=1),
+ ConcreteInstr("RETURN_VALUE", lineno=1),
+ ]
+ if PY314
+ else (
+ [ConcreteInstr("RETURN_CONST", 1, lineno=1)]
+ if PY312
+ else [
+ ConcreteInstr("LOAD_CONST", 1, lineno=1),
+ ConcreteInstr("RETURN_VALUE", lineno=1),
+ ]
+ )
+ )
)
),
)
@@ -321,7 +335,9 @@
]
+ (
[
- ConcreteInstr("LOAD_CONST", 1),
+ ConcreteInstr("LOAD_COMMON_CONSTANT",
CommonConstant.CONSTANT_NONE)
+ if PY315
+ else ConcreteInstr("LOAD_CONST", 1),
ConcreteInstr("RETURN_VALUE"),
]
if PY314
@@ -445,7 +461,9 @@
]
+ (
[
- ConcreteInstr("LOAD_CONST", 1),
+ ConcreteInstr("LOAD_COMMON_CONSTANT",
CommonConstant.CONSTANT_NONE)
+ if PY315
+ else ConcreteInstr("LOAD_CONST", 1),
ConcreteInstr("RETURN_VALUE"),
]
if PY314
@@ -740,6 +758,32 @@
# without EXTENDED_ARG
concrete = ConcreteBytecode.from_code(code_obj)
+ if PY315:
+ ann_code = concrete.consts[0]
+ func_code = concrete.consts[1]
+ expected_py315 = [
+ ConcreteInstr("RESUME", 0, lineno=0),
+ ConcreteInstr("CACHE", 0, lineno=0),
+ ConcreteInstr("LOAD_CONST", 0, lineno=1),
+ ConcreteInstr("MAKE_FUNCTION", lineno=1),
+ ConcreteInstr("LOAD_CONST", 1, lineno=1),
+ ConcreteInstr("MAKE_FUNCTION", lineno=1),
+ ConcreteInstr("SET_FUNCTION_ATTRIBUTE", 16, lineno=1),
+ ConcreteInstr("STORE_NAME", 0, lineno=1),
+ ConcreteInstr("LOAD_COMMON_CONSTANT", 7, lineno=1),
+ ConcreteInstr("RETURN_VALUE", lineno=1),
+ ]
+ expected_consts = [ann_code, func_code]
+ self.assertSequenceEqual(concrete.names, ["foo"])
+ self.assertSequenceEqual(concrete.consts, expected_consts)
+ self.assertInstructionListEqual(list(concrete), expected_py315)
+ concrete = ConcreteBytecode.from_code(code_obj, extended_arg=True)
+ ann_code = concrete.consts[0]
+ func_code = concrete.consts[1]
+ self.assertEqual(concrete.names, ["foo"])
+ self.assertEqual(concrete.consts, expected_consts)
+ self.assertInstructionListEqual(list(concrete), expected_py315)
+ return
if PY314:
ann_code = concrete.consts[0]
func_code = concrete.consts[1]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/tests/test_misc.py
new/bytecode-0.19.0/tests/test_misc.py
--- old/bytecode-0.18.1/tests/test_misc.py 2026-06-03 16:17:07.000000000
+0200
+++ new/bytecode-0.19.0/tests/test_misc.py 2026-08-21 23:16:51.972825800
+0200
@@ -7,7 +7,7 @@
import bytecode
from bytecode import BasicBlock, Bytecode, ControlFlowGraph, Instr, Label
-from bytecode.utils import PY312, PY313, PY314
+from bytecode.utils import PY312, PY313, PY314, PY315
from . import disassemble
@@ -422,7 +422,33 @@
code = code.to_concrete_bytecode()
# without line numbers
- if PY314:
+ if PY315:
+ # RESUME gained a CACHE entry in 3.15, shifting all offsets by 2
+ expected = """
+ 0 RESUME 0
+ 2 CACHE 0
+ 4 LOAD_FAST_BORROW 0
+ 6 LOAD_SMALL_INT 1
+ 8 COMPARE_OP 88
+ 10 CACHE 0
+ 12 POP_JUMP_IF_FALSE 3
+ 14 CACHE 0
+ 16 NOT_TAKEN
+ 18 LOAD_SMALL_INT 1
+ 20 RETURN_VALUE
+ 22 LOAD_FAST_BORROW 0
+ 24 LOAD_SMALL_INT 2
+ 26 COMPARE_OP 88
+ 28 CACHE 0
+ 30 POP_JUMP_IF_FALSE 3
+ 32 CACHE 0
+ 34 NOT_TAKEN
+ 36 LOAD_SMALL_INT 2
+ 38 RETURN_VALUE
+ 40 LOAD_SMALL_INT 3
+ 42 RETURN_VALUE
+"""
+ elif PY314:
# COMPARE_OP use the 4 lowest bits as a cache
expected = """
0 RESUME 0
@@ -511,7 +537,32 @@
self.check_dump_bytecode(code, expected.lstrip("\n"))
# with line numbers
- if PY314:
+ if PY315:
+ expected = """
+L. 1 0: RESUME 0
+ 2: CACHE 0
+L. 2 4: LOAD_FAST_BORROW 0
+ 6: LOAD_SMALL_INT 1
+ 8: COMPARE_OP 88
+ 10: CACHE 0
+ 12: POP_JUMP_IF_FALSE 3
+ 14: CACHE 0
+ 16: NOT_TAKEN
+L. 3 18: LOAD_SMALL_INT 1
+ 20: RETURN_VALUE
+L. 4 22: LOAD_FAST_BORROW 0
+ 24: LOAD_SMALL_INT 2
+ 26: COMPARE_OP 88
+ 28: CACHE 0
+ 30: POP_JUMP_IF_FALSE 3
+ 32: CACHE 0
+ 34: NOT_TAKEN
+L. 5 36: LOAD_SMALL_INT 2
+ 38: RETURN_VALUE
+L. 6 40: LOAD_SMALL_INT 3
+ 42: RETURN_VALUE
+"""
+ elif PY314:
expected = """
L. 1 0: RESUME 0
L. 2 2: LOAD_FAST_BORROW 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bytecode-0.18.1/tox.ini new/bytecode-0.19.0/tox.ini
--- old/bytecode-0.18.1/tox.ini 2026-06-03 16:17:07.000000000 +0200
+++ new/bytecode-0.19.0/tox.ini 2026-08-21 23:16:51.972825800 +0200
@@ -1,5 +1,5 @@
[tox]
-envlist = py3, py38, py39, py310, py311, py312, py313, py314, fmt, docs
+envlist = py3, py38, py39, py310, py311, py312, py313, py314, py315, fmt, docs
isolated_build = true
[testenv]