Skip to content
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

Migrate to pyproject.toml #379

Merged
merged 24 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7eb62dd
Migrate to pyproject.toml, and convert the build to use py-build-cmake
nirosys Oct 17, 2024
c5c5590
Switch to pkgutil.extend_path (revisit PEP420, this may be unneeded),…
nirosys Oct 17, 2024
f143a42
Remove install.py; Update ion-c to latest (fixes sub-directory builds)
nirosys Oct 17, 2024
bff1587
Update benchmark-cli to use new python code path
nirosys Oct 18, 2024
36eeb75
Add new pyproject.toml and CMakeLists
nirosys Oct 19, 2024
f70105d
Adjust IONC_BUILD_TESTS override
nirosys Oct 21, 2024
41b60fe
Update main github actions workflow
nirosys Oct 21, 2024
a358f91
Install build module
nirosys Oct 21, 2024
f69ecf7
Lower pyparsing version to support 3.8
nirosys Oct 21, 2024
fd2ff2f
Further migration to pyproject.toml; move 3rd party configs into pypr…
nirosys Nov 8, 2024
d33a4a4
Update main workflow to include test dependencies when installing
nirosys Jan 15, 2025
56cf105
Update extension to link against decNumber as a static lib
nirosys Jan 15, 2025
480350e
Update extension name, changed to _ioncmodule and is now at the top-l…
nirosys Jan 15, 2025
eb51696
Fix version, it got lost in the rebase
nirosys Jan 15, 2025
12427ad
Remove requirements files; add py-build-cmake cache to gitignore
nirosys Jan 15, 2025
60ab03a
Add ionc_version method to return the version of Ion C used in the ex…
nirosys Jan 16, 2025
e6e16a2
Quick update pass for C Extension documentation
nirosys Jan 16, 2025
dddd696
Remove libm from linked libraries for windows build
nirosys Jan 16, 2025
1d5923b
Update regression test to use pyproject for PR source (will need to b…
nirosys Jan 17, 2025
2434835
Update package cache to only install dependencies, not our package
nirosys Jan 17, 2025
49ca0eb
Update benchmark cli's path for PR content to account for updated layout
nirosys Jan 17, 2025
070015a
Update virtualenv version to match HEAD's dependabot update
nirosys Jan 17, 2025
0ce40af
Remove unneeded virtualenv install; expand wording on C ext use; remo…
nirosys Jan 22, 2025
3fdf19b
Address actionlint issues
nirosys Jan 22, 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
11 changes: 5 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ jobs:

- name: Create a virtual environment
run: git submodule init && git submodule update && python3 -m venv ./venv && . venv/bin/activate
- run: pip install --upgrade setuptools
- run: pip install -r requirements.txt
- run: pip install -e .
- run: python -m pip install build
- run: python -m pip install '.[test]'
# Run our tests, but do not run the benchmark tests since they pull in libraries that do not have pypy support.
- run: py.test --ignore tests/test_benchmark_cli.py --ignore tests/test_benchmark_spec.py

Expand All @@ -42,8 +41,8 @@ jobs:

- name: Create a virtual environment
run: git submodule init && git submodule update && python3 -m venv ./venv && . venv/Scripts/activate
- run: pip install --upgrade setuptools
- run: pip install -r requirements.txt
- run: pip install -e .
- run: python -m pip install build
- run: python -m build
- run: python -m pip install -e '.[test]'
# Run our tests, but do not run the benchmark tests since they pull in libraries that do not have pypy support.
- run: py.test --ignore tests/test_benchmark_cli.py --ignore tests/test_benchmark_spec.py
35 changes: 15 additions & 20 deletions .github/workflows/performance-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ env:
specs: '{command:read,format:ion_text} {command:write,format:ion_text} {command:read,format:ion_binary} {command:write,format:ion_binary}'
test_data_id: 'generated-test-data'
run_cli: 'python amazon/ionbenchmark/ion_benchmark_cli.py'
run_cli_new: 'python src-python/amazon/ionbenchmark/ion_benchmark_cli.py'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just replace run_cli instead of run_cli_new?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new run_cli_new is temporary, to allow this PR to run the perf regression workflow. Since it pulls down the current HEAD which has the pre-PR layout, I need to run the benchmark CLI from that revision with run_cli.

Once this PR is merged, then I can follow up with a PR to replace run_cli with run_cli_new, so that the perf regression workflow continues working using the src-python layout for everything.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense.



jobs:
Expand All @@ -38,7 +39,7 @@ jobs:
mkdir -p testData
for test in nestedStruct nestedList sexp realWorldDataSchema01 realWorldDataSchema02 realWorldDataSchema03
do
java -jar $jar_file generate -S ${{env.data_size}} --input-ion-schema $schema_dir/${test}.isl testData/${test}.10n
java -jar "$jar_file" generate -S "${{env.data_size}}" --input-ion-schema "$schema_dir/${test}.isl" "testData/${test}.10n"
done
- name: Upload test Ion Data to artifacts
uses: actions/upload-artifact@v4
Expand All @@ -55,23 +56,20 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '3.13'
cache: 'pip'
cache-dependency-path: |
**/requirements.txt
**/requirements_benchmark.txt
cache-dependency-path: pyproject.toml
- run: |
pip install -r requirements.txt
[ -e "requirements_benchmark.txt" ] && pip install -r requirements_benchmark.txt # include benchmark requirements if they exist.
# TODO: See if there's a way to cache the ion-c build output if it hasn't changed
python -m pip freeze '.[test,benchmarking]' > requirements.txt # capture only dependencies.
python -m pip install -r requirements.txt

detect-regression:
name: Check
runs-on: ubuntu-latest
needs: [generate-test-data, prepopulate-pip-cache]
strategy:
matrix:
python-version: ['3.9', '3.11']
python-version: ['3.13']
test-data: ['nestedStruct', 'nestedList', 'sexp', 'realWorldDataSchema01', 'realWorldDataSchema02', 'realWorldDataSchema03']
fail-fast: false
steps:
Expand All @@ -95,9 +93,7 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: |
**/requirements.txt
**/requirements_benchmark.txt
cache-dependency-path: pyproject.toml

- name: Download Test Data
id: 'download'
Expand All @@ -106,12 +102,13 @@ jobs:
name: ${{env.test_data_id}}

# Generates performance results for the previous commit
- name: Create a virtual environment
- name: Create a virtual environment for baseline
working-directory: ./baseline
run: |
pip install -r requirements.txt
[ -e "requirements_benchmark.txt" ] && pip install -r requirements_benchmark.txt # include benchmark requirements if they exist.
pip install .

- name: Run baseline performance benchmark
id: 'baseline'
working-directory: ./baseline
Expand All @@ -125,17 +122,15 @@ jobs:
echo "report=$PWD/report.ion" >> "$GITHUB_OUTPUT"

# Generates performance results for the current commit
- name: Create a virtual environment and setup the package
- name: Create a virtual environment for PR changes
working-directory: ./new
run: |
pip install -r requirements.txt
[ -e "requirements_benchmark.txt" ] && pip install -r requirements_benchmark.txt # include benchmark requirements if they exist.
pip install .
run: pip install '.[test,benchmarking]'

- name: Run new performance benchmark
id: 'new'
working-directory: ./new
run: |
${{env.run_cli}} spec '${{env.specs}}' -d '${{env.spec_defaults}}' \
${{env.run_cli_new}} spec '${{env.specs}}' -d '${{env.spec_defaults}}' \
-O '{input_file:"${{steps.download.outputs.download-path}}/${{ matrix.test-data }}.10n"}' \
-o "$PWD/report.ion" -r '${{env.report_statistics}}'
echo "::group::Ion Report"
Expand All @@ -146,4 +141,4 @@ jobs:
# Compare results and identify regression
- name: Detect performance regression
working-directory: ./new
run: ${{env.run_cli}} compare --fail ${{steps.baseline.outputs.report}} ${{steps.new.outputs.report}} -c '${{env.compare_statistics}}'
run: ${{env.run_cli_new}} compare --fail ${{steps.baseline.outputs.report}} ${{steps.new.outputs.report}} -c '${{env.compare_statistics}}'
17 changes: 7 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@ jobs:

- name: Create a virtual environment
run: git submodule init && git submodule update && python3 -m venv ./venv && . venv/bin/activate
- name: Install dependencies..
run: |
pip install --upgrade setuptools
pip install -r requirements.txt
pip install -e .
- name: Run Tests
run: py.test --ignore tests/test_benchmark_cli.py --ignore tests/test_benchmark_spec.py
- run: python -m pip install build
- run: python -m build .
- run: python -m pip install -e .
- run: py.test --ignore tests/test_benchmark_cli.py --ignore tests/test_benchmark_spec.py

source-distribution:
if: startsWith(github.ref, 'refs/tags/')
Expand All @@ -40,13 +37,13 @@ jobs:
- uses: actions/checkout@v4

- name: Build sdist
run: python3 setup.py sdist
run: python -m pip install build && python -m build -s

- name: Upload source to Github
uses: actions/upload-artifact@v4
with:
name: source
path: ./dist/amazon.ion-*.tar.gz
path: ./dist/amazon_ion-*.tar.gz

- uses: aws-actions/configure-aws-credentials@v4
with:
Expand All @@ -60,7 +57,7 @@ jobs:

- name: Upload source to s3
run: |
zip ion-python-source ./dist/amazon.ion-*.tar.gz
zip ion-python-source ./dist/amazon_ion-*.tar.gz
aws s3 mv ion-python-source.zip ${{ secrets.AWS_SOURCE_BUCKET_URL }} --acl bucket-owner-full-control

- name: Install the released source from PYPI
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
/amazon/ion/ion-c-build/
/temp_*.ion
/temp_*.10n

/.py-build-cmake_cache
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
url = https://github.com/amazon-ion/ion-tests
branch = master
[submodule "ion-c"]
path = ion-c
path = src/ion-c
url = https://github.com/amazon-ion/ion-c
branch = master
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.6 FATAL_ERROR)
project(amazon)

add_subdirectory(src)
73 changes: 65 additions & 8 deletions C_EXTENSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,73 @@ b'\xe0\x01\x00\xea\xe9\x81\x83\xd6\x87\xb4\x83abc\xd3\x8a!{'

## Development

Architecture of Ion Python C extension:
The Ion Python C extension is built as part of the PEP 517 build process using py-build-cmake, and leaning on
Ion C's existing cmake build. A revision of Ion C is included as a submodule in this repo under `src/ion-c`.
If you would like to update the version of Ion C, simply update the submodule to point to the desired revision.

The file `src/CMakeLists.txt` acts as the build script for the C extension itself, which then includes the Ion C
codebase into the build tree.

With the extension built, it will be exposed to python as `amazon._ioncmodule`. For example:
```python
>>> import amazon._ioncmodule as ionc
>>> ionc.ionc_version()
'v1.1.3 (rev: d61c09a)'
>>>
```
ioncmodule.c
|
|
Ion C -------> Ion C binaries -----> setup.py ------> C extension -------------------> Ion Python simpleion module
compile setup import ionc module

The `amazon.ion.simpleion` module then makes use of this extension when it is available to provide more efficient
Ion reading and writing. Importing `amazon._ioncmodule` directly can determine if it is available, however simpleion
also provides the field `__IS_C_EXTENSION_SUPPORTED`.
```python
>>> import amazon.ion.simpleion as ion
>>> ion.__IS_C_EXTENSION_SUPPORTED
True
>>>
```

In order to build the extension, along with the package itself, we can use python's build module:
```python
ion-python# python -m build .
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
- py-build-cmake~=0.1.8
* Getting build dependencies for sdist...
* Building sdist...
* Building wheel from sdist
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
- py-build-cmake~=0.1.8
* Getting build dependencies for wheel...
* Building wheel...
...
Successfully built amazon_ion-0.13.0.tar.gz and amazon_ion-0.13.0-cp310-cp310-linux_x86_64.whl
```
This will build both the source wheel, and the binary wheel for the current system. Installing the module can
be done with pip. Depending on what you're doing with the package you may want to install different dependencies.
Different sets of optional dependencies are provided, such as `test`, and `benchmarking`. More details can be
found in the `pyproject.toml`.

To install the package and dependencies for unit tests you can run:
```python
ion-python# python -m pip install '.[test]'
Processing /ion-python
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: amazon_ion
Building wheel for amazon_ion (pyproject.toml) ... done
Created wheel for amazon_ion: filename=amazon_ion-0.13.0-cp310-cp310-linux_x86_64.whl size=573770 sha256=96ef01efea7519a1a38d9fc9e42139ab82125aafa328cfb4a4823458de802fa1
Stored in directory: /root/.cache/pip/wheels/78/55/f9/c6d69051d6a93c725251429f62d0d5b7d16d8c982a3772d666
Successfully built amazon_ion
Installing collected packages: amazon_ion
Attempting uninstall: amazon_ion
Found existing installation: amazon_ion 0.13.0
Uninstalling amazon_ion-0.13.0:
Successfully uninstalled amazon_ion-0.13.0
Successfully installed amazon_ion-0.13.0
```
After setup, C extension will be built and imported to simpleion module. If there are changes in `ioncmodule.c`, build the latest C extension by running `python setup.py build_ext --inplace`.
Installing with `-e` will also allow you to update the python side of the package without having to re-install.


## Technical Details
Expand Down
Loading
Loading