python

Manipulate Python code in Moonbit

python
Native-Only
moon add Kaida-Amethyst/python@0.1.7
Download zip
Version
0.1.7
License
Apache-2.0
Last updated
9 months ago
Downloads
5K
README

#🐍 Python.mbt

⚠️ Project Status Notice This project is currently in early development. API changes may occur without backward compatibility. Not recommended for production use. Contributors and testers welcome!

#✨ Key Features

Moonbit-Python is the first CPython-based bridge for Moonbit language, offering:

  • Python Ecosystem Integration - Directly interoperate with top Python libraries like Numpy, Matplotlib, and PyTorch
  • Type-Safe Interactions - Strongly-typed interfaces ensuring safe object handling

#📦 Environment Setup

#Python Installation

Requires Python 3.9+. Recommended installation methods:

Linux (Debian/Ubuntu)

sudo apt-get update && sudo apt-get install python3.13 python3.13-dev

macOS (Homebrew)

brew install python@3.13

Windows

  1. Visit Python Official Download Page
  2. Download latest 3.x installer
  3. Enable "Add Python to PATH" during installation

#Environment Verification

# Verify Python version python3 --version

#🔧 Project Configuration

#Add Dependency

Update package index and install core library:

moon update moon add Kaida-Amethyst/python

💡 Note: Current package manager has known issues with native-only libraries. Ignore related error messages. Track official fixes at Moonbitlang

#Build Configuration

Add to your project's moon.pkg.json:

{ "import": [ "Kaida-Amethyst/python" ] }

#🚀 Quick Start

#Example: Using collections.Counter

typealias @python.(PyInteger, PyList, PyTuple)

fn main {
// It's equivalent to `nums = [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]`
let nums = [1L, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
let py_nums = nums.map(PyInteger::from) |> PyList::from
println(py_nums) // Output: [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

// It's equivalent to `import collections`
guard @python.pyimport("collections") is Some(collections)

// It's equivalent to `from collections import Counter`
guard collections.get_attr("Counter") is Some(PyCallable(counter))

let args = PyTuple::new(1)
args.. set(0, py_nums)

// It's equivalent to `cnt = Counter(nums)`
guard counter.invoke?(args~) is Ok(Some(cnt))
guard cnt is PyDict(cnt)

// `print(cnt)`
println(cnt) // Output: Counter({4: 4, 3: 3, 1: 2, 2: 2})
}

#Running the Example

moon run main --target native

Equivalent Python implementation:

from collections import Counter l = [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4] print(Counter(l)) # Counter({4: 4, 3: 3, 1: 2, 2: 2})

#🤝 Contributing

We welcome contributions through:

  1. Issue reporting
  2. Pull requests
  3. Ecosystem documentation improvements


📜 License: Apache-2.0 License (See LICENSE file)

#🐍 Python.mbt

⚠️ 项目状态提示 本项目目前处于早期开发阶段,API可能发生不兼容变更,暂不建议用于生产环境。欢迎开发者参与测试和功能建议!

#🌟项目亮点

Moonbit-Python 是首个基于CPython的Moonbit语言桥接工具,具有以下核心优势:

  • 无缝调用Python生态 - 直接操作Numpy、Matplotlib、PyTorch等顶级Python库
  • 类型安全交互 - 提供强类型接口保障与Python对象的安全交互

#📦 环境准备

#Python安装指南

要求Python 3.9+版本,推荐使用最新稳定版:

Linux (Debian/Ubuntu)

sudo apt-get update && sudo apt-get install python3.13 python3.13-dev

macOS (Homebrew)

brew install python@3.13

Windows

  1. 访问Python官方网站
  2. 下载最新3.x版本安装包
  3. 安装时勾选 "Add Python to PATH"

#环境验证

# 验证Python版本 python3 --version

#🔧 项目配置

#添加依赖

更新包索引并安装核心库:

moon update moon add Kaida-Amethyst/python

💡 注意:当前包管理器对纯Native库的支持存在已知问题,可忽略相关错误提示。官方修复进度请关注Moonbitlang

#构建配置

在项目根目录的 moon.pkg.json 中添加:

{ "import": [ "Kaida-Amethyst/python" ] }

#🚀 快速入门

一个使用python 中Counter的例子

typealias @python.(PyInteger, PyList, PyTuple)

fn main {
// It's equivalent to `nums = [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]`
let nums = [1L, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
let py_nums = nums.map(PyInteger::from) |> PyList::from
println(py_nums) // Output: [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

// It's equivalent to `import collections`
guard @python.pyimport("collections") is Some(collections)

// It's equivalent to `from collections import Counter`
guard collections.get_attr("Counter") is Some(PyCallable(counter))

let args = PyTuple::new(1)
args.. set(0, py_nums)

// It's equivalent to `cnt = Counter(nums)`
guard counter.invoke?(args~) is Ok(Some(cnt))
guard cnt is PyDict(cnt)

// `print(cnt)`
println(cnt) // Output: Counter({4: 4, 3: 3, 1: 2, 2: 2})
}

#运行示例

moon run main --target native

等效Python代码:

from collections import Counter l = [1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4] print(Counter(l)) # Counter({4: 4, 3: 3, 1: 2, 2: 2})

#🤝 参与贡献

我们欢迎任何形式的贡献,包括但不限于:

  1. 提交Issue报告问题
  2. 发起Pull Request改进代码
  3. 编写生态库扩展文档


📜 许可证:Apache-2.0 License(详见LICENSE文件)

#
IsPyObject

pub trait IsPyObject {
obj(Self) -> PyObject
obj_ref(Self) ->
PyObjectRef

type_name(Self) -> String
}

#
PyRuntimeError

pub suberror PyRuntimeError {
TypeMismatchError
IndexOutOfBoundsError
KeyIsUnHashableError
InVokeError
}

#
PyBool

pub struct PyBool {
// private fields
}

impl Show for PyBool

#
PyBool::create

fn PyBool::create(obj : PyObject) -> PyBool raise PyRuntimeError

Create a python boolean object from a python object. If the object is not a boolean, it will raise a TypeMismatchError.

#
PyBool::create_by_ref

Create a python boolean object from a python object reference. If the object is not a boolean, it will raise a TypeMismatchError.

#
PyBool::dump

fn PyBool::dump(self : PyBool) -> Unit

#
PyBool::from

fn PyBool::from(value : Bool) -> PyBool

Create a python boolean object from moonbit bool.

Example

let t = PyBool::from(true);

inspect(t, content="True")

The above code is equivalent to:

t = True print(t) # Output: True

#
PyBool::is_false

fn PyBool::is_false(self : PyBool) -> Bool

Return true if it is false, using python interpreter.

Example

let t = PyBool::from(true);
let f = PyBool::from(false);

assert_false(t.is_false());
assert_true(f.is_false());

#
PyBool::is_true

fn PyBool::is_true(self : PyBool) -> Bool

Return true if it is true, using python interpreter.

Example

let t = PyBool::from(true);
let f = PyBool::from(false);

assert_true(t.is_true());
assert_false(f.is_true());

#
PyBool::not

fn PyBool::not(self : PyBool) -> PyBool

Return the reverse of the boolean value.

Example

let t = PyBool::from(true);
let f = t.not();

assert_true(f.is_false());

#
PyBool::to_bool

fn PyBool::to_bool(self : PyBool) -> Bool

#
PyCallable

pub struct PyCallable {
// private fields
}

impl Show for PyCallable

#
PyCallable::create

fn PyCallable::create(obj : PyObject) -> PyCallable raise PyRuntimeError

Create a python callable object from a PyObject. If the object is not callable, a TypeMismatchError is raised.

#
PyCallable::create_by_ref

Create a python callable object from a PyObjectRef. If the object is not callable, a TypeMismatchError is raised.

#
PyCallable::dump

fn PyCallable::dump(self : PyCallable) -> Unit

#
PyCallable::invoke

fn PyCallable::invoke(self : PyCallable, args? : PyTuple, kwargs? : PyDict, print_err? : Bool) -> PyObjectEnum? raise PyRuntimeError

#
PyDict

pub struct PyDict {
// private fields
}

impl Show for PyDict

#
PyDict::contains

fn PyDict::contains(self : PyDict, key : String) -> Bool

Check if the dict contains the key. Note that the key is a string. If the key is not string, use containsObj instead.

#
PyDict::containsObj

fn PyDict::containsObj(self : PyDict, key : PyObject) -> Bool

Check if the dict contains the key.

#
PyDict::create

fn PyDict::create(obj : PyObject) -> PyDict raise PyRuntimeError

Create a python dict object. If the python object is not a dict, it will raise a TypeMismatchError.

#
PyDict::create_by_ref

Create a python dict object from a python object reference. If the python object is not a dict, it will raise a TypeMismatchError.

#
PyDict::drop

fn PyDict::drop(self : PyDict) -> Unit

#
PyDict::dump

fn PyDict::dump(self : PyDict) -> Unit

Let python interpret print the dict directly.

Note: This is different from println(dict) and dict.dump(). although they always print the same content.

#
PyDict::get

fn PyDict::get(self : PyDict, key : String) -> PyObjectEnum?

Return the elements of the dict by its key.

Example

let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));

inspect(dict.get("one").unwrap(), content="PyInteger(1)")
inspect(dict.get("two"), content="Some(PyFloat(2.0))")
inspect(dict.get("four"), content="None")

#
PyDict::getByObj

fn PyDict::getByObj(self : PyDict, key : PyObject) -> PyObjectEnum?

Return the elements of the dict by its key, when the key is not string.

#
PyDict::items

fn PyDict::items(self : PyDict) -> PyList

Get the items of the dict.

Notes: It is slight different from the python dict.items() method. In python, dict.items() returns a view object that displays a list of all the items. While here in moonbit, items() returns a list of all the items.

Example

let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));

inspect(dict.items(), content="[('one', 1), ('two', 2.0), ('three', True)]")

#
PyDict::keys

fn PyDict::keys(self : PyDict) -> PyList

Get the keys of the dict.

Notes: It is slight different from the python dict.keys() method. In python, dict.keys() returns a view object that displays a list of all the keys. While here in moonbit, keys() returns a list of all the keys.

Example

let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));

inspect(dict.keys(), content="[\'one\', \'two\', \'three\']")

The above code is equivalent to:

d = { 'one': 1, 'two': 2.0, 'three': True } dict_keys = d.keys() print(dict_keys) # Output: dict_keys(['one', 'two', 'three'])

#
PyDict::len

fn PyDict::len(self : PyDict) -> Int

Return the length of the dict.

Example

let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyString::from("three"));

assert_eq(dict.len(), 3);

#
PyDict::new

fn PyDict::new() -> PyDict

Creates a new python dict object.

Example

let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));

inspect(dict, content="{\'one\': 1, \'two\': 2.0, \'three\': True}")

The above code is equivalent to:

d = { 'one': 1, 'two': 2.0, 'three': True } print(d) # Output: {'one': 1, 'two': 2.0, 'three': True}

#
PyDict::op_get

fn PyDict::op_get(self : PyDict, key : String) -> PyObjectEnum

Return the elements of the dict by its key.

Note: Will panic if the key is not found.

Example

let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));

inspect(dict["one"], content="PyInteger(1)")
inspect(dict["two"], content="PyFloat(2.0)")
inspect(dict["three"], content="PyBool(True)")

#
PyDict::op_set

fn[V : IsPyObject] PyDict::op_set(self : PyDict, key : String, val : V) -> Unit

Set the elements of the dict by its key (String).

Example

let dict = PyDict::new()

dict["one"] = PyInteger::from(1);
dict["two"] = PyFloat::from(2.0);
dict["three"] = PyBool::from(true);

inspect(dict, content="{\'one\': 1, \'two\': 2.0, \'three\': True}")

The above code is equivalent to:

d = dict() d['one'] = 1 d['two'] = 2.0 d['three'] = True

#
PyDict::set

fn[V : IsPyObject] PyDict::set(self : PyDict, key : String, val : V) -> Unit

Set the elements of the dict by its key (String).

Example

let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));

inspect(dict, content="{\'one\': 1, \'two\': 2.0, \'three\': True}")

The above code is equivalent to:

d = dict() d['one'] = 1 d['two'] = 2.0 d['three'] = True

#
PyDict::setByObj

fn[K : IsPyObject, V : IsPyObject] PyDict::setByObj(self : PyDict, key : K, val : V) -> Unit raise PyRuntimeError

Set the elements of the dict by its key. (Object)

Example

let dict = PyDict::new()
dict
..setByObj(PyInteger::from(1), PyInteger::from(1))
..setByObj(PyInteger::from(2), PyInteger::from(4))
..setByObj(PyInteger::from(3), PyInteger::from(9))

inspect(dict, content="{1: 1, 2: 4, 3: 9}")

The above code is equivalent to:

d = dict() d[1] = 1 d[2] = 4 d[3] = 9 print(d) # Output: {1: 1, 2: 4, 3: 9}

#
PyDict::values

fn PyDict::values(self : PyDict) -> PyList

Get the values of the dict.

Notes: It is slight different from the python dict.values() method. In python, dict.values() returns a view object that displays a list of all the values. While here in moonbit, values() returns a list of all the values.

Example

let dict = PyDict::new()
dict
..set("one", PyInteger::from(1))
..set("two", PyFloat::from(2.0))
..set("three", PyBool::from(true));

inspect(dict.values(), content="[1, 2.0, True]")

The above code is equivalent to:

d = { 'one': 1, 'two': 2.0, 'three': True } dict_values = d.values() print(dict_values) # Output: dict_values([1, 2.0, True])

#
PyFloat

pub struct PyFloat {
// private fields
}

impl Show for PyFloat

#
PyFloat::create

fn PyFloat::create(obj : PyObject) -> PyFloat raise PyRuntimeError

Create a python float object from a python object. If the python object is not a float, it will raise a TypeMismatchError.

#
PyFloat::create_by_ref

Ceate a python float object from a python object reference. If the python object is not a float, it will raise a TypeMismatchError.

#
PyFloat::drop

fn PyFloat::drop(self : PyFloat) -> Unit

#
PyFloat::dump

fn PyFloat::dump(self : PyFloat) -> Unit

Print the PyFloat object direcly.

Different from use println, dump means we made python interpreter print the object directly.

#
PyFloat::from

fn PyFloat::from(value : Double) -> PyFloat

Create a PyFloat from a Double value.

Example

let f = @python.PyFloat::from(3.5);
inspect(f, content="3.5")

#
PyFloat::to_double

fn PyFloat::to_double(self : PyFloat) -> Double

Convert a PyFloat to a Double.

Example

let f = @python.PyFloat::from(3.5);
assert_eq(f.to_double(), 3.5);

#
PyInteger

pub struct PyInteger {
// private fields
}

impl Show for PyInteger

#
PyInteger::create

fn PyInteger::create(obj : PyObject) -> PyInteger raise PyRuntimeError

Create a python integer object from a python object. If

#
PyInteger::create_by_ref

#
PyInteger::create_unchecked

fn PyInteger::create_unchecked(obj : PyObject) -> PyInteger

#
PyInteger::drop

fn PyInteger::drop(self : PyInteger) -> Unit

#
PyInteger::dump

fn PyInteger::dump(self : PyInteger) -> Unit

Print the PyInteger object direcly.

Different from use println, dump means we made python interpreter print the object directly.

#
PyInteger::from

fn PyInteger::from(value : Int64) -> PyInteger

Create a PyInteger from an integer.

Example

let i = @python.PyInteger::from(42);
inspect(i, content="42")

#
PyInteger::to_double

fn PyInteger::to_double(self : PyInteger) -> Double

Convert a PyInteger to a double.

Example

let i = @python.PyInteger::from(42);
assert_eq(i.to_double(), 42.0);

#
PyInteger::to_int64

fn PyInteger::to_int64(self : PyInteger) -> Int64

Convert a PyInteger to an integer.

Example

let i = @python.PyInteger::from(42);
assert_eq(i.to_int64(), 42);

#
PyList

pub struct PyList {
// private fields
}

impl Show for PyList

#
PyList::append

fn[T : IsPyObject] PyList::append(self : PyList, item : T) -> Unit

Append an item to the end of the list.

Example

let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
inspect(list, content="[1, 2.0, \'hello\']")

The above code is equivalent to the following Python code:

list = [] list.append(1) list.append(2.0) list.append("hello") print(list) # Output: [1, 2.0, 'hello']

#
PyList::create

fn PyList::create(obj : PyObject) -> PyList raise PyRuntimeError

Create a python list object from a pyobject. If the pyobject is not a list, it will raise a TypeMismatchError.

#
PyList::create_by_ref

Create a python list object from a pyobject reference. If the pyobject is not a list, it will raise a TypeMismatchError.

#
PyList::drop

fn PyList::drop(self : PyList) -> Unit

#
PyList::dump

fn PyList::dump(self : PyList) -> Unit

Let python interpreter print the list directly.

Note: It is different from println(list) and list.dump() although they always print the same content.

#
PyList::from

fn[T : IsPyObject] PyList::from(items : Array[T]) -> PyList

Create a new python list from a python object array

Example

let arr: Array[&IsPyObject] = Array::new()
let one = PyInteger::from(1);
let two = PyFloat::from(2.0);
let three = PyString::from("three");

arr.push(one)
arr.push(two)
arr.push(three)

let list = PyList::from(arr);
inspect(list, content="[1, 2.0, \'three\']")

#
PyList::get

fn PyList::get(self : PyList, idx : Int) -> PyObjectEnum?

Get the item at the specified index.

Notes: Although python support negative index, the moonbit api does not support it. Code like list.get(-1) will return None.

Example

let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));

inspect(list.get(0).unwrap(), content="PyInteger(1)")
inspect(list.get(1), content="Some(PyFloat(2.0))")
inspect(list.get(3), content="None")
inspect(list.get(-1), content="None")

#
PyList::len

fn PyList::len(self : PyList) -> Int

Returns the length of the list.

Example

let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));

assert_eq(list.len(), 3);

The above code is equivalent to the following Python code:

list = [] list.append(1) list.append(2.0) list.append("hello") print(len(list)) # Output: 3

#
PyList::new

fn PyList::new() -> PyList

Create an empty python list.

Example

let list = @python.PyList::new();
inspect(list, content="[]")
assert_eq(list.len(), 0);

#
PyList::op_get

fn PyList::op_get(self : PyList, idx : Int) -> PyObjectEnum

Get the item at the specified index.

Notes: Although python support negative index, the moonbit api does not support it. which means code like list[-1] will be panic.

Example

let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));

inspect(list[0], content="PyInteger(1)")
inspect(list[1], content="PyFloat(2.0)")
inspect(list[2], content="PyString(hello)")

#
PyList::op_set

fn[T : IsPyObject] PyList::op_set(self : PyList, idx : Int, item : T) -> Unit

Set the item at the specified index.

Notes: Although python support negative index, the moonbit api does not support it. which means code like list[-1] = ... will be panic.

Example

let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
inspect(list, content="[1, 2.0, \'hello\']")

list[0] = @python.PyInteger::from(42);
inspect(list, content="[42, 2.0, \'hello\']")

#
PyList::set

fn[T : IsPyObject] PyList::set(self : PyList, idx : Int, item : T) -> Unit raise PyRuntimeError

Set the item at the specified index.

Notes: Although python support negative index, the moonbit api does not support it. which means code like list.set(-1) = ... will raise IndexOutOfBoundsError.

Example

let list = @python.PyList::new();
list.append(@python.PyInteger::from(1));
list.append(@python.PyFloat::from(2.0));
list.append(@python.PyString::from("hello"));
inspect(list, content="[1, 2.0, \'hello\']")

list.set(0, @python.PyInteger::from(42));
inspect(list, content="[42, 2.0, \'hello\']")

#
PyModule

pub struct PyModule {
// private fields
}

impl Show for PyModule

#
PyModule::create

fn PyModule::create(obj : PyObject) -> PyModule raise PyRuntimeError

#
PyModule::create_by_ref

#
PyModule::dump

fn PyModule::dump(self : PyModule) -> Unit

#
PyModule::get_attr

fn PyModule::get_attr(self : PyModule, attr : String, print_err? : Bool) -> PyObjectEnum?

Get attribute by name.

Example

let collections = pyimport("collections").unwrap()
guard collections.get_attr("Counter").unwrap() is PyCallable(counter)

let list = [1L, 2L, 2L, 3L, 3L, 3L].map(PyInteger::from) |> PyList::from
let args = PyTuple::new(1)
args .. set(0, list)
guard counter.invoke(args~) is Some(PyDict(cnt))
inspect(cnt, content="Counter({3: 3, 2: 2, 1: 1})")

guard cnt.obj().get_attr("total") is Some(PyCallable(total))
inspect(total.invoke().unwrap(), content="PyInteger(6)")

// The above code is equivalent to the following python code:

import collections from collections import Counter list = [1, 2, 2, 3, 3, 3] cnt = Counter(list) print(cnt) # Counter({3: 3, 2: 2, 1: 1}) total = cnt.total() print(total) # 6

#
PyModule::get_name

fn PyModule::get_name(self : PyModule) -> String

Get the name of the module.

Example

let os = @python.pyimport("os").unwrap()

inspect(os.get_name(), content="os")

#
PyObject

pub struct PyObject {
// private fields
}

impl Show for PyObject

#
PyObject::drop

fn PyObject::drop(self : PyObject) -> Unit

#
PyObject::dump

fn PyObject::dump(self : PyObject) -> Unit

#
PyObject::get_attr

fn PyObject::get_attr(self : PyObject, attr : String, print_err? : Bool) -> PyObjectEnum?

#
PyObject::is_bool

fn PyObject::is_bool(self : PyObject) -> Bool

#
PyObject::is_callable

fn PyObject::is_callable(self : PyObject) -> Bool

#
PyObject::is_dict

fn PyObject::is_dict(self : PyObject) -> Bool

#
PyObject::is_float

fn PyObject::is_float(self : PyObject) -> Bool

#
PyObject::is_int

fn PyObject::is_int(self : PyObject) -> Bool

#
PyObject::is_list

fn PyObject::is_list(self : PyObject) -> Bool

#
PyObject::is_module

fn PyObject::is_module(self : PyObject) -> Bool

#
PyObject::is_null

fn PyObject::is_null(self : PyObject) -> Bool

#
PyObject::is_string

fn PyObject::is_string(self : PyObject) -> Bool

#
PyObject::is_tuple

fn PyObject::is_tuple(self : PyObject) -> Bool

#
PyObject::type_name

fn PyObject::type_name(self : PyObject) -> String

#
PyObject::type_of

fn PyObject::type_of(self : PyObject) -> PyType

#
PyObjectEnum

pub(all) enum PyObjectEnum {
PyInteger(PyInteger)
PyFloat(PyFloat)
PyBool(PyBool)
PyString(PyString)
PyTuple(PyTuple)
PyList(PyList)
PyDict(PyDict)
PyModule(PyModule)
PyCallable(PyCallable)
PyClass(PyObject)
}

#
PyObjectEnum::create

fn PyObjectEnum::create(obj : PyObject) -> PyObjectEnum

#
PyObjectEnum::create_by_ref

#
PyObjectEnum::dump

fn PyObjectEnum::dump(self : PyObjectEnum) -> Unit

#
PyString

pub struct PyString {
// private fields
}

impl Show for PyString

#
PyString::create

fn PyString::create(obj : PyObject) -> PyString raise PyRuntimeError

Create a python string from a python object. If the python object is not a string, it will raise a TypeMismatchError.

#
PyString::create_by_ref

Create a python string from a python object reference. If the python object is not a string, it will raise a TypeMismatchError.

#
PyString::drop

fn PyString::drop(self : PyString) -> Unit

#
PyString::dump

fn PyString::dump(self : PyString) -> Unit

Print the PyString object direcly.

Different from use println, dump means we made python interpreter print the object directly.

#
PyString::from

fn PyString::from(s : String) -> PyString

Create a PyString from a string

Example

let s = @python.PyString::from("hello");
inspect(s, content="hello");

#
PyTuple

pub struct PyTuple {
// private fields
}

impl Show for PyTuple

#
PyTuple::create

fn PyTuple::create(obj : PyObject) -> PyTuple raise PyRuntimeError

Create a PyTuple object from a python object. If the python object is not a tuple, it will raise a TypeMismatchError.

#
PyTuple::create_by_ref

Create a PyTuple object from a python object reference. If the python object is not a tuple, it will raise a TypeMismatchError.

#
PyTuple::drop

fn PyTuple::drop(self : PyTuple) -> Unit

#
PyTuple::dump

fn PyTuple::dump(self : PyTuple) -> Unit

#
PyTuple::get

fn PyTuple::get(self : PyTuple, idx : Int) -> PyObjectEnum?

Get the item at the given index.

Notes: Although python supports negative index, in moonbit, we don't have plan to support it. Code like tuple.get(-1) will return None.

Example:

let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));

inspect(tuple, content="(1, 2.0, \'three\')")
inspect(tuple.get(0).unwrap(), content="PyInteger(1)")
inspect(tuple.get(1).unwrap(), content="PyFloat(2.0)")
inspect(tuple.get(2).unwrap(), content="PyString(three)")
inspect(tuple.get(3), content="None")

The above code is equivalent the following python code:

tuple = (1, 2.0, "three") print(tuple) # Output: (1, 2.0, 'three') print(tuple[0]) # Output: 1 print(tuple[1]) # Output: 2.0 print(tuple[2]) # Output: three

#
PyTuple::len

fn PyTuple::len(self : PyTuple) -> UInt64

Return the size of the tuple.

Example:

let tuple = PyTuple::new(3)

assert_eq(tuple.len(), 3);

#
PyTuple::new

fn PyTuple::new(size : UInt64) -> PyTuple

Create a PyTuple object.

Notes: Tuple type must know the size of the tuple.

Example:

let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));

inspect(tuple, content="(1, 2.0, \'three\')")

#
PyTuple::op_get

fn PyTuple::op_get(self : PyTuple, idx : Int) -> PyObjectEnum

Get the item at the given index.

Notes: Although python supports negative index, in moonbit, we don't have plan to support it. Code like tuple[-1] will return None.

Example:

let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));

inspect(tuple[0], content="PyInteger(1)")
inspect(tuple[1], content="PyFloat(2.0)")
inspect(tuple[2], content="PyString(three)")

#
PyTuple::op_set

fn[T : IsPyObject] PyTuple::op_set(self : PyTuple, idx : Int, item : T) -> Unit

Set the item at the given index.

Notes: Although python supports negative index, in moonbit, we don't have plan to support it. Code like tuple[-1] = item will raise IndexOutOfBoundError.

Example:

let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));

inspect(tuple, content="(1, 2.0, \'three\')")

#
PyTuple::set

fn[T : IsPyObject] PyTuple::set(self : PyTuple, idx : Int, item : T) -> Unit

Set the item at the given index.

Notes: Although python supports negative index, in moonbit, we don't have plan to support it. Code like tuple.set(-1, item) will raise IndexOutOfBoundError.

Example:

let tuple = PyTuple::new(3)
tuple
..set(0, PyInteger::from(1))
..set(1, PyFloat::from(2.0))
..set(2, PyString::from("three"));

inspect(tuple, content="(1, 2.0, \'three\')")

#
PyType

pub enum PyType {
PyInteger
PyFloat
PyBool
PyString
PyTuple
PyList
PyDict
PyModule
PyCallable
PyClass
}

#
init_py

fn init_py() -> Unit

#
pyimport

fn pyimport(name : String, print_err? : Bool) -> PyModule?

Import a python module

Example

let os = @python.pyimport("os")

assert_true(os is Some(_))

#
strip_quot

fn strip_quot(s : String) -> String

elimnate the quotes from a string

Example

let s = "\'os\'"
inspect(@python.strip_quot(s), content="os")