Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
c7dde7e
Initial implementation of vendoring.
ZeroIntensity Jan 9, 2025
57d2f44
Fix names.
ZeroIntensity Jan 9, 2025
6b9fa7d
Drop the _impl suffix.
ZeroIntensity Jan 9, 2025
eaa312f
Fixup names on for the generated header-only version of pyawaitable.
AraHaan Jan 10, 2025
1f7c253
Reformat some header files.
ZeroIntensity Jan 11, 2025
687db9d
Strip unneeded code.
ZeroIntensity Jan 11, 2025
fbc97e1
Change vendor location.
ZeroIntensity Jan 11, 2025
271becb
Remove setuptools.
ZeroIntensity Jan 11, 2025
c8b9e8d
Setup automatic Hatch build.
ZeroIntensity Jan 11, 2025
19b2a50
Other stuff.
ZeroIntensity Jan 11, 2025
1b0caaa
Remove .clang-format
ZeroIntensity Jan 11, 2025
48d9b10
Handle extern variables in the vendor script.
ZeroIntensity Jan 11, 2025
506e9a3
Set up a test build for setuptools.
ZeroIntensity Jan 11, 2025
2ebd2a3
Stuff.
ZeroIntensity Jan 11, 2025
05cf885
Remove debug code.
ZeroIntensity Jan 11, 2025
4826dbd
Fix setuptools build.
ZeroIntensity Jan 11, 2025
0dd8fbd
Fix some workflows.
ZeroIntensity Jan 11, 2025
f43f07c
Force a specific order on generating pyawaitable.h from the C source …
AraHaan Jan 11, 2025
ddf78fb
Force users of the generated header to use Python 3.9+ to compile.
AraHaan Jan 11, 2025
79a3514
Removed PyAwaitable_AwaitFunction.
AraHaan Jan 11, 2025
398c447
Merge remote-tracking branch 'upstream/master' into vendor
AraHaan Jan 11, 2025
3f88aea
Relocate the Py_LIMITED_API check on the generated pyawaitable.h header.
AraHaan Jan 11, 2025
e47b875
Mark PyAwaitable_Type with _PyAwaitable_API.
AraHaan Jan 12, 2025
38d7ef4
WIP, Updated PyAwaitable_New that takes in module object.
AraHaan Jan 12, 2025
5ba93df
Create a dummy internal pyawaitable module object instead of storing …
AraHaan Jan 23, 2025
33dc051
Allow hatch_build.py to be executed manually.
ZeroIntensity Feb 9, 2025
69fc7f3
Store types on the interpreter state.
ZeroIntensity Feb 9, 2025
da75431
Clean up genwrapper_next()
ZeroIntensity Feb 9, 2025
abb8549
Add some optimization macros.
ZeroIntensity Feb 9, 2025
6a82aaa
Use some likely and unlikely indications.
ZeroIntensity Feb 9, 2025
24a303a
Don't pass a module to PyAwaitable_Init() in the tests.
ZeroIntensity Feb 9, 2025
eaace18
Undefine macros at the end of the vendor.
ZeroIntensity Feb 9, 2025
20403d3
Fix variable name.
ZeroIntensity Feb 9, 2025
d59fb6d
Rename some tests.
ZeroIntensity Feb 9, 2025
cb4a8b7
Add comment for requirements.txt
ZeroIntensity Feb 9, 2025
0e4aa30
Fix some PEP 7 compliance.
ZeroIntensity Feb 9, 2025
2b2294e
Do some reformatting.
ZeroIntensity Feb 9, 2025
a108c74
Fix use of _pyawaitable_modules
ZeroIntensity Feb 9, 2025
b3fceea
Change some of the docs.
ZeroIntensity Feb 9, 2025
8d0b359
Skeleton for new tests.
ZeroIntensity Feb 10, 2025
1e7a34a
Fix build failures.
ZeroIntensity Feb 10, 2025
e295c24
Remove tracer bullet.
ZeroIntensity Feb 10, 2025
2aa7cd6
Rename pyproject.
ZeroIntensity Feb 10, 2025
1b8f291
Fix test setup.
ZeroIntensity Feb 11, 2025
616a6c3
Add object files to gitignore.
ZeroIntensity Feb 11, 2025
3e8566f
Store an actual module object on the interpreter state.
ZeroIntensity Feb 11, 2025
577283e
Update optimize.h
ZeroIntensity Feb 13, 2025
4018f56
Apply suggestions from code review
AraHaan Feb 13, 2025
38a4734
Apply suggestions from code review
AraHaan Feb 13, 2025
2015c82
Add Py_mod_multiple_interpreters & Py_mod_gil module slots.
AraHaan Feb 14, 2025
986fabd
Fix type name.
ZeroIntensity Feb 14, 2025
273037e
Store a dictionary instead of a module on the interpreter.
ZeroIntensity Feb 14, 2025
261f383
Pull from origin.
ZeroIntensity Feb 15, 2025
25c0956
Fix merge conflict.
ZeroIntensity Feb 15, 2025
3073b61
Fix build failure.
ZeroIntensity Feb 15, 2025
eccf0e1
GetModule -> GetState to fix undefined symbol
ZeroIntensity Feb 15, 2025
c4dcadf
Fix missing call to PyType_Ready()
ZeroIntensity Feb 15, 2025
2254667
Remove unused internal function.
ZeroIntensity Feb 15, 2025
33fe0a8
Rename public functions for a consistent style.
ZeroIntensity Feb 15, 2025
bc257e5
Use DONE_IF_OK()
ZeroIntensity Feb 15, 2025
3f7ffb8
Remove PyAwaitable_Type from the public API in favor of PyAwaitable_G…
ZeroIntensity Feb 15, 2025
1418585
Use PyAwaitable_GetType() in the implementation
ZeroIntensity Feb 15, 2025
28ab279
Expect a MemoryError and fix warnings.
ZeroIntensity Feb 15, 2025
8192d76
Fix tests.
ZeroIntensity Feb 15, 2025
2fac7b4
Reformat.
ZeroIntensity Feb 15, 2025
0c966a8
minor crash bugfix
AraHaan Feb 15, 2025
fbda70d
Add a simple test for add_await
ZeroIntensity Feb 15, 2025
a6b15df
Use a more portable solution for tests that require coroutines.
ZeroIntensity Feb 15, 2025
5a18731
Add a test for AddAwait() with no memory.
ZeroIntensity Feb 15, 2025
51ed010
Fix build failures.
ZeroIntensity Feb 15, 2025
302fe60
Fix return value indicator.
ZeroIntensity Feb 15, 2025
ba7e4fb
Expect a MemoryError since the ValueError can't be allocated
ZeroIntensity Feb 15, 2025
ca703c0
Add some tests surrounding awaitable behavior.
ZeroIntensity Feb 15, 2025
886a2d3
Add an error message _pyawaitable_test can't be imported.
ZeroIntensity Feb 15, 2025
8075fc1
Get CI working for the new tests.
ZeroIntensity Feb 15, 2025
c3217b0
Always build now that it's fast.
ZeroIntensity Feb 15, 2025
2cf0a0c
Always run on pull requests.
ZeroIntensity Feb 15, 2025
e180709
Fix merge conflicts.
ZeroIntensity Feb 15, 2025
966d9af
Only get ParamSpec if type checking is enabled.
ZeroIntensity Feb 15, 2025
105d14f
Properly fix ParamSpec use.
ZeroIntensity Feb 15, 2025
1c46cfa
Include pyawaitable.h to get the PyErr_GetRaisedException() backport
ZeroIntensity Feb 15, 2025
5677c81
Fix NULL error restoration.
ZeroIntensity Feb 15, 2025
a106426
Remove flaky tests.
ZeroIntensity Feb 15, 2025
bd54041
Apparently those were less flaky than I thought.
ZeroIntensity Feb 15, 2025
aac8760
Apparently, exception allocation failure isn't a MemoryError on <3.11
ZeroIntensity Feb 15, 2025
90a713a
Don't use stupid Py_Is
ZeroIntensity Feb 15, 2025
77ffea9
Py -> PY :(
ZeroIntensity Feb 15, 2025
745f03c
Fix syntax errors in the build workflow.
ZeroIntensity Feb 16, 2025
7391283
Add release level versioning to the vendor script.
ZeroIntensity Feb 16, 2025
2f1218e
Fix some quirks with pip.
ZeroIntensity Feb 16, 2025
e025785
Install with verbosity enabled for tests.
ZeroIntensity Feb 16, 2025
64b7467
Fix sdist targets.
ZeroIntensity Feb 16, 2025
36b9bb6
Replace . with - to fix stupid pip.
ZeroIntensity Feb 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .clang-format

This file was deleted.

149 changes: 53 additions & 96 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,102 +1,59 @@
name: Build Wheels
name: Build

on:
push:
tags:
- v*
branches:
- master
paths:
- 'src/**'
pull_request:
branches:
- master
paths:
- '.github/workflows/build.yml'
push:
tags:
- v*
branches:
- master
paths:
- 'src/**'
pull_request:
branches:
- master

concurrency:
group: build-${{ github.head_ref }}
cancel-in-progress: true

env:
CIBW_BUILD: cp3{9,10,11,12,13}-*
PYAWAITABLE_OPTIMIZED: 1
group: build-${{ github.head_ref }}
cancel-in-progress: true

jobs:
binary-wheels-standard:
name: Binary wheels for ${{ startsWith(matrix.os, 'macos-') && 'macOS' || startsWith(matrix.os, 'windows-') && 'Windows' || 'Linux' }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
- uses: actions/checkout@v2
with:
# Fetch all tags
fetch-depth: 0

- name: Build wheels
uses: pypa/[email protected]
env:
CIBW_ARCHS_MACOS: x86_64
HATCH_BUILD_HOOKS_ENABLE: "true"

- uses: actions/upload-artifact@v4
with:
name: artifacts
path: wheelhouse/*.whl
if-no-files-found: error

binary-wheels-arm:
name: Build Linux wheels for ARM
runs-on: ubuntu-latest
if: >
github.event_name == 'push'
&&
(github.ref == 'refs/heads/master' || startsWith(github.event.ref, 'refs/tags'))

steps:
- uses: actions/checkout@v2
with:
# Fetch all tags
fetch-depth: 0

- name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: arm64

- name: Build wheels
uses: pypa/[email protected]
env:
CIBW_ARCHS_LINUX: aarch64
HATCH_BUILD_HOOKS_ENABLE: "true"

- uses: actions/upload-artifact@v4
with:
name: artifacts
path: wheelhouse/*.whl
if-no-files-found: error

publish:
name: Publish release
needs:
- binary-wheels-standard
- binary-wheels-arm
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')

steps:
- uses: actions/download-artifact@v3
with:
name: artifacts
path: dist

- name: Push build artifacts to PyPI
uses: pypa/[email protected]
with:
skip_existing: true
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
pure-python-wheel-and-sdist:
name: Build a pure Python wheel and source distribution
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Install build dependencies
run: python -m pip install --upgrade build

- name: Build
run: python -m build

- uses: actions/upload-artifact@v4
with:
name: artifacts
path: dist/*
if-no-files-found: error

publish:
name: Publish release
needs:
- pure-python-wheel-and-sdist
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')

steps:
- uses: actions/download-artifact@v4
with:
name: artifacts
path: dist

- name: Push build artifacts to PyPI
uses: pypa/[email protected]
with:
skip_existing: true
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
86 changes: 6 additions & 80 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ on:
branches:
- master
pull_request:
types:
- "opened"
- "reopened"
- "synchronize"
branches:
- master

concurrency:
group: test-${{ github.head_ref }}
Expand All @@ -35,8 +33,6 @@ jobs:
filters: |
source:
- 'src/**'
csource:
- 'src/_pyawaitable/**'

run-tests:
needs: changes
Expand All @@ -56,82 +52,14 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Install Pytest
run: pip install pytest pytest-asyncio typing_extensions

- name: Build PyAwaitable
run: pip install .
run: pip install . --verbose

- name: Build PyAwaitable Test Package
run: pip install setuptools wheel && pip install ./tests/extension/ --no-build-isolation
run: pip install ./tests --verbose

- name: Run tests
run: pytest -W error

memory-errors:
needs:
- changes
- run-tests
if: ${{ needs.changes.outputs.csource == 'true' }}
name: Check for memory errors
runs-on: ubuntu-latest
env:
PYTHONMALLOC: malloc
steps:
- uses: actions/checkout@v2

- name: Set up Python 3.12
uses: actions/setup-python@v2
with:
python-version: 3.12

- name: Install Pytest
run: |
pip install pytest pytest-asyncio pytest-memray typing_extensions
shell: bash

- name: Build PyAwaitable
run: pip install .

- name: Build PyAwaitable Test Package
run: pip install setuptools wheel && pip install tests/extension/ --no-build-isolation

- name: Install Valgrind
run: sudo apt-get update && sudo apt-get -y install valgrind

- name: Run tests with Valgrind
run: valgrind --suppressions=valgrind-python.supp --error-exitcode=1 pytest -x

memory-leaks:
needs:
- changes
- memory-errors
if: ${{ needs.changes.outputs.csource == 'true' }}
name: Check for memory leaks
runs-on: ubuntu-latest
env:
PYTHONMALLOC: malloc
steps:
- uses: actions/checkout@v2

- name: Set up Python 3.12
uses: actions/setup-python@v2
with:
python-version: 3.12

- name: Install Pytest
run: |
pip install pytest pytest-asyncio pytest-memray typing_extensions
shell: bash

- name: Build PyAwaitable
run: pip install .

- name: Build PyAwaitable Test Package
run: pip install setuptools wheel && pip install tests/extension/ --no-build-isolation

- name: Run tests with Memray tracking
run: pytest --enable-leak-tracking -W error --stacks=50 --native
run: python -W error -m unittest tests/main.py --verbose

tests-pass:
runs-on: ubuntu-latest
Expand All @@ -140,12 +68,10 @@ jobs:

needs:
- run-tests
- memory-errors
- memory-leaks

steps:
- name: Check whether all tests passed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
allowed-skips: ${{ toJSON(needs) }}
allowed-skips: ${{ toJSON(needs) }}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ __pycache__/
*.egg-info
test/
dist/
pyawaitable-vendor/
*.so
src/pyawaitable/pyawaitable.h
pcbuild/
*.o

# LSP
compile_flags.txt
Expand All @@ -17,6 +19,7 @@ build/
*.sln
*.user
*.vcxproj*
.clang-format

# Misc
test.py
Expand Down
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased

- Moved away from function pointer tables for loading PyAwaitable--everything is now vendored upon installation.
- Improved performance with compiler optimizations.
- `PyAwaitable_` prefixes are now required, and the old `pyawaitable_*` functions have been removed.
- The warning emitted when a PyAwaitable object is not awaited is now a `ResourceWarning` (was a `RuntimeWarning`).
- `PyAwaitable_AddAwait` now raises a `ValueError` if the passed object is `NULL` or self, and also now raises a `TypeError` if the passed object is not a coroutine.
- **Breaking Change:** `PyAwaitable_Init` no longer takes a module object.
- **Breaking Change:** Renamed `awaitcallback` to `PyAwaitable_Callback`
- **Breaking Change:** Renamed `awaitcallback_err` to `PyAwaitable_Error`
- **Breaking Change:** Renamed `defercallback` to `PyAwaitable_Defer`

## [1.4.0] - 2025-02-09

Expand Down
16 changes: 2 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,8 @@ It's highly recommended to do this inside of a [virtual environment](https://doc

## Running Tests

PyAwaitable uses three libraries for unit testing:

- [pytest](https://docs.pytest.org/en/8.2.x/), as the general testing framework.
- [pytest-asyncio](https://pytest-asyncio.readthedocs.io/en/latest/), for asynchronous tests.
- [pytest-memray](https://pytest-memray.readthedocs.io/en/latest/), for detection of memory leaks. Note this isn't available for Windows, so simply omit this in your installation.

Installation is trivial:

```
$ pip install pytest pytest-asyncio pytest-memray
```

Tests generally access the PyAwaitable API functions using [ctypes](https://docs.python.org/3/library/ctypes.html), but there's also an extension module solely built for tests called `_pyawaitable_test`. You can install this with the following command:
PyAwaitable uses [Hatch](https://hatch.pypa.io), so that will handle everything for you:

```
$ pip install setuptools wheel && pip install ./test/extension/ --no-build-isolation
$ hatch test
```
1 change: 0 additions & 1 deletion MANIFEST.in

This file was deleted.

Loading