profile
viewpoint
David Hewitt davidhewitt @reinfer Oxford, UK https://www.linkedin.com/in/david-hewitt-4a393775/ Addicted to Rust. Full-stack developer; other than Rust you'll find me using Python, Vue.js and C++.

davidhewitt/password-check 2

A simple pwned password checker in Rust.

davidhewitt/fix-rs 1

fix-rs is a FIX (Financial Information Exchange) engine written in Rust.

davidhewitt/mio-anonymous-pipes 1

mio::Evented wrapper for windows anonymous pipes

davidhewitt/addr 0

Reliably parse domain names and email addresses in Rust

davidhewitt/alacritty 0

A cross-platform, GPU-accelerated terminal emulator

davidhewitt/Async-PyO3-Examples 0

A repo to help people to interact with asyncio with PyO3 native extensions

davidhewitt/atom-vue 0

Vue component file syntax for Atom

davidhewitt/ax88179_178a 0

Experimental network driver written in Rust

issue commentPyO3/pyo3

Fails to build on Windows: FromUtf8Error

Yes, it builds now. Thank you!

rtentser

comment created time in an hour

push eventPyO3/pyo3

davidhewitt

commit sha bc25f2ac33a1a70f5d17c5c5a11f17e2c6b6e100

Upload documentation for master

view details

push time in 9 hours

pull request commentPyO3/pyo3

Remove `unsafe` for some safe functions

iirc, removing unsafe shouldn't actually be a breaking change. all functions can be called in an unsafe block and also can be coerced to unsafe function pointers, so the worst that can happen is code gets a warning that it has a unnecessary unsafe block.

nw0

comment created time in 14 hours

issue commentPyO3/pyo3

option to select the python installation used

Thanks for the answer and all the options :) Well my case is a bit more tricky. I'm working on a proprietary software in which the python part must be hidden. To have a python script running it could be a weakness in my application ... I will figure it out.

jimy-byerley

comment created time in 17 hours

issue commentPyO3/pyo3

Fails to build on Windows: FromUtf8Error

Yes, it can be. I've made a mistake of using cyrillic username when installed the system.

rtentser

comment created time in 21 hours

PR opened PyO3/pyo3

Remove `unsafe` for some safe functions

Closes #1389, which noted that some safe functions are marked unsafe.

Noted that this is a breaking change.

+9 -10

0 comment

6 changed files

pr created time in 21 hours

issue openedPyO3/pyo3

Fails to build on Windows: FromUtf8Error

🐛 Bug Reports

error: failed to run custom build command for `pyo3 v0.13.1`

Caused by:
  process didn't exit successfully: `C:\Users\Рома\Sources\helloCargo\target\debug\build\pyo3-44c835d8235e3b6f\build-script-build` (exit code: 1)
  --- stderr
  Error: FromUtf8Error { bytes: [118, 101, 114, 115, 105, 111, 110, 95, 109, 97, 106, 111, 114, 32, 51, 13, 10, 118, 101, 114, 115, 105, 111, 110, 95, 109, 105, 110, 111, 114, 32, 56, 13, 10, 105, 109, 112, 108, 101, 109, 101, 
110, 116, 97, 116, 105, 111, 110, 32, 67, 80, 121, 116, 104, 111, 110, 13, 10, 108, 100, 95, 118, 101, 114, 115, 105, 111, 110, 32, 51, 46, 56, 13, 10, 98, 97, 115, 101, 95, 112, 114, 101, 102, 105, 120, 32, 67, 58, 92, 85, 115, 101, 114, 115, 92, 208, 238, 236, 224, 92, 65, 112, 112, 68, 97, 116, 97, 92, 76, 111, 99, 97, 108, 92, 80, 114, 111, 103, 114, 97, 109, 115, 92, 80, 121, 116, 104, 111, 110, 92, 80, 121, 116, 104, 111, 110, 51, 56, 13, 10, 102, 114, 97, 109, 101, 119, 111, 114, 107, 32, 70, 97, 108, 115, 101, 13, 10, 115, 104, 97, 114, 101, 100, 32, 70, 97, 108, 115, 101, 13, 10, 101, 120, 101, 99, 117, 116, 97, 98, 108, 101, 32, 67, 58, 92, 85, 115, 101, 114, 115, 92, 208, 238, 236, 224, 92, 65, 112, 112, 68, 97, 116, 97, 92, 76, 111, 99, 97, 108, 92, 80, 114, 111, 103, 114, 97, 109, 115, 92, 80, 121, 116, 104, 111, 110, 92, 80, 121, 116, 104, 111, 110, 51, 56, 92, 112, 121, 116, 104, 
111, 110, 46, 101, 120, 101, 13, 10, 99, 97, 108, 99, 115, 105, 122, 101, 95, 112, 111, 105, 110, 116, 101, 114, 32, 56, 13, 10], error: Utf8Error { valid_up_to: 95, error_len: Some(1) } }
warning: build failed, waiting for other jobs to finish...
error: build failed

🌍 Environment

  • Your operating system and version: Windows 10

  • Your python version: 3.8.7

  • How did you install python (e.g. apt or pyenv)? Did you use a virtualenv?: Manual installation (exe from official site).

  • Your Rust version (rustc --version): 1.49.0 (e1884a8e3 2020-12-29)

  • Your PyO3 version: 0.12.4, 0.13.1

  • Have you tried using latest PyO3 master (replace version = "0.x.y" with git = "https://github.com/PyO3/pyo3")?: No.

💥 Reproducing

Just add

[dependencies.pyo3]
version = "0.13"
features = ["extension-module"]

to a project generated by cargo new and build.

created time in a day

pull request commentPyO3/pyo3

Added async/await example to the guide

I also took a look at the #[test] proc macros, and it turns out they were a bit easier than I thought they would be. Tests can be simplified to this now:

use std::{time::Duration, thread};

use pyo3::prelude::*;

#[pyo3_asyncio::tokio::test]
async fn test_async_sleep() -> PyResult<()> {
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(())
}

#[pyo3_asyncio::tokio::test]
fn test_blocking_sleep() -> PyResult<()> {
    thread::sleep(Duration::from_secs(1));
    Ok(())
}

pyo3_asyncio::testing::test_main!(#[pyo3_asyncio::tokio::main], "Example Test Suite");

Although many of the caveats still apply as I discussed here. I think it's a cleaner solution, but it is a breaking change, so idk if it should be included in the 0.13 release.

awestlake87

comment created time in a day

PR opened PyO3/pyo3

Use fully-qualified Result in pyobject_native_type_base

This allows using macros such as create_exception! in modules where Result has been aliased, for example to a single-parameter type with a module-specific error type. And in any event, seems like good macro hygiene to use fully-qualified names wherever possible.

+2 -2

0 comment

1 changed file

pr created time in a day

pull request commentPyO3/pyo3

Added async/await example to the guide

Also, I created a PR to create proc macros like #[pyo3_asyncio::async_std::main] to simplify the initialization. If we were to merge PR #10 in pyo3-asyncio we could condense the initialization example down to this:

#[pyo3_asyncio::async_std::main]
async fn main() -> PyResult<()> {
    let fut = Python::with_gil(|py| {
        let asyncio = py.import("asyncio")?;
        // convert asyncio.sleep into a Rust Future
        pyo3_asyncio::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
    })?;
    fut.await?;
    Ok(())
}
awestlake87

comment created time in a day

pull request commentPyO3/pyo3

Added async/await example to the guide

Alright, I think I've addressed (or at least responded to) all of your comments and added some of my own minor changes. Let me know what you guys think!

awestlake87

comment created time in 2 days

Pull request review commentPyO3/pyo3

Added async/await example to the guide

+# Async / Await++Both Python and Rust have support for async functions, but bindings for these functions are not as +straightforward as they are for blocking functions. Both languages have a fairly distinct model for +async functions and Python's needs in particular can sometimes be restrictive.++[pyo3-asyncio](https://github.com/awestlake87/pyo3-asyncio) was created to provide conversions +between async Python and async Rust as well as manage the nitty gritty details of Python's event +loop.++## Awaiting an Async Python Function in Rust++Let's take a look at a dead simple async Python function:++```python+async def py_sleep():+    await asyncio.sleep(1)+```++This function simply sleeps for 1 second and returns. So what does this look like to PyO3? ++First, it helps to have a little background on Python's async functions. +Async functions in python are simply functions that return a `coroutine` object. You can read more about +`coroutine` objects in the [Python 3 docs](https://docs.python.org/3/library/asyncio-task.html), but+for our purposes, we really don't need to know much about them. The key factor here is that calling+an `async` function is _just like calling a regular function_, the only difference is that we have+to do something special with the object that it returns.++Normally in Python, that something special is the `await` keyword, but in Rust, we don't have the +luxury of using Python's syntax. Luckily, Rust also has an `await` keyword that does something+similar, we just need to find a way of converting a `&PyAny` into a Rust future so we can use the+`await` keyword on it.++That's where pyo3-asyncio comes in. `pyo3_asyncio::into_future` performs this conversion for us:++```rust+let future = Python::with_gil(|py| {+    // import the module containing the py_sleep function+    let example = py.import("example")?;++    // calling the py_sleep method like a normal function returns a coroutine+    let coroutine = example.call_method0("py_sleep")?;++    // convert the coroutine into a Rust future+    pyo3_asyncio::into_future(py, coroutine)+})?;++// await the future+future.await;+```++## Awaiting a Rust Future in Python++Here we have the same async function as before written in Rust using the +[`async-std`](https://async.rs/) runtime:++```rust+async fn rust_sleep() {+    async_std::task::sleep(Duration::from_secs(1)).await;+}+```++Similar to Python, Rust's async functions also return a special object called a+`Future`:++```rust+let future = rust_sleep();+```++We can convert this future object into Python to make it "Awaitable". This tells Python that you can+use the `await` keyword with it. In order to do this, we'll call +`pyo3_asyncio::async_std::into_coroutine`:++```rust+#[pyfunction]+fn call_rust_sleep(py: Python) -> PyResult<PyObject> {+    pyo3_asyncio::async_std::into_coroutine(py, async move {+        rust_sleep().await;+        Ok(())+    })+}+```++In Python, we can call this pyo3 function just like any other async function:++```python+from example import call_rust_sleep++async def rust_sleep():+    await call_rust_sleep()+```++## Managing Event Loops++Python's event loop requires some special treatment, especially regarding the main thread. Some of+Python's Asyncio features, like proper signal handling, require control over the main thread, which+doesn't always play well with Rust.++Luckily, Rust's event loops are pretty flexible and don't _need_ control over the main thread, so in+pyo3-asyncio, we decided the best way to handle Rust/Python interop was to just surrender the main+thread to Python and run Rust's event loops in the background. Unfortunately, since most event loop +implementations _prefer_ control over the main thread, this can still make some things awkward.++### PyO3 Asyncio Initialization++Because Python needs to control the main thread, we can't use the convenient proc macros from Rust+runtimes to handle the main function or test functions. ++Instead, the initialization for PyO3 has to be done manually from the main function and the main 

I haven't been following the conversation on the auto-initialize, so I'm not sure what I should add here. AFAIK there are no problems with the current implementation using the auto-initialize feature. Are you suggesting that we add an example of what someone should do if they want to disable auto-initialize?

Signal handling appears to work properly in my project that uses pyo3-asyncio, so that difference between Py_InitializeEx(0) and Py_InitializeEx(1) kinda surprises me. Maybe that's something we should look at a bit further.

awestlake87

comment created time in 2 days

Pull request review commentPyO3/pyo3

Added async/await example to the guide

+# Async / Await++Both Python and Rust have support for async functions, but bindings for these functions are not as +straightforward as they are for blocking functions. Both languages have a fairly distinct model for +async functions and Python's needs in particular can sometimes be restrictive.++[pyo3-asyncio](https://github.com/awestlake87/pyo3-asyncio) was created to provide conversions +between async Python and async Rust as well as manage the nitty gritty details of Python's event +loop.++## Awaiting an Async Python Function in Rust++Let's take a look at a dead simple async Python function:++```python+async def py_sleep():+    await asyncio.sleep(1)+```++This function simply sleeps for 1 second and returns. So what does this look like to PyO3? ++First, it helps to have a little background on Python's async functions. +Async functions in python are simply functions that return a `coroutine` object. You can read more about +`coroutine` objects in the [Python 3 docs](https://docs.python.org/3/library/asyncio-task.html), but+for our purposes, we really don't need to know much about them. The key factor here is that calling+an `async` function is _just like calling a regular function_, the only difference is that we have+to do something special with the object that it returns.++Normally in Python, that something special is the `await` keyword, but in Rust, we don't have the +luxury of using Python's syntax. Luckily, Rust also has an `await` keyword that does something+similar, we just need to find a way of converting a `&PyAny` into a Rust future so we can use the+`await` keyword on it.++That's where pyo3-asyncio comes in. `pyo3_asyncio::into_future` performs this conversion for us:

I added the future docs.rs links to the guide for many of the pyo3-asyncio functions. The only difference is that I noticed - and _ are different between the crate name and the folder name in the docs so the actual links should be something like this: https://docs.rs/pyo3-asyncio/latest/pyo3_asyncio/fn.into_future.html. I discovered this by poking around with the async-std docs.rs links.

awestlake87

comment created time in 2 days

Pull request review commentPyO3/pyo3

Added async/await example to the guide

+# Async / Await++Both Python and Rust have support for async functions, but bindings for these functions are not as +straightforward as they are for blocking functions. Both languages have a fairly distinct model for +async functions and Python's needs in particular can sometimes be restrictive.++[pyo3-asyncio](https://github.com/awestlake87/pyo3-asyncio) was created to provide conversions +between async Python and async Rust as well as manage the nitty gritty details of Python's event +loop.++## Awaiting an Async Python Function in Rust++Let's take a look at a dead simple async Python function:++```python+async def py_sleep():+    await asyncio.sleep(1)+```++This function simply sleeps for 1 second and returns. So what does this look like to PyO3? ++First, it helps to have a little background on Python's async functions. +Async functions in python are simply functions that return a `coroutine` object. You can read more about +`coroutine` objects in the [Python 3 docs](https://docs.python.org/3/library/asyncio-task.html), but+for our purposes, we really don't need to know much about them. The key factor here is that calling+an `async` function is _just like calling a regular function_, the only difference is that we have+to do something special with the object that it returns.++Normally in Python, that something special is the `await` keyword, but in Rust, we don't have the +luxury of using Python's syntax. Luckily, Rust also has an `await` keyword that does something+similar, we just need to find a way of converting a `&PyAny` into a Rust future so we can use the+`await` keyword on it.++That's where pyo3-asyncio comes in. `pyo3_asyncio::into_future` performs this conversion for us:++```rust+let future = Python::with_gil(|py| {+    // import the module containing the py_sleep function+    let example = py.import("example")?;++    // calling the py_sleep method like a normal function returns a coroutine+    let coroutine = example.call_method0("py_sleep")?;++    // convert the coroutine into a Rust future+    pyo3_asyncio::into_future(py, coroutine)+})?;++// await the future+future.await;+```++## Awaiting a Rust Future in Python++Here we have the same async function as before written in Rust using the +[`async-std`](https://async.rs/) runtime:++```rust+async fn rust_sleep() {+    async_std::task::sleep(Duration::from_secs(1)).await;+}+```++Similar to Python, Rust's async functions also return a special object called a+`Future`:++```rust+let future = rust_sleep();+```++We can convert this future object into Python to make it "Awaitable". This tells Python that you can

I was thinking about using code quotes here since the Python 3 docs seem to highlight the word awaitable the same as coroutine.

awestlake87

comment created time in 2 days

Pull request review commentPyO3/pyo3

Added async/await example to the guide

+# Async / Await++Both Python and Rust have support for async functions, but bindings for these functions are not as +straightforward as they are for blocking functions. Both languages have a fairly distinct model for +async functions and Python's needs in particular can sometimes be restrictive.++[pyo3-asyncio](https://github.com/awestlake87/pyo3-asyncio) was created to provide conversions +between async Python and async Rust as well as manage the nitty gritty details of Python's event +loop.++## Awaiting an Async Python Function in Rust++Let's take a look at a dead simple async Python function:++```python+async def py_sleep():+    await asyncio.sleep(1)+```++This function simply sleeps for 1 second and returns. So what does this look like to PyO3? ++First, it helps to have a little background on Python's async functions. +Async functions in python are simply functions that return a `coroutine` object. You can read more about +`coroutine` objects in the [Python 3 docs](https://docs.python.org/3/library/asyncio-task.html), but+for our purposes, we really don't need to know much about them. The key factor here is that calling+an `async` function is _just like calling a regular function_, the only difference is that we have+to do something special with the object that it returns.++Normally in Python, that something special is the `await` keyword, but in Rust, we don't have the +luxury of using Python's syntax. Luckily, Rust also has an `await` keyword that does something+similar, we just need to find a way of converting a `&PyAny` into a Rust future so we can use the+`await` keyword on it.++That's where pyo3-asyncio comes in. `pyo3_asyncio::into_future` performs this conversion for us:++```rust+let future = Python::with_gil(|py| {+    // import the module containing the py_sleep function+    let example = py.import("example")?;++    // calling the py_sleep method like a normal function returns a coroutine+    let coroutine = example.call_method0("py_sleep")?;++    // convert the coroutine into a Rust future+    pyo3_asyncio::into_future(py, coroutine)+})?;++// await the future+future.await;+```++## Awaiting a Rust Future in Python++Here we have the same async function as before written in Rust using the +[`async-std`](https://async.rs/) runtime:++```rust+async fn rust_sleep() {+    async_std::task::sleep(Duration::from_secs(1)).await;+}+```++Similar to Python, Rust's async functions also return a special object called a+`Future`:++```rust+let future = rust_sleep();+```++We can convert this future object into Python to make it "Awaitable". This tells Python that you can+use the `await` keyword with it. In order to do this, we'll call +`pyo3_asyncio::async_std::into_coroutine`:++```rust+#[pyfunction]+fn call_rust_sleep(py: Python) -> PyResult<PyObject> {

The return type here would actually be asyncio.Future here since the event loop waits on us to run the future on the Rust event loop and call asyncio.Future.set_result.

into_coroutine is a bit of a misnomer, but I wasn't really sure what to call it honestly. into_future is already taken, maybe into_awaitable would be a better name?

awestlake87

comment created time in 2 days

Pull request review commentPyO3/pyo3

Added async/await example to the guide

 - [Calling Python from Rust](python_from_rust.md) - [GIL, mutability and object types](types.md) - [Parallelism](parallelism.md)+- [Async / Await](async-await.md)

Ok, should I go ahead and do that here or do you want to do that as part of #1401?

awestlake87

comment created time in 2 days

pull request commentPyO3/pyo3

release: 0.13.2

I'm ok with merging it for 0.13.2. Like you said on the PR, the link to docs.rs should be pretty straightforward

davidhewitt

comment created time in 2 days

push eventProject-Dream-Weaver/Pyre

Harrison Burt

commit sha 15be2ee8e57d72d13b1e65321d5942a0e6fa952b

fix my dumbass

view details

Harrison Burt

commit sha 63c891821f1b8d553195923e1d9622d09767df37

lets just make a fork to test this...

view details

push time in 2 days

push eventProject-Dream-Weaver/Pyre

Harrison Burt

commit sha 79045f1b041d61ea4c6ee3d90bbcc94a23ddbca7

test call soon threadsafe

view details

push time in 2 days

startedbenpye/wsl-ssh-pageant

started time in 2 days

Pull request review commentPyO3/pyo3

guide: organise more chapters into sublevels

 macro_rules! py_run_impl {  /// Test readme and user guide #[doc(hidden)]+#[cfg(feature = "macros")] pub mod doc_test {     macro_rules! doc_comment {-        ($x:expr, $module:item) => {-            #[doc = $x]+        ($doc:expr, $module:item) => {+            #[doc = $doc]+            #[allow(non_snake_case)]             $module         };     }      macro_rules! doctest {-        ($x:expr, $y:ident) => {-            doc_comment!(include_str!($x), mod $y {});+        ($($path:ident)/+.md) => {+            $crate::paste::paste!(+                doc_comment!(+                    include_str!(concat!("..", $("/", stringify!($path)),+, ".md")),+                    mod [<$($path)_+ _md>] {}+                );+            );

Also, why is paste! necessary here?

davidhewitt

comment created time in 2 days

Pull request review commentPyO3/pyo3

guide: organise more chapters into sublevels

 macro_rules! py_run_impl {  /// Test readme and user guide #[doc(hidden)]+#[cfg(feature = "macros")] pub mod doc_test {     macro_rules! doc_comment {-        ($x:expr, $module:item) => {-            #[doc = $x]+        ($doc:expr, $module:item) => {+            #[doc = $doc]+            #[allow(non_snake_case)]             $module         };     }      macro_rules! doctest {-        ($x:expr, $y:ident) => {-            doc_comment!(include_str!($x), mod $y {});+        ($($path:ident)/+.md) => {+            $crate::paste::paste!(+                doc_comment!(+                    include_str!(concat!("..", $("/", stringify!($path)),+, ".md")),+                    mod [<$($path)_+ _md>] {}+                );+            );

Why do we need this? I prefer to keep this simple for future contributors.

davidhewitt

comment created time in 2 days

push eventProject-Dream-Weaver/Pyre

Harrison Burt

commit sha b1c589e78dd3a4970285d3a1a9b8be40409c25ff

start adding body parsing

view details

Harrison Burt

commit sha 2a2ef295ec3e8aedb7d3be46a46396759be3215a

Merge remote-tracking branch 'origin/main' into main

view details

push time in 2 days

push eventProject-Dream-Weaver/Pyre

Harrison Burt

commit sha 739b166cfe4cd2c1dd7b8d249b1afbccfaaeeb71

Update README.md

view details

push time in 2 days

push eventProject-Dream-Weaver/Pyre

chillfish8

commit sha 933008b67ea34aee2d7d1bbb834bd998fd2005d4

add jemalloc if on unix

view details

push time in 2 days

push eventProject-Dream-Weaver/Pyre

Harrison Burt

commit sha 5ef7a3c19866bec773fe7e6aa176fc2d8d156479

nvm drop trio support

view details

push time in 3 days

push eventProject-Dream-Weaver/Pyre

Harrison Burt

commit sha 8ab9e7d17eb8936d6052aecd09bcccb069834a2c

test trio support

view details

push time in 3 days

push eventProject-Dream-Weaver/Pyre

Harrison Burt

commit sha 44b75df82df5e6035f51fba87a8d0231c338415b

test stuff with benches on linux

view details

Harrison Burt

commit sha 8888ba46c1884e388ce88afe369dbe54e3d63173

Merge remote-tracking branch 'origin/main' into main

view details

push time in 3 days

pull request commentPyO3/pyo3

release: 0.13.2

I was thinking #1393 would be merged after this release since 0.13.2 would unblock the first public release of pyo3-asyncio. There are a few API doc links I'd like to add in there that would only be available after docs.rs generates them.

I could probably guess at what they would be in the meantime though, so it's up to you guys.

davidhewitt

comment created time in 3 days

issue commentPyO3/pyo3

Automatically implement Python getters and setters for public Rust struct fields

In that case, I think #[pyclass(dataclass)] is preferable over #[pyclass(pod)] or #[pyclass(get_set_all)]. "pod" is potentially confusing for people who don't know the term. "get_set_all" is explicit, but it can't be used as the same attribute for #1376. "dataclass" references an existing well known Python concept and concisely encapsulated the behavior both from this PR and from #1376.

kangalioo

comment created time in 3 days

more