bytecode 0.15.1__tar.gz → 0.16.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bytecode-0.15.1 → bytecode-0.16.1}/.coveragerc +0 -2
- {bytecode-0.15.1 → bytecode-0.16.1}/.github/workflows/cis.yml +7 -6
- {bytecode-0.15.1 → bytecode-0.16.1}/.github/workflows/docs.yml +1 -2
- {bytecode-0.15.1 → bytecode-0.16.1}/.github/workflows/frameworks.yml +2 -3
- {bytecode-0.15.1 → bytecode-0.16.1}/.github/workflows/release.yml +54 -39
- bytecode-0.16.1/.pre-commit-config.yaml +16 -0
- {bytecode-0.15.1/src/bytecode.egg-info → bytecode-0.16.1}/PKG-INFO +8 -7
- {bytecode-0.15.1 → bytecode-0.16.1}/README.rst +5 -5
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/cfg.rst +12 -12
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/changelog.rst +30 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/usage.rst +10 -9
- bytecode-0.16.1/pyproject.toml +84 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/__init__.py +16 -13
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/bytecode.py +4 -7
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/cfg.py +28 -23
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/concrete.py +204 -110
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/flags.py +108 -58
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/instr.py +96 -46
- bytecode-0.16.1/src/bytecode/utils.py +7 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/version.py +2 -2
- {bytecode-0.15.1 → bytecode-0.16.1/src/bytecode.egg-info}/PKG-INFO +8 -7
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode.egg-info/SOURCES.txt +1 -1
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/__init__.py +1 -1
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/cell_free_vars_cases.py +16 -1
- bytecode-0.16.1/tests/frameworks/module.py +259 -0
- bytecode-0.16.1/tests/frameworks/sitecustomize.py +132 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_bytecode.py +106 -8
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_cfg.py +41 -14
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_concrete.py +117 -20
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_flags.py +96 -40
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_instr.py +32 -19
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_misc.py +45 -4
- bytecode-0.16.1/tox.ini +37 -0
- bytecode-0.15.1/.pre-commit-config.yaml +0 -17
- bytecode-0.15.1/pyproject.toml +0 -78
- bytecode-0.15.1/setup.py +0 -27
- bytecode-0.15.1/tests/frameworks/module.py +0 -203
- bytecode-0.15.1/tests/frameworks/sitecustomize.py +0 -34
- bytecode-0.15.1/tox.ini +0 -47
- {bytecode-0.15.1 → bytecode-0.16.1}/.github/FUNDING.yml +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/.github/dependabot.yml +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/.gitignore +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/.readthedocs.yaml +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/COPYING +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/MANIFEST.in +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/TODO.rst +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/codecov.yml +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/Makefile +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/api.rst +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/byteplay_codetransformer.rst +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/conf.py +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/index.rst +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/make.bat +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/requirements.txt +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/doc/todo.rst +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/scripts/frameworks/boto3/run.sh +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/scripts/frameworks/boto3/setup.sh +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/setup.cfg +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/py.typed +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode.egg-info/dependency_links.txt +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode.egg-info/requires.txt +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode.egg-info/top_level.txt +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/exception_handling_cases.py +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/frameworks/function.py +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/long_lines_example.py +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_code.py +0 -0
- {bytecode-0.15.1 → bytecode-0.16.1}/tests/util_annotation.py +0 -0
|
@@ -13,7 +13,6 @@ on:
|
|
|
13
13
|
- "src/**"
|
|
14
14
|
- "tests/*"
|
|
15
15
|
- pyproject.toml
|
|
16
|
-
- setup.py
|
|
17
16
|
- tox.ini
|
|
18
17
|
|
|
19
18
|
jobs:
|
|
@@ -23,9 +22,9 @@ jobs:
|
|
|
23
22
|
steps:
|
|
24
23
|
- uses: actions/checkout@v4
|
|
25
24
|
- name: Set up Python
|
|
26
|
-
uses: actions/setup-python@
|
|
25
|
+
uses: actions/setup-python@v5
|
|
27
26
|
with:
|
|
28
|
-
python-version: "3.
|
|
27
|
+
python-version: "3.12"
|
|
29
28
|
- name: Install tools
|
|
30
29
|
run: |
|
|
31
30
|
python -m pip install --upgrade pip
|
|
@@ -51,8 +50,10 @@ jobs:
|
|
|
51
50
|
toxenv: py310
|
|
52
51
|
- python-version: "3.11"
|
|
53
52
|
toxenv: py311
|
|
54
|
-
- python-version: "3.12
|
|
53
|
+
- python-version: "3.12"
|
|
55
54
|
toxenv: py312
|
|
55
|
+
- python-version: "3.13"
|
|
56
|
+
toxenv: py313
|
|
56
57
|
steps:
|
|
57
58
|
- uses: actions/checkout@v4
|
|
58
59
|
- name: Get history and tags for SCM versioning to work
|
|
@@ -60,7 +61,7 @@ jobs:
|
|
|
60
61
|
git fetch --prune --unshallow
|
|
61
62
|
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
|
|
62
63
|
- name: Set up Python ${{ matrix.python-version }}
|
|
63
|
-
uses: actions/setup-python@
|
|
64
|
+
uses: actions/setup-python@v5
|
|
64
65
|
with:
|
|
65
66
|
python-version: ${{ matrix.python-version }}
|
|
66
67
|
- name: Install dependencies
|
|
@@ -73,7 +74,7 @@ jobs:
|
|
|
73
74
|
run: |
|
|
74
75
|
tox
|
|
75
76
|
- name: Upload coverage to Codecov
|
|
76
|
-
uses: codecov/codecov-action@
|
|
77
|
+
uses: codecov/codecov-action@v5
|
|
77
78
|
if: github.event_name != 'schedule'
|
|
78
79
|
with:
|
|
79
80
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
@@ -13,7 +13,6 @@ on:
|
|
|
13
13
|
- "src/**"
|
|
14
14
|
- "doc/**"
|
|
15
15
|
- pyproject.toml
|
|
16
|
-
- setup.py
|
|
17
16
|
|
|
18
17
|
jobs:
|
|
19
18
|
docs:
|
|
@@ -26,7 +25,7 @@ jobs:
|
|
|
26
25
|
git fetch --prune --unshallow
|
|
27
26
|
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
|
|
28
27
|
- name: Set up Python
|
|
29
|
-
uses: actions/setup-python@
|
|
28
|
+
uses: actions/setup-python@v5
|
|
30
29
|
with:
|
|
31
30
|
python-version: '3.x'
|
|
32
31
|
- name: Install dependencies
|
|
@@ -12,7 +12,6 @@ on:
|
|
|
12
12
|
- "src/**"
|
|
13
13
|
- "tests/frameworks/*"
|
|
14
14
|
- pyproject.toml
|
|
15
|
-
- setup.py
|
|
16
15
|
- tox.ini
|
|
17
16
|
|
|
18
17
|
jobs:
|
|
@@ -22,7 +21,7 @@ jobs:
|
|
|
22
21
|
strategy:
|
|
23
22
|
fail-fast: false
|
|
24
23
|
matrix:
|
|
25
|
-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
|
|
24
|
+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
26
25
|
|
|
27
26
|
steps:
|
|
28
27
|
- uses: actions/checkout@v4
|
|
@@ -30,7 +29,7 @@ jobs:
|
|
|
30
29
|
fetch-depth: 0
|
|
31
30
|
|
|
32
31
|
- name: Set up Python
|
|
33
|
-
uses: actions/setup-python@
|
|
32
|
+
uses: actions/setup-python@v5
|
|
34
33
|
with:
|
|
35
34
|
python-version: ${{ matrix.python-version }}-dev
|
|
36
35
|
|
|
@@ -19,7 +19,7 @@ jobs:
|
|
|
19
19
|
git fetch --prune --unshallow
|
|
20
20
|
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
|
|
21
21
|
- name: Setup Python
|
|
22
|
-
uses: actions/setup-python@
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
23
|
with:
|
|
24
24
|
python-version: '3.x'
|
|
25
25
|
- name: Build sdist
|
|
@@ -33,9 +33,9 @@ jobs:
|
|
|
33
33
|
pip install dist/*.tar.gz
|
|
34
34
|
python -X dev -m pytest tests
|
|
35
35
|
- name: Store artifacts
|
|
36
|
-
uses: actions/upload-artifact@
|
|
36
|
+
uses: actions/upload-artifact@v4
|
|
37
37
|
with:
|
|
38
|
-
name:
|
|
38
|
+
name: cibw-sdist
|
|
39
39
|
path: dist/*
|
|
40
40
|
|
|
41
41
|
build_wheel:
|
|
@@ -49,7 +49,7 @@ jobs:
|
|
|
49
49
|
git fetch --prune --unshallow
|
|
50
50
|
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
|
|
51
51
|
- name: Setup Python
|
|
52
|
-
uses: actions/setup-python@
|
|
52
|
+
uses: actions/setup-python@v5
|
|
53
53
|
with:
|
|
54
54
|
python-version: '3.x'
|
|
55
55
|
- name: Build wheels
|
|
@@ -63,53 +63,68 @@ jobs:
|
|
|
63
63
|
pip install dist/*.whl
|
|
64
64
|
python -X dev -m pytest tests
|
|
65
65
|
- name: Store artifacts
|
|
66
|
-
uses: actions/upload-artifact@
|
|
66
|
+
uses: actions/upload-artifact@v4
|
|
67
67
|
with:
|
|
68
|
-
name:
|
|
68
|
+
name: cibw-wheel
|
|
69
69
|
path: dist/*.whl
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
name: Create Release and Upload Release Asset
|
|
73
|
-
runs-on: ubuntu-latest
|
|
74
|
-
if: github.event_name == 'push'
|
|
75
|
-
needs: [build_wheel, build_sdist]
|
|
76
|
-
steps:
|
|
77
|
-
- name: Create Release
|
|
78
|
-
id: create_release
|
|
79
|
-
uses: actions/create-release@v1
|
|
80
|
-
env:
|
|
81
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
82
|
-
with:
|
|
83
|
-
tag_name: ${{ github.ref }}
|
|
84
|
-
release_name: Release ${{ github.ref }}
|
|
85
|
-
draft: false
|
|
86
|
-
prerelease: ${{ contains(github.ref, 'rc') || contains(github.ref, 'a') || contains(github.ref, 'b')}}
|
|
87
|
-
- uses: actions/download-artifact@v3
|
|
88
|
-
with:
|
|
89
|
-
name: artifact
|
|
90
|
-
path: dist
|
|
91
|
-
- name: Upload Release Asset
|
|
92
|
-
id: upload-release-asset
|
|
93
|
-
uses: shogo82148/actions-upload-release-asset@v1
|
|
94
|
-
env:
|
|
95
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
96
|
-
with:
|
|
97
|
-
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
98
|
-
asset_path: dist/*
|
|
99
|
-
|
|
100
|
-
upload_pypi:
|
|
71
|
+
publish:
|
|
101
72
|
if: github.event_name == 'push'
|
|
102
73
|
needs: [build_wheel, build_sdist]
|
|
103
74
|
runs-on: ubuntu-latest
|
|
104
75
|
steps:
|
|
105
|
-
-
|
|
76
|
+
- name: Download all the dists
|
|
77
|
+
uses: actions/download-artifact@v4.1.8
|
|
106
78
|
with:
|
|
107
|
-
|
|
79
|
+
pattern: cibw-*
|
|
108
80
|
path: dist
|
|
81
|
+
merge-multiple: true
|
|
109
82
|
|
|
110
|
-
- uses: pypa/gh-action-pypi-publish@
|
|
83
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
111
84
|
with:
|
|
112
85
|
user: __token__
|
|
113
86
|
password: ${{ secrets.pypi_password }}
|
|
114
87
|
# To test:
|
|
115
88
|
# repository_url: https://test.pypi.org/legacy/
|
|
89
|
+
|
|
90
|
+
github-release:
|
|
91
|
+
name: >-
|
|
92
|
+
Sign the Python 🐍 distribution 📦 with Sigstore
|
|
93
|
+
and create a GitHub Release
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
needs:
|
|
96
|
+
- publish
|
|
97
|
+
|
|
98
|
+
permissions:
|
|
99
|
+
contents: write
|
|
100
|
+
id-token: write
|
|
101
|
+
|
|
102
|
+
steps:
|
|
103
|
+
- name: Download all the dists
|
|
104
|
+
uses: actions/download-artifact@v4.1.8
|
|
105
|
+
with:
|
|
106
|
+
pattern: cibw-*
|
|
107
|
+
path: dist
|
|
108
|
+
merge-multiple: true
|
|
109
|
+
- name: Sign the dists with Sigstore
|
|
110
|
+
uses: sigstore/gh-action-sigstore-python@v2.1.0
|
|
111
|
+
with:
|
|
112
|
+
password: ${{ secrets.pypi_password }}
|
|
113
|
+
inputs: >-
|
|
114
|
+
./dist/*.tar.gz
|
|
115
|
+
./dist/*.whl
|
|
116
|
+
- name: Create GitHub Release
|
|
117
|
+
env:
|
|
118
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
119
|
+
run: >-
|
|
120
|
+
gh release create
|
|
121
|
+
'${{ github.ref_name }}'
|
|
122
|
+
--repo '${{ github.repository }}'
|
|
123
|
+
--generate-notes
|
|
124
|
+
- name: Upload artifact signatures to GitHub Release
|
|
125
|
+
env:
|
|
126
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
127
|
+
run: >-
|
|
128
|
+
gh release upload
|
|
129
|
+
'${{ github.ref_name }}' dist/**
|
|
130
|
+
--repo '${{ github.repository }}'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
default_language_version:
|
|
3
|
+
python: python3.11
|
|
4
|
+
repos:
|
|
5
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
6
|
+
# Ruff version.
|
|
7
|
+
rev: v0.1.5
|
|
8
|
+
hooks:
|
|
9
|
+
# Run the linter.
|
|
10
|
+
- id: ruff
|
|
11
|
+
# Run the formatter.
|
|
12
|
+
- id: ruff-format
|
|
13
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
14
|
+
rev: v1.7.0
|
|
15
|
+
hooks:
|
|
16
|
+
- id: mypy
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: bytecode
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.1
|
|
4
4
|
Summary: Python module to generate and modify bytecode
|
|
5
5
|
Author-email: Victor Stinner <victor.stinner@gmail.com>
|
|
6
6
|
Maintainer-email: "Matthieu C. Dartiailh" <m.dartiailh@gmail.com>
|
|
@@ -41,6 +41,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
41
41
|
Classifier: Programming Language :: Python :: 3.10
|
|
42
42
|
Classifier: Programming Language :: Python :: 3.11
|
|
43
43
|
Classifier: Programming Language :: Python :: 3.12
|
|
44
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
44
45
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
45
46
|
Requires-Python: >=3.8
|
|
46
47
|
Description-Content-Type: text/x-rst
|
|
@@ -67,9 +68,9 @@ bytecode
|
|
|
67
68
|
:alt: Code coverage of bytecode on codecov.io
|
|
68
69
|
:target: https://codecov.io/github/MatthieuDartiailh/bytecode
|
|
69
70
|
|
|
70
|
-
.. image:: https://img.shields.io/badge/
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
|
|
72
|
+
:target: https://github.com/astral-sh/ruff
|
|
73
|
+
:alt: Ruff
|
|
73
74
|
|
|
74
75
|
``bytecode`` is a Python module to generate and modify bytecode.
|
|
75
76
|
|
|
@@ -92,9 +93,9 @@ Example executing ``print('Hello World!')``:
|
|
|
92
93
|
|
|
93
94
|
from bytecode import Instr, Bytecode
|
|
94
95
|
|
|
95
|
-
bytecode = Bytecode([Instr("
|
|
96
|
+
bytecode = Bytecode([Instr("LOAD_GLOBAL", (True, 'print')),
|
|
96
97
|
Instr("LOAD_CONST", 'Hello World!'),
|
|
97
|
-
Instr("
|
|
98
|
+
Instr("CALL", 1),
|
|
98
99
|
Instr("POP_TOP"),
|
|
99
100
|
Instr("LOAD_CONST", None),
|
|
100
101
|
Instr("RETURN_VALUE")])
|
|
@@ -18,9 +18,9 @@ bytecode
|
|
|
18
18
|
:alt: Code coverage of bytecode on codecov.io
|
|
19
19
|
:target: https://codecov.io/github/MatthieuDartiailh/bytecode
|
|
20
20
|
|
|
21
|
-
.. image:: https://img.shields.io/badge/
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
|
|
22
|
+
:target: https://github.com/astral-sh/ruff
|
|
23
|
+
:alt: Ruff
|
|
24
24
|
|
|
25
25
|
``bytecode`` is a Python module to generate and modify bytecode.
|
|
26
26
|
|
|
@@ -43,9 +43,9 @@ Example executing ``print('Hello World!')``:
|
|
|
43
43
|
|
|
44
44
|
from bytecode import Instr, Bytecode
|
|
45
45
|
|
|
46
|
-
bytecode = Bytecode([Instr("
|
|
46
|
+
bytecode = Bytecode([Instr("LOAD_GLOBAL", (True, 'print')),
|
|
47
47
|
Instr("LOAD_CONST", 'Hello World!'),
|
|
48
|
-
Instr("
|
|
48
|
+
Instr("CALL", 1),
|
|
49
49
|
Instr("POP_TOP"),
|
|
50
50
|
Instr("LOAD_CONST", None),
|
|
51
51
|
Instr("RETURN_VALUE")])
|
|
@@ -20,7 +20,7 @@ Dump the control flow graph of the :ref:`conditional jump example
|
|
|
20
20
|
|
|
21
21
|
label_else = Label()
|
|
22
22
|
label_print = Label()
|
|
23
|
-
bytecode = Bytecode([Instr('
|
|
23
|
+
bytecode = Bytecode([Instr('LOAD_GLOBAL', (True, 'print')),
|
|
24
24
|
Instr('LOAD_NAME', 'test'),
|
|
25
25
|
Instr('POP_JUMP_IF_FALSE', label_else),
|
|
26
26
|
Instr('LOAD_CONST', 'yes'),
|
|
@@ -28,7 +28,7 @@ Dump the control flow graph of the :ref:`conditional jump example
|
|
|
28
28
|
label_else,
|
|
29
29
|
Instr('LOAD_CONST', 'no'),
|
|
30
30
|
label_print,
|
|
31
|
-
Instr('
|
|
31
|
+
Instr('CALL', 1),
|
|
32
32
|
Instr('LOAD_CONST', None),
|
|
33
33
|
Instr('RETURN_VALUE')])
|
|
34
34
|
|
|
@@ -38,7 +38,7 @@ Dump the control flow graph of the :ref:`conditional jump example
|
|
|
38
38
|
Output::
|
|
39
39
|
|
|
40
40
|
block1:
|
|
41
|
-
|
|
41
|
+
LOAD_GLOBAL (True, 'print')
|
|
42
42
|
LOAD_NAME 'test'
|
|
43
43
|
POP_JUMP_IF_FALSE <block3>
|
|
44
44
|
-> block2
|
|
@@ -52,7 +52,7 @@ Output::
|
|
|
52
52
|
-> block4
|
|
53
53
|
|
|
54
54
|
block4:
|
|
55
|
-
|
|
55
|
+
CALL 1
|
|
56
56
|
LOAD_CONST None
|
|
57
57
|
RETURN_VALUE
|
|
58
58
|
|
|
@@ -107,7 +107,7 @@ Example of a ``display_blocks()`` function::
|
|
|
107
107
|
|
|
108
108
|
label_else = Label()
|
|
109
109
|
label_print = Label()
|
|
110
|
-
bytecode = Bytecode([Instr('
|
|
110
|
+
bytecode = Bytecode([Instr('LOAD_GLOBAL', (True, 'print')),
|
|
111
111
|
Instr('LOAD_NAME', 'test'),
|
|
112
112
|
Instr('POP_JUMP_IF_FALSE', label_else),
|
|
113
113
|
Instr('LOAD_CONST', 'yes'),
|
|
@@ -115,7 +115,7 @@ Example of a ``display_blocks()`` function::
|
|
|
115
115
|
label_else,
|
|
116
116
|
Instr('LOAD_CONST', 'no'),
|
|
117
117
|
label_print,
|
|
118
|
-
Instr('
|
|
118
|
+
Instr('CALL', 1),
|
|
119
119
|
Instr('LOAD_CONST', None),
|
|
120
120
|
Instr('RETURN_VALUE')])
|
|
121
121
|
|
|
@@ -125,7 +125,7 @@ Example of a ``display_blocks()`` function::
|
|
|
125
125
|
Output::
|
|
126
126
|
|
|
127
127
|
Block #1
|
|
128
|
-
|
|
128
|
+
LOAD_GLOBAL (True, 'print')
|
|
129
129
|
LOAD_NAME 'test'
|
|
130
130
|
POP_JUMP_IF_FALSE <block #3>
|
|
131
131
|
=> <block #2>
|
|
@@ -139,7 +139,7 @@ Output::
|
|
|
139
139
|
=> <block #4>
|
|
140
140
|
|
|
141
141
|
Block #4
|
|
142
|
-
|
|
142
|
+
CALL 1
|
|
143
143
|
LOAD_CONST None
|
|
144
144
|
RETURN_VALUE
|
|
145
145
|
|
|
@@ -193,7 +193,7 @@ Example to a recursive ``display_block()`` function::
|
|
|
193
193
|
|
|
194
194
|
label_else = Label()
|
|
195
195
|
label_print = Label()
|
|
196
|
-
bytecode = Bytecode([Instr('
|
|
196
|
+
bytecode = Bytecode([Instr('LOAD_GLOBAL', (True, 'print')),
|
|
197
197
|
Instr('LOAD_NAME', 'test'),
|
|
198
198
|
Instr('POP_JUMP_IF_FALSE', label_else),
|
|
199
199
|
Instr('LOAD_CONST', 'yes'),
|
|
@@ -201,7 +201,7 @@ Example to a recursive ``display_block()`` function::
|
|
|
201
201
|
label_else,
|
|
202
202
|
Instr('LOAD_CONST', 'no'),
|
|
203
203
|
label_print,
|
|
204
|
-
Instr('
|
|
204
|
+
Instr('CALL', 1),
|
|
205
205
|
Instr('LOAD_CONST', None),
|
|
206
206
|
Instr('RETURN_VALUE')])
|
|
207
207
|
|
|
@@ -211,7 +211,7 @@ Example to a recursive ``display_block()`` function::
|
|
|
211
211
|
Output::
|
|
212
212
|
|
|
213
213
|
Block #1
|
|
214
|
-
|
|
214
|
+
LOAD_GLOBAL (True, 'print')
|
|
215
215
|
LOAD_NAME 'test'
|
|
216
216
|
POP_JUMP_IF_FALSE <block #3>
|
|
217
217
|
=> <block #2>
|
|
@@ -221,7 +221,7 @@ Output::
|
|
|
221
221
|
JUMP_FORWARD <block #4>
|
|
222
222
|
|
|
223
223
|
Block #4
|
|
224
|
-
|
|
224
|
+
CALL 1
|
|
225
225
|
LOAD_CONST None
|
|
226
226
|
RETURN_VALUE
|
|
227
227
|
|
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
ChangeLog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
2025-01-21: Version 0.16.1
|
|
5
|
+
--------------------------
|
|
6
|
+
|
|
7
|
+
Bugfixes:
|
|
8
|
+
|
|
9
|
+
- fix flag inference for async code PR #157
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
2024-10-28: Version 0.16.0
|
|
13
|
+
--------------------------
|
|
14
|
+
|
|
15
|
+
New features:
|
|
16
|
+
|
|
17
|
+
- Add support for Python 3.13 PR #146
|
|
18
|
+
|
|
19
|
+
Support for Python 3.13, comes with a number of changes reflecting changes in
|
|
20
|
+
CPython bytecode itself:
|
|
21
|
+
|
|
22
|
+
- handle the ability of comparison to cast with new enum variants:
|
|
23
|
+
LT_CAST, LE_CAST, etc
|
|
24
|
+
- allow LOAD_FAST to access free and cell vars
|
|
25
|
+
|
|
26
|
+
Bugfixes:
|
|
27
|
+
|
|
28
|
+
- Properly handle TryEnd with no matching TryBegin in stack size computation on
|
|
29
|
+
the CFG PR #149
|
|
30
|
+
- Ensure that empty or small (one-instruction) try blocks are handled without
|
|
31
|
+
problems when compiling and de-compiling abstract code for CPython 3.11 and
|
|
32
|
+
later. PR #145
|
|
33
|
+
|
|
4
34
|
2023-10-13: Version 0.15.1
|
|
5
35
|
--------------------------
|
|
6
36
|
|
|
@@ -22,9 +22,9 @@ Example using abstract bytecode to execute ``print('Hello World!')``::
|
|
|
22
22
|
|
|
23
23
|
from bytecode import Instr, Bytecode
|
|
24
24
|
|
|
25
|
-
bytecode = Bytecode([Instr("
|
|
25
|
+
bytecode = Bytecode([Instr("LOAD_GLOBAL", (True, 'print')),
|
|
26
26
|
Instr("LOAD_CONST", 'Hello World!'),
|
|
27
|
-
Instr("
|
|
27
|
+
Instr("CALL", 1),
|
|
28
28
|
Instr("POP_TOP"),
|
|
29
29
|
Instr("LOAD_CONST", None),
|
|
30
30
|
Instr("RETURN_VALUE")])
|
|
@@ -46,9 +46,9 @@ Example using concrete bytecode to execute ``print('Hello World!')``::
|
|
|
46
46
|
bytecode = ConcreteBytecode()
|
|
47
47
|
bytecode.names = ['print']
|
|
48
48
|
bytecode.consts = ['Hello World!', None]
|
|
49
|
-
bytecode.extend([ConcreteInstr("
|
|
49
|
+
bytecode.extend([ConcreteInstr("LOAD_GLOBAL", 1),
|
|
50
50
|
ConcreteInstr("LOAD_CONST", 0),
|
|
51
|
-
ConcreteInstr("
|
|
51
|
+
ConcreteInstr("CALL", 1),
|
|
52
52
|
ConcreteInstr("POP_TOP"),
|
|
53
53
|
ConcreteInstr("LOAD_CONST", 1),
|
|
54
54
|
ConcreteInstr("RETURN_VALUE")])
|
|
@@ -110,14 +110,15 @@ Bytecode of ``for x in (1, 2, 3): print(x)``:
|
|
|
110
110
|
loop_start,
|
|
111
111
|
Instr("FOR_ITER", loop_exit),
|
|
112
112
|
Instr("STORE_NAME", "x"),
|
|
113
|
-
Instr("
|
|
113
|
+
Instr("LOAD_GLOBAL", (True, "print")),
|
|
114
114
|
Instr("LOAD_NAME", "x"),
|
|
115
|
-
Instr("
|
|
115
|
+
Instr("CALL", 1),
|
|
116
116
|
Instr("POP_TOP"),
|
|
117
|
-
Instr("
|
|
117
|
+
Instr("JUMP_BACKWARD", loop_start),
|
|
118
118
|
# Python 3.8 removed the need to manually manage blocks in loops
|
|
119
119
|
# This is now handled internally by the interpreter
|
|
120
120
|
loop_exit,
|
|
121
|
+
Instr("END_FOR"),
|
|
121
122
|
Instr("LOAD_CONST", None),
|
|
122
123
|
Instr("RETURN_VALUE"),
|
|
123
124
|
]
|
|
@@ -146,7 +147,7 @@ Bytecode of the Python code ``print('yes' if test else 'no')``::
|
|
|
146
147
|
|
|
147
148
|
label_else = Label()
|
|
148
149
|
label_print = Label()
|
|
149
|
-
bytecode = Bytecode([Instr('
|
|
150
|
+
bytecode = Bytecode([Instr('LOAD_GLOBAL', (True, 'print')),
|
|
150
151
|
Instr('LOAD_NAME', 'test'),
|
|
151
152
|
Instr('POP_JUMP_IF_FALSE', label_else),
|
|
152
153
|
Instr('LOAD_CONST', 'yes'),
|
|
@@ -154,7 +155,7 @@ Bytecode of the Python code ``print('yes' if test else 'no')``::
|
|
|
154
155
|
label_else,
|
|
155
156
|
Instr('LOAD_CONST', 'no'),
|
|
156
157
|
label_print,
|
|
157
|
-
Instr('
|
|
158
|
+
Instr('CALL', 1),
|
|
158
159
|
Instr('LOAD_CONST', None),
|
|
159
160
|
Instr('RETURN_VALUE')])
|
|
160
161
|
code = bytecode.to_code()
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "bytecode"
|
|
3
|
+
description = "Python module to generate and modify bytecode"
|
|
4
|
+
readme = "README.rst"
|
|
5
|
+
requires-python = ">=3.8"
|
|
6
|
+
license = { file = "COPYING" }
|
|
7
|
+
authors = [{ name = "Victor Stinner", email = "victor.stinner@gmail.com" }]
|
|
8
|
+
maintainers = [{ name = "Matthieu C. Dartiailh", email = "m.dartiailh@gmail.com" }]
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Development Status :: 4 - Beta",
|
|
11
|
+
"Intended Audience :: Developers",
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Natural Language :: English",
|
|
14
|
+
"Operating System :: OS Independent",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.8",
|
|
17
|
+
"Programming Language :: Python :: 3.9",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
23
|
+
]
|
|
24
|
+
dependencies = ["typing_extensions;python_version<'3.10'"]
|
|
25
|
+
dynamic = ["version"]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
homepage = "https://github.com/MatthieuDartiailh/bytecode"
|
|
30
|
+
documentation = "https://bytecode.readthedocs.io/en/latest/"
|
|
31
|
+
repository = "https://github.com/MatthieuDartiailh/bytecode"
|
|
32
|
+
changelog = "https://github.com/MatthieuDartiailh/bytecode/blob/main/doc/changelog.rst"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
[build-system]
|
|
36
|
+
requires = ["setuptools>=61.2", "wheel", "setuptools_scm[toml]>=3.4.3"]
|
|
37
|
+
build-backend = "setuptools.build_meta"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools_scm]
|
|
40
|
+
write_to = "src/bytecode/version.py"
|
|
41
|
+
write_to_template = """
|
|
42
|
+
# This file is auto-generated by setuptools-scm do NOT edit it.
|
|
43
|
+
|
|
44
|
+
from collections import namedtuple
|
|
45
|
+
|
|
46
|
+
#: A namedtuple of the version info for the current release.
|
|
47
|
+
_version_info = namedtuple("_version_info", "major minor micro status")
|
|
48
|
+
|
|
49
|
+
parts = "{version}".split(".", 3)
|
|
50
|
+
version_info = _version_info(
|
|
51
|
+
int(parts[0]),
|
|
52
|
+
int(parts[1]),
|
|
53
|
+
int(parts[2]),
|
|
54
|
+
parts[3] if len(parts) == 4 else "",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Remove everything but the 'version_info' from this module.
|
|
58
|
+
del namedtuple, _version_info, parts
|
|
59
|
+
|
|
60
|
+
__version__ = "{version}"
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
src = ["src"]
|
|
65
|
+
extend-exclude = ["tests/instruments/hardware/nifpga/scope_based"]
|
|
66
|
+
line-length = 88
|
|
67
|
+
|
|
68
|
+
[tool.ruff.lint]
|
|
69
|
+
select = ["B", "C", "E", "F", "W", "B9", "I", "C90", "RUF"]
|
|
70
|
+
extend-ignore = ["E203", "E266", "E501", "F403", "F401", "RUF012"]
|
|
71
|
+
|
|
72
|
+
[tool.ruff.lint.isort]
|
|
73
|
+
combine-as-imports = true
|
|
74
|
+
extra-standard-library = ["opcode"]
|
|
75
|
+
|
|
76
|
+
[tool.ruff.lint.mccabe]
|
|
77
|
+
max-complexity = 42
|
|
78
|
+
|
|
79
|
+
[tool.mypy]
|
|
80
|
+
follow_imports = "normal"
|
|
81
|
+
strict_optional = true
|
|
82
|
+
|
|
83
|
+
[tool.pytest.ini_options]
|
|
84
|
+
minversion = "6.0"
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
__all__ = [
|
|
2
|
-
"
|
|
3
|
-
"Instr",
|
|
4
|
-
"SetLineno",
|
|
2
|
+
"BinaryOp",
|
|
5
3
|
"Bytecode",
|
|
6
|
-
"
|
|
4
|
+
"Compare",
|
|
5
|
+
"CompilerFlags",
|
|
7
6
|
"ConcreteBytecode",
|
|
7
|
+
"ConcreteInstr",
|
|
8
8
|
"ControlFlowGraph",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
9
|
+
"Instr",
|
|
10
|
+
"Label",
|
|
11
|
+
"SetLineno",
|
|
12
12
|
"__version__",
|
|
13
13
|
]
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ from io import StringIO
|
|
|
16
16
|
from typing import List, Union
|
|
17
17
|
|
|
18
18
|
# import needed to use it in bytecode.py
|
|
19
|
-
from bytecode.bytecode import (
|
|
19
|
+
from bytecode.bytecode import (
|
|
20
20
|
BaseBytecode,
|
|
21
21
|
Bytecode,
|
|
22
22
|
_BaseBytecodeList,
|
|
@@ -24,15 +24,18 @@ from bytecode.bytecode import ( # noqa
|
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
# import needed to use it in bytecode.py
|
|
27
|
-
from bytecode.cfg import BasicBlock, ControlFlowGraph
|
|
27
|
+
from bytecode.cfg import BasicBlock, ControlFlowGraph
|
|
28
28
|
|
|
29
29
|
# import needed to use it in bytecode.py
|
|
30
|
-
from bytecode.concrete import
|
|
31
|
-
|
|
30
|
+
from bytecode.concrete import (
|
|
31
|
+
ConcreteBytecode,
|
|
32
|
+
ConcreteInstr,
|
|
33
|
+
_ConvertBytecodeToConcrete,
|
|
34
|
+
)
|
|
32
35
|
from bytecode.flags import CompilerFlags
|
|
33
36
|
|
|
34
37
|
# import needed to use it in bytecode.py
|
|
35
|
-
from bytecode.instr import (
|
|
38
|
+
from bytecode.instr import (
|
|
36
39
|
UNSET,
|
|
37
40
|
BinaryOp,
|
|
38
41
|
CellVar,
|
|
@@ -180,7 +183,7 @@ def format_bytecode(
|
|
|
180
183
|
for block_index, block in enumerate(bytecode, 1):
|
|
181
184
|
cfg_labels[id(block)] = "block%s" % block_index
|
|
182
185
|
|
|
183
|
-
for
|
|
186
|
+
for block in bytecode:
|
|
184
187
|
buffer.write("%s:\n" % cfg_labels[id(block)])
|
|
185
188
|
seen_instr = False
|
|
186
189
|
for index, instr in enumerate(block):
|