Skip to content

Commit 85ee6ab

Browse files
authored
Migrate to pyproject.toml (#379)
* Migrate to pyproject.toml, and convert the build to use py-build-cmake * Switch to pkgutil.extend_path (revisit PEP420, this may be unneeded), and update paths for ionc headers in extension * Remove install.py; Update ion-c to latest (fixes sub-directory builds) * Update benchmark-cli to use new python code path * Add new pyproject.toml and CMakeLists * Adjust IONC_BUILD_TESTS override * Update main github actions workflow * Install build module * Lower pyparsing version to support 3.8 * Further migration to pyproject.toml; move 3rd party configs into pyproject, update release workflow, and address max-int digits issue for test vectors * Update main workflow to include test dependencies when installing * Update extension to link against decNumber as a static lib * Update extension name, changed to _ioncmodule and is now at the top-level * Fix version, it got lost in the rebase * Remove requirements files; add py-build-cmake cache to gitignore * Add ionc_version method to return the version of Ion C used in the extension * Quick update pass for C Extension documentation * Remove libm from linked libraries for windows build * Update regression test to use pyproject for PR source (will need to be updated to do the same for baseline once merged) * Update package cache to only install dependencies, not our package * Update benchmark cli's path for PR content to account for updated layout * Update virtualenv version to match HEAD's dependabot update * Remove unneeded virtualenv install; expand wording on C ext use; remove commented cmake code * Address actionlint issues
1 parent 71ec37a commit 85ee6ab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+237
-368
lines changed

.github/workflows/main.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ jobs:
2121

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

@@ -42,8 +41,8 @@ jobs:
4241

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

.github/workflows/performance-regression.yml

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ env:
1515
specs: '{command:read,format:ion_text} {command:write,format:ion_text} {command:read,format:ion_binary} {command:write,format:ion_binary}'
1616
test_data_id: 'generated-test-data'
1717
run_cli: 'python amazon/ionbenchmark/ion_benchmark_cli.py'
18+
run_cli_new: 'python src-python/amazon/ionbenchmark/ion_benchmark_cli.py'
1819

1920

2021
jobs:
@@ -38,7 +39,7 @@ jobs:
3839
mkdir -p testData
3940
for test in nestedStruct nestedList sexp realWorldDataSchema01 realWorldDataSchema02 realWorldDataSchema03
4041
do
41-
java -jar $jar_file generate -S ${{env.data_size}} --input-ion-schema $schema_dir/${test}.isl testData/${test}.10n
42+
java -jar "$jar_file" generate -S "${{env.data_size}}" --input-ion-schema "$schema_dir/${test}.isl" "testData/${test}.10n"
4243
done
4344
- name: Upload test Ion Data to artifacts
4445
uses: actions/upload-artifact@v4
@@ -55,23 +56,20 @@ jobs:
5556
- uses: actions/checkout@v4
5657
- uses: actions/setup-python@v5
5758
with:
58-
python-version: '3.10'
59+
python-version: '3.13'
5960
cache: 'pip'
60-
cache-dependency-path: |
61-
**/requirements.txt
62-
**/requirements_benchmark.txt
61+
cache-dependency-path: pyproject.toml
6362
- run: |
64-
pip install -r requirements.txt
65-
[ -e "requirements_benchmark.txt" ] && pip install -r requirements_benchmark.txt # include benchmark requirements if they exist.
66-
# TODO: See if there's a way to cache the ion-c build output if it hasn't changed
63+
python -m pip freeze '.[test,benchmarking]' > requirements.txt # capture only dependencies.
64+
python -m pip install -r requirements.txt
6765
6866
detect-regression:
6967
name: Check
7068
runs-on: ubuntu-latest
7169
needs: [generate-test-data, prepopulate-pip-cache]
7270
strategy:
7371
matrix:
74-
python-version: ['3.9', '3.11']
72+
python-version: ['3.13']
7573
test-data: ['nestedStruct', 'nestedList', 'sexp', 'realWorldDataSchema01', 'realWorldDataSchema02', 'realWorldDataSchema03']
7674
fail-fast: false
7775
steps:
@@ -95,9 +93,7 @@ jobs:
9593
with:
9694
python-version: ${{ matrix.python-version }}
9795
cache: 'pip'
98-
cache-dependency-path: |
99-
**/requirements.txt
100-
**/requirements_benchmark.txt
96+
cache-dependency-path: pyproject.toml
10197

10298
- name: Download Test Data
10399
id: 'download'
@@ -106,12 +102,13 @@ jobs:
106102
name: ${{env.test_data_id}}
107103

108104
# Generates performance results for the previous commit
109-
- name: Create a virtual environment
105+
- name: Create a virtual environment for baseline
110106
working-directory: ./baseline
111107
run: |
112108
pip install -r requirements.txt
113109
[ -e "requirements_benchmark.txt" ] && pip install -r requirements_benchmark.txt # include benchmark requirements if they exist.
114110
pip install .
111+
115112
- name: Run baseline performance benchmark
116113
id: 'baseline'
117114
working-directory: ./baseline
@@ -125,17 +122,15 @@ jobs:
125122
echo "report=$PWD/report.ion" >> "$GITHUB_OUTPUT"
126123
127124
# Generates performance results for the current commit
128-
- name: Create a virtual environment and setup the package
125+
- name: Create a virtual environment for PR changes
129126
working-directory: ./new
130-
run: |
131-
pip install -r requirements.txt
132-
[ -e "requirements_benchmark.txt" ] && pip install -r requirements_benchmark.txt # include benchmark requirements if they exist.
133-
pip install .
127+
run: pip install '.[test,benchmarking]'
128+
134129
- name: Run new performance benchmark
135130
id: 'new'
136131
working-directory: ./new
137132
run: |
138-
${{env.run_cli}} spec '${{env.specs}}' -d '${{env.spec_defaults}}' \
133+
${{env.run_cli_new}} spec '${{env.specs}}' -d '${{env.spec_defaults}}' \
139134
-O '{input_file:"${{steps.download.outputs.download-path}}/${{ matrix.test-data }}.10n"}' \
140135
-o "$PWD/report.ion" -r '${{env.report_statistics}}'
141136
echo "::group::Ion Report"
@@ -146,4 +141,4 @@ jobs:
146141
# Compare results and identify regression
147142
- name: Detect performance regression
148143
working-directory: ./new
149-
run: ${{env.run_cli}} compare --fail ${{steps.baseline.outputs.report}} ${{steps.new.outputs.report}} -c '${{env.compare_statistics}}'
144+
run: ${{env.run_cli_new}} compare --fail ${{steps.baseline.outputs.report}} ${{steps.new.outputs.report}} -c '${{env.compare_statistics}}'

.github/workflows/release.yml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,10 @@ jobs:
2020

2121
- name: Create a virtual environment
2222
run: git submodule init && git submodule update && python3 -m venv ./venv && . venv/bin/activate
23-
- name: Install dependencies..
24-
run: |
25-
pip install --upgrade setuptools
26-
pip install -r requirements.txt
27-
pip install -e .
28-
- name: Run Tests
29-
run: py.test --ignore tests/test_benchmark_cli.py --ignore tests/test_benchmark_spec.py
23+
- run: python -m pip install build
24+
- run: python -m build .
25+
- run: python -m pip install -e .
26+
- run: py.test --ignore tests/test_benchmark_cli.py --ignore tests/test_benchmark_spec.py
3027

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

4239
- name: Build sdist
43-
run: python3 setup.py sdist
40+
run: python -m pip install build && python -m build -s
4441

4542
- name: Upload source to Github
4643
uses: actions/upload-artifact@v4
4744
with:
4845
name: source
49-
path: ./dist/amazon.ion-*.tar.gz
46+
path: ./dist/amazon_ion-*.tar.gz
5047

5148
- uses: aws-actions/configure-aws-credentials@v4
5249
with:
@@ -60,7 +57,7 @@ jobs:
6057

6158
- name: Upload source to s3
6259
run: |
63-
zip ion-python-source ./dist/amazon.ion-*.tar.gz
60+
zip ion-python-source ./dist/amazon_ion-*.tar.gz
6461
aws s3 mv ion-python-source.zip ${{ secrets.AWS_SOURCE_BUCKET_URL }} --acl bucket-owner-full-control
6562
6663
- name: Install the released source from PYPI

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
/amazon/ion/ion-c-build/
1818
/temp_*.ion
1919
/temp_*.10n
20-
20+
/.py-build-cmake_cache

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
url = https://github.com/amazon-ion/ion-tests
44
branch = master
55
[submodule "ion-c"]
6-
path = ion-c
6+
path = src/ion-c
77
url = https://github.com/amazon-ion/ion-c
88
branch = master

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
cmake_minimum_required(VERSION 3.6 FATAL_ERROR)
2+
project(amazon)
3+
4+
add_subdirectory(src)

C_EXTENSION.md

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,73 @@ b'\xe0\x01\x00\xea\xe9\x81\x83\xd6\x87\xb4\x83abc\xd3\x8a!{'
7676

7777
## Development
7878

79-
Architecture of Ion Python C extension:
79+
The Ion Python C extension is built as part of the PEP 517 build process using py-build-cmake, and leaning on
80+
Ion C's existing cmake build. A revision of Ion C is included as a submodule in this repo under `src/ion-c`.
81+
If you would like to update the version of Ion C, simply update the submodule to point to the desired revision.
82+
83+
The file `src/CMakeLists.txt` acts as the build script for the C extension itself, which then includes the Ion C
84+
codebase into the build tree.
85+
86+
With the extension built, it will be exposed to python as `amazon._ioncmodule`. For example:
87+
```python
88+
>>> import amazon._ioncmodule as ionc
89+
>>> ionc.ionc_version()
90+
'v1.1.3 (rev: d61c09a)'
91+
>>>
8092
```
81-
ioncmodule.c
82-
|
83-
|
84-
85-
Ion C -------> Ion C binaries -----> setup.py ------> C extension -------------------> Ion Python simpleion module
86-
compile setup import ionc module
93+
94+
The `amazon.ion.simpleion` module then makes use of this extension when it is available to provide more efficient
95+
Ion reading and writing. Importing `amazon._ioncmodule` directly can determine if it is available, however simpleion
96+
also provides the field `__IS_C_EXTENSION_SUPPORTED`.
97+
```python
98+
>>> import amazon.ion.simpleion as ion
99+
>>> ion.__IS_C_EXTENSION_SUPPORTED
100+
True
101+
>>>
102+
```
103+
104+
In order to build the extension, along with the package itself, we can use python's build module:
105+
```python
106+
ion-python# python -m build .
107+
* Creating isolated environment: venv+pip...
108+
* Installing packages in isolated environment:
109+
- py-build-cmake~=0.1.8
110+
* Getting build dependencies for sdist...
111+
* Building sdist...
112+
* Building wheel from sdist
113+
* Creating isolated environment: venv+pip...
114+
* Installing packages in isolated environment:
115+
- py-build-cmake~=0.1.8
116+
* Getting build dependencies for wheel...
117+
* Building wheel...
118+
...
119+
Successfully built amazon_ion-0.13.0.tar.gz and amazon_ion-0.13.0-cp310-cp310-linux_x86_64.whl
120+
```
121+
This will build both the source wheel, and the binary wheel for the current system. Installing the module can
122+
be done with pip. Depending on what you're doing with the package you may want to install different dependencies.
123+
Different sets of optional dependencies are provided, such as `test`, and `benchmarking`. More details can be
124+
found in the `pyproject.toml`.
125+
126+
To install the package and dependencies for unit tests you can run:
127+
```python
128+
ion-python# python -m pip install '.[test]'
129+
Processing /ion-python
130+
Installing build dependencies ... done
131+
Getting requirements to build wheel ... done
132+
Preparing metadata (pyproject.toml) ... done
133+
Building wheels for collected packages: amazon_ion
134+
Building wheel for amazon_ion (pyproject.toml) ... done
135+
Created wheel for amazon_ion: filename=amazon_ion-0.13.0-cp310-cp310-linux_x86_64.whl size=573770 sha256=96ef01efea7519a1a38d9fc9e42139ab82125aafa328cfb4a4823458de802fa1
136+
Stored in directory: /root/.cache/pip/wheels/78/55/f9/c6d69051d6a93c725251429f62d0d5b7d16d8c982a3772d666
137+
Successfully built amazon_ion
138+
Installing collected packages: amazon_ion
139+
Attempting uninstall: amazon_ion
140+
Found existing installation: amazon_ion 0.13.0
141+
Uninstalling amazon_ion-0.13.0:
142+
Successfully uninstalled amazon_ion-0.13.0
143+
Successfully installed amazon_ion-0.13.0
87144
```
88-
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`.
145+
Installing with `-e` will also allow you to update the python side of the package without having to re-install.
89146

90147

91148
## Technical Details

0 commit comments

Comments
 (0)