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.
Files changed (67) hide show
  1. {bytecode-0.15.1 → bytecode-0.16.1}/.coveragerc +0 -2
  2. {bytecode-0.15.1 → bytecode-0.16.1}/.github/workflows/cis.yml +7 -6
  3. {bytecode-0.15.1 → bytecode-0.16.1}/.github/workflows/docs.yml +1 -2
  4. {bytecode-0.15.1 → bytecode-0.16.1}/.github/workflows/frameworks.yml +2 -3
  5. {bytecode-0.15.1 → bytecode-0.16.1}/.github/workflows/release.yml +54 -39
  6. bytecode-0.16.1/.pre-commit-config.yaml +16 -0
  7. {bytecode-0.15.1/src/bytecode.egg-info → bytecode-0.16.1}/PKG-INFO +8 -7
  8. {bytecode-0.15.1 → bytecode-0.16.1}/README.rst +5 -5
  9. {bytecode-0.15.1 → bytecode-0.16.1}/doc/cfg.rst +12 -12
  10. {bytecode-0.15.1 → bytecode-0.16.1}/doc/changelog.rst +30 -0
  11. {bytecode-0.15.1 → bytecode-0.16.1}/doc/usage.rst +10 -9
  12. bytecode-0.16.1/pyproject.toml +84 -0
  13. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/__init__.py +16 -13
  14. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/bytecode.py +4 -7
  15. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/cfg.py +28 -23
  16. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/concrete.py +204 -110
  17. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/flags.py +108 -58
  18. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/instr.py +96 -46
  19. bytecode-0.16.1/src/bytecode/utils.py +7 -0
  20. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/version.py +2 -2
  21. {bytecode-0.15.1 → bytecode-0.16.1/src/bytecode.egg-info}/PKG-INFO +8 -7
  22. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode.egg-info/SOURCES.txt +1 -1
  23. {bytecode-0.15.1 → bytecode-0.16.1}/tests/__init__.py +1 -1
  24. {bytecode-0.15.1 → bytecode-0.16.1}/tests/cell_free_vars_cases.py +16 -1
  25. bytecode-0.16.1/tests/frameworks/module.py +259 -0
  26. bytecode-0.16.1/tests/frameworks/sitecustomize.py +132 -0
  27. {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_bytecode.py +106 -8
  28. {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_cfg.py +41 -14
  29. {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_concrete.py +117 -20
  30. {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_flags.py +96 -40
  31. {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_instr.py +32 -19
  32. {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_misc.py +45 -4
  33. bytecode-0.16.1/tox.ini +37 -0
  34. bytecode-0.15.1/.pre-commit-config.yaml +0 -17
  35. bytecode-0.15.1/pyproject.toml +0 -78
  36. bytecode-0.15.1/setup.py +0 -27
  37. bytecode-0.15.1/tests/frameworks/module.py +0 -203
  38. bytecode-0.15.1/tests/frameworks/sitecustomize.py +0 -34
  39. bytecode-0.15.1/tox.ini +0 -47
  40. {bytecode-0.15.1 → bytecode-0.16.1}/.github/FUNDING.yml +0 -0
  41. {bytecode-0.15.1 → bytecode-0.16.1}/.github/dependabot.yml +0 -0
  42. {bytecode-0.15.1 → bytecode-0.16.1}/.gitignore +0 -0
  43. {bytecode-0.15.1 → bytecode-0.16.1}/.readthedocs.yaml +0 -0
  44. {bytecode-0.15.1 → bytecode-0.16.1}/COPYING +0 -0
  45. {bytecode-0.15.1 → bytecode-0.16.1}/MANIFEST.in +0 -0
  46. {bytecode-0.15.1 → bytecode-0.16.1}/TODO.rst +0 -0
  47. {bytecode-0.15.1 → bytecode-0.16.1}/codecov.yml +0 -0
  48. {bytecode-0.15.1 → bytecode-0.16.1}/doc/Makefile +0 -0
  49. {bytecode-0.15.1 → bytecode-0.16.1}/doc/api.rst +0 -0
  50. {bytecode-0.15.1 → bytecode-0.16.1}/doc/byteplay_codetransformer.rst +0 -0
  51. {bytecode-0.15.1 → bytecode-0.16.1}/doc/conf.py +0 -0
  52. {bytecode-0.15.1 → bytecode-0.16.1}/doc/index.rst +0 -0
  53. {bytecode-0.15.1 → bytecode-0.16.1}/doc/make.bat +0 -0
  54. {bytecode-0.15.1 → bytecode-0.16.1}/doc/requirements.txt +0 -0
  55. {bytecode-0.15.1 → bytecode-0.16.1}/doc/todo.rst +0 -0
  56. {bytecode-0.15.1 → bytecode-0.16.1}/scripts/frameworks/boto3/run.sh +0 -0
  57. {bytecode-0.15.1 → bytecode-0.16.1}/scripts/frameworks/boto3/setup.sh +0 -0
  58. {bytecode-0.15.1 → bytecode-0.16.1}/setup.cfg +0 -0
  59. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode/py.typed +0 -0
  60. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode.egg-info/dependency_links.txt +0 -0
  61. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode.egg-info/requires.txt +0 -0
  62. {bytecode-0.15.1 → bytecode-0.16.1}/src/bytecode.egg-info/top_level.txt +0 -0
  63. {bytecode-0.15.1 → bytecode-0.16.1}/tests/exception_handling_cases.py +0 -0
  64. {bytecode-0.15.1 → bytecode-0.16.1}/tests/frameworks/function.py +0 -0
  65. {bytecode-0.15.1 → bytecode-0.16.1}/tests/long_lines_example.py +0 -0
  66. {bytecode-0.15.1 → bytecode-0.16.1}/tests/test_code.py +0 -0
  67. {bytecode-0.15.1 → bytecode-0.16.1}/tests/util_annotation.py +0 -0
@@ -1,7 +1,5 @@
1
1
  [run]
2
2
  branch = True
3
- omit =
4
- setup.py
5
3
 
6
4
  [paths]
7
5
  source =
@@ -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@v4
25
+ uses: actions/setup-python@v5
27
26
  with:
28
- python-version: "3.10"
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-dev"
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@v4
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@v3
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@v4
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@v4
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@v4
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@v3
36
+ uses: actions/upload-artifact@v4
37
37
  with:
38
- name: artifact
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@v4
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@v3
66
+ uses: actions/upload-artifact@v4
67
67
  with:
68
- name: artifact
68
+ name: cibw-wheel
69
69
  path: dist/*.whl
70
70
 
71
- release_upload:
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
- - uses: actions/download-artifact@v3
76
+ - name: Download all the dists
77
+ uses: actions/download-artifact@v4.1.8
106
78
  with:
107
- name: artifact
79
+ pattern: cibw-*
108
80
  path: dist
81
+ merge-multiple: true
109
82
 
110
- - uses: pypa/gh-action-pypi-publish@master
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
1
+ Metadata-Version: 2.2
2
2
  Name: bytecode
3
- Version: 0.15.1
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/code%20style-black-000000.svg
71
- :alt: Code formatted using Black
72
- :target: https://github.com/psf/black
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("LOAD_NAME", 'print'),
96
+ bytecode = Bytecode([Instr("LOAD_GLOBAL", (True, 'print')),
96
97
  Instr("LOAD_CONST", 'Hello World!'),
97
- Instr("CALL_FUNCTION", 1),
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/code%20style-black-000000.svg
22
- :alt: Code formatted using Black
23
- :target: https://github.com/psf/black
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("LOAD_NAME", 'print'),
46
+ bytecode = Bytecode([Instr("LOAD_GLOBAL", (True, 'print')),
47
47
  Instr("LOAD_CONST", 'Hello World!'),
48
- Instr("CALL_FUNCTION", 1),
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('LOAD_NAME', 'print'),
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('CALL_FUNCTION', 1),
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
- LOAD_NAME 'print'
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
- CALL_FUNCTION 1
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('LOAD_NAME', 'print'),
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('CALL_FUNCTION', 1),
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
- LOAD_NAME 'print'
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
- CALL_FUNCTION 1
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('LOAD_NAME', 'print'),
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('CALL_FUNCTION', 1),
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
- LOAD_NAME 'print'
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
- CALL_FUNCTION 1
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("LOAD_NAME", 'print'),
25
+ bytecode = Bytecode([Instr("LOAD_GLOBAL", (True, 'print')),
26
26
  Instr("LOAD_CONST", 'Hello World!'),
27
- Instr("CALL_FUNCTION", 1),
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("LOAD_NAME", 0),
49
+ bytecode.extend([ConcreteInstr("LOAD_GLOBAL", 1),
50
50
  ConcreteInstr("LOAD_CONST", 0),
51
- ConcreteInstr("CALL_FUNCTION", 1),
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("LOAD_NAME", "print"),
113
+ Instr("LOAD_GLOBAL", (True, "print")),
114
114
  Instr("LOAD_NAME", "x"),
115
- Instr("CALL_FUNCTION", 1),
115
+ Instr("CALL", 1),
116
116
  Instr("POP_TOP"),
117
- Instr("JUMP_ABSOLUTE", loop_start),
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('LOAD_NAME', 'print'),
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('CALL_FUNCTION', 1),
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
- "Label",
3
- "Instr",
4
- "SetLineno",
2
+ "BinaryOp",
5
3
  "Bytecode",
6
- "ConcreteInstr",
4
+ "Compare",
5
+ "CompilerFlags",
7
6
  "ConcreteBytecode",
7
+ "ConcreteInstr",
8
8
  "ControlFlowGraph",
9
- "CompilerFlags",
10
- "Compare",
11
- "BinaryOp",
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 ( # noqa
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 # noqa
27
+ from bytecode.cfg import BasicBlock, ControlFlowGraph
28
28
 
29
29
  # import needed to use it in bytecode.py
30
- from bytecode.concrete import _ConvertBytecodeToConcrete # noqa
31
- from bytecode.concrete import ConcreteBytecode, ConcreteInstr
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 ( # noqa
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 block_index, block in enumerate(bytecode, 1):
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):