Giter Site home page Giter Site logo

pyo3 / pyo3 Goto Github PK

View Code? Open in Web Editor NEW
11.0K 90.0 661.0 83.29 MB

Rust bindings for the Python interpreter

Home Page: https://pyo3.rs

License: Other

Rust 97.26% Python 2.40% Makefile 0.11% Shell 0.17% C 0.01% HTML 0.05%
rust python binding ffi python-c-api

pyo3's Introduction

PyO3

actions status benchmark codecov crates.io minimum rustc 1.56 discord server contributing notes

Rust bindings for Python, including tools for creating native Python extension modules. Running and interacting with Python code from a Rust binary is also supported.

Usage

PyO3 supports the following software versions:

  • Python 3.7 and up (CPython, PyPy, and GraalPy)
  • Rust 1.56 and up

You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn.

Using Rust from Python

PyO3 can be used to generate a native Python module. The easiest way to try this out for the first time is to use maturin. maturin is a tool for building and publishing Rust-based Python packages with minimal configuration. The following steps install maturin, use it to generate and build a new Python package, and then launch Python to import and execute a function from the package.

First, follow the commands below to create a new directory containing a new Python virtualenv, and install maturin into the virtualenv using Python's package manager, pip:

# (replace string_sum with the desired package name)
$ mkdir string_sum
$ cd string_sum
$ python -m venv .env
$ source .env/bin/activate
$ pip install maturin

Still inside this string_sum directory, now run maturin init. This will generate the new package source. When given the choice of bindings to use, select pyo3 bindings:

$ maturin init
✔ 🤷 What kind of bindings to use? · pyo3
  ✨ Done! New project created string_sum

The most important files generated by this command are Cargo.toml and lib.rs, which will look roughly like the following:

Cargo.toml

[package]
name = "string_sum"
version = "0.1.0"
edition = "2021"

[lib]
# The name of the native library. This is the name which will be used in Python to import the
# library (i.e. `import string_sum`). If you change this, you must also change the name of the
# `#[pymodule]` in `src/lib.rs`.
name = "string_sum"
# "cdylib" is necessary to produce a shared library for Python to import from.
#
# Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
# to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
# crate-type = ["cdylib", "rlib"]
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.21.2", features = ["extension-module"] }

src/lib.rs

use pyo3::prelude::*;

/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
    Ok((a + b).to_string())
}

/// A Python module implemented in Rust. The name of this function must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
#[pymodule]
fn string_sum(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
    Ok(())
}

Finally, run maturin develop. This will build the package and install it into the Python virtualenv previously created and activated. The package is then ready to be used from python:

$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
'25'

To make changes to the package, just edit the Rust source code and then re-run maturin develop to recompile.

To run this all as a single copy-and-paste, use the bash script below (replace string_sum in the first command with the desired package name):

mkdir string_sum && cd "$_"
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop

If you want to be able to run cargo test or use this project in a Cargo workspace and are running into linker issues, there are some workarounds in the FAQ.

As well as with maturin, it is possible to build using setuptools-rust or manually. Both offer more flexibility than maturin but require more configuration to get started.

Using Python from Rust

To embed Python into a Rust binary, you need to ensure that your Python installation contains a shared library. The following steps demonstrate how to ensure this (for Ubuntu), and then give some example code which runs an embedded Python interpreter.

To install the Python shared library on Ubuntu:

sudo apt install python3-dev

To install the Python shared library on RPM based distributions (e.g. Fedora, Red Hat, SuSE), install the python3-devel package.

Start a new project with cargo new and add pyo3 to the Cargo.toml like this:

[dependencies.pyo3]
version = "0.21.2"
features = ["auto-initialize"]

Example program displaying the value of sys.version and the current user name:

use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

fn main() -> PyResult<()> {
    Python::with_gil(|py| {
        let sys = py.import_bound("sys")?;
        let version: String = sys.getattr("version")?.extract()?;

        let locals = [("os", py.import_bound("os")?)].into_py_dict_bound(py);
        let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
        let user: String = py.eval_bound(code, None, Some(&locals))?.extract()?;

        println!("Hello {}, I'm Python {}", user, version);
        Ok(())
    })
}

The guide has a section with lots of examples about this topic.

Tools and libraries

  • maturin Build and publish crates with pyo3, rust-cpython or cffi bindings as well as rust binaries as python packages
  • setuptools-rust Setuptools plugin for Rust support.
  • pyo3-built Simple macro to expose metadata obtained with the built crate as a PyDict
  • rust-numpy Rust binding of NumPy C-API
  • dict-derive Derive FromPyObject to automatically transform Python dicts into Rust structs
  • pyo3-log Bridge from Rust to Python logging
  • pythonize Serde serializer for converting Rust objects to JSON-compatible Python objects
  • pyo3-asyncio Utilities for working with Python's Asyncio library and async functions
  • rustimport Directly import Rust files or crates from Python, without manual compilation step. Provides pyo3 integration by default and generates pyo3 binding code automatically.

Examples

  • autopy A simple, cross-platform GUI automation library for Python and Rust.
    • Contains an example of building wheels on TravisCI and appveyor using cibuildwheel
  • ballista-python A Python library that binds to Apache Arrow distributed query engine Ballista.
  • bed-reader Read and write the PLINK BED format, simply and efficiently.
    • Shows Rayon/ndarray::parallel (including capturing errors, controlling thread num), Python types to Rust generics, Github Actions
  • cryptography Python cryptography library with some functionality in Rust.
  • css-inline CSS inlining for Python implemented in Rust.
  • datafusion-python A Python library that binds to Apache Arrow in-memory query engine DataFusion.
  • deltalake-python Native Delta Lake Python binding based on delta-rs with Pandas integration.
  • fastbloom A fast bloom filter | counting bloom filter implemented by Rust for Rust and Python!
  • fastuuid Python bindings to Rust's UUID library.
  • feos Lightning fast thermodynamic modeling in Rust with fully developed Python interface.
  • forust A lightweight gradient boosted decision tree library written in Rust.
  • greptimedb Support Python scripting in the database
  • haem A Python library for working on Bioinformatics problems.
  • html-py-ever Using html5ever through kuchiki to speed up html parsing and css-selecting.
  • hyperjson A hyper-fast Python module for reading/writing JSON data using Rust's serde-json.
  • inline-python Inline Python code directly in your Rust code.
  • johnnycanencrypt OpenPGP library with Yubikey support.
  • jsonschema-rs Fast JSON Schema validation library.
  • mocpy Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere.
  • opendal A data access layer that allows users to easily and efficiently retrieve data from various storage services in a unified way.
  • orjson Fast Python JSON library.
  • ormsgpack Fast Python msgpack library.
  • point-process High level API for pointprocesses as a Python library.
  • polaroid Hyper Fast and safe image manipulation library for Python written in Rust.
  • polars Fast multi-threaded DataFrame library in Rust | Python | Node.js.
  • pydantic-core Core validation logic for pydantic written in Rust.
  • pyheck Fast case conversion library, built by wrapping heck.
    • Quite easy to follow as there's not much code.
  • pyre Fast Python HTTP server written in Rust.
  • ril-py A performant and high-level image processing library for Python written in Rust.
  • river Online machine learning in python, the computationally heavy statistics algorithms are implemented in Rust.
  • rust-python-coverage Example PyO3 project with automated test coverage for Rust and Python.
  • tiktoken A fast BPE tokeniser for use with OpenAI's models.
  • tokenizers Python bindings to the Hugging Face tokenizers (NLP) written in Rust.
  • tzfpy A fast package to convert longitude/latitude to timezone name.
  • utiles Fast Python web-map tile utilities
  • wasmer-python Python library to run WebAssembly binaries.

Articles and other media

Contributing

Everyone is welcomed to contribute to PyO3! There are many ways to support the project, such as:

  • help PyO3 users with issues on GitHub and Discord
  • improve documentation
  • write features and bugfixes
  • publish blogs and examples of how to use PyO3

Our contributing notes and architecture guide have more resources if you wish to volunteer time for PyO3 and are searching where to start.

If you don't have time to contribute yourself but still wish to support the project's future success, some of our maintainers have GitHub sponsorship pages:

License

PyO3 is licensed under the Apache-2.0 license or the MIT license, at your option.

Python is licensed under the Python License.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in PyO3 by you, as defined in the Apache License, shall be dual-licensed as above, without any additional terms or conditions.

Deploys by Netlify

pyo3's People

Contributors

adamreichold avatar alex avatar alexander-n avatar althonos avatar batconjurer avatar birkenfeld avatar bors[bot] avatar davidhewitt avatar deantvv avatar dependabot[bot] avatar dgrunwald avatar fafhrd91 avatar icxolu avatar ijl avatar indygreg avatar kngwyu avatar konstin avatar lilyfoote avatar macisamuele avatar mejrs avatar messense avatar nw0 avatar pganssle avatar ravenexp avatar ricohageman avatar scalexm avatar sebpuetz avatar snuderl avatar tpt avatar vlad-shcherbina avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyo3's Issues

no method named `extract` found for type `&&pyo3::PyInstance` in the current scope

error[E0599]: no method named `extract` found for type `&&pyo3::PyInstance` in the current scope
  --> src/lib.rs:11:1
   |
11 | #[py::modinit(_is_minified_js)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: items from traits can only be used if the trait is in scope
   = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
           candidate #1: `use pyo3::ObjectProtocol;`

error: aborting due to previous error(s)

https://travis-ci.org/messense/is-minified-js/jobs/246491562

segfault with large data

I have a function with signature:

#[pyfn(m, "extract_entity")]
fn extract_entity_py(py: Python, content: Vec<Vec<String>>) -> PyResult<Vec<Vec<Vec<Entity>>>> {}

with large data it segfaults (small data is fine), it happens on Linux, on macOS it's mostly fine.

dmesg log:

[262892.915631] pytest[17095]: segfault at 8b1 ip 0000000000454295 sp 00007ffc02678980 error 4 in python3.6[400000+26e000]
[262928.148360] pytest[17275]: segfault at 7f20212fbd58 ip 00007f20212fbd58 sp 00007ffc94a31de8 error 15 in libc-2.17.so[7f20212fb000+2000]
[262939.497128] pytest[17385]: segfault at 7ff0a03e9d58 ip 00007ff0a03e9d58 sp 00007ffd8be92d78 error 15 in libc-2.17.so[7ff0a03e9000+2000]

Another approach to PyObject handling

seems custom class implementation works well. Should we try to use same approach for python native types?

idea behind class implementation:

  1. developer does not have access to class instance, only to reference, reference is tight to gil lifetime
  2. to store reference to instance to rust struct, instance ref needs to be converted to Py<CLS> instance.

same approach could be used for native objects:

  1. access to PyObject can be restricted to &'p PyObject, 'p is gil livetime
  2. to store ref, it would need to be converted to Py<PyObject>. alternative: instead of Py<PyObject>, PyObject itself can be smart pointer, (it can be universal py pointer),
    but specific classes like PyList or PyTuple can be converted to Py<PyTuple> for storage purpose
    or to PyObject pointer.

pros: for native object references:

  1. PyClone can be replace with normal Clone
  2. no need to acquire Gil for reference counting
  3. no need for py parameter for any function call.

attribute access and `py: Python` parameter

when developer defines new class, pyo3 actually rewrite code of struct, so for example:

#[py:class]
struct MyCLS {
  data: i32
}

becomes:

struct MyCLS {
  _unsafe_inner: PyObject
}

struct MyCLS_Storage {
  data: i32
}

impl MyCLS {
  fn data(&self, py: Python) -> &i32 {...}
  fn data_mut(&self, py: Python) -> &mut i32 {...}
}

I think this is confusing. first of all access to attribute is not obvious and plus all apis are polluted with py: Python.

as a note, we do this because we actually store data on PyObject instance, and all memory for MyCLS is managed by python.

also we create special MyCLS::create_instance() method that accepts all attributes.

here is some idea:

struct PyPtr<T> {
   inner: ffi:PyObject,
   _t: PhantomeData<T>
}

struct Py<'p T> {
   inner: ffi:PyObject,
   _t: PhantomeData<&'p GILGuard>,
}

impl<T> PyPtr<T> {
  fn as_ref(&self, py: Python<'p>) -> Py<'p T>;
  fn into_ref(self, py: Python<'p>) -> Py<'p T>;
}

impl<'p> Py<'p> {
  fn as_ref() -> &'p T;

  fn as_ptr(&self) -> PyPtr<T>;
  fn into_ptr(self) -> PyPtr<T>;
}

impl<'p> Deref for Py<'p> {
  fn deref(self) -> &'p T;
}

I am not sure if this going to work.

Generate getter/setter for fields

Add proc attr that automatically creates getter and setter for struct field

#[py::class]
struct cls {
    #[prop(setter, getter)]
    num: i32
}

Translating futures into generators

What are your thoughts on being able to translate a future into something like a python generator or async function?

It'd probably be tricky because of lifetimes and cpython interpreter internals, but I reckon having a way to do asynchronous things transparently between Rust and Python would be pretty cool.

Provide comparison between PyO3 and rust-cpython

When I come to the PyO3 frontpage, having never seen PyO3 before, my first questions are "how is this different from rust-cpython?" and "Why would I want to use this instead?"

So far, all I've been able to determine is:

  1. Judging by #5 and my experience using rust-cpython on stable, this adds a dependency on nightly Rust.
  2. This uses attributes rather than macros
  3. I don't remember the list of ToPyObject impls being this long in rust-cpython.

It'd be a good idea to add a blurb to the README explaining:

  1. What motivated the fork (ie. how PyO3's goals differ from rust-cpython's)
  2. What PyO3 does better
  3. What PyO3 does worse (ie. successfully compiling on stable)

buffer::test::test_array_buffer fails on macOS

Python 3.6.1

---- buffer::test::test_array_buffer stdout ----
	thread 'buffer::test::test_array_buffer' panicked at 'called `Result::unwrap()` on an `Err` value: PyErr { ptype: <class 'ImportError'>, pvalue: Some(ImportError('dlopen(/usr/local/var/pyenv/versions/3.6.1/lib/python3.6/lib-dynload/array.cpython-36m-darwin.so, 2): Symbol not found: _PyUnicode_AsUnicode\n  Referenced from: /usr/local/var/pyenv/versions/3.6.1/lib/python3.6/lib-dynload/array.cpython-36m-darwin.so\n  Expected in: flat namespace\n in /usr/local/var/pyenv/versions/3.6.1/lib/python3.6/lib-dynload/array.cpython-36m-darwin.so',)), ptraceback: None }', src/libcore/result.rs:859
stack backtrace:
   0:        0x10ee56653 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::h34a7b169ac42b490
   1:        0x10ee58538 - std::panicking::default_hook::{{closure}}::hcc7f46907143dca1
   2:        0x10ee580ff - std::panicking::default_hook::h9cd165f254d86e53
   3:        0x10ee5a987 - std::panicking::rust_panic_with_hook::h2bd2f0b446f0face
   4:        0x10ee5a824 - std::panicking::begin_panic::h1732f61ecaaa434e
   5:        0x10ee5a792 - std::panicking::begin_panic_fmt::h2948dd4668f99175
   6:        0x10ee5a6f7 - rust_begin_unwind
   7:        0x10ee83200 - core::panicking::panic_fmt::hb2e726f3b579b19d
   8:        0x10ec7c94a - core::result::unwrap_failed::h39dbcd24d04994f5
   9:        0x10ec7104d - <core::result::Result<T, E>>::unwrap::hbc5ffec2e7604cfd
  10:        0x10ecbcb0d - pyo3::buffer::test::test_array_buffer::h5c35f98ee8f623ce
  11:        0x10ee27371 - <F as test::FnBox<T>>::call_box::h25c8de40327cf077
  12:        0x10ee5bafa - __rust_maybe_catch_panic
  13:        0x10ee1b7e1 - std::sys_common::backtrace::__rust_begin_short_backtrace::hf5cfceb0e0eecdf5
  14:        0x10ee1c577 - std::panicking::try::do_call::h925dfbccc5e1b5d9
  15:        0x10ee5bafa - __rust_maybe_catch_panic
  16:        0x10ee22594 - <F as alloc::boxed::FnBox<A>>::call_box::h70bc89ffeca4ac62
  17:        0x10ee57b75 - std::sys::imp::thread::Thread::new::thread_start::h5852519f9f48a1f2
  18:     0x7fff8e54693a - _pthread_body
  19:     0x7fff8e546886 - _pthread_start

Create rust type for exceptions defined in python

at the moment if you need to raise exception defined in python code, first you need to import it then store type object somewhere in static variable, then for each raise operation you need to create python instance and only then you can use it as err.

better approach would be to create actual rust type and attach to it required python type info. then it would be possible just call PyErr::new::<SomeType>() instead of PyErr::from_instance

Fix __str__ method

PyObjectProtocol::__str__ has to accept encoding and error params. Python3 only

Custom class name

Allow to override python class name, something like:

#[py::class(MyClass)]
struct test {
}

Better Iterator support

  1. we need to add std::iter::IntoIterator for PyTuple, PyList, PyDict
  2. all iterators need to work with $PyObjectRef
  3. PyIterator does not need to use py.from_xxx_ptr api, it has <'p> already. (this needs some thoughts)

Change sig of PyIterProtocol.__next__ method ?

Should we change method signature for __next__ method?
at the moment developer is responsible for returning StopIteration exception:

PyIterProtocol.__next__() -> PyResult<Success>

should we change it, and handle StopIteration internally?

PyIterProtocol.__next__() -> PyResult<Option<Success>>

"_: Python" in README.md results in an error

In the README.md example, the line

fn sum_as_string_py(_: Python, a:i64, b:i64) -> PyResult<String> {

results in an error

error: custom attribute panicked
 --> src/lib.rs:9:1
  |
9 | #[py::modinit(rust2py)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = help: message: unsupported argument: Wild

and the way to solve it is replace _: Python with _py: Python, or any other name for the variable.

PyDict::iter

add dictionary items iterator

Iterator<Item = (&PyObjectRef, &PyObjectRef)>

Make it easy to convert Rust error types to Python exceptions

error[E0277]: the trait bound `pyo3::PyErr: std::convert::From<std::io::Error>` is not satisfied
  --> src/lib.rs:11:17
   |
11 |     let mut f = fs::File::open(path)?;
   |                 ^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<std::io::Error>` is not implemented for `pyo3::PyErr`
   |
   = help: the following implementations were found:
             <pyo3::PyErr as std::convert::From<pyo3::PyDowncastError<'p>>>
   = note: required by `std::convert::From::from`

This is annoying, makes it hard to use try! or ?. We could implement From trait for some of the Rust error types like std::io::Error.

0.1.0 release

I think last task before release is documentation. I am happy with api.

Change sig of PyAsyncProtocol.__anext__ method ?

Should we change method signature for __anext__ method, similar to PyIterProtocol.__next__?

PyAsyncProtocol.__anext__() -> PyResult<Success>

to

PyAsyncProtocol.__anext__() -> PyResult<Option<Success>>

SIGSEGV: invalid memory reference in test_class

 RUST_BACKTRACE=1 cargo test --verbose --test test_class
       Fresh quote v0.3.15
       Fresh libc v0.2.23
       Fresh utf8-ranges v1.0.0
       Fresh num-traits v0.1.37
       Fresh log v0.3.7
       Fresh void v1.0.2
       Fresh regex-syntax v0.4.1
       Fresh unicode-xid v0.0.4
       Fresh memchr v1.0.1
       Fresh thread-id v3.1.0
       Fresh unreachable v0.1.1
       Fresh synom v0.11.3
       Fresh aho-corasick v0.6.3
       Fresh thread_local v0.3.3
       Fresh syn v0.11.11
       Fresh regex v0.2.2
       Fresh env_logger v0.4.2
       Fresh pyo3cls v0.1.0 (file:///Users/messense/Projects/PyO3/pyo3cls)
       Fresh pyo3 v0.1.0 (file:///Users/messense/Projects/PyO3)
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `/Users/messense/Projects/PyO3/target/debug/deps/test_class-27aaf9ec0adb8344`

running 26 tests
test binary_arithmetic ... ok
test delitem ... ok
test comparisons ... ok
test callable ... ok
test data_is_dropped ... ok
test context_manager ... ok
test class_with_properties ... ok
test contains ... ok
test empty_class ... ok
test empty_class_in_module ... ok
test empty_class_with_new ... ok
test new_with_two_args ... ok
test inplace_operations ... ok
error: process didn't exit successfully: `/Users/messense/Projects/PyO3/target/debug/deps/test_class-27aaf9ec0adb8344` (signal: 11, SIGSEGV: invalid memory reference)

Caused by:
  process didn't exit successfully: `/Users/messense/Projects/PyO3/target/debug/deps/test_class-27aaf9ec0adb8344` (signal: 11, SIGSEGV: invalid memory reference)

macOS 10.12.5
Python 3.6.1

0.2 release

I want to add #15 support before release.

@messense do you want to work on anything before 0.2 release?

Ideas and progress

  1. Seems rust-cpython is on hold right now, no changes, pr hangs without attention for months.
  2. as I have now enough experience with rust_cpython py_class implementation, I think it is not good solution. It is separate language within rust. it is very hard to understand and extend.

I work on new py class implementation based on procedural macros and specialization, but that requires rust nightly. should be ready in several days.

some of PyNumberProtocol methods are broken

current signature:

fn __add__(&self, rhs: Self::Other) -> Self::Result

but python treat it as:

fn __add__(lhs: Self::Left, rhs: Self::Right) -> Self::Result

&self is Self::Left or Self::Right, depends on actual expression

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.