Skip to main content

TravisCI CircleCI

x-python

This is a CPython bytecode interpreter written Python.

You can use this to:

  • Learn about how the internals of CPython works since this models that

  • Experiment with additional opcodes, or ways to change the run-time environment

  • Use as a sandboxed environment for trying pieces of execution

  • Have one Python program that runs multiple versions of Python bytecode. For a number of things you can run Python 2.5 or 2.6 bytecode from inside Python 3.7; No need to install Python 2.5 or 2.6!

  • Use in a dynamic fuzzer or in coholic execution for analysis

The sandboxed environment in a debugger I find interesting. Since there is a separate execution, and traceback stack, inside a debugger you can try things out in the middle of a debug session without effecting the real execution. On the other hand if a sequence of executions works out, it is possible to copy this (under certain circumstances) back into CPython’s execution stack.

Going the other way, I may at some point hook in my debugger into this interpreter and then you’ll have a conventional pdb/gdb like debugger also with the ability to step bytecode instructions.

I may also experiment with faster ways to support trace callbacks such as those used in a debugger. In particular I may add a BREAKPOINT instruction to support fast breakpoints and breakpointing on a particular instruction that doesn’t happen to be on a line boundary.

Although this is far in the future, suppose you to add a race detector? It might be easier to prototype it in Python here. (This assumes the interpreter supports threading well, I suspect it doesn’t)

Another unexplored avenue implied above is mixing interpretation and direct CPython execution. In fact, there are bugs so this happens right now, but it will be turned into a feature. Some functions or classes you may want to not run under a slow interpreter while others you do want to run under the interpreter.

Examples:

What to know instructions get run when you write some simple code? Try this:

$ xpython -vc "x, y = 2, 3; x **= y"
INFO:xpython.vm:L. 1   @  0: LOAD_CONST (2, 3)
INFO:xpython.vm:       @  2: UNPACK_SEQUENCE 2
INFO:xpython.vm:       @  4: STORE_NAME x
INFO:xpython.vm:       @  6: STORE_NAME y
INFO:xpython.vm:L. 1   @  8: LOAD_NAME x
INFO:xpython.vm:       @ 10: LOAD_NAME y
INFO:xpython.vm:       @ 12: INPLACE_POWER
INFO:xpython.vm:       @ 14: STORE_NAME x
INFO:xpython.vm:       @ 16: LOAD_CONST None
INFO:xpython.vm:       @ 18: RETURN_VALUE

Option -c is the same as Python’s flag (program passed in as string) and -v is also analogus Python’s flag. Here, it shows the bytecode instructions run.

Want the execution stack stack and block stack in addition? Add another v:

$ xpython -vvc "x, y = 2, 3; x **= y"

DEBUG:xpython.vm:make_frame: code=<code object <module> at 0x7f7acd353420, file "<string x, y = 2, 3; x **= y>", line 1>, callargs={}, f_globals=(<class 'dict'>, 140165406216272), f_locals=(<class 'NoneType'>, 94599533407680)
DEBUG:xpython.vm:<Frame at 0x7f7acd322650: '<string x, y = 2, 3; x **= y>':1 @-1>
DEBUG:xpython.vm:  frame.stack: []
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:L. 1   @  0: LOAD_CONST (2, 3) <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: [(2, 3)]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @  2: UNPACK_SEQUENCE 2 <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: [3, 2]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @  4: STORE_NAME x <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: [3]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @  6: STORE_NAME y <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: []
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:L. 1   @  8: LOAD_NAME x <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: [2]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 10: LOAD_NAME y <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: [2, 3]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 12: INPLACE_POWER  <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: [8]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 14: STORE_NAME x <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: []
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 16: LOAD_CONST None <module> in <string x, y = 2, 3; x **= y>:1
DEBUG:xpython.vm:  frame.stack: [None]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 18: RETURN_VALUE  <module> in <string x, y = 2, 3; x **= y>:1

The above showed straight-line code, so you see all of the instructions. But don’t confuse this with a disassembler like pydisasm from xdis. The below example, with conditional branching example makes this more clear:

$ xpython -vvc "x = 6 if __name__ != '__main__' else 10"
DEBUG:xpython.vm:make_frame: code=<code object <module> at 0x7fd8061cd270, file "<string x = 6 if __name__ !=>", line 1>, callargs={}, f_globals=(<class 'dict'>, 140565793497328), f_locals=(<class 'NoneType'>, 94471841324480)
DEBUG:xpython.vm:<Frame at 0x7fd8061d1490: '<string x = 6 if __name__ !=>':1 @-1>
DEBUG:xpython.vm:  frame.stack: []
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:L. 1   @  0: LOAD_NAME __name__ <module> in <string x = 6 if __name__ !=>:1
DEBUG:xpython.vm:  frame.stack: ['__main__']
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @  2: LOAD_CONST __main__ <module> in <string x = 6 if __name__ !=>:1
DEBUG:xpython.vm:  frame.stack: ['__main__', '__main__']
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @  4: COMPARE_OP 3 <module> in <string x = 6 if __name__ !=>:1
DEBUG:xpython.vm:  frame.stack: [False]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @  6: POP_JUMP_IF_FALSE 12 <module> in <string x = 6 if __name__ !=>:1
DEBUG:xpython.vm:  frame.stack: []
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 12: LOAD_CONST 10 <module> in <string x = 6 if __name__ !=>:1
DEBUG:xpython.vm:  frame.stack: [10]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 14: STORE_NAME x <module> in <string x = 6 if __name__ !=>:1
DEBUG:xpython.vm:  frame.stack: []
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 16: LOAD_CONST None <module> in <string x = 6 if __name__ !=>:1
DEBUG:xpython.vm:  frame.stack: [None]
DEBUG:xpython.vm:  blocks     : []
INFO:xpython.vm:       @ 18: RETURN_VALUE  <module> in <string x = 6 if __name__ !=>:1

Status:

Currently bytecode from Python versions 3.7 - 3.2, and 2.7 - 2.5 are supported. We also support PyPy bytecode. Until there is more interest or I get help or funding, extending to 3.8 and beyond is on hold.

xdis eases the difficulty of cross-version interpretation, expanding to handle multiple Python versions, and printing instructions.

Whereas Byterun was a bit loose in accepting bytecode opcodes that is invalid for particular Python but may be valid for another; x-python is more stringent. This has pros and cons. On the plus side Byterun might run certain Python 3.4 bytecode because the opcode sets are similar. However starting with Python 3.5 and beyond the likelihood gets much less because, while the underlying opcode names may be the same, the semantics of the operation may change subtely. See for example https://github.com/nedbat/byterun/issues/34.

Internally Byterun needs the kind of overhaul we have here to be able to scale to support bytecode for more Pythons, and to be able to run bytecode across different versions of Python. Specifically, you can’t rely on Python’s dis module if you expect to expect to run a bytecode other than the bytecode that the interpreter is running.

In x-python there is a clear distinction between the version being interpreted and the version of Python that is running. There is tighter control of opcodes and an opcode’s implementation is kept for each Python version. So we’ll warn early when something is invalid. You can run 3.3 bytecode using Python 3.7 (largely).

The “largely” part is because the interpreter has always made use of Python builtins. When a Python version running the interperter matches a supported bytecode close enough, the interpreter can (and does) make use interpreter internals. For example, built-in functions like range() are supported this way.

Currently running 2.7 bytecode on 3.x is often not feasible since the runtime and internal libraries used like inspect are too different.

Over time more of Python’s internals may get added so we have better cross-version compatability, so that is a possibility. Harder is to run later byecode from earlier Python versions. The callenge here is that many new features like asynchronous I/O and concurrency primatives are not in the older versions and may not easily be simulated. However that too is a possibility if there is interest.

You can run many of the tests that Python uses to test itself, and those work. Right now this program works best on Python up to 3.4 when life in Python was much simpler. It runs over 300 in Python’s test suite for itself without problems.

Moving back and forward from 3.4 things worse. Python 3.5 is pretty good. Python 3.6 and 3.7 is okay but needs work.

History

This is a fork of Byterun. which is a pure-Python implementation of a Python bytecode execution virtual machine. Net Batchelder started it (based on work from Paul Swartz) to get a better understanding of bytecodes so he could fix branch coverage bugs in coverage.py.

Metadata

Release files for x-python 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for x-python 1.2.0
File Size Uploaded
x-python-1.2.0.tar.gz 109.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for x-python 1.2.0
File
x_python-1.2.0-py3.7.egg Legacy Egg format - - Details
x_python-1.2.0-py3.6.egg Legacy Egg format - - Details
x_python-1.2.0-py3.5.egg Legacy Egg format - - Details
x_python-1.2.0-py3.4.egg Legacy Egg format - - Details
x_python-1.2.0-py3.3.egg Legacy Egg format - - Details
x_python-1.2.0-py3.2.egg Legacy Egg format - - Details
x_python-1.2.0-py3-none-any.whl Python 3 none any Details
x_python-1.2.0-py2.7.egg Legacy Egg format - - Details
x_python-1.2.0-py2-none-any.whl Python 2 none any Details

Total release size: 1.0 MB

Release files / x-python-1.2.0.tar.gz

Download URL x-python-1.2.0.tar.gz
Size 109.4 kB
Tags Source
SHA-256 checksum
How to use checksums
6cb754891a6948575e3dd4c98777cc86173705838efb546e8d8df51d1e52d912
BLAKE2b-256 checksum
How to use checksums
a28cf5a6b214141002be87941570af0195a38f0aebb018eae9282355fe0eb60e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py3.7.egg

Download URL x_python-1.2.0-py3.7.egg
Size 111.1 kB
Tags Egg
SHA-256 checksum
How to use checksums
0000beccebe0ea969faac56c817f6b21ccca0d29335741f5ef3a55bf2dfa038d
BLAKE2b-256 checksum
How to use checksums
1eeca9aa75e7aa17ffd003f275438dfc5b299447d4d03af93e150aa33bbff5fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py3.6.egg

Download URL x_python-1.2.0-py3.6.egg
Size 111.0 kB
Tags Egg
SHA-256 checksum
How to use checksums
70ce35baaec92e9f9f63a5fe158c91209ac5e05e27674abebca870b9692e4139
BLAKE2b-256 checksum
How to use checksums
7bb92dd1b4c58a23d85ab870dff86653599598bbf36a3d32406e0825040cf05c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py3.5.egg

Download URL x_python-1.2.0-py3.5.egg
Size 112.5 kB
Tags Egg
SHA-256 checksum
How to use checksums
5a2a5e6ee861f21d9de79d65ef436336c78b8d407ba75850a2060453a7690b05
BLAKE2b-256 checksum
How to use checksums
ded9e28d1b99019be00f3187fc6af5c0c6b654265735ca798ffd9169fc3cfc24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py3.4.egg

Download URL x_python-1.2.0-py3.4.egg
Size 112.8 kB
Tags Egg
SHA-256 checksum
How to use checksums
b092b797ea1855f73cc68959194dd2b6d2922baddd94c2b4291c3b83622347fd
BLAKE2b-256 checksum
How to use checksums
627231b675695549e4fa353828aea4b7fd80e43e356ca3cab21b8d772bdaa890
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py3.3.egg

Download URL x_python-1.2.0-py3.3.egg
Size 114.3 kB
Tags Egg
SHA-256 checksum
How to use checksums
7c104ba8fb01296a91a62f9d6ac86c3c52613faf2167407091ebe18a66d5b013
BLAKE2b-256 checksum
How to use checksums
e15e421dbb08b068e235c29b7c71c00b1f0afbdc871378aa0d81d64db5b63ae2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py3.2.egg

Download URL x_python-1.2.0-py3.2.egg
Size 112.1 kB
Tags Egg
SHA-256 checksum
How to use checksums
80d81ee46746aa7c573dde70b8438f3e951a134f46646518eba1fc9d27c43e53
BLAKE2b-256 checksum
How to use checksums
c1521d4abd46d50a001e536b1b55ff0f85109bd68c44a2c93af07734137206ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py3-none-any.whl

Download URL x_python-1.2.0-py3-none-any.whl
Size 53.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e776fd79818b67e490b9b005b4ff526b5efc73f327c280ed28f778afc4c1a144
BLAKE2b-256 checksum
How to use checksums
917f9a88ff0a9d5f2224c55d47727bf1b1c1a74987cda8493d2003342eda72f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py2.7.egg

Download URL x_python-1.2.0-py2.7.egg
Size 110.5 kB
Tags Egg
SHA-256 checksum
How to use checksums
27ca142d35739d99393a72f8b17c89222fa4a6665688a4cd369fa9e88e8ce0d9
BLAKE2b-256 checksum
How to use checksums
1aba62fa94bbab203604e779a8e6f4eb5f3f9455eb062047cca7d53a20f998db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release files / x_python-1.2.0-py2-none-any.whl

Download URL x_python-1.2.0-py2-none-any.whl
Size 53.9 kB
Tags Python 2
SHA-256 checksum
How to use checksums
cd43070393733751c196b5e544f6bc801bbd7d369c3f377c0623e013e936d3ad
BLAKE2b-256 checksum
How to use checksums
e84f41b155582bba09734322355e3c9cf7ea42c938129a049e74dd4c51a833d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.7

Release history Release notifications | RSS feed

1.5.3

3 release files

1.5.1

6 release files

1.5.0

16 release files

1.4.0

7 release files

1.3.5

10 release files

1.3.4

10 release files

1.3.3

10 release files

1.3.1

9 release files

1.3.0

1 release file

1.2.1

10 release files

This release

1.2.0 This release

10 release files

1.0.1

8 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page