rustpython / rustpython Goto Github PK
View Code? Open in Web Editor NEWA Python Interpreter written in Rust
Home Page: https://rustpython.github.io
License: MIT License
A Python Interpreter written in Rust
Home Page: https://rustpython.github.io
License: MIT License
Somehow it should be easy to port rustpython to the web using the wasm backend of rust. We require a sort of manual / script on how to do this and a nice website which is automatically updated with the latest version of rustpython.
As evidenced by:
$ python -c 'print((1,2) == (1,2))'
True
$ cargo run -- -c 'print((1,2) == (1,2))'
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `/home/daniel/personal_dev/RustPython/target/debug/rustpython -c 'print((1,2) == (1,2))'`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "UnrecognizedToken { token: Some((15, EqEqual, 16)), expected: [\"\\\")\\\"\", \"\\\",\\\"\", \"\\\"in\\\"\", \"\\\"|\\\"\"] }"', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Python allows any hashable object to be used as a key.
To reproduce:
mkdir reproducer
echo "import spam" > reproducer/reproducer.py
touch spam.py
python reproducer/reproducer.py
Traceback (most recent call last):
File "reproducer/reproducer.py", line 1, in <module>
import spam
ModuleNotFoundError: No module named 'spam'
cargo run reproducer/reproducer.py
We, incorrectly, don't error in this situation.
Reproducer:
$ echo 'print(4)' > test.py
$ cargo run test.py
Finished dev [unoptimized + debuginfo] target(s) in 0.09s
Running `target/debug/rustpython test.py`
4
$ echo -n 'print(4)' > test.py
$ cargo run test.py
Finished dev [unoptimized + debuginfo] target(s) in 0.10s
Running `target/debug/rustpython test.py`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "UnrecognizedToken { token: None, expected: [\"\\\"!=\\\"\", \"\\\"%\\\"\", \"\\\"%=\\\"\", \"\\\"&\\\"\", \"\\\"&=\\\"\", \"\\\"(\\\"\", \"\\\")\\\"\", \"\\\"*\\\"\", \"\\\"**\\\"\", \"\\\"**=\\\"\", \"\\\"*=\\\"\", \"\\\"+\\\"\", \"\\\"+=\\\"\", \"\\\",\\\"\", \"\\\"-\\\"\", \"\\\"-=\\\"\", \"\\\".\\\"\", \"\\\"/\\\"\", \"\\\"//\\\"\", \"\\\"//=\\\"\", \"\\\"/=\\\"\", \"\\\":\\\"\", \"\\\"<\\\"\", \"\\\"<<=\\\"\", \"\\\"<=\\\"\", \"\\\"=\\\"\", \"\\\"==\\\"\", \"\\\">\\\"\", \"\\\">=\\\"\", \"\\\">>=\\\"\", \"\\\"@\\\"\", \"\\\"@=\\\"\", \"\\\"[\\\"\", \"\\\"\\\\\\\\n\\\"\", \"\\\"]\\\"\", \"\\\"^\\\"\", \"\\\"^=\\\"\", \"\\\"and\\\"\", \"\\\"as\\\"\", \"\\\"in\\\"\", \"\\\"is\\\"\", \"\\\"not\\\"\", \"\\\"or\\\"\", \"\\\"|\\\"\", \"\\\"|=\\\"\"] }"', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
This is a good instant reward issue ๐
Go to the file vm/src/builtins.rs
and implement the builtin_ord
function.
See the documentation for its description:
file:///usr/share/doc/python/html/library/functions.html#ord
>>>>> class String(str):
..... def foo(self):
..... return "foo"
.....
>>>>> String()
''
>>>>> String().foo()
Traceback (most recent call last):
File <unknown>, line 0, in <module>
AttributeError: RefCell { value: [PyObj class "str"] } object has no attribute foo
>>>>> type(String())
<class 'str'>
Equality is not recommended for usage with None, but it should work.
Currently we will initialise all Rust stdlib modules on start-up; it would be preferable to only load modules once they are actually imported, to reduce the amount of work we do at startup (and memory usage throughout the process).
$ python -c 'print("foo" "bar")'
foobar
$ cargo run -- -c 'print("foo" "bar")' STASH master [ 20:08:55 ]
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `/home/daniel/personal_dev/RustPython/target/debug/rustpython -c 'print("foo" "bar")'`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "UnrecognizedToken { token: Some((14, String { value: \"bar\" }, 18)), expected: [\"\\\"!=\\\"\", \"\\\"%\\\"\", \"\\\"%=\\\"\", \"\\\"&\\\"\", \"\\\"&=\\\"\", \"\\\"(\\\"\", \"\\\")\\\"\", \"\\\"*\\\"\", \"\\\"**\\\"\", \"\\\"**=\\\"\", \"\\\"*=\\\"\", \"\\\"+\\\"\", \"\\\"+=\\\"\", \"\\\",\\\"\", \"\\\"-\\\"\", \"\\\"-=\\\"\", \"\\\".\\\"\", \"\\\"/\\\"\", \"\\\"//\\\"\", \"\\\"//=\\\"\", \"\\\"/=\\\"\", \"\\\":\\\"\", \"\\\";\\\"\", \"\\\"<\\\"\", \"\\\"<<=\\\"\", \"\\\"<=\\\"\", \"\\\"=\\\"\", \"\\\"==\\\"\", \"\\\">\\\"\", \"\\\">=\\\"\", \"\\\">>=\\\"\", \"\\\"@\\\"\", \"\\\"@=\\\"\", \"\\\"[\\\"\", \"\\\"\\\\\\\\n\\\"\", \"\\\"]\\\"\", \"\\\"^\\\"\", \"\\\"^=\\\"\", \"\\\"and\\\"\", \"\\\"as\\\"\", \"\\\"in\\\"\", \"\\\"is\\\"\", \"\\\"not\\\"\", \"\\\"or\\\"\", \"\\\"|\\\"\", \"\\\"|=\\\"\"] }"', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
When I execute cargo run
and type 1<ENTER>
on the REPL, the parser crashes:
Welcome to the magnificent Rust Python 0.0.1 interpreter
>>>>> 1
thread 'main' panicked at 'Not impl Some('\r')', parser\src\lexer.rs:582:21
This is somehow related to Windows newlines (\r\n
), so I'll try to come up with a PR which fixes this issue on Windows.
Running the locals builtin function causes a type exception
>>>>> locals()
thread 'main' panicked at 'Object doesn't have a type!', vm/src/pyobject.rs:379:21
At the moment, any functions which take a variable number of arguments haven't been updated to use arg_check!
because it doesn't support it.
Currently we emit instructions to build a tuple, but the contents are constant, so we can just emit the constructed tuple.
This is causing tests/snippets/perf_fib.py
to fail.
Good first issue! Go to the file vm/src/builtins.rs and implement the max
function.
It could be argued that bytecode objects may refer to python objects which are immutable, such as tuples, None and integers.
This would mean that the bytecode::Constant enum would disappear:
https://github.com/RustPython/RustPython/blob/master/vm/src/bytecode.rs#L113
This would also mean that the bytecode class becomes depending upon the vm. This might be a downside, so we cannot separate the bytecode package into a seperate package, but on the other hand, I like the idea of referring to PyObjectRef objects straight from bytecode.
This is a voting issue, what do you think?
If I want to write:
if __name__ == "__main__":
print("Hello, world!")
I can run this with Python3 but not with RustPython. It fails with this error:
emacs-mbp% cargo run --release test.py
Finished release [optimized] target(s) in 0.11s
Running `target/release/rustpython test.py`
Traceback (most recent call last):
File test.py, line 1, in <module>
NameError: Has not attribute '__name__'
thread 'main' panicked at 'Exception: RefCell { value: [PyObj instance] }', src/main.rs:69:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.
emacs-mbp%
Captured from review comment on #89.
We currently treat them as a TypeError, but CPython rejects them as invalid syntax.
(This issue will be introduced in #115, but is small enough for me to come back and fix it after that has landed.)
So that we aren't reloading them every time we import a new stdlib module.
(Captured from review comments on #89.)
We need converters from cpython's bytecode into rustpython bytecode. The sourcefile can be found in py_code_object/src/convert.rs
. The idea is to take cpython bytecode (which differs per cpython version) and convert it into rustpython bytecode.
cargo run
is failing on my windows 7 machine.
I am using rust 1.26. I am getting this error
error[E0658]: use of unstable library feature 'iterator_step_by': unstable replacement of Range::step_by (see issue #27741)
--> vm\src\obj\objsequence.rs:56:34
|
56 | self[start..stop].iter().step_by(step).cloned().collect()
| ^^^^^^^
error[E0658]: use of unstable library feature 'iterator_step_by': unstable replacement of Range::step_by (see issue #27741)
--> vm\src\obj\objstr.rs:220:35
|
220 | self[start..stop].chars().step_by(step).collect()
| ^^^^^^^
error: aborting due to 2 previous errors.
The active toolchain is stable-x86_64-pc-windows-msvc (default).
In objint.rs
we have:
pub fn get_value(obj: PyObjectRef) -> i32 {
but in objstr.rs
we have:
pub fn get_value(obj: &PyObjectRef) -> String {
Obviously return types are going to be different, but having the same calling convention would be good.
Need to implement this code generator https://github.com/RustPython/RustPython/blob/master/parser/src/compiler/compile_py_code_object.rs
you can use the compile.rs file in the same folder as a reference.
It omits quotes:
$ cargo run -- -c 'print([""])'
[]
$ cargo run -- -c 'print(["", "a", "b"])'
[, a, b]
Which they should be.
I've started looking at this, so creating the issue so people are aware.
For this project we will need a good artwork / logo design.
Eg:
Ok(PyObject::new(kind, vm.get_type()))
(Where kind could be any PyObjectKind.)
These objects can no longer be compared for equality.
We can make a crate for traits of the bytecode protocol, then we can implement features like dumping the bytecode or other debugging tool around it.
This is gonna be some sort of a poll. So the question is, how to write proper documentation for this project. Both rust and python have documentation options. For rust, there appears to be some rust format tool, which is the default. For python there is readthedocs and sphinx.
I now see the following options:
Proposals are welcome, we can vote them with the like options!
This doesn't match regular Python behaviour (and is what is causing tests/snippets/function_args.py
to fail).
It would be nice if we could run this code somehow on top of redox os (https://www.redox-os.org/)
$ cargo run -- -c 'print("""foo""")'
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `/home/daniel/personal_dev/RustPython/target/debug/rustpython -c 'print("""foo""")'`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "UnrecognizedToken { token: Some((10, String { value: \"foo\" }, 14)), expected: [\"\\\"!=\\\"\", \"\\\"%\\\"\", \"\\\"%=\\\"\", \"\\\"&\\\"\", \"\\\"&=\\\"\", \"\\\"(\\\"\", \"\\\")\\\"\", \"\\\"*\\\"\", \"\\\"**\\\"\", \"\\\"**=\\\"\", \"\\\"*=\\\"\", \"\\\"+\\\"\", \"\\\"+=\\\"\", \"\\\",\\\"\", \"\\\"-\\\"\", \"\\\"-=\\\"\", \"\\\".\\\"\", \"\\\"/\\\"\", \"\\\"//\\\"\", \"\\\"//=\\\"\", \"\\\"/=\\\"\", \"\\\":\\\"\", \"\\\";\\\"\", \"\\\"<\\\"\", \"\\\"<<=\\\"\", \"\\\"<=\\\"\", \"\\\"=\\\"\", \"\\\"==\\\"\", \"\\\">\\\"\", \"\\\">=\\\"\", \"\\\">>=\\\"\", \"\\\"@\\\"\", \"\\\"@=\\\"\", \"\\\"[\\\"\", \"\\\"\\\\\\\\n\\\"\", \"\\\"]\\\"\", \"\\\"^\\\"\", \"\\\"^=\\\"\", \"\\\"and\\\"\", \"\\\"as\\\"\", \"\\\"in\\\"\", \"\\\"is\\\"\", \"\\\"not\\\"\", \"\\\"or\\\"\", \"\\\"|\\\"\", \"\\\"|=\\\"\"] }"', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Note that the unrecognized token is "foo"
, so the first ""
of the opening quotes have been parsed as the empty string (which shouldn't be immediately followed by another string, hence the error).
This is due to lalrpop's dependency on petgraph; a new version of petgraph has been released to address the issue and fixing it in lalrpop is being tracked at lalrpop/lalrpop#400
Create a prototype on how to interact with a python library with a C-API extension.
See also:
https://pythoncapi.readthedocs.io/
There are some questions regarding C extensions. Primary question: how to handle this? Maybe in a similar way to cpyext?
This is a large task. Head over to vm/src/builtins.rs
and implement the builtin_format
function. Try to start with a simple example and extend from there.
Also add a snippet in the tests/snippets
directory to test your implementation.
CPython:
>>> True is True
True
>>> False is False
True
>>> t = not False
>>> t is True
True
>>> t is False
False
RustPython:
>>>>> True is True
False
>>>>> False is False
False
>>>>> t = not False
>>>>> t is True
False
>>>>> t is False
False
Both of these statements cause panics:
print(int(1))
print(float(1.0))
when they should be supported. The panics look like this:
thread 'main' panicked at 'Inner error getting int', vm/src/objint.rs:19:9
(This also stops int/float subclasses from being usable; there's no way to instantiate them.)
The standard library is now located in the Lib
folder. Many modules are still missing (if not all).
If you would like to contribute, this is an easy start. Have a look at the cpython or pypy standard library. Take care about eventual copy rights.
#54 implements most (perhaps all?) of the import syntax, but it doesn't include support for relative imports (e.g. from .foo import bar
, from ..spam import eggs
).
There are four math functions which are pretty complex.
math.erf
math.erfc
math.gamma
math.lgamma
They are implemented in cpython, as can be seen here:
https://github.com/python/cpython/blob/master/Modules/mathmodule.c#L113
The documentation is listed here:
https://docs.python.org/3/library/math.html#special-functions
In rust python, they must be implemented in vm/src/stdlib/math.rs
.
This should work, but doesn't:
int.__new__(int, 5)
I think type.__new__
gets called instead of int.__new__
, given this:
>>>>> object.__new__(object)
<class 'type'>
I was pretty sure there was a problem with getattribute, but I've been waiting for a good example to fix.
The top level project should be able to just cargo run file.py
We need to:
parser
and VM
cratesVM
-compatiable bytecodesrc
$ python -c 'if (1,2) == (1,2): print("matching")'
matching
$ cargo run -- -c 'if (1,2) == (1,2): print("matching")'
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `/home/daniel/personal_dev/RustPython/target/debug/rustpython -c 'if (1,2) == (1,2): print("matching")'`
thread 'main' panicked at 'TypeError in COMPARE_OP: can't compare [PyObj tuple] with [PyObj tuple]', vm/src/pyobject.rs:595:18
note: Run with `RUST_BACKTRACE=1` for a backtrace.
This code:
x = 1
print(type(x))
print(type(x-1))
produces this output:
<class 'int'>
<class 'type'>
This is caused by VirtualMachine._sub
(and its compatriots) using self.get_type()
as the type of the new object, rather than using the type information from the arguments.
Add support for keyword arguments.
Right now, while it is implicitly understood we are targeting Python-3, it's a good idea to be explicit about it. At-least README.md should be updated to mention this.
This should also help us target compliance, Python's Test suits etc.
$ python -c 'print((1,))'
(1,)
$ cargo run -- -c 'print((1,))'
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `/home/daniel/personal_dev/RustPython/target/debug/rustpython -c 'print((1,))'`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "UnrecognizedToken { token: Some((0, Rpar, 0)), expected: [\"\\\"(\\\"\", \"\\\"+\\\"\", \"\\\"-\\\"\", \"\\\"False\\\"\", \"\\\"None\\\"\", \"\\\"True\\\"\", \"\\\"[\\\"\", \"\\\"lambda\\\"\", \"name\", \"number\", \"string\"] }"', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.