Skip to content

Commit 0467a59

Browse files
authored
Merge pull request #7 from arihant2math/updates
Update docs
2 parents 8d70ae4 + 773c41a commit 0467a59

File tree

9 files changed

+303
-47
lines changed

9 files changed

+303
-47
lines changed

Diff for: src/SUMMARY.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# Summary
22

3-
- [Introduction](./intro.md)
4-
- [Writing Functions](./writing_functions.md)
3+
- [Introduction](introduction/index.md)
4+
- [Getting Started](getting_started/index.md)
5+
- [Installation](getting_started/installation.md)
6+
- [Initial Setup](getting_started/initial_setup.md)
7+
- [Interop](interop/index.md)
8+
- [Calling Rust from Python](interop/rust_from_python.md)
9+
- [Calling Python from Rust](interop/python_from_rust.md)

Diff for: src/getting_started/index.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Getting Started
2+
3+
- [Installation](./installation.md)
4+
- [Initial Setup](./initial_setup.md)

Diff for: src/getting_started/initial_setup.md

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Initial Setup
2+
3+
First `rustpython_vm` needs to be imported.
4+
If `rustpython` is installed, it can be imported as a re-export:
5+
```rust
6+
use rustpython::vm;
7+
```
8+
9+
if `rustpython_vm` is installed, it can be imported just like any other module.
10+
11+
```rust
12+
use rustpython::vm;
13+
14+
fn main() -> vm::PyResult<()> {
15+
vm::Interpreter::without_stdlib(Default::default()).enter(|vm| {
16+
let scope = vm.new_scope_with_builtins();
17+
let source = r#"print("Hello World!")"#;
18+
let code_obj = vm
19+
.compile(source, vm::compiler::Mode::Exec, "<embedded>".to_owned())
20+
.map_err(|err| vm.new_syntax_error(&err, Some(source)))?;
21+
22+
vm.run_code_obj(code_obj, scope)?;
23+
24+
Ok(())
25+
})
26+
}
27+
```
28+
29+
This will print `Hello World!` to the console.
30+
31+
## Adding the standard library
32+
If the `stdlib` feature is enabled,
33+
the standard library can be added to the interpreter by calling `add_native_modules`
34+
with the result of `rustpython_stdlib::get_module_inits()`.
35+
```rust
36+
use rustpython::vm as vm;
37+
use std::process::ExitCode;
38+
use vm::{Interpreter, builtins::PyStrRef};
39+
40+
fn py_main(interp: &Interpreter) -> vm::PyResult<PyStrRef> {
41+
interp.enter(|vm| {
42+
let scope = vm.new_scope_with_builtins();
43+
let source = r#"print("Hello World!")"#;
44+
let code_obj = vm
45+
.compile(source, vm::compiler::Mode::Exec, "<embedded>".to_owned())
46+
.map_err(|err| vm.new_syntax_error(&err, Some(source)))?;
47+
48+
vm.run_code_obj(code_obj, scope)?;
49+
})
50+
}
51+
52+
fn main() -> ExitCode {
53+
// Add standard library path
54+
let mut settings = vm::Settings::default();
55+
settings.path_list.push("Lib".to_owned());
56+
let interp = vm::Interpreter::with_init(settings, |vm| {
57+
vm.add_native_modules(rustpython_stdlib::get_module_inits());
58+
});
59+
let result = py_main(&interp);
60+
let result = result.map(|result| {
61+
println!("name: {result}");
62+
});
63+
ExitCode::from(interp.run(|_vm| result))
64+
}
65+
```
66+
67+
to import a module, the following code can be used:
68+
```rust, no_run
69+
// Add local library path
70+
vm.insert_sys_path(vm.new_pyobj("<module_path>"))
71+
.expect("add examples to sys.path failed");
72+
let module = vm.import("<module_name>", 0)?;
73+
```

Diff for: src/getting_started/installation.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Installation
2+
## Requirements
3+
RustPython requires Rust latest stable version to be installed
4+
5+
## Stable
6+
The latest stable version of the library can be installed using the following command:
7+
```bash
8+
cargo add rustpython
9+
```
10+
11+
or by adding the following to your `Cargo.toml`:
12+
```toml
13+
[dependencies]
14+
rustpython = "0.4"
15+
```
16+
17+
## Nightly
18+
Nightly releases are built weekly and are released on git.
19+
```toml
20+
[dependencies]
21+
rustpython = { git = "https://github.com/RustPython/RustPython", tag = "2025-02-24-main-13" }
22+
```
23+
24+
The tag should be pointed to the latest tag found at https://github.com/RustPython/RustPython/tags.
25+
26+
## Features
27+
By default `threading`, `stdlib`, and `importlib` are enabled.
28+
### `bz2`
29+
If you'd like to use the `bz2` module, you can enable the `bz2` feature.
30+
### `stdlib`
31+
`stdlib` is the default feature that enables the standard library.
32+
### `sqlite`
33+
If you'd like to use the `sqlite3` module, you can enable the `sqlite` feature.
34+
### `ssl`
35+
If you'd like to make https requests, you can enable the ssl feature,
36+
which also lets you install the pip package manager.
37+
Note that on Windows, you may need to install OpenSSL, or you can enable the ssl-vendor feature instead,
38+
which compiles OpenSSL for you but requires a C compiler, perl, and make.
39+
OpenSSL version 3 is expected and tested in CI. Older versions may not work.
40+

Diff for: src/interop/index.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Interpretation between Rust and Python
2+
- [Calling Rust from Python](./rust_from_python.md)
3+
- [Calling Python from Rust](./python_from_rust.md)

Diff for: src/interop/python_from_rust.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Calling Python from Rust
2+
TODO.

Diff for: src/interop/rust_from_python.md

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Calling Rust from Python
2+
## Structure
3+
```rust, ignore
4+
use rustpython::vm::pymodule;
5+
#[pymodule]
6+
mod test_module {
7+
#[pyattr]
8+
pub const THE_ANSWER: i32 = 42;
9+
10+
#[pyfunction]
11+
pub fn add(a: i32, b: i32) -> i32 {
12+
a + b
13+
}
14+
15+
#[pyattr]
16+
#[pyclass]
17+
pub struct TestClass {
18+
pub value: i32,
19+
}
20+
21+
#[pyclass]
22+
impl TestClass {
23+
#[pygetset]
24+
pub fn value(&self) -> i32 {
25+
self.value
26+
}
27+
28+
#[pymethod]
29+
pub fn get_info(&self) -> i32 {
30+
self.value * 2
31+
}
32+
}
33+
}
34+
```
35+
This code defines a Python module named `test_module` with two items:
36+
a constant named `THE_ANSWER` and a function named `add`.
37+
The `#[pymodule]` attribute is used to mark the module,
38+
and the `#[pyattr]` and `#[pyfunction]` attributes are used to mark the constant and function, respectively.
39+
40+
RustPython allows for 3 types of items in a module:
41+
- Variables: Defined using the `#[pyattr]` attribute.
42+
- Functions: Defined using the `#[pyfunction]` attribute.
43+
- Classes: Defined using the `#[pyclass]` attribute.
44+
45+
## General Configuration
46+
Most attributes have a `name` parameter that can be used to specify the name of the item in Python.
47+
If the `name` parameter is not provided, the Rust identifier is used as the name in Python.
48+
49+
## Variables
50+
Variables are defined using the `#[pyattr]` attribute.
51+
A variable can either be a constant or a function.
52+
Note that classes are treated as attributes in RustPython
53+
and are annotated with `#[pyattr]` as well, but that can be done away with if needed.
54+
```rust, no_run
55+
#[pyattr]
56+
const THE_ANSWER: i32 = 42;
57+
// ... or
58+
#[pyattr]
59+
fn the_answer() -> i32 {
60+
42
61+
}
62+
// ... or
63+
// this will cache the result of the function
64+
// and return the same value every time it is called
65+
#[pyattr(once)]
66+
fn cached_answer() -> i32 {
67+
42
68+
}
69+
```
70+
71+
## Valid Arguments/Return Types
72+
Every input and return value must be convertible to `PyResult`. This is defined as `IntoPyResult` trait. So any return value of them must implement `IntoPyResult`. It will be `PyResult<PyObjectRef>`, `PyObjectRef` and any `PyResult<T>` when T implements `IntoPyObject`. Practically we can list them like:
73+
- Any `T` when `PyResult<T>` is possible
74+
- `PyObjectRef`
75+
- `PyResult<()>` and `()` as `None`
76+
- `PyRef<T: PyValue>` like `PyIntRef`, `PyStrRef`
77+
- `T: PyValue` like `PyInt`, `PyStr`
78+
- Numbers like `usize` or `f64` for `PyInt` and `PyFloat`
79+
- `String` for `PyStr`
80+
- And more types implementing `IntoPyObject`.
81+
82+
The `vm` paramter is optional. We add it as the last parameter unless we don't use `vm` at all - very rare case. It takes an object `obj` as `PyObjectRef`, which is a general python object. It returns `PyResult<String>`, which will turn into `PyResult<PyObjectRef>` the same representation of `PyResult`. The `vm` parameter does not need to be passed in by the python code.
83+
84+
If needed a seperate struct can be used for arguments using the `FromArgs` trait like so:
85+
86+
```rust
87+
#[derive(FromArgs)]
88+
struct BisectArgs {
89+
a: PyObjectRef,
90+
x: PyObjectRef
91+
#[pyarg(any, optional)]
92+
lo: OptionalArg<ArgIndex>,
93+
#[pyarg(any, optional)]
94+
hi: OptionalArg<ArgIndex>,
95+
#[pyarg(named, default)]
96+
key: Option<PyObjectRef>,
97+
}
98+
99+
#[pyfunction]
100+
fn bisect_left(
101+
BisectArgs { a, x, lo, hi, key }: BisectArgs,
102+
vm: &VirtualMachine,
103+
) -> PyResult<usize> {
104+
// ...
105+
}
106+
107+
// or ...
108+
109+
#[pyfunction]
110+
fn bisect_left(
111+
args: BisectArgs,
112+
vm: &VirtualMachine,
113+
) -> PyResult<usize> {
114+
// ...
115+
}
116+
```
117+
118+
## Errors
119+
120+
Returning a PyResult is the supported error handling strategy. Builtin python errors are created with `vm.new_xxx_error` methods.
121+
122+
### Custom Errors
123+
124+
```
125+
#[pyattr(once)]
126+
fn error(vm: &VirtualMachine) -> PyTypeRef {
127+
vm.ctx.new_exception_type(
128+
"<module_name>",
129+
"<error_name>",
130+
Some(vec![vm.ctx.exceptions.exception_type.to_owned()]),
131+
)
132+
}
133+
134+
// convenience function
135+
fn new_error(message: &str, vm: &VirtualMachine) -> PyBaseExceptionRef {
136+
vm.new_exception_msg(vm.class("<module_name>", "<error_name>"), message.to_owned())
137+
}
138+
```
139+
140+
## Functions
141+
Functions are defined using the `#[pyfunction]` attribute.
142+
```rust, no_run
143+
#[pyfunction]
144+
fn add(a: i32, b: i32) -> i32 {
145+
a + b
146+
}
147+
```
148+
149+
## Classes
150+
Classes are defined using the `#[pyclass]` attribute.
151+
```rust, no_run
152+
#[pyclass]
153+
pub struct TestClass {
154+
pub value: i32,
155+
}
156+
#[pyclass]
157+
impl TestClass {
158+
}
159+
```
160+
### Associated Data
161+
TODO.
162+
### Methods
163+
TODO.
164+
### Getters and Setters
165+
TODO.
166+
### Class Methods
167+
TODO.
168+
### Static Methods
169+
TODO.
170+
### Inheritance
171+
TODO.

Diff for: src/introduction/index.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Introduction
2+
3+
RustPython is a Python interpreter written in Rust.

Diff for: src/writing_functions.md

-45
This file was deleted.

0 commit comments

Comments
 (0)