-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add Python bindings #269
Conversation
3d750c2
to
0107fdf
Compare
Can we configure pyo3 to rename the enum variants so they follow the ALL_CAPS_SNAKE_CASE style that's typical of Python, rather than the CamelCase style of Rust? |
I suggest we format the example using Black. |
There is no automatic way of achieving this unfortunately. We'd have to add I thought it was not a good idea to create new enums for this single purpose. |
I really don't want to ship the Python bindings with that obviously unidiomatic style. That's the kind of thing that would be really tedious to fix later, particularly for users. I suggest implementing a derive macro to automatically add the PyO3-specific attribute on all the enum variants. This means adding a crate like |
Can we remove Black from the requirements.txt file that we provide with the example? Users don't need Black in order to run the example. |
After some testing, I'm not even sure if it's possible. If I add Manually adding the full attribute that would be needed, that is
Unless I miss something, implementing this directly inside PyO3 might be the only solution. |
I've opened PyO3/pyo3#3383 in that direction. But if we want to quickly ship something, duplicating the enums might be the only option. |
I'm not in a hurry to release the Python bindings. Let's take the time to do it right. So I think we should wait for the response to the new PyO3 issue and see if either we or the PyO3 developers can implement something that helps all PyO3 users with this problem. |
08d540d
to
93e0251
Compare
My work to support renaming enum variants was merged into PyO3 so I'm switching to temporarily pull the master branch. There is discussion to release PyO3 0.20 in a few weeks. As always, if someone can test the pygame example on macOS and report back here that would be nice. I would be surprised if it doesn't work out of the box since it's SDL under the hood. |
Unfortunately, the Pygame example does not run on macOS. Attempting to instantiate the macOS adapter fails with the following error:
|
Thanks @mwcampbell for the feedback. Looking at pygame's source code it's now obvious. It's actually the safest way to pass a pointer, but I'm not sure we should only expect to receive a PyCapsule here. I'll see how other windowing libraries do this. |
3b1d9e4
to
c1251b0
Compare
While rebasing this I played a bit with ruff this morning. My understanding is that it doesn't do formatting but linting. As such it would not replace black. It was able to point me to a couple of issues in the pygame example, the question is: do we want to run these two tools just for one Python file? This would mean adding another step in the formatting CI job. |
531ac2a
to
e746a50
Compare
@mwcampbell The Pygame example should work on macOS hopefully now. Can you please confirm? |
Ruff has an experimental formatter that should be pretty similar to Black in its output. While it is not yet stable, given this project doesn't have that much Python code, I think it should be sufficient. |
4acd838
to
08bea62
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope you don't mind a random drive by review, I saw this and felt like I might have some useful words. Feel free to disregard my comments if they're outside the goals of this PR. It's cool to see more Rust-Python wheels!
- uses: actions/checkout@v3 | ||
- uses: actions/setup-python@v4 | ||
with: | ||
python-version: 3.7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Python 3.7 was EOL'd on 2023-06-07
. Also, this should probably match the python version in the release
job which could be part of the matrix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was OK when I started this PR, but it should be updated indeed.
uses: PyO3/maturin-action@v1 | ||
with: | ||
target: ${{ matrix.rust-target }} | ||
manylinux: auto | ||
args: --release --out dist --sdist |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's my understanding (I could be wrong) that this will only build the wheel for the python version specified in the actions/python@v4
action (in this case 3.7
). Getting a good matrix can be rough. In the past, I've used pypa/cibuildwheel
as seen here which definitely has some negatives (the whole build runs in a docker container which can have different libraries than the host).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. In fact, here is the link to the download page of a test upload I did: https://test.pypi.org/project/accesskit/#files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL about test.pypi.org. Cool.
Well, I don't work on the Python client for Fluvio anymore (and it looks like there hasn't been a release in a while) but it's my recollection that pypa/cibuildwheel
action took a long time (~30 minutes) because each of the python versions was done in serial.
One thing that I also recall being a pretty rough time was if there's OpenSSL 3 in the dependency tree. This uses a different version of perl than OpenSSL 1 and the pypa images didn't have it. I'm currently failing at finding the github issue for this :/
You might be able to get away with just adding a python-version
list to your matrix and have them run in parallel. It's unclear what kind of target OS/arch/python version support you're looking for. pypa/cibuildwheel
has a lot of python versions and targets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have to check, maybe we have to link to OpenSSL on Linux through the zbus crate.
I see that some Rust projects only publish pre-compiled wheels for one Python version, is it acceptable? I know pretty much nothing about how Python packaging works, but I know that it didn't take long for my system to generate the wheel using the tarball. It includes the pre-built native binaries so at least the user doesn't have to do that.
Again, thank you very much for stopping by.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, zbus doesn't depend on OpenSSL. On Linux, we don't depend on any C libraries other than the base system libraries (libc, pthread, etc.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't 100% sure as I am not familiar with D-Bus authentication mechanism, but no OpenSSL involved here thankfully!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coming back to this: we actually only need to build wheels for the oldest Python version we want to support because I'm using the limited ABI3 feature which provide backward compatibility. Since we are not doing much from the Python side, it's best to enable it and only build for, let's say, Pyton 3.9.
Thanks @simlay for the review. We certainly need more feedback from people like you who have previous experience building Python packages with Rust. |
08bea62
to
33fbfc2
Compare
Finally verified that the pygame example runs on macOS. Reviewing the code now. |
I'm not sure I understand why it's necessary to place pyproject.toml at the root of the repository, rather than under bindings/python. Is it just so we can include the license files in the built packages, or is there another reason as well? |
The doc comment for the Python Windows There are still two references to Python 3.7: in the new CI workflow, and in the README for the pygame example. My review is now complete. |
7e5e105
to
a86e68c
Compare
@mwcampbell I believe to have addressed all your comments. I needed to test the CI on my fork before pushing it. I've attached the wheels to the GitHub release as well. As for the macOS adapter, I went with a PyCapsule as it would be more cumbersome to create a |
I'd like to have #324 merged before we release accesskit_python 0.1 as the API of the Unix adapter will have to be updated. |
The latest changes look good to me. So now I just have to figure out how we'll publish on PyPI. |
2aada59
to
ab9ac0c
Compare
@mwcampbell I currently don't have access to a Linux desktop environment to test the pygame example. If you can do it before merging, otherwise I'll take care of it later. Thanks. |
The pygame example still works on Linux! |
Just one more question before we merge this: It looks like the CI workflow doesn't currently use PyPI's "trusted publisher" feature. How hard would it be to use that feature? |
I've setup the workflow to use this feature. You'll need to configure it on the PyPI side as described on this page. Information you will have to provide as shown in a screenshot on the page:
Not sure about switching from your personal account to an organization though. |
Adds a new crate containing bindings for the Python programming language.
Wheels will be automatically uploaded to
pypi.org
for the most common platforms/architectures.The pygame example is on par with the SDL example, except for Linux where hit-testing is probably not possible due to pygame not exposing window real size.
I'm not 100% sure about the unsendable types: is it enough to just document the fact that they must only be used from the main thread? Or should we protect users more?
TODO
PYPI_TOKEN
repository secret