From 5a6ea35d857fd6232838a12c69211dce2bcf3e5a Mon Sep 17 00:00:00 2001 From: Julian Gilbey <jdg@debian.org> Date: Fri, 13 Oct 2023 12:07:05 +0100 Subject: [PATCH] New upstream version 0.15.1 --- .github/workflows/cis.yml | 4 ++-- .github/workflows/docs.yml | 2 +- .github/workflows/frameworks.yml | 2 +- .github/workflows/release.yml | 4 ++-- doc/api.rst | 12 ++++++------ doc/changelog.rst | 12 +++++++++++- src/bytecode/concrete.py | 3 ++- src/bytecode/instr.py | 18 +++++++++++++----- tests/test_concrete.py | 6 +++++- tests/test_instr.py | 8 +++++++- 10 files changed, 50 insertions(+), 21 deletions(-) diff --git a/.github/workflows/cis.yml b/.github/workflows/cis.yml index 09e2da8..f1e1922 100644 --- a/.github/workflows/cis.yml +++ b/.github/workflows/cis.yml @@ -21,7 +21,7 @@ jobs: name: Lint code runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: @@ -54,7 +54,7 @@ jobs: - python-version: "3.12-dev" toxenv: py312 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Get history and tags for SCM versioning to work run: | git fetch --prune --unshallow diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index cff1aa9..a8ab0f3 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,7 +20,7 @@ jobs: name: Docs building runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Get history and tags for SCM versioning to work run: | git fetch --prune --unshallow diff --git a/.github/workflows/frameworks.yml b/.github/workflows/frameworks.yml index b6e4a39..79b4be8 100644 --- a/.github/workflows/frameworks.yml +++ b/.github/workflows/frameworks.yml @@ -25,7 +25,7 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f25f83a..aa44198 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get history and tags for SCM versioning to work run: | git fetch --prune --unshallow @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get history and tags for SCM versioning to work run: | git fetch --prune --unshallow diff --git a/doc/api.rst b/doc/api.rst index cf91ba8..db54cae 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -351,11 +351,11 @@ Intrinsic operations .. class:: Intrinsic1Op - Enum for the argument of the ``CALL_INSTRINSIC_1`` instruction (3.12+). + Enum for the argument of the ``CALL_INTRINSIC_1`` instruction (3.12+). - ``INSTRINSIC_1_INVALID`` - ``INSTRINSIC_PRINT`` - ``INSTRINSIC_IMPORT_STAR`` + ``INTRINSIC_1_INVALID`` + ``INTRINSIC_PRINT`` + ``INTRINSIC_IMPORT_STAR`` ``INTRINSIC_STOPITERATION_ERROR`` ``INTRINSIC_ASYNC_GEN_WRAP`` ``INTRINSIC_UNARY_POSITIVE`` @@ -368,9 +368,9 @@ Intrinsic operations .. class:: Intrinsic2Op - Enum for the argument of the ``CALL_INSTRINSIC_2`` instruction (3.12+). + Enum for the argument of the ``CALL_INTRINSIC_2`` instruction (3.12+). - ``INSTRINSIC_2_INVALID`` + ``INTRINSIC_2_INVALID`` ``INTRINSIC_PREP_RERAISE_STAR`` ``INTRINSIC_TYPEVAR_WITH_BOUND`` ``INTRINSIC_TYPEVAR_WITH_CONSTRAINTS`` diff --git a/doc/changelog.rst b/doc/changelog.rst index 01a1950..dfc4328 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -1,6 +1,16 @@ ChangeLog ========= +2023-10-13: Version 0.15.1 +-------------------------- + +Bugfixes: + +- Disallow creating an instruction targeting a pseudo/instrumented opcode PR #133 +- Fixes encoding of 0 as a varint PR #132 +- Correct spelling of "INTRINSIC" in several places; this affected + some ops in Python 3.12. PR #131 + 2023-09-01: Version 0.15.0 -------------------------- @@ -17,7 +27,7 @@ New features: a ``tuple[bool, bool, str]`` as argument - ``POP_JUMP_IF_*`` instructions are undirected in Python 3.12 - ``YIELD_VALUE`` now takes an argument - - Support for ``CALL_INSTRINSIC_1/2`` led to the addition of 2 new enums to + - Support for ``CALL_INTRINSIC_1/2`` led to the addition of 2 new enums to represent the argument 2023-05-24: Version 0.14.2 diff --git a/src/bytecode/concrete.py b/src/bytecode/concrete.py index 4a65a5e..4908e1c 100644 --- a/src/bytecode/concrete.py +++ b/src/bytecode/concrete.py @@ -818,9 +818,10 @@ class ConcreteBytecode(_bytecode._BaseBytecodeList[Union[ConcreteInstr, SetLinen while value: temp.append(value & 63 | (64 if temp else 0)) value >>= 6 + temp = temp or [0] if set_begin_marker: temp[-1] |= 128 - return reversed(temp or [0]) + return reversed(temp) def _assemble_exception_table(self) -> bytes: table = bytearray() diff --git a/src/bytecode/instr.py b/src/bytecode/instr.py index f65e5af..e927cdf 100644 --- a/src/bytecode/instr.py +++ b/src/bytecode/instr.py @@ -14,7 +14,9 @@ except ImportError: import bytecode as _bytecode -# --- Instruction argument tools and abstractions +# --- Instruction argument tools and + +MIN_INSTRUMENTED_OPCODE = getattr(_opcode, "MIN_INSTRUMENTED_OPCODE", 256) # Instructions relying on a bit to modify its behavior. # The lowest bit is used to encode custom behavior. @@ -104,9 +106,9 @@ class BinaryOp(enum.IntEnum): @enum.unique class Intrinsic1Op(enum.IntEnum): - INSTRINSIC_1_INVALID = 0 - INSTRINSIC_PRINT = 1 - INSTRINSIC_IMPORT_STAR = 2 + INTRINSIC_1_INVALID = 0 + INTRINSIC_PRINT = 1 + INTRINSIC_IMPORT_STAR = 2 INTRINSIC_STOPITERATION_ERROR = 3 INTRINSIC_ASYNC_GEN_WRAP = 4 INTRINSIC_UNARY_POSITIVE = 5 @@ -120,7 +122,7 @@ class Intrinsic1Op(enum.IntEnum): @enum.unique class Intrinsic2Op(enum.IntEnum): - INSTRINSIC_2_INVALID = 0 + INTRINSIC_2_INVALID = 0 INTRINSIC_PREP_RERAISE_STAR = 1 INTRINSIC_TYPEVAR_WITH_BOUND = 2 INTRINSIC_TYPEVAR_WITH_CONSTRAINTS = 3 @@ -734,6 +736,12 @@ class BaseInstr(Generic[A]): except KeyError: raise ValueError(f"invalid operation name: {name}") + if opcode >= MIN_INSTRUMENTED_OPCODE: + raise ValueError( + f"operation {name} is an instrumented or pseudo opcode. " + "Only base opcodes are supported" + ) + self._check_arg(name, opcode, arg) self._name = name diff --git a/tests/test_concrete.py b/tests/test_concrete.py index 32c179a..3b75ba9 100644 --- a/tests/test_concrete.py +++ b/tests/test_concrete.py @@ -529,7 +529,6 @@ class ConcreteBytecodeTests(TestCase): ], ) - # XXX adjust test for 3.12 in which load_classderef does not exist anymore def test_load_classderef(self): i_name = ( "LOAD_FROM_DICT_OR_DEREF" @@ -682,6 +681,11 @@ class ConcreteBytecodeTests(TestCase): ) self.assertInstructionListEqual(concrete, concrete.copy()) + def test_encode_varint(self): + self.assertListEqual(list(ConcreteBytecode._encode_varint(0)), [0]) + self.assertListEqual(list(ConcreteBytecode._encode_varint(0, True)), [128]) + self.assertListEqual(list(ConcreteBytecode._encode_varint(64, False)), [65, 0]) + class ConcreteFromCodeTests(TestCase): def test_extended_arg(self): diff --git a/tests/test_instr.py b/tests/test_instr.py index d36c315..1437b87 100644 --- a/tests/test_instr.py +++ b/tests/test_instr.py @@ -138,6 +138,12 @@ class InstrTests(TestCase): self.assertIn("arg", r) self.assertIn("_x_", r) + def test_reject_pseudo_opcode(self): + if sys.version_info >= (3, 12): + with self.assertRaises(ValueError) as e: + Instr("LOAD_METHOD", "x") + self.assertIn("is an instrumented or pseudo opcode", str(e.exception)) + def test_invalid_arg(self): label = Label() block = BasicBlock() @@ -208,7 +214,7 @@ class InstrTests(TestCase): for name in [opcode.opname[i] for i in INTRINSIC_1OP]: self.assertRaises(TypeError, Instr, name, 1) - Instr(name, Intrinsic1Op.INSTRINSIC_PRINT) + Instr(name, Intrinsic1Op.INTRINSIC_PRINT) for name in [opcode.opname[i] for i in INTRINSIC_2OP]: self.assertRaises(TypeError, Instr, name, 1) -- GitLab