Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Python module in Rust
Search
dv
June 08, 2017
190
0
Share
Python module in Rust
dv
June 08, 2017
More Decks by dv
See All by dv
First try for CAS, SymPy with codegen
wdv4758h
0
710
Android Memory Leak Profiling - VMFive
wdv4758h
0
310
CPython's bug in feature that nobody uses
wdv4758h
0
120
Vim 手指健康操
wdv4758h
3
930
FreeBSD ports system
wdv4758h
0
150
Featured
See All Featured
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
64
54k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
490
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.1k
Optimizing for Happiness
mojombo
378
71k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.4k
sira's awesome portfolio website redesign presentation
elsirapls
0
220
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
370
Designing Experiences People Love
moore
143
24k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
520
How STYLIGHT went responsive
nonsquared
100
6.1k
Transcript
Python module in Rust Chiu-Hsiang Hsu PyCon TW 2017
Who am I • Software Engineer @ Deep Sentinel (My
First Job !) • Last Year: First try for CAS, SymPy with codegen • GitHub: @wdv4758h
Talk's Assumption Version: Python 3.6 Platform: Linux Your Skills: Some
Python, Some C
Fast overview of Rust ecosystem
Rust Survey 2016 Python
Rust Language: Why Rust Memory Safety without GC Compiled Language
Strong, Static Type
Who is using Rust ? https://www.rust-lang.org/friends.html
Benchmarks Game http://benchmarksgame.alioth.debian.org/
Benchmarks Game - Where is Python different weight class ...
Benchmarks Game - Python http://benchmarksgame.alioth.debian.org/
Rust is young May 15, 2015
Rust 1.18.0 (2017-06-08) 6 week release cycle
Crates (like PyPI) https://crates.io/
Cargo (like pip + setuptools) http://doc.crates.io/
rustup (like pyenv) https://www.rustup.rs/
rustup (like pyenv) compiler version
rustup (like pyenv) target platform
RFCs (like PEP) https://github.com/rust-lang/rfcs
Official Tutorial https://doc.rust-lang.org/book/
Standard Library Documentation https://doc.rust-lang.org/std/
Documentation for Crates You can build your docs by cargo
doc API doc with your docstring autogen for your crates: https://docs.rs/
Documentation for Crates https://docs.rs/
Documentation for Crates https://docs.rs/
Official Repos https://github.com/rust-lang/
Official Repos https://github.com/rust-lang-nursery/
Rust is a lower level language than Python
Lower Level https://doc.rust-lang.org/std/fmt/index.html format! (like str.format)
Lower Level . Rust iterator (like Python iterator) https://doc.rust-lang.org/std/iter/trait.Iterator.html
Lower Level . Rust iterator (like Python iterator) https://doc.rust-lang.org/std/iter/trait.Iterator.html
Lower Level . Rust iterator (like Python iterator) https://doc.rust-lang.org/std/iter/trait.Iterator.html
Lower Level . Rust iterator (like Python iterator) https://doc.rust-lang.org/std/iter/trait.Iterator.html
Lower Level .. Rust lambda (like Python lambda) https://doc.rust-lang.org/book/closures.html
Lower Level ... Wait ! It doesn't look like that
low level !?
Lower Level ... Wait ! It doesn't look like that
low level !? I pick what I want to show you :P
Compiler
Compiler
Compiler
Compiler
Python Code • Pure Python Code • Python Code +
Binary built from (C/C++/…) • Python Code + Other Language's Code
Python + Binary Make Friends !
How can Python play with binary • ctypes • CFFI
• CPython Extension • ...
ctypes • pip • IPython • PyInstaller • SymPy •
prompt_toolkit • ... Cases CPython Extension • NumPy • Pillow • simplejson • TensorFlow • psutil • ... CFFI • Cryptography • psycopg2cffi • pyzmq • ...
ctypes - quick view import ctypes from ctypes import c_char_p
, c_void_p lib = ctypes.cdll.LoadLibrary("pycontw.so") lib.hello_world.argtypes = (c_void_p,) lib.hello.argtypes = (c_char_p,) lib.hello.restypes = c_char_p
ctypes - flow C Code Shared Library Python Code ctypes
libffi
CFFI - quick view from cffi import FFI ffi =
FFI() lib = ffi.dlopen("pycontw.so") ffi.cdef(""" void hello_world(); char* hello(const char* name); """)
CFFI - flow (ABI level) C Code Shared Library Python
Code CFFI libffi
CPython Extension - import PyInit_pycontw() import pycontw Find Pure Python
Package or Module Find pycontw.so
CPython Extension - flow C Code Shared Library Python Code
CPython C API
CPython Extension - simple call path import Find <modulename>.so POSIX
dlsym PyModule_Create() PyInit_<modulename>()
CPython Extension - quick view static PyMethodDef pycontw_methods[] = {
{"hello_world", hello_world, METH_VARARGS, NULL}, {"hello", hello, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} };
CPython Extension - quick view static PyModuleDef pycontw_module = {
PyModuleDef_HEAD_INIT, "pycontw", "PyCon TW 2017", -1, pycontw_methods, NULL, NULL, NULL, NULL };
CPython Extension - quick view PyMODINIT_FUNC PyInit_pycontw() { return PyModule_Create(&pycontw_module);
}
CPython Extension - quick view And you need to implement
functions with CPython C API
CPython Extension - build from distutils.core import setup, Extension module1
= Extension('pycontw', sources = ['cpython-extension-sample.c']) setup(name = 'pycontw', version = '1.0', description = 'This is a demo package', ext_modules = [module1])
CPython Extension - build $ python setup.py build
Back to things related to Python
Rust with ctypes/CFFI ?
Sure
CPython + Rust: by ctypes or CFFI #[repr(C)] struct MyData
{ a: i32, // Other members... }
CPython + Rust: by ctypes or CFFI extern "C" fn
myfunc() { println!("It's PyCon TW 2017 !!!"); }
CPython + Rust: by ctypes or CFFI • ctypes: use
it like C • CFFI: provide a C header for Rust code
Rust for CPython Extension ?
not so easy, but possible
CPython + Rust: by rust-cpython Repo: github.com/wdv4758h/pycontw-rust-module
CPython Extension with rust-cpython Rust Code Shared Library Python Code
rust-cpython CPython C API
rust-cpython - quick view // things like Python "import" #[macro_use]
extern crate cpython; use cpython::{PyObject, PyResult, Python};
rust-cpython - quick view fn hello_world(py: Python) -> PyResult<PyObject> {
println!("It's PyCon TW 2017"); Ok(py.None()) }
rust-cpython - quick view fn hello(_: Python, name: &str) ->
PyResult<String> { Ok(format!("It's PyCon TW 2017, hello {} !!!", name)) }
rust-cpython - quick view py_module_initializer!(pycontw, initpycontw, PyInit_pycontw, |py, m| {
m.add(py, "__doc__", "PyCon TW 2017")?; m.add(py, "hello", py_fn!(py, hello(name: &str)))?; m.add(py, "hello_world", py_fn!(py, hello_world()))?; Ok(()) });
rust-cpython - Cargo.toml [package] name = "pycontw" version = "0.1.0"
[lib] name = "pycontw" crate-type = ["cdylib"] [dependencies] cpython = { version = "0.1.0", features = ["extension-module"] }
rust-cpython - build $ cargo build
rust-cpython - build $ cargo build --release
setuptools-rust https://github.com/PyO3/setuptools-rust
setuptools-rust - setup.py from setuptools import setup from setuptools_rust import
RustExtension setup( name='pycontw', version='2017', rust_extensions=[RustExtension('pycontw', './Cargo.toml')], packages=['pycontw'], # Rust extensions are not zip safe, just like C extensions zip_safe=False, )
Build Your Rust CPython Extension $ python setup.py build
CPython Extension in Rust Simple Examples
Hello
Print
Hash
Hash with random sate
Rust Vec for Python
Dropbox Brotli in Rust
Dropbox Brotli in Rust Simple Wrapper
Dropbox Brotli in Rust - Cargo.toml [dependencies] brotli = "1.0.8"
Dropbox Brotli in Rust - src/lib.rs extern crate brotli as
_brotli; use _brotli::enc::reader::CompressorReader; py_module_initializer!(pycontw, initpycontw, PyInit_pycontw, |py, m| { m.add(py, "brotli", py_fn!(py, brotli(data: Vec<u8>)))?; Ok(()) });
Dropbox Brotli in Rust - src/lib.rs fn brotli(_: Python, data:
Vec<u8>) -> PyResult<Vec<u8>> { let quality = 5_u32; let lg_window_size = 20_u32; let mut enc_data = vec![]; let mut reader = CompressorReader::new(data.as_slice(), 4096, quality, lg_window_size); let _ = reader.read_to_end(&mut enc_data); Ok(enc_data) }
More Resource- Rust by Example http://rustbyexample.com/
More Resource - Awesome Rust https://github.com/rust-unofficial/awesome-rust
Future Work • Build module by CI for multiple platforms
• Cross Compile module • More complete Python & Rust integration • ...
Question ?