From 0c048817ee8c2c8fd0637c83f1e2e6c0239f9273 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 14:44:37 +0100 Subject: [PATCH 01/27] try utilizing cores if available for tests --- pyproject.toml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5d6fc86..a815351 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,8 @@ docs = [ test = [ "pytest", "pytest-coverage", - "pytest-lazy-fixtures" + "pytest-lazy-fixtures", + "pytest-xdist" ] [project.entry-points."mapchete.cli.commands"] @@ -84,7 +85,17 @@ branch = true source = ["mapchete_eo"] [tool.pytest.ini_options] -addopts = "--durations 20 --verbose --nf --cov=mapchete_eo --cov-report=term-missing:skip-covered" +addopts = [ + "--durations=20", + "--verbose", + "--nf", + "--cov=mapchete_eo", + "--cov-report=term-missing:skip-covered", + "--cov-append", + "--numprocesses=auto", + "--dist=loadscope", + "--max-worker-restart=3" +] testpaths = ["tests"] markers = [ "remote: marks tests which require acces to remote resources (deselect with '-m \"not remote\"')", From 8202661038cc43b19fd4b340a562cdbf28b1712c Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 15:18:33 +0100 Subject: [PATCH 02/27] try making tests run more concurrent --- .github/workflows/python-package.yml | 11 +- .github/workflows/sync-dependencies.yml | 74 +++- .test_durations | 495 ++++++++++++++++++++++++ pyproject.toml | 8 +- uv.lock | 14 + 5 files changed, 588 insertions(+), 14 deletions(-) create mode 100644 .test_durations diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index e8c62e2..1685315 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -21,6 +21,7 @@ jobs: matrix: python-version: ["3.10", "3.11", "3.12", "3.13"] os: ["ubuntu-latest"] + split: [1, 2, 3, 4] steps: - uses: actions/checkout@v4 @@ -69,7 +70,15 @@ jobs: CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt - run: uv run pytest -v --cov mapchete_eo --cov-report xml:coverage.xml --cov-report=term-missing:skip-covered --junitxml=pytest.xml + run: | + # Use --splits 4 (matches matrix) and --group ${{ matrix.split }} + uv run pytest -v \ + --splits 4 \ + --group ${{ matrix.split }} \ + --cov mapchete_eo \ + --cov-report xml:coverage.xml \ + --cov-report=term-missing:skip-covered \ + --junitxml=pytest.xml - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5 diff --git a/.github/workflows/sync-dependencies.yml b/.github/workflows/sync-dependencies.yml index 114ea60..2196740 100644 --- a/.github/workflows/sync-dependencies.yml +++ b/.github/workflows/sync-dependencies.yml @@ -1,25 +1,44 @@ name: sync-dependencies on: + push: + branches: + - main + paths-ignore: + - "docs/**" + - "README.rst" + - "conda/meta.yaml" schedule: - cron: '0 0 * * *' pull_request: - paths: - - "pyproject.toml" workflow_dispatch: jobs: sync-and-prepare: runs-on: ubuntu-latest outputs: - changed: ${{ steps.check.outputs.changed }} + any_changed: ${{ steps.changed-files.outputs.any_changed }} + sync_needed: ${{ steps.check.outputs.changed }} steps: - uses: actions/checkout@v4 with: + # Fetch more than 1 commit so the action can compare branches + fetch-depth: 0 ref: ${{ github.event.pull_request.head.ref || github.ref }} + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v45 + with: + files: | + pyproject.toml + uv.lock + - name: Install uv uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + cache-dependency-glob: "uv.lock" - name: Sync and Upgrade run: | @@ -30,12 +49,16 @@ jobs: run: | uvx pyproject2conda yaml -f pyproject.toml --output conda/meta.yaml --python-include infer - - name: Check for changes + - name: Check for Changes id: check + # Only evaluate changes if we actually ran the sync steps above + if: github.event_name != 'pull_request' || steps.changed-files.outputs.any_changed == 'true' run: | if [ -n "$(git status --porcelain)" ]; then echo "changed=true" >> $GITHUB_OUTPUT - fi + else + echo "changed=false" >> $GITHUB_OUTPUT + fi - name: Upload artifacts for testing if: steps.check.outputs.changed == 'true' @@ -48,13 +71,17 @@ jobs: run-tests: needs: sync-and-prepare - if: needs.sync-and-prepare.outputs.changed == 'true' + if: needs.sync-and-prepare.outputs.sync_needed == 'true' uses: ./.github/workflows/python-package.yml secrets: inherit finalize: needs: [sync-and-prepare, run-tests] - if: success() + if: | + always() && + (needs.run-tests.result == 'success' || needs.run-tests.result == 'skipped') && + needs.sync-and-prepare.result == 'success' && + needs.sync-and-prepare.outputs.sync_needed == 'true' runs-on: ubuntu-latest permissions: contents: write @@ -74,6 +101,7 @@ jobs: run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" + git pull --rebase origin ${{ github.event.pull_request.head.ref }} git add uv.lock conda/meta.yaml git commit -m "chore: sync uv.lock and conda recipe (tests passed)" || echo "No changes" git push origin HEAD:${{ github.event.pull_request.head.ref }} @@ -90,4 +118,34 @@ jobs: delete-branch: true assignees: Scartography reviewers: ungarj - labels: dependencies, automated-pr \ No newline at end of file + labels: dependencies, automated-pr + + summary: + name: Final Summary + needs: [sync-and-prepare, run-tests, finalize] + if: always() + runs-on: ubuntu-latest + steps: + - name: Report Status + run: | + function get_status_msg() { + case "$1" in + success) echo "โœ… success" ;; + failure) echo "โŒ failure" ;; + skipped) echo "โญ๏ธ skipped" ;; + *) echo "๐Ÿšซ $1" ;; + esac + } + + echo "### ๐Ÿš€ Sync Workflow Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Job | Result |" >> $GITHUB_STEP_SUMMARY + echo "| :--- | :--- |" >> $GITHUB_STEP_SUMMARY + echo "| **Sync and Prepare** | $(get_status_msg ${{ needs.sync-and-prepare.result }}) |" >> $GITHUB_STEP_SUMMARY + echo "| **Run Tests** | $(get_status_msg ${{ needs.run-tests.result }}) |" >> $GITHUB_STEP_SUMMARY + echo "| **Finalize (Push/PR)** | $(get_status_msg ${{ needs.finalize.result }}) |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [[ "${{ needs.sync-and-prepare.result }}" == "failure" || "${{ needs.run-tests.result }}" == "failure" || "${{ needs.finalize.result }}" == "failure" ]]; then + exit 1 + fi \ No newline at end of file diff --git a/.test_durations b/.test_durations new file mode 100644 index 0000000..3561134 --- /dev/null +++ b/.test_durations @@ -0,0 +1,495 @@ +{ + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[addition]": 0.02747501799603924, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[darken_only]": 0.023157491930760443, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[difference]": 0.02528056496521458, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[divide]": 0.0205113019910641, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[dodge]": 0.025632940989453346, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[grain_extract]": 0.016219747019931674, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[grain_merge]": 0.016658742038998753, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[hard_light]": 0.04240808601025492, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[lighten_only]": 0.023242022027261555, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[multiply]": 0.015484275063499808, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[normal]": 0.020084135059732944, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[overlay]": 0.024758323037531227, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[screen]": 0.017105940962210298, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[soft_light]": 0.030472446989733726, + "tests/image_operations/test_compositing.py::test_blend_base_all_functions[subtract]": 0.016983597015496343, + "tests/image_operations/test_compositing.py::test_composite_dispatch[addition]": 0.01745839003706351, + "tests/image_operations/test_compositing.py::test_composite_dispatch[darken_only]": 0.02161226695170626, + "tests/image_operations/test_compositing.py::test_composite_dispatch[difference]": 0.01554171391762793, + "tests/image_operations/test_compositing.py::test_composite_dispatch[divide]": 0.016168369038496166, + "tests/image_operations/test_compositing.py::test_composite_dispatch[dodge]": 0.043999356974381953, + "tests/image_operations/test_compositing.py::test_composite_dispatch[grain_extract]": 0.016078629007097334, + "tests/image_operations/test_compositing.py::test_composite_dispatch[grain_merge]": 0.016296723042614758, + "tests/image_operations/test_compositing.py::test_composite_dispatch[hard_light]": 0.02932557003805414, + "tests/image_operations/test_compositing.py::test_composite_dispatch[lighten_only]": 0.015507381001953036, + "tests/image_operations/test_compositing.py::test_composite_dispatch[multiply]": 0.04293998400680721, + "tests/image_operations/test_compositing.py::test_composite_dispatch[normal]": 0.0264303790172562, + "tests/image_operations/test_compositing.py::test_composite_dispatch[overlay]": 0.024814189004246145, + "tests/image_operations/test_compositing.py::test_composite_dispatch[screen]": 0.021048340073321015, + "tests/image_operations/test_compositing.py::test_composite_dispatch[soft_light]": 0.020744400972034782, + "tests/image_operations/test_compositing.py::test_composite_dispatch[subtract]": 0.015535001992247999, + "tests/image_operations/test_compositing.py::test_fuzzy_alpha_mask_basic[GradientPosition.edge]": 0.0009742909460328519, + "tests/image_operations/test_compositing.py::test_fuzzy_alpha_mask_basic[GradientPosition.inside]": 0.0010655990918166935, + "tests/image_operations/test_compositing.py::test_fuzzy_alpha_mask_basic[GradientPosition.outside]": 0.0009597970056347549, + "tests/image_operations/test_compositing.py::test_fuzzy_alpha_mask_invalid_gradient_position": 0.0014310479164123535, + "tests/image_operations/test_compositing.py::test_fuzzy_alpha_mask_invalid_input": 0.0004694870440289378, + "tests/image_operations/test_compositing.py::test_fuzzy_alpha_mask_mask_none_branch": 0.001788338995538652, + "tests/image_operations/test_compositing.py::test_fuzzy_alpha_mask_without_mask": 0.0009372819913551211, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_invalid_dimensions": 0.0004989919834770262, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_ndim_and_band_branches": 0.00215786206535995, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[False-False-0-1]": 0.0011915279319509864, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[False-False-0-3]": 0.001085878990124911, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[False-False-3-1]": 0.001358760055154562, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[False-False-3-3]": 0.0014658250729553401, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[False-True-0-1]": 0.0012807860039174557, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[False-True-0-3]": 0.0014843399985693395, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[False-True-3-1]": 0.0014943289570510387, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[False-True-3-3]": 0.0015538950101472437, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[True-False-0-1]": 0.0012270099250599742, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[True-False-0-3]": 0.0011487489682622254, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[True-False-3-1]": 0.0014162419829517603, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[True-False-3-3]": 0.001520356978289783, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[True-True-0-1]": 0.0018789279856719077, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[True-True-0-3]": 0.0016341289738193154, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[True-True-3-1]": 0.001748255977872759, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_shapes[True-True-3-3]": 0.0016111570876091719, + "tests/image_operations/test_compositing.py::test_fuzzy_mask_timer_invoked": 0.0006819989648647606, + "tests/image_operations/test_compositing.py::test_to_rgba_expanded_mask_and_non_maskedarray": 0.001010721956845373, + "tests/image_operations/test_compositing.py::test_to_rgba_expanded_mask_bool_array": 0.0006230709841474891, + "tests/image_operations/test_compositing.py::test_to_rgba_expanded_mask_bool_scalar": 0.000663355051074177, + "tests/image_operations/test_compositing.py::test_to_rgba_four_band_array": 0.0005699560279026628, + "tests/image_operations/test_compositing.py::test_to_rgba_invalid_band_counts": 0.0005909050232730806, + "tests/image_operations/test_compositing.py::test_to_rgba_mixed_mask_values": 0.0006260359659790993, + "tests/image_operations/test_compositing.py::test_to_rgba_shapes_and_types[1]": 0.0028945350204594433, + "tests/image_operations/test_compositing.py::test_to_rgba_shapes_and_types[2]": 0.0023943420965224504, + "tests/image_operations/test_compositing.py::test_to_rgba_shapes_and_types[3]": 0.002835660008713603, + "tests/image_operations/test_compositing.py::test_to_rgba_shapes_and_types[4]": 0.002390858076978475, + "tests/image_operations/test_compositing.py::test_to_rgba_two_band_array": 0.0006550539401359856, + "tests/image_operations/test_compositing.py::test_to_rgba_type_error": 0.000979276024736464, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint16-1000.0-None-1-test_2d_array]": 0.0054614400141872466, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint16-1000.0-None-1-test_3d_array]": 0.01222759298980236, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint16-1000.0-None-1-test_4d_array]": 0.05226414097705856, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint16-5000.0-20000-None-test_2d_array]": 0.005197493068408221, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint16-5000.0-20000-None-test_3d_array]": 0.011955820955336094, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint16-5000.0-20000-None-test_4d_array]": 0.052265033998992294, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint8-10000.0-100-0-test_2d_array]": 0.005471104988828301, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint8-10000.0-100-0-test_3d_array]": 0.01185706100659445, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint8-10000.0-100-0-test_4d_array]": 0.05315406795125455, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint8-10000.0-None-None-test_2d_array]": 0.005603604891803116, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint8-10000.0-None-None-test_3d_array]": 0.012162666011136025, + "tests/image_operations/test_dtype_scale.py::test_dtype_scale_parametrized[uint8-10000.0-None-None-test_4d_array]": 0.052096807048656046, + "tests/image_operations/test_fillnodata.py::test_fillnodata[0-all]": 0.06657315097982064, + "tests/image_operations/test_fillnodata.py::test_fillnodata[0-nodata_neighbors]": 0.09477580297971144, + "tests/image_operations/test_fillnodata.py::test_fillnodata[0-patch_size]": 0.33408485795371234, + "tests/image_operations/test_fillnodata.py::test_fillnodata[3-all]": 0.0721894379821606, + "tests/image_operations/test_fillnodata.py::test_fillnodata[3-nodata_neighbors]": 0.07471038494259119, + "tests/image_operations/test_fillnodata.py::test_fillnodata[3-patch_size]": 0.6584852960659191, + "tests/image_operations/test_filters.py::test_blur": 0.009293556970078498, + "tests/image_operations/test_filters.py::test_contour": 0.0038351669791154563, + "tests/image_operations/test_filters.py::test_detail": 0.00513302197214216, + "tests/image_operations/test_filters.py::test_edge_enhance": 0.0058984310599043965, + "tests/image_operations/test_filters.py::test_edge_enhance_more": 0.004982320009730756, + "tests/image_operations/test_filters.py::test_emboss": 0.003366024000570178, + "tests/image_operations/test_filters.py::test_errors": 0.0017979000112973154, + "tests/image_operations/test_filters.py::test_find_edges": 0.003812610055319965, + "tests/image_operations/test_filters.py::test_gaussian_blur": 0.004273301979992539, + "tests/image_operations/test_filters.py::test_median": 0.02205004292773083, + "tests/image_operations/test_filters.py::test_sharpen": 0.004216330999042839, + "tests/image_operations/test_filters.py::test_sharpen_16bit": 0.027201544027775526, + "tests/image_operations/test_filters.py::test_smooth": 0.004471794003620744, + "tests/image_operations/test_filters.py::test_smooth_more": 0.005679284979123622, + "tests/image_operations/test_filters.py::test_unsharp_mask": 0.006288687989581376, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_band_length_mismatch": 0.002115806972142309, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_invalid_dtype": 0.0014351180288940668, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[False-float320]": 0.0024850130430422723, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[False-float321]": 0.002174310036934912, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[False-uint160]": 0.0024217719910666347, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[False-uint161]": 0.00345520896371454, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[False-uint80]": 0.002505785960238427, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[False-uint81]": 0.0022629709565080702, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[True-float320]": 0.002781039976980537, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[True-float321]": 0.002581835025921464, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[True-uint160]": 0.0028203539550304413, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[True-uint161]": 0.005257883982267231, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[True-uint80]": 0.0029998860554769635, + "tests/image_operations/test_linear_normalization.py::test_linear_normalization_parametrized[True-uint81]": 0.0025721220299601555, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0-0]": 0.004390693036839366, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0-20]": 0.012451718968804926, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0-2]": 0.012185394065454602, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0.25-0]": 0.00460412900429219, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0.25-20]": 0.012430558970663697, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0.25-2]": 0.012490249006077647, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0.45-0]": 0.004420366953127086, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0.45-20]": 0.015220648958347738, + "tests/image_operations/test_sigmoidal.py::test_sigmodial_output_array[0.45-2]": 0.027650283998809755, + "tests/platforms/sentinel2/test_base.py::test_config": 0.001983843045309186, + "tests/platforms/sentinel2/test_base.py::test_footprint_buffer": 3.374863700941205, + "tests/platforms/sentinel2/test_base.py::test_format_available": 0.002298919949680567, + "tests/platforms/sentinel2/test_base.py::test_jp2_config": 0.001508881978224963, + "tests/platforms/sentinel2/test_base.py::test_max_cloud_cover": 8.705017596948892, + "tests/platforms/sentinel2/test_base.py::test_mercator_grids": 4.852157827001065, + "tests/platforms/sentinel2/test_base.py::test_multiple_sources": 7.050293488951866, + "tests/platforms/sentinel2/test_base.py::test_parse_brdfconfig[classes0]": 0.0013886810629628599, + "tests/platforms/sentinel2/test_base.py::test_parse_brdfconfig[classes1]": 0.0010458689066581428, + "tests/platforms/sentinel2/test_base.py::test_parse_mask_config[mask_config0]": 0.0008757910691201687, + "tests/platforms/sentinel2/test_base.py::test_parse_mask_config[mask_config1]": 0.0005635970155708492, + "tests/platforms/sentinel2/test_base.py::test_parse_mask_config[mask_config2]": 0.0005518300458788872, + "tests/platforms/sentinel2/test_base.py::test_parse_mask_config[mask_config3]": 0.0005434370250441134, + "tests/platforms/sentinel2/test_base.py::test_parse_mask_config[mask_config4]": 0.0005243420600891113, + "tests/platforms/sentinel2/test_base.py::test_parse_mask_config[mask_config5]": 0.0005280280602164567, + "tests/platforms/sentinel2/test_base.py::test_preprocessing": 4.190078109968454, + "tests/platforms/sentinel2/test_base.py::test_read": 2.629748016013764, + "tests/platforms/sentinel2/test_base.py::test_read_area": 6.248457027075347, + "tests/platforms/sentinel2/test_base.py::test_read_area_stac": 0.09149731404613703, + "tests/platforms/sentinel2/test_base.py::test_read_brdf": 4.4624212920316495, + "tests/platforms/sentinel2/test_base.py::test_read_empty": 2.579033744055778, + "tests/platforms/sentinel2/test_base.py::test_read_empty_raise_emptystackexception": 1.9297253339900635, + "tests/platforms/sentinel2/test_base.py::test_read_empty_raise_nosourceproducts": 1.5590643690084107, + "tests/platforms/sentinel2/test_base.py::test_read_levelled_cube_np_array": 2.5668825529282913, + "tests/platforms/sentinel2/test_base.py::test_read_levelled_cube_np_array_sort": 2.5311628690105863, + "tests/platforms/sentinel2/test_base.py::test_read_levelled_cube_xarray": 2.5620864069787785, + "tests/platforms/sentinel2/test_base.py::test_read_masked": 3.311515403969679, + "tests/platforms/sentinel2/test_base.py::test_read_np[sentinel2_antimeridian_east_mapchete-tile1]": 0.9069647639989853, + "tests/platforms/sentinel2/test_base.py::test_read_np[sentinel2_antimeridian_west_mapchete-tile2]": 0.9356734140310436, + "tests/platforms/sentinel2/test_base.py::test_read_np[sentinel2_stac_mapchete-tile0]": 2.4356599639868364, + "tests/platforms/sentinel2/test_base.py::test_read_np_brdf[sentinel2_antimeridian_east_mapchete-tile1]": 2.225426297984086, + "tests/platforms/sentinel2/test_base.py::test_read_np_brdf[sentinel2_antimeridian_west_mapchete-tile2]": 2.2057644450105727, + "tests/platforms/sentinel2/test_base.py::test_read_np_brdf[sentinel2_stac_mapchete-tile0]": 4.301355217001401, + "tests/platforms/sentinel2/test_base.py::test_read_np_empty": 2.4205688440124504, + "tests/platforms/sentinel2/test_base.py::test_read_np_empty_raise_emptystackexception": 1.7058006419683807, + "tests/platforms/sentinel2/test_base.py::test_read_np_empty_raise_nosourceproducts": 1.5016806469648145, + "tests/platforms/sentinel2/test_base.py::test_read_np_masked[sentinel2_antimeridian_east_mapchete-tile1]": 1.410974409955088, + "tests/platforms/sentinel2/test_base.py::test_read_np_masked[sentinel2_antimeridian_west_mapchete-tile2]": 1.8012724060099572, + "tests/platforms/sentinel2/test_base.py::test_read_np_masked[sentinel2_stac_mapchete-tile0]": 3.151386073033791, + "tests/platforms/sentinel2/test_base.py::test_read_sorted": 3.311071910953615, + "tests/platforms/sentinel2/test_base.py::test_remote_s2_read_xarray[sentinel2_mapchete]": 17.93703579402063, + "tests/platforms/sentinel2/test_base.py::test_remote_s2_read_xarray_cdse[sentinel2_cdse_mapchete]": 0.0006970440153963864, + "tests/platforms/sentinel2/test_base.py::test_s2_eo_bands_to_assets_indexes_invalid_band": 0.004074167052749544, + "tests/platforms/sentinel2/test_base.py::test_s2_eo_bands_to_band_locations": 0.006278573011513799, + "tests/platforms/sentinel2/test_base.py::test_s2_jp2_band_paths": 0.33675642602611333, + "tests/platforms/sentinel2/test_base.py::test_s2_time_ranges": 13.457557518966496, + "tests/platforms/sentinel2/test_base.py::test_static_stac_max_cloud_cover": 1.6009970500599593, + "tests/platforms/sentinel2/test_brdf.py::test_brdf_correction_values": 0.25164560502162203, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B01]": 2.0201742639765143, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B02]": 2.6510110640665516, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B03]": 1.9767385150771588, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B04]": 2.304710447904654, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B05]": 1.6781919300556183, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B06]": 1.6491216709837317, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B07]": 1.8958658300107345, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B08]": 1.929339813941624, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B09]": 1.3438402159372345, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B11]": 1.3550781779922545, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B12]": 1.7654629389289767, + "tests/platforms/sentinel2/test_brdf.py::test_get_all_12_bands_brdf_param[L2ABand.B8A]": 1.944854044006206, + "tests/platforms/sentinel2/test_brdf.py::test_run_sentinel2_brdf[False]": 1.108940432954114, + "tests/platforms/sentinel2/test_brdf.py::test_run_sentinel2_brdf[True]": 3.849642435030546, + "tests/platforms/sentinel2/test_config.py::test_valid_configs[config_dict0]": 0.0017986460006795824, + "tests/platforms/sentinel2/test_config.py::test_valid_configs[config_dict1]": 0.0013771060039289296, + "tests/platforms/sentinel2/test_config.py::test_valid_configs[config_dict2]": 0.001604837947525084, + "tests/platforms/sentinel2/test_config.py::test_valid_configs[config_dict3]": 0.0013796810526400805, + "tests/platforms/sentinel2/test_config.py::test_valid_configs[config_dict4]": 0.001435134036000818, + "tests/platforms/sentinel2/test_config.py::test_valid_configs[config_dict5]": 0.001364692987408489, + "tests/platforms/sentinel2/test_config.py::test_valid_configs[config_dict6]": 0.001306772988755256, + "tests/platforms/sentinel2/test_mappers.py::test_earthsearch_to_s2metadata[https://earth-search.aws.element84.com/v1/collections/sentinel-2-c1-l2a/items/S2A_T33TWL_20250109T100401_L2A]": 13.757002817001194, + "tests/platforms/sentinel2/test_masks.py::test_masks_to_slices": 0.06525860301917419, + "tests/platforms/sentinel2/test_masks.py::test_masks_to_xarray[all]": 0.38193697994574904, + "tests/platforms/sentinel2/test_masks.py::test_masks_to_xarray[first]": 0.3715611160150729, + "tests/platforms/sentinel2/test_masks.py::test_read_masks": 0.17846268200082704, + "tests/platforms/sentinel2/test_masks.py::test_read_single_product_mask": 0.1446483989711851, + "tests/platforms/sentinel2/test_metadata_parser.py::test_baseline_version": 0.0020067079458385706, + "tests/platforms/sentinel2/test_metadata_parser.py::test_broken_metadata_xml": 0.9741459439974278, + "tests/platforms/sentinel2/test_metadata_parser.py::test_earthsearch_mapper_jp2": 1.376912574050948, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item[https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs/items/S2A_33TWN_20220701_0_L2A]": 1.4542959689279087, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item[https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/33/T/WL/2022/6/S2A_33TWL_20220614_0_L2A/S2A_33TWL_20220614_0_L2A.json]": 2.7687373380176723, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_backwards[stac_item_pb0214]": 1.6082245649886318, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_backwards[stac_item_pb0300]": 1.4313008290482685, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_backwards[stac_item_pb0301]": 1.3935926550184377, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_backwards[stac_item_pb0400]": 1.4392666770145297, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_backwards[stac_item_pb0400_offset]": 1.408376585924998, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_backwards[stac_item_pb0509]": 1.4022297330084257, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_backwards[stac_item_sentinel2_jp2]": 0.9959072370547801, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_backwards[stac_item_sentinel2_jp2_local]": 0.8368749999790452, + "tests/platforms/sentinel2/test_metadata_parser.py::test_from_stac_item_invalid": 0.9716060050413944, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_product_paths[full_stac_item_pb0509]": 0.043483745015691966, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_product_paths[stac_item_sentinel2_jp2]": 2.1120258329901844, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_remote_product_paths[stac_item_pb0214]": 2.756435305054765, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_remote_product_paths[stac_item_pb0300]": 2.784506898955442, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_remote_product_paths[stac_item_pb0301]": 2.8314540749415755, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_remote_product_paths[stac_item_pb0400]": 2.9059985509957187, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_remote_product_paths[stac_item_pb0400_offset]": 2.7590442650252953, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_remote_product_paths[stac_item_pb0509]": 2.8912722429959103, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_remote_product_paths[stac_item_sentinel2_jp2]": 2.1194846130674705, + "tests/platforms/sentinel2/test_metadata_parser.py::test_full_remote_product_paths[stac_item_sentinel2_jp2_local]": 1.9682693229988217, + "tests/platforms/sentinel2/test_metadata_parser.py::test_future_baseline_version": 0.0017558230319991708, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_band_masks[s2_l2a_metadata]": 4.024078749935143, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_bounds[s2_l2a_metadata]": 0.0015406660386361182, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_crs[s2_l2a_metadata]": 0.0017228220240212977, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_footprint[s2_l2a_metadata]": 0.0038015080499462783, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_geoinfo[Resolution.10m-s2_l2a_metadata]": 0.001930560974869877, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_geoinfo[Resolution.120m-s2_l2a_metadata]": 0.0018698520143516362, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_geoinfo[Resolution.20m-s2_l2a_metadata]": 0.001734111923724413, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_geoinfo[Resolution.60m-s2_l2a_metadata]": 0.0017183910822495818, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_l1c_cloud_mask[s2_l2a_metadata]": 2.26254390302347, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_l1c_cloud_mask[s2_l2a_safe_metadata]": 0.27005737100262195, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_product_id[s2_l2a_metadata]": 0.027594062965363264, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_snow_ice_mask[s2_l2a_metadata]": 0.6880759729538113, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_snow_ice_mask[s2_l2a_safe_metadata]": 0.020233373972587287, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_sun_angles[s2_l2a_metadata]": 0.004394571995362639, + "tests/platforms/sentinel2/test_metadata_parser.py::test_metadata_viewing_incidence_angles[s2_l2a_metadata]": 1.6864654429955408, + "tests/platforms/sentinel2/test_metadata_parser.py::test_product_empty_detector_footprints": 0.5229771320009604, + "tests/platforms/sentinel2/test_metadata_parser.py::test_product_missing_detector_footprints": 0.4836923920083791, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_band_masks[s2_l2a_metadata_remote]": 1.3339992340188473, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_band_masks[s2_l2a_roda_metadata_remote]": 1.1100813719676808, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_bounds[s2_l2a_earthsearch_remote]": 0.0013894999865442514, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_bounds[s2_l2a_metadata_remote]": 0.001479254977311939, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_bounds[s2_l2a_roda_metadata_jp2_masks_remote]": 0.0013697670656256378, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_bounds[s2_l2a_roda_metadata_remote]": 0.0014065849827602506, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_crs[s2_l2a_earthsearch_remote]": 0.0015532049583271146, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_crs[s2_l2a_metadata_remote]": 0.00163803604664281, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_crs[s2_l2a_roda_metadata_jp2_masks_remote]": 0.0014731829869560897, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_crs[s2_l2a_roda_metadata_remote]": 0.0015747839934192598, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_footprint[s2_l2a_earthsearch_remote]": 0.0035539789823815227, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_footprint[s2_l2a_metadata_remote]": 0.004066015011630952, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_footprint[s2_l2a_roda_metadata_jp2_masks_remote]": 0.003181067935656756, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_footprint[s2_l2a_roda_metadata_remote]": 0.0030448059551417828, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.10m-s2_l2a_earthsearch_remote]": 0.0016056380700320005, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.10m-s2_l2a_metadata_remote]": 0.001477087032981217, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.10m-s2_l2a_roda_metadata_jp2_masks_remote]": 0.0014184479950927198, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.10m-s2_l2a_roda_metadata_remote]": 0.0013943819794803858, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.120m-s2_l2a_earthsearch_remote]": 0.0013752649538218975, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.120m-s2_l2a_metadata_remote]": 0.0015532270190306008, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.120m-s2_l2a_roda_metadata_jp2_masks_remote]": 0.001407130912411958, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.120m-s2_l2a_roda_metadata_remote]": 0.001700843044091016, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.20m-s2_l2a_earthsearch_remote]": 0.001595355977769941, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.20m-s2_l2a_metadata_remote]": 0.0016495439922437072, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.20m-s2_l2a_roda_metadata_jp2_masks_remote]": 0.001585899037308991, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.20m-s2_l2a_roda_metadata_remote]": 0.001643332070671022, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.60m-s2_l2a_earthsearch_remote]": 0.0015935349510982633, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.60m-s2_l2a_metadata_remote]": 0.0018187289242632687, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.60m-s2_l2a_roda_metadata_jp2_masks_remote]": 0.001652298029512167, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_geoinfo[Resolution.60m-s2_l2a_roda_metadata_remote]": 0.0015973839908838272, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_l1c_cloud_mask[s2_l2a_earthsearch_remote]": 2.156080327986274, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_l1c_cloud_mask[s2_l2a_metadata_remote]": 0.6717894550529309, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_l1c_cloud_mask[s2_l2a_roda_metadata_jp2_masks_remote]": 2.2731940929661505, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_l1c_cloud_mask[s2_l2a_roda_metadata_remote]": 0.6041684480151162, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_product_id[s2_l2a_earthsearch_remote]": 2.235684805957135, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_product_id[s2_l2a_metadata_remote]": 0.2888293949654326, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_product_id[s2_l2a_roda_metadata_jp2_masks_remote]": 0.2814498719526455, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_product_id[s2_l2a_roda_metadata_remote]": 0.43184277205727994, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_snow_ice_mask[s2_l2a_earthsearch_remote]": 0.7713326570228674, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_snow_ice_mask[s2_l2a_metadata_remote]": 0.19989442906808108, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_snow_ice_mask[s2_l2a_roda_metadata_jp2_masks_remote]": 0.7788925099885091, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_snow_ice_mask[s2_l2a_roda_metadata_remote]": 0.20523222594056278, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_sun_angles[s2_l2a_earthsearch_remote]": 0.002939209050964564, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_sun_angles[s2_l2a_metadata_remote]": 0.0034840439911931753, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_sun_angles[s2_l2a_roda_metadata_jp2_masks_remote]": 0.004907626949716359, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_sun_angles[s2_l2a_roda_metadata_remote]": 0.0034520389745011926, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_viewing_incidence_angles[s2_l2a_earthsearch_remote]": 2.2763753920444287, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_viewing_incidence_angles[s2_l2a_metadata_remote]": 1.8392579249921255, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_viewing_incidence_angles[s2_l2a_roda_metadata_jp2_masks_remote]": 3.181112397054676, + "tests/platforms/sentinel2/test_metadata_parser.py::test_remote_metadata_viewing_incidence_angles[s2_l2a_roda_metadata_remote]": 1.9811666219611652, + "tests/platforms/sentinel2/test_metadata_parser.py::test_sinergise_mapper[tileinfo_gml_schema-03.01]": 1.413982905971352, + "tests/platforms/sentinel2/test_metadata_parser.py::test_sinergise_mapper[tileinfo_jp2_schema-04.00]": 0.4840659759938717, + "tests/platforms/sentinel2/test_metadata_parser.py::test_unavailable_metadata_xml": 0.0021093920222483575, + "tests/platforms/sentinel2/test_metadata_parser.py::test_xml_mapper": 0.021407801017630845, + "tests/platforms/sentinel2/test_product.py::test_footprint_nodata_mask": 0.9880557750002481, + "tests/platforms/sentinel2/test_product.py::test_footprint_nodata_mask_tile": 0.02066751994425431, + "tests/platforms/sentinel2/test_product.py::test_footprint_nodata_mask_tile_antimeridian[antimeridian_item1]": 0.32099126907996833, + "tests/platforms/sentinel2/test_product.py::test_footprint_nodata_mask_tile_antimeridian[antimeridian_item2]": 0.1720430989516899, + "tests/platforms/sentinel2/test_product.py::test_footprint_nodata_mask_tile_antimeridian[antimeridian_item3]": 0.1576888159615919, + "tests/platforms/sentinel2/test_product.py::test_footprint_nodata_mask_tile_antimeridian[antimeridian_item4]": 0.16738473204895854, + "tests/platforms/sentinel2/test_product.py::test_get_mask[mask_config0]": 0.162624056043569, + "tests/platforms/sentinel2/test_product.py::test_get_mask[mask_config1]": 0.14117647300008684, + "tests/platforms/sentinel2/test_product.py::test_get_mask[mask_config2]": 0.0765968089690432, + "tests/platforms/sentinel2/test_product.py::test_product[s2_stac_item]": 0.02881906199036166, + "tests/platforms/sentinel2/test_product.py::test_product_asset_cache": 0.019768005004152656, + "tests/platforms/sentinel2/test_product.py::test_product_brdf_cache": 0.6730666770017706, + "tests/platforms/sentinel2/test_product.py::test_product_read_cloud_mask": 0.6429401799687184, + "tests/platforms/sentinel2/test_product.py::test_product_read_cloud_mask_tile": 0.04377003404079005, + "tests/platforms/sentinel2/test_product.py::test_product_read_cloud_probability": 0.3858486779499799, + "tests/platforms/sentinel2/test_product.py::test_product_read_cloud_probability_tile": 0.0470780860632658, + "tests/platforms/sentinel2/test_product.py::test_product_read_scl": 0.6278949079569429, + "tests/platforms/sentinel2/test_product.py::test_product_read_scl_remote[False]": 4.631564696028363, + "tests/platforms/sentinel2/test_product.py::test_product_read_scl_remote[True]": 2.038880535052158, + "tests/platforms/sentinel2/test_product.py::test_product_read_scl_tile": 0.04397649294696748, + "tests/platforms/sentinel2/test_product.py::test_product_read_snow_ice_mask": 1.0254169359686784, + "tests/platforms/sentinel2/test_product.py::test_product_read_snow_ice_mask_tile": 0.04121314804069698, + "tests/platforms/sentinel2/test_product.py::test_product_read_snow_probability": 0.3439020580262877, + "tests/platforms/sentinel2/test_product.py::test_product_read_snow_probability_tile": 0.04113753995625302, + "tests/platforms/sentinel2/test_product.py::test_product_remote[stac_item_pb0300]": 1.7174827420385554, + "tests/platforms/sentinel2/test_product.py::test_product_remote[stac_item_pb0301]": 1.5334328030585311, + "tests/platforms/sentinel2/test_product.py::test_product_remote[stac_item_pb0400]": 1.2670045249979012, + "tests/platforms/sentinel2/test_product.py::test_product_remote[stac_item_pb0400_offset]": 1.5344932819716632, + "tests/platforms/sentinel2/test_product.py::test_product_remote[stac_item_pb0509]": 1.5252540079527535, + "tests/platforms/sentinel2/test_product.py::test_product_remote[stac_item_sentinel2_jp2]": 0.6452486359630711, + "tests/platforms/sentinel2/test_product.py::test_product_remote[stac_item_sentinel2_jp2_local]": 0.48943534999853, + "tests/platforms/sentinel2/test_product.py::test_read": 0.12481322302483022, + "tests/platforms/sentinel2/test_product.py::test_read_apply_offset[coastal]": 3.991928486037068, + "tests/platforms/sentinel2/test_product.py::test_read_apply_offset_cdse": 0.000610358954872936, + "tests/platforms/sentinel2/test_product.py::test_read_brdf[blue-False]": 0.37355343403760344, + "tests/platforms/sentinel2/test_product.py::test_read_brdf[blue-True]": 1.5025699560064822, + "tests/platforms/sentinel2/test_product.py::test_read_brdf[green-False]": 0.6900056139566004, + "tests/platforms/sentinel2/test_product.py::test_read_brdf[green-True]": 1.4960489349905401, + "tests/platforms/sentinel2/test_product.py::test_read_brdf[red-False]": 0.40672189102042466, + "tests/platforms/sentinel2/test_product.py::test_read_brdf[red-True]": 1.7623488730168901, + "tests/platforms/sentinel2/test_product.py::test_read_brdf_correction_weight[0.9]": 1.6430480379494838, + "tests/platforms/sentinel2/test_product.py::test_read_brdf_correction_weight[1.2]": 2.060092733008787, + "tests/platforms/sentinel2/test_product.py::test_read_brdf_scl_classes": 1.5702068409882486, + "tests/platforms/sentinel2/test_product.py::test_read_brdf_scl_classes_inversed": 1.8778649670421146, + "tests/platforms/sentinel2/test_product.py::test_read_broken_product": 6.560756538063288, + "tests/platforms/sentinel2/test_product.py::test_read_empty": 0.028899069933686405, + "tests/platforms/sentinel2/test_product.py::test_read_empty_raise": 0.06427797302603722, + "tests/platforms/sentinel2/test_product.py::test_read_levelled_cube_broken_slice": 2.88817063200986, + "tests/platforms/sentinel2/test_product.py::test_read_levelled_cube_np_array[None]": 2.79278873099247, + "tests/platforms/sentinel2/test_product.py::test_read_levelled_cube_np_array[read_mask1]": 0.013342177961021662, + "tests/platforms/sentinel2/test_product.py::test_read_levelled_cube_np_array[read_mask2]": 2.697574253019411, + "tests/platforms/sentinel2/test_product.py::test_read_levelled_cube_np_array[read_mask3]": 2.722054585989099, + "tests/platforms/sentinel2/test_product.py::test_read_levelled_cube_xarray": 2.690093282959424, + "tests/platforms/sentinel2/test_product.py::test_read_masked": 0.4621350590023212, + "tests/platforms/sentinel2/test_product.py::test_read_np": 0.11507009906927124, + "tests/platforms/sentinel2/test_product.py::test_read_np_brdf[s2_stac_item]": 2.0674190279096365, + "tests/platforms/sentinel2/test_product.py::test_read_np_brdf_remote[stac_item_sentinel2_jp2]": 0.00020772800780832767, + "tests/platforms/sentinel2/test_product.py::test_read_np_empty": 0.03180230897851288, + "tests/platforms/sentinel2/test_product.py::test_read_np_empty_raise": 0.029290049918927252, + "tests/platforms/sentinel2/test_product.py::test_read_np_masked": 0.42818377900402993, + "tests/platforms/sentinel2/test_product.py::test_remote_product_asset_cache": 2.286486368975602, + "tests/platforms/sentinel2/test_product.py::test_s2_bandpass_adjustment": 0.21549554698867723, + "tests/platforms/sentinel2/test_search.py::test_source_search[eo:cloud_cover < 1-2]": 0.03035943501163274, + "tests/platforms/sentinel2/test_search.py::test_source_search[eo:cloud_cover < 10-6]": 0.03140434093074873, + "tests/platforms/sentinel2/test_search.py::test_source_search[eo:cloud_cover < 100-10]": 0.06142712401924655, + "tests/platforms/sentinel2/test_search.py::test_source_search[eo:cloud_cover = 0-0]": 0.031669934978708625, + "tests/platforms/sentinel2/test_search.py::test_static_search[eo:cloud_cover < 1-2]": 0.02885854197666049, + "tests/platforms/sentinel2/test_search.py::test_static_search[eo:cloud_cover < 10-6]": 0.03004466707352549, + "tests/platforms/sentinel2/test_search.py::test_static_search[eo:cloud_cover < 100-10]": 0.029338946973439306, + "tests/platforms/sentinel2/test_search.py::test_static_search[eo:cloud_cover = 0-0]": 0.030236275983043015, + "tests/platforms/sentinel2/test_search.py::test_utm_search[eo:cloud_cover < 100-6]": 3.56616465409752, + "tests/platforms/sentinel2/test_search.py::test_utm_search[eo:cloud_cover < 20-2]": 1.1390097149997018, + "tests/platforms/sentinel2/test_search.py::test_utm_search[eo:cloud_cover < 50-5]": 0.9784941989346407, + "tests/platforms/sentinel2/test_search.py::test_utm_search[eo:cloud_cover = 0-0]": 0.8476943800342269, + "tests/platforms/sentinel2/test_sources.py::test_known_sources[EarthSearch]": 10.73534650192596, + "tests/platforms/sentinel2/test_sources.py::test_known_sources[EarthSearch_legacy]": 10.092815645039082, + "tests/platforms/sentinel2/test_sources.py::test_known_sources_cdse[CDSE]": 0.0020375250023789704, + "tests/test_array.py::test_buffer_array": 0.005485897010657936, + "tests/test_array.py::test_color_array": 0.0020455889753066003, + "tests/test_array.py::test_dataarray_to_masked_array[None-test_2d_array]": 0.004460195952560753, + "tests/test_array.py::test_dataarray_to_masked_array[None-test_3d_array]": 0.008064593945164233, + "tests/test_array.py::test_dataarray_to_masked_array[int16-test_2d_array]": 0.003503874992020428, + "tests/test_array.py::test_dataarray_to_masked_array[int16-test_3d_array]": 0.008299021050333977, + "tests/test_array.py::test_dataarray_to_masked_array[int8-test_2d_array]": 0.0038685810286551714, + "tests/test_array.py::test_dataarray_to_masked_array[int8-test_3d_array]": 0.009275005024392158, + "tests/test_array.py::test_dataset_to_masked_array[test_4d_array]": 0.030502091976813972, + "tests/test_array.py::test_hex_to_rgb": 0.0015188250108622015, + "tests/test_array.py::test_outlier_pixels": 0.0014740689657628536, + "tests/test_array.py::test_to_dataarray_2d": 0.0031221960089169443, + "tests/test_array.py::test_to_dataarray_3d": 0.008921402040868998, + "tests/test_array.py::test_to_dataset_4d": 0.030386677011847496, + "tests/test_catalog.py::test_pf_qa_eo_bands": 0.0055837309919297695, + "tests/test_catalog.py::test_pf_qa_items": 0.02100792998680845, + "tests/test_catalog.py::test_pf_sr_eo_bands": 0.006120294041465968, + "tests/test_catalog.py::test_pf_sr_items": 0.04002152202883735, + "tests/test_catalog.py::test_static_catalog_cloud_percent": 0.08748594898497686, + "tests/test_catalog.py::test_write_static_catalog": 0.06601657095598057, + "tests/test_catalog.py::test_write_static_catalog_convert_assets": 2.8609698539949022, + "tests/test_catalog.py::test_write_static_catalog_copy_assets": 0.03840501396916807, + "tests/test_catalog.py::test_write_static_catalog_copy_assets_relative_output_path": 0.050937864056322724, + "tests/test_catalog.py::test_write_static_catalog_metadata_assets": 0.3990071499138139, + "tests/test_cli.py::test_s2_brdf": 0.8465904539916664, + "tests/test_cli.py::test_s2_mask": 3.60595026507508, + "tests/test_cli.py::test_s2_rgb": 2.147041318065021, + "tests/test_cli.py::test_static_catalog[S2AWS_COG]": 6.099808478960767, + "tests/test_cli.py::test_static_catalog[https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a]": 6.116953557997476, + "tests/test_cli.py::test_static_catalog[s2_stac_collection]": 0.09012396400794387, + "tests/test_eostac.py::test_format_available": 0.0008139190031215549, + "tests/test_eostac.py::test_pf_eo_bands_to_band_locations": 0.009266757988370955, + "tests/test_eostac.py::test_preprocessing": 0.17805811297148466, + "tests/test_eostac.py::test_stac_read_xarray": 1.6960782959940843, + "tests/test_eostac.py::test_stac_read_xarray_dem": 0.001339796930551529, + "tests/test_io.py::test_asset_mpath[False-False-s2_remote_stac_item]": 1.1392202789429575, + "tests/test_io.py::test_asset_mpath[False-False-s2_stac_item]": 0.012956345977727324, + "tests/test_io.py::test_asset_mpath[False-True-s2_remote_stac_item]": 0.7375237249070778, + "tests/test_io.py::test_asset_mpath[False-True-s2_stac_item]": 0.038546107010915875, + "tests/test_io.py::test_asset_mpath[True-False-s2_remote_stac_item]": 0.9341105150524527, + "tests/test_io.py::test_asset_mpath[True-False-s2_stac_item]": 0.009397296991664916, + "tests/test_io.py::test_asset_mpath[True-True-s2_remote_stac_item]": 1.2865020069293678, + "tests/test_io.py::test_asset_mpath[True-True-s2_stac_item]": 0.0113605220685713, + "tests/test_io.py::test_get_item_property_date": 0.007168113021180034, + "tests/test_io.py::test_get_item_property_extra_fields": 0.009429466037545353, + "tests/test_io.py::test_get_item_property_properties[constellation]": 0.010661338921636343, + "tests/test_io.py::test_get_item_property_properties[created]": 0.010573686973657459, + "tests/test_io.py::test_get_item_property_properties[earthsearch:boa_offset_applied]": 0.008713165938388556, + "tests/test_io.py::test_get_item_property_properties[eo:cloud_cover]": 0.009642872959375381, + "tests/test_io.py::test_get_item_property_properties[instruments]": 0.007850684050936252, + "tests/test_io.py::test_get_item_property_properties[mgrs:grid_square]": 0.00848225795198232, + "tests/test_io.py::test_get_item_property_properties[mgrs:latitude_band]": 0.008716051001101732, + "tests/test_io.py::test_get_item_property_properties[mgrs:utm_zone]": 0.00923531799344346, + "tests/test_io.py::test_get_item_property_properties[platform]": 0.0056854840368032455, + "tests/test_io.py::test_get_item_property_properties[proj:code]": 0.008854468003846705, + "tests/test_io.py::test_get_item_property_properties[s2:datastrip_id]": 0.008668126887641847, + "tests/test_io.py::test_get_item_property_properties[s2:granule_id]": 0.009204970963764936, + "tests/test_io.py::test_get_item_property_properties[s2:processing_baseline]": 0.008481213066261262, + "tests/test_io.py::test_get_item_property_properties[s2:sequence]": 0.009101283038035035, + "tests/test_io.py::test_get_item_property_properties[updated]": 0.008696808014065027, + "tests/test_io.py::test_get_product_cache_path[date_day_first]": 0.011351365013979375, + "tests/test_io.py::test_get_product_cache_path[date_year_first]": 0.010631259065121412, + "tests/test_io.py::test_get_product_cache_path[hash]": 0.009745093993842602, + "tests/test_io.py::test_get_product_cache_path[product_id]": 0.010181970021221787, + "tests/test_io.py::test_item_fix_antimeridian_footprint[antimeridian_item1]": 0.024502616026438773, + "tests/test_io.py::test_item_fix_antimeridian_footprint[antimeridian_item2]": 0.013430883002001792, + "tests/test_io.py::test_item_fix_antimeridian_footprint[antimeridian_item4]": 0.016807293985038996, + "tests/test_io.py::test_products_to_slices": 0.13237671501701698, + "tests/test_io.py::test_products_to_slices_empty": 0.0019939069752581418, + "tests/test_io.py::test_slice": 0.27503947395598516, + "tests/test_io_assets.py::test_asset_mpath": 0.005828400957398117, + "tests/test_io_assets.py::test_asset_mpath_error": 0.008365546993445605, + "tests/test_io_assets.py::test_convert_asset": 0.16047057398827747, + "tests/test_io_assets.py::test_convert_asset_ignore_existing": 0.08890369301661849, + "tests/test_io_assets.py::test_convert_asset_overwrite": 0.104567005939316, + "tests/test_io_assets.py::test_convert_raster_profile": 0.1344476529629901, + "tests/test_io_assets.py::test_convert_raster_resolution": 0.9596544230007567, + "tests/test_io_assets.py::test_copy_asset": 0.012949296971783042, + "tests/test_io_assets.py::test_copy_asset_overwrite": 0.01191058405674994, + "tests/test_io_assets.py::test_get_assets_convert": 0.19853142701322213, + "tests/test_io_assets.py::test_get_assets_copy": 0.009843890031334013, + "tests/test_io_assets.py::test_get_metadata_assets": 0.09368471399648115, + "tests/test_io_assets.py::test_get_metadata_assets_convert": 0.00032625702442601323, + "tests/test_io_assets.py::test_should_be_converted[kwargs0-False]": 0.018744352040812373, + "tests/test_io_assets.py::test_should_be_converted[kwargs1-False]": 0.005718397907912731, + "tests/test_io_assets.py::test_should_be_converted[kwargs2-True]": 0.02730111504206434, + "tests/test_io_assets.py::test_should_be_converted[kwargs3-True]": 0.02709350601071492, + "tests/test_io_assets.py::test_should_be_converted[kwargs4-False]": 0.029382515989709646, + "tests/test_io_assets.py::test_should_be_converted[kwargs5-True]": 0.024284082057420164, + "tests/test_io_to_np_array.py::test_products_to_np_array": 0.4191035510157235, + "tests/test_io_to_np_array.py::test_products_to_np_array_eo_bands": 0.454228141985368, + "tests/test_io_to_np_array.py::test_products_to_np_array_merge_datastrip_id[average]": 2.6118432390503585, + "tests/test_io_to_np_array.py::test_products_to_np_array_merge_datastrip_id[first]": 2.676347849017475, + "tests/test_io_to_np_array.py::test_products_to_np_array_merge_date": 2.6554894400178455, + "tests/test_io_to_xarray.py::test_products_to_xarray": 0.40498878399375826, + "tests/test_io_to_xarray.py::test_products_to_xarray_eo_bands": 0.38362827501259744, + "tests/test_io_to_xarray.py::test_products_to_xarray_merge_datastrip_id[average]": 2.4619697419693694, + "tests/test_io_to_xarray.py::test_products_to_xarray_merge_datastrip_id[first]": 2.4519185239914805, + "tests/test_io_to_xarray.py::test_products_to_xarray_merge_date": 2.68571502098348, + "tests/test_processes.py::test_eoxcloudless_8bit_dtype_scale_mapchete": 0.14268450590316206, + "tests/test_processes.py::test_merge_rasters": 0.30440815509064123, + "tests/test_product.py::test_blacklist": 0.008242515032179654, + "tests/test_s2_mgrs.py::test_s2_tiles_from_bounds": 0.9898865380673669, + "tests/test_s2_mgrs.py::test_s2_tiles_from_bounds_antimeridian[bounds0]": 1.5580842979834415, + "tests/test_s2_mgrs.py::test_s2_tiles_from_bounds_antimeridian[bounds1]": 1.691765567054972, + "tests/test_s2_mgrs.py::test_s2_tiles_from_bounds_antimeridian[bounds2]": 1.5249707679613493, + "tests/test_s2_mgrs.py::test_s2_tiles_from_bounds_antimeridian[bounds3]": 1.3066548249917105, + "tests/test_s2_mgrs.py::test_s2tile_antimeridian_footprint[01UCV-MultiPolygon]": 0.0058781790430657566, + "tests/test_s2_mgrs.py::test_s2tile_antimeridian_footprint[30VXL-Polygon]": 0.005977724038530141, + "tests/test_s2_mgrs.py::test_s2tile_bounds[stac_item_pb0214]": 0.022479081992059946, + "tests/test_s2_mgrs.py::test_s2tile_bounds[stac_item_pb0300]": 0.01715554401744157, + "tests/test_s2_mgrs.py::test_s2tile_bounds[stac_item_pb0301]": 0.017765935976058245, + "tests/test_s2_mgrs.py::test_s2tile_bounds[stac_item_pb0400]": 0.01810686493990943, + "tests/test_s2_mgrs.py::test_s2tile_bounds[stac_item_pb0400_offset]": 0.021515206957701594, + "tests/test_s2_mgrs.py::test_s2tile_bounds[stac_item_pb0509]": 0.023277497966773808, + "tests/test_s2_mgrs.py::test_s2tile_from_tile_id_invalid_square[27CWJ]": 0.013335846946574748, + "tests/test_s2_mgrs.py::test_sentinel2_jp2_static_catalog": 0.0006238450296223164, + "tests/test_sort.py::test_sort[False-cloud_cover]": 0.0663950580637902, + "tests/test_sort.py::test_sort[False-date]": 0.06632311595603824, + "tests/test_sort.py::test_sort[True-cloud_cover]": 0.06292309000855312, + "tests/test_sort.py::test_sort[True-date]": 0.07374277000781149 +} \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index a815351..bc97269 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ test = [ "pytest", "pytest-coverage", "pytest-lazy-fixtures", - "pytest-xdist" + "pytest-split" ] [project.entry-points."mapchete.cli.commands"] @@ -88,13 +88,11 @@ source = ["mapchete_eo"] addopts = [ "--durations=20", "--verbose", + "--splitting-algorithm", "least_duration", "--nf", "--cov=mapchete_eo", "--cov-report=term-missing:skip-covered", - "--cov-append", - "--numprocesses=auto", - "--dist=loadscope", - "--max-worker-restart=3" + "--cov-append" ] testpaths = ["tests"] markers = [ diff --git a/uv.lock b/uv.lock index a99191d..cfcb132 100644 --- a/uv.lock +++ b/uv.lock @@ -1753,6 +1753,7 @@ test = [ { name = "pytest" }, { name = "pytest-coverage" }, { name = "pytest-lazy-fixtures" }, + { name = "pytest-split" }, ] [package.metadata] @@ -1771,6 +1772,7 @@ requires-dist = [ { name = "pytest", marker = "extra == 'test'" }, { name = "pytest-coverage", marker = "extra == 'test'" }, { name = "pytest-lazy-fixtures", marker = "extra == 'test'" }, + { name = "pytest-split", marker = "extra == 'test'" }, { name = "retry" }, { name = "rtree" }, { name = "scipy" }, @@ -3421,6 +3423,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/60/a0/a07399bd4842282fe3c2da264746069d5216640bc0940b7a359e2c950aa6/pytest_lazy_fixtures-1.4.0-py3-none-any.whl", hash = "sha256:c5db4506fa0ade5887189d1a18857fec4c329b4f49043fef6732c67c9553389a", size = 9680, upload-time = "2025-09-16T18:42:30.534Z" }, ] +[[package]] +name = "pytest-split" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/16/8af4c5f2ceb3640bb1f78dfdf5c184556b10dfe9369feaaad7ff1c13f329/pytest_split-0.11.0.tar.gz", hash = "sha256:8ebdb29cc72cc962e8eb1ec07db1eeb98ab25e215ed8e3216f6b9fc7ce0ec2b5", size = 13421, upload-time = "2026-02-03T09:14:31.469Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/a1/d4423657caaa8be9b31e491592b49cebdcfd434d3e74512ce71f6ec39905/pytest_split-0.11.0-py3-none-any.whl", hash = "sha256:899d7c0f5730da91e2daf283860eb73b503259cb416851a65599368849c7f382", size = 11911, upload-time = "2026-02-03T09:14:33.708Z" }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" From 0822f175ac464d504d354b72c751977abb47dbb7 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 17:46:55 +0100 Subject: [PATCH 03/27] fixing the sync-deps in PR, try beuitifying the tests --- .github/workflows/python-package.yml | 39 +++++++++++++++---------- .github/workflows/sync-dependencies.yml | 24 +++++++++++---- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 1685315..b0a2aa1 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -15,7 +15,10 @@ permissions: jobs: test: + # ๐Ÿท๏ธ This makes the UI subdivided and easy to read! + name: ๐Ÿ ${{ matrix.python-version }} โ€ข ๐Ÿงฉ Split ${{ matrix.split }}/${{ strategy.job-total / 4 }} runs-on: ${{ matrix.os }} + strategy: fail-fast: false matrix: @@ -23,45 +26,51 @@ jobs: os: ["ubuntu-latest"] split: [1, 2, 3, 4] + # Move common env vars here to keep the "run" step clean + env: + CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt + OPENBLAS_NUM_THREADS: 1 + OMP_NUM_THREADS: 1 + steps: - - uses: actions/checkout@v4 + - name: โฌ‡๏ธ Checkout + uses: actions/checkout@v4 - - name: Download updated dependencies + - name: ๐Ÿ“ฆ Load Updated Artifacts uses: actions/download-artifact@v4 continue-on-error: true with: name: updated-deps - - name: Set up Python ${{ matrix.python-version }} + - name: ๐Ÿ—๏ธ Setup Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Lint + - name: ๐Ÿงน Lint Check run: | python -m pip install pre-commit pre-commit run --show-diff-on-failure --all-files - - name: Install GIS Dependencies + - name: ๐ŸŒ Install GIS System Deps run: | sudo apt-add-repository -y ppa:ubuntugis/ubuntugis-unstable sudo apt-get -y update sudo apt-get install -y gdal-bin libgdal-dev libproj-dev libgeos-dev g++ - - name: Install uv + - name: โšก Setup uv uses: astral-sh/setup-uv@v5 with: enable-cache: true - - name: Install dependencies + - name: ๐Ÿ› ๏ธ Sync Environment env: - CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt GDAL_CONFIG: /usr/bin/gdal-config run: | - # uv sync will prefer the downloaded uv.lock if it exists uv sync --all-extras + uv pip install pytest-split - - name: run + - name: ๐Ÿงช Run Partitioned Tests env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -69,19 +78,19 @@ jobs: AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} - CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt run: | - # Use --splits 4 (matches matrix) and --group ${{ matrix.split }} uv run pytest -v \ --splits 4 \ --group ${{ matrix.split }} \ --cov mapchete_eo \ --cov-report xml:coverage.xml \ --cov-report=term-missing:skip-covered \ - --junitxml=pytest.xml + --junitxml=pytest-${{ matrix.python-version }}-${{ matrix.split }}.xml - - name: Upload coverage reports to Codecov + - name: ๐Ÿ“Š Upload to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - slug: mapchete/mapchete-eo \ No newline at end of file + slug: mapchete/mapchete-eo + # Adding flags makes the Codecov UI prettier too! + flags: py${{ matrix.python-version }},split${{ matrix.split }} \ No newline at end of file diff --git a/.github/workflows/sync-dependencies.yml b/.github/workflows/sync-dependencies.yml index 2196740..ff89847 100644 --- a/.github/workflows/sync-dependencies.yml +++ b/.github/workflows/sync-dependencies.yml @@ -75,7 +75,7 @@ jobs: uses: ./.github/workflows/python-package.yml secrets: inherit - finalize: +finalize: needs: [sync-and-prepare, run-tests] if: | always() && @@ -89,8 +89,19 @@ jobs: steps: - uses: actions/checkout@v4 with: + fetch-depth: 0 ref: ${{ github.event.pull_request.head.ref || github.ref }} + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Sync Local Branch with Remote + run: | + BRANCH_NAME="${{ github.event.pull_request.head.ref || github.ref_name }}" + git pull --rebase origin $BRANCH_NAME + - name: Download updated files uses: actions/download-artifact@v4 with: @@ -99,12 +110,13 @@ jobs: - name: Push to Existing PR if: github.event_name == 'pull_request' run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git pull --rebase origin ${{ github.event.pull_request.head.ref }} git add uv.lock conda/meta.yaml - git commit -m "chore: sync uv.lock and conda recipe (tests passed)" || echo "No changes" - git push origin HEAD:${{ github.event.pull_request.head.ref }} + if git diff --cached --quiet; then + echo "No changes detected after rebase." + else + git commit -m "chore: sync uv.lock and conda recipe (tests passed)" + git push origin HEAD:${{ github.event.pull_request.head.ref }} + fi - name: Create New Pull Request if: github.event_name != 'pull_request' From 8508cfa25b7e1b8244d362084ec36c332df8aba8 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 17:49:51 +0100 Subject: [PATCH 04/27] some linting issues --- .github/workflows/python-package.yml | 14 +++++++------- .github/workflows/sync-dependencies.yml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index b0a2aa1..e3be464 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -15,8 +15,8 @@ permissions: jobs: test: - # ๐Ÿท๏ธ This makes the UI subdivided and easy to read! - name: ๐Ÿ ${{ matrix.python-version }} โ€ข ๐Ÿงฉ Split ${{ matrix.split }}/${{ strategy.job-total / 4 }} + # ๐Ÿท๏ธ Fixed naming logic: Simple and clean subdivision + name: "๐Ÿ ${{ matrix.python-version }} โ€ข ๐Ÿงฉ Split ${{ matrix.split }} of 4" runs-on: ${{ matrix.os }} strategy: @@ -26,17 +26,18 @@ jobs: os: ["ubuntu-latest"] split: [1, 2, 3, 4] - # Move common env vars here to keep the "run" step clean + # Global Job Environment - keeps the individual steps surgical env: CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt OPENBLAS_NUM_THREADS: 1 OMP_NUM_THREADS: 1 + MKL_NUM_THREADS: 1 steps: - name: โฌ‡๏ธ Checkout uses: actions/checkout@v4 - - name: ๐Ÿ“ฆ Load Updated Artifacts + - name: ๐Ÿ“ฆ Download updated dependencies uses: actions/download-artifact@v4 continue-on-error: true with: @@ -52,7 +53,7 @@ jobs: python -m pip install pre-commit pre-commit run --show-diff-on-failure --all-files - - name: ๐ŸŒ Install GIS System Deps + - name: ๐ŸŒ Install GIS Dependencies run: | sudo apt-add-repository -y ppa:ubuntugis/ubuntugis-unstable sudo apt-get -y update @@ -63,7 +64,7 @@ jobs: with: enable-cache: true - - name: ๐Ÿ› ๏ธ Sync Environment + - name: ๐Ÿ› ๏ธ Install dependencies env: GDAL_CONFIG: /usr/bin/gdal-config run: | @@ -92,5 +93,4 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} slug: mapchete/mapchete-eo - # Adding flags makes the Codecov UI prettier too! flags: py${{ matrix.python-version }},split${{ matrix.split }} \ No newline at end of file diff --git a/.github/workflows/sync-dependencies.yml b/.github/workflows/sync-dependencies.yml index ff89847..74949d5 100644 --- a/.github/workflows/sync-dependencies.yml +++ b/.github/workflows/sync-dependencies.yml @@ -75,7 +75,7 @@ jobs: uses: ./.github/workflows/python-package.yml secrets: inherit -finalize: + finalize: needs: [sync-and-prepare, run-tests] if: | always() && From 5e62ddddd5a0f6348620d6a48055f965431dc574 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 5 Feb 2026 16:59:47 +0000 Subject: [PATCH 05/27] chore: sync uv.lock and conda recipe (tests passed) --- uv.lock | 292 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 160 insertions(+), 132 deletions(-) diff --git a/uv.lock b/uv.lock index cfcb132..790b100 100644 --- a/uv.lock +++ b/uv.lock @@ -25,7 +25,7 @@ wheels = [ [[package]] name = "aiobotocore" -version = "2.26.0" +version = "3.1.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -34,11 +34,12 @@ dependencies = [ { name = "jmespath" }, { name = "multidict" }, { name = "python-dateutil" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4d/f8/99fa90d9c25b78292899fd4946fce97b6353838b5ecc139ad8ba1436e70c/aiobotocore-2.26.0.tar.gz", hash = "sha256:50567feaf8dfe2b653570b4491f5bc8c6e7fb9622479d66442462c021db4fadc", size = 122026, upload-time = "2025-11-28T07:54:59.956Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/86/6b22e645d2f340b6c0f7164e57641bd926b9c08d73428e4962fb0f3ae71b/aiobotocore-3.1.2.tar.gz", hash = "sha256:d9b5bfff63df96a0ba78f7e5d10a063ab2dd8497e9c15ecf9d9660dafb853172", size = 122621, upload-time = "2026-02-05T10:21:37.434Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/58/3bf0b7d474607dc7fd67dd1365c4e0f392c8177eaf4054e5ddee3ebd53b5/aiobotocore-2.26.0-py3-none-any.whl", hash = "sha256:a793db51c07930513b74ea7a95bd79aaa42f545bdb0f011779646eafa216abec", size = 87333, upload-time = "2025-11-28T07:54:58.457Z" }, + { url = "https://files.pythonhosted.org/packages/cd/22/4d16dca3bd1d6475a53063eb72150269cea1a0a201b55288b3402f61f119/aiobotocore-3.1.2-py3-none-any.whl", hash = "sha256:1141cec16c47cc3e466d89fcccc5c57291a3751a15488fe7fbaea8550f94f468", size = 87701, upload-time = "2026-02-05T10:21:36.183Z" }, ] [[package]] @@ -271,30 +272,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.41.5" +version = "1.42.42" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/81/450cd4143864959264a3d80f9246175a20de8c1e50ec889c710eaa28cdd9/boto3-1.41.5.tar.gz", hash = "sha256:bc7806bee681dfdff2fe2b74967b107a56274f1e66ebe4d20dc8eee1ea408d17", size = 111594, upload-time = "2025-11-26T20:27:47.021Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c8/ac/9ef2cc431e00ecbf1ac197938ddea120e75b516b4c57028a1fd517d3e882/boto3-1.42.42.tar.gz", hash = "sha256:8c2537156f5ccd72bbbfe4fc27a8a80bf3e4f80523f306417f3fb6023d13edda", size = 112831, upload-time = "2026-02-04T20:28:45.494Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/56/f47a80254ed4991cce9a2f6d8ae8aafbc8df1c3270e966b2927289e5a12f/boto3-1.41.5-py3-none-any.whl", hash = "sha256:bb278111bfb4c33dca8342bda49c9db7685e43debbfa00cc2a5eb854dd54b745", size = 139344, upload-time = "2025-11-26T20:27:45.571Z" }, + { url = "https://files.pythonhosted.org/packages/5e/0a/3966f239e1d9da93cb755dc0213835ce4e9ed93645192878d0a055ecdc31/boto3-1.42.42-py3-none-any.whl", hash = "sha256:8c78169ef47dc29863ebb11ba99134b1b418d3dfdd836419830f22552f8afe43", size = 140599, upload-time = "2026-02-04T20:28:43.056Z" }, ] [[package]] name = "botocore" -version = "1.41.5" +version = "1.42.42" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/90/22/7fe08c726a2e3b11a0aef8bf177e83891c9cb2dc1809d35c9ed91a9e60e6/botocore-1.41.5.tar.gz", hash = "sha256:0367622b811597d183bfcaab4a350f0d3ede712031ce792ef183cabdee80d3bf", size = 14668152, upload-time = "2025-11-26T20:27:38.026Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/96/4eca9755ca444402c46c73cc8ff252c8eb73ab0ccf35ca76d89e7b7820ac/botocore-1.42.42.tar.gz", hash = "sha256:cb75639f5ba7bf73b83ac18bcd87f07b7f484f302748da974dad2801a83a1d60", size = 14926585, upload-time = "2026-02-04T20:28:33.66Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/4e/21cd0b8f365449f1576f93de1ec8718ed18a7a3bc086dfbdeb79437bba7a/botocore-1.41.5-py3-none-any.whl", hash = "sha256:3fef7fcda30c82c27202d232cfdbd6782cb27f20f8e7e21b20606483e66ee73a", size = 14337008, upload-time = "2025-11-26T20:27:35.208Z" }, + { url = "https://files.pythonhosted.org/packages/e6/51/aac7e419521d5519e13087a7198623655648c939822bd7f4bdc9ccbe07f9/botocore-1.42.42-py3-none-any.whl", hash = "sha256:1c9df5fc31e9073a9aa956271c4007d72f5d342cafca5f4154ea099bc6f83085", size = 14600186, upload-time = "2026-02-04T20:28:29.268Z" }, ] [[package]] @@ -813,7 +814,7 @@ wheels = [ [[package]] name = "dateparser" -version = "1.2.2" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, @@ -821,9 +822,9 @@ dependencies = [ { name = "regex" }, { name = "tzlocal" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/30/064144f0df1749e7bb5faaa7f52b007d7c2d08ec08fed8411aba87207f68/dateparser-1.2.2.tar.gz", hash = "sha256:986316f17cb8cdc23ea8ce563027c5ef12fc725b6fb1d137c14ca08777c5ecf7", size = 329840, upload-time = "2025-06-26T09:29:23.211Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/2c/668dfb8c073a5dde3efb80fa382de1502e3b14002fd386a8c1b0b49e92a9/dateparser-1.3.0.tar.gz", hash = "sha256:5bccf5d1ec6785e5be71cc7ec80f014575a09b4923e762f850e57443bddbf1a5", size = 337152, upload-time = "2026-02-04T16:00:06.162Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/22/f020c047ae1346613db9322638186468238bcfa8849b4668a22b97faad65/dateparser-1.2.2-py3-none-any.whl", hash = "sha256:5a5d7211a09013499867547023a2a0c91d5a27d15dd4dbcea676ea9fe66f2482", size = 315453, upload-time = "2025-06-26T09:29:21.412Z" }, + { url = "https://files.pythonhosted.org/packages/9a/c7/95349670e193b2891176e1b8e5f43e12b31bff6d9994f70e74ab385047f6/dateparser-1.3.0-py3-none-any.whl", hash = "sha256:8dc678b0a526e103379f02ae44337d424bd366aac727d3c6cf52ce1b01efbb5a", size = 318688, upload-time = "2026-02-04T16:00:04.652Z" }, ] [[package]] @@ -907,7 +908,7 @@ wheels = [ [[package]] name = "fastapi" -version = "0.128.0" +version = "0.128.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, @@ -915,9 +916,9 @@ dependencies = [ { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/52/08/8c8508db6c7b9aae8f7175046af41baad690771c9bcde676419965e338c7/fastapi-0.128.0.tar.gz", hash = "sha256:1cc179e1cef10a6be60ffe429f79b829dce99d8de32d7acb7e6c8dfdf7f2645a", size = 365682, upload-time = "2025-12-27T15:21:13.714Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/59/28bde150415783ff084334e3de106eb7461a57864cf69f343950ad5a5ddd/fastapi-0.128.1.tar.gz", hash = "sha256:ce5be4fa26d4ce6f54debcc873d1fb8e0e248f5c48d7502ba6c61457ab2dc766", size = 374260, upload-time = "2026-02-04T17:35:10.542Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/05/5cbb59154b093548acd0f4c7c474a118eda06da25aa75c616b72d8fcd92a/fastapi-0.128.0-py3-none-any.whl", hash = "sha256:aebd93f9716ee3b4f4fcfe13ffb7cf308d99c9f3ab5622d8877441072561582d", size = 103094, upload-time = "2025-12-27T15:21:12.154Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/3953db1979ea131c68279b997c6465080118b407f0800445b843f8e164b3/fastapi-0.128.1-py3-none-any.whl", hash = "sha256:ee82146bbf91ea5bbf2bb8629e4c6e056c4fbd997ea6068501b11b15260b50fb", size = 103810, upload-time = "2026-02-04T17:35:08.02Z" }, ] [[package]] @@ -1658,7 +1659,7 @@ wheels = [ [[package]] name = "mapchete" -version = "2025.12.0" +version = "2026.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -1690,9 +1691,9 @@ dependencies = [ { name = "tilematrix" }, { name = "tqdm" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/5c/3748dc530e52b6c5e3cf1bc0c61a566ea04c2aa77740dc1995136bbc4fb0/mapchete-2025.12.0.tar.gz", hash = "sha256:f1de70541220e5383cdd08bd69e457158fc11fc0ad468cf14788db27a0740459", size = 161034, upload-time = "2025-12-16T13:29:56.581Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/16/eb57c3765f66a326af8ebc3d3ed587e8e9132e072fe920e5509b2f7ef34b/mapchete-2026.2.1.tar.gz", hash = "sha256:693bd3db2c04e18c54b66f4f1cb17be64afdd0d546bba022f95163d13b2e8c39", size = 162900, upload-time = "2026-02-04T11:14:35.162Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/80/e9/a6ce8678ee0fa5bb10585955780569a64dc3344a99eb4b264ec5b629663c/mapchete-2025.12.0-py2.py3-none-any.whl", hash = "sha256:a7a9321b4f45a92c89fd339cdcc4873edd93bc1e31bb433d793aed2463f6c019", size = 229544, upload-time = "2025-12-16T13:29:55.32Z" }, + { url = "https://files.pythonhosted.org/packages/79/53/88dee445ca5eae1eeb2a3a1397f70d74afff6f7573d450110cca24df1b6c/mapchete-2026.2.1-py3-none-any.whl", hash = "sha256:2cc70a641fcbdbd0bcb75e547f86d42988a5ddc0095b9605df93e2e7ba55a624", size = 231360, upload-time = "2026-02-04T11:14:36.968Z" }, ] [package.optional-dependencies] @@ -1918,7 +1919,7 @@ wheels = [ [[package]] name = "matplotlib" -version = "3.9.4" +version = "3.10.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "contourpy", version = "1.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, @@ -1933,38 +1934,62 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/17/1747b4154034befd0ed33b52538f5eb7752d05bb51c5e2a31470c3bc7d52/matplotlib-3.9.4.tar.gz", hash = "sha256:1e00e8be7393cbdc6fedfa8a6fba02cf3e83814b285db1c60b906a023ba41bc3", size = 36106529, upload-time = "2024-12-13T05:56:34.184Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/94/27d2e2c30d54b56c7b764acc1874a909e34d1965a427fc7092bb6a588b63/matplotlib-3.9.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c5fdd7abfb706dfa8d307af64a87f1a862879ec3cd8d0ec8637458f0885b9c50", size = 7885089, upload-time = "2024-12-13T05:54:24.224Z" }, - { url = "https://files.pythonhosted.org/packages/c6/25/828273307e40a68eb8e9df832b6b2aaad075864fdc1de4b1b81e40b09e48/matplotlib-3.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d89bc4e85e40a71d1477780366c27fb7c6494d293e1617788986f74e2a03d7ff", size = 7770600, upload-time = "2024-12-13T05:54:27.214Z" }, - { url = "https://files.pythonhosted.org/packages/f2/65/f841a422ec994da5123368d76b126acf4fc02ea7459b6e37c4891b555b83/matplotlib-3.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddf9f3c26aae695c5daafbf6b94e4c1a30d6cd617ba594bbbded3b33a1fcfa26", size = 8200138, upload-time = "2024-12-13T05:54:29.497Z" }, - { url = "https://files.pythonhosted.org/packages/07/06/272aca07a38804d93b6050813de41ca7ab0e29ba7a9dd098e12037c919a9/matplotlib-3.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18ebcf248030173b59a868fda1fe42397253f6698995b55e81e1f57431d85e50", size = 8312711, upload-time = "2024-12-13T05:54:34.396Z" }, - { url = "https://files.pythonhosted.org/packages/98/37/f13e23b233c526b7e27ad61be0a771894a079e0f7494a10d8d81557e0e9a/matplotlib-3.9.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:974896ec43c672ec23f3f8c648981e8bc880ee163146e0312a9b8def2fac66f5", size = 9090622, upload-time = "2024-12-13T05:54:36.808Z" }, - { url = "https://files.pythonhosted.org/packages/4f/8c/b1f5bd2bd70e60f93b1b54c4d5ba7a992312021d0ddddf572f9a1a6d9348/matplotlib-3.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:4598c394ae9711cec135639374e70871fa36b56afae17bdf032a345be552a88d", size = 7828211, upload-time = "2024-12-13T05:54:40.596Z" }, - { url = "https://files.pythonhosted.org/packages/74/4b/65be7959a8fa118a3929b49a842de5b78bb55475236fcf64f3e308ff74a0/matplotlib-3.9.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4dd29641d9fb8bc4492420c5480398dd40a09afd73aebe4eb9d0071a05fbe0c", size = 7894430, upload-time = "2024-12-13T05:54:44.049Z" }, - { url = "https://files.pythonhosted.org/packages/e9/18/80f70d91896e0a517b4a051c3fd540daa131630fd75e02e250365353b253/matplotlib-3.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30e5b22e8bcfb95442bf7d48b0d7f3bdf4a450cbf68986ea45fca3d11ae9d099", size = 7780045, upload-time = "2024-12-13T05:54:46.414Z" }, - { url = "https://files.pythonhosted.org/packages/a2/73/ccb381026e3238c5c25c3609ba4157b2d1a617ec98d65a8b4ee4e1e74d02/matplotlib-3.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bb0030d1d447fd56dcc23b4c64a26e44e898f0416276cac1ebc25522e0ac249", size = 8209906, upload-time = "2024-12-13T05:54:49.459Z" }, - { url = "https://files.pythonhosted.org/packages/ab/33/1648da77b74741c89f5ea95cbf42a291b4b364f2660b316318811404ed97/matplotlib-3.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aca90ed222ac3565d2752b83dbb27627480d27662671e4d39da72e97f657a423", size = 8322873, upload-time = "2024-12-13T05:54:53.066Z" }, - { url = "https://files.pythonhosted.org/packages/57/d3/8447ba78bc6593c9044c372d1609f8ea10fb1e071e7a9e0747bea74fc16c/matplotlib-3.9.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a181b2aa2906c608fcae72f977a4a2d76e385578939891b91c2550c39ecf361e", size = 9099566, upload-time = "2024-12-13T05:54:55.522Z" }, - { url = "https://files.pythonhosted.org/packages/23/e1/4f0e237bf349c02ff9d1b6e7109f1a17f745263809b9714a8576dc17752b/matplotlib-3.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:1f6882828231eca17f501c4dcd98a05abb3f03d157fbc0769c6911fe08b6cfd3", size = 7838065, upload-time = "2024-12-13T05:54:58.337Z" }, - { url = "https://files.pythonhosted.org/packages/1a/2b/c918bf6c19d6445d1cefe3d2e42cb740fb997e14ab19d4daeb6a7ab8a157/matplotlib-3.9.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dfc48d67e6661378a21c2983200a654b72b5c5cdbd5d2cf6e5e1ece860f0cc70", size = 7891131, upload-time = "2024-12-13T05:55:02.837Z" }, - { url = "https://files.pythonhosted.org/packages/c1/e5/b4e8fc601ca302afeeabf45f30e706a445c7979a180e3a978b78b2b681a4/matplotlib-3.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47aef0fab8332d02d68e786eba8113ffd6f862182ea2999379dec9e237b7e483", size = 7776365, upload-time = "2024-12-13T05:55:05.158Z" }, - { url = "https://files.pythonhosted.org/packages/99/06/b991886c506506476e5d83625c5970c656a491b9f80161458fed94597808/matplotlib-3.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fba1f52c6b7dc764097f52fd9ab627b90db452c9feb653a59945de16752e965f", size = 8200707, upload-time = "2024-12-13T05:55:09.48Z" }, - { url = "https://files.pythonhosted.org/packages/c3/e2/556b627498cb27e61026f2d1ba86a78ad1b836fef0996bef5440e8bc9559/matplotlib-3.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:173ac3748acaac21afcc3fa1633924609ba1b87749006bc25051c52c422a5d00", size = 8313761, upload-time = "2024-12-13T05:55:12.95Z" }, - { url = "https://files.pythonhosted.org/packages/58/ff/165af33ec766ff818306ea88e91f9f60d2a6ed543be1eb122a98acbf3b0d/matplotlib-3.9.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320edea0cadc07007765e33f878b13b3738ffa9745c5f707705692df70ffe0e0", size = 9095284, upload-time = "2024-12-13T05:55:16.199Z" }, - { url = "https://files.pythonhosted.org/packages/9f/8b/3d0c7a002db3b1ed702731c2a9a06d78d035f1f2fb0fb936a8e43cc1e9f4/matplotlib-3.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a4a4cfc82330b27042a7169533da7991e8789d180dd5b3daeaee57d75cd5a03b", size = 7841160, upload-time = "2024-12-13T05:55:19.991Z" }, - { url = "https://files.pythonhosted.org/packages/49/b1/999f89a7556d101b23a2f0b54f1b6e140d73f56804da1398f2f0bc0924bc/matplotlib-3.9.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:37eeffeeca3c940985b80f5b9a7b95ea35671e0e7405001f249848d2b62351b6", size = 7891499, upload-time = "2024-12-13T05:55:22.142Z" }, - { url = "https://files.pythonhosted.org/packages/87/7b/06a32b13a684977653396a1bfcd34d4e7539c5d55c8cbfaa8ae04d47e4a9/matplotlib-3.9.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3e7465ac859ee4abcb0d836137cd8414e7bb7ad330d905abced457217d4f0f45", size = 7776802, upload-time = "2024-12-13T05:55:25.947Z" }, - { url = "https://files.pythonhosted.org/packages/65/87/ac498451aff739e515891bbb92e566f3c7ef31891aaa878402a71f9b0910/matplotlib-3.9.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4c12302c34afa0cf061bea23b331e747e5e554b0fa595c96e01c7b75bc3b858", size = 8200802, upload-time = "2024-12-13T05:55:28.461Z" }, - { url = "https://files.pythonhosted.org/packages/f8/6b/9eb761c00e1cb838f6c92e5f25dcda3f56a87a52f6cb8fdfa561e6cf6a13/matplotlib-3.9.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b8c97917f21b75e72108b97707ba3d48f171541a74aa2a56df7a40626bafc64", size = 8313880, upload-time = "2024-12-13T05:55:30.965Z" }, - { url = "https://files.pythonhosted.org/packages/d7/a2/c8eaa600e2085eec7e38cbbcc58a30fc78f8224939d31d3152bdafc01fd1/matplotlib-3.9.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0229803bd7e19271b03cb09f27db76c918c467aa4ce2ae168171bc67c3f508df", size = 9094637, upload-time = "2024-12-13T05:55:33.701Z" }, - { url = "https://files.pythonhosted.org/packages/71/1f/c6e1daea55b7bfeb3d84c6cb1abc449f6a02b181e7e2a5e4db34c3afb793/matplotlib-3.9.4-cp313-cp313-win_amd64.whl", hash = "sha256:7c0d8ef442ebf56ff5e206f8083d08252ee738e04f3dc88ea882853a05488799", size = 7841311, upload-time = "2024-12-13T05:55:36.737Z" }, - { url = "https://files.pythonhosted.org/packages/c0/3a/2757d3f7d388b14dd48f5a83bea65b6d69f000e86b8f28f74d86e0d375bd/matplotlib-3.9.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a04c3b00066a688834356d196136349cb32f5e1003c55ac419e91585168b88fb", size = 7919989, upload-time = "2024-12-13T05:55:39.024Z" }, - { url = "https://files.pythonhosted.org/packages/24/28/f5077c79a4f521589a37fe1062d6a6ea3534e068213f7357e7cfffc2e17a/matplotlib-3.9.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:04c519587f6c210626741a1e9a68eefc05966ede24205db8982841826af5871a", size = 7809417, upload-time = "2024-12-13T05:55:42.412Z" }, - { url = "https://files.pythonhosted.org/packages/36/c8/c523fd2963156692916a8eb7d4069084cf729359f7955cf09075deddfeaf/matplotlib-3.9.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308afbf1a228b8b525fcd5cec17f246bbbb63b175a3ef6eb7b4d33287ca0cf0c", size = 8226258, upload-time = "2024-12-13T05:55:47.259Z" }, - { url = "https://files.pythonhosted.org/packages/f6/88/499bf4b8fa9349b6f5c0cf4cead0ebe5da9d67769129f1b5651e5ac51fbc/matplotlib-3.9.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb3b02246ddcffd3ce98e88fed5b238bc5faff10dbbaa42090ea13241d15764", size = 8335849, upload-time = "2024-12-13T05:55:49.763Z" }, - { url = "https://files.pythonhosted.org/packages/b8/9f/20a4156b9726188646a030774ee337d5ff695a965be45ce4dbcb9312c170/matplotlib-3.9.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8a75287e9cb9eee48cb79ec1d806f75b29c0fde978cb7223a1f4c5848d696041", size = 9102152, upload-time = "2024-12-13T05:55:51.997Z" }, - { url = "https://files.pythonhosted.org/packages/10/11/237f9c3a4e8d810b1759b67ff2da7c32c04f9c80aa475e7beb36ed43a8fb/matplotlib-3.9.4-cp313-cp313t-win_amd64.whl", hash = "sha256:488deb7af140f0ba86da003e66e10d55ff915e152c78b4b66d231638400b1965", size = 7896987, upload-time = "2024-12-13T05:55:55.941Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/8a/76/d3c6e3a13fe484ebe7718d14e269c9569c4eb0020a968a327acb3b9a8fe6/matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3", size = 34806269, upload-time = "2025-12-10T22:56:51.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/be/a30bd917018ad220c400169fba298f2bb7003c8ccbc0c3e24ae2aacad1e8/matplotlib-3.10.8-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:00270d217d6b20d14b584c521f810d60c5c78406dc289859776550df837dcda7", size = 8239828, upload-time = "2025-12-10T22:55:02.313Z" }, + { url = "https://files.pythonhosted.org/packages/58/27/ca01e043c4841078e82cf6e80a6993dfecd315c3d79f5f3153afbb8e1ec6/matplotlib-3.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b3c1cc42aa184b3f738cfa18c1c1d72fd496d85467a6cf7b807936d39aa656", size = 8128050, upload-time = "2025-12-10T22:55:04.997Z" }, + { url = "https://files.pythonhosted.org/packages/cb/aa/7ab67f2b729ae6a91bcf9dcac0affb95fb8c56f7fd2b2af894ae0b0cf6fa/matplotlib-3.10.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ee40c27c795bda6a5292e9cff9890189d32f7e3a0bf04e0e3c9430c4a00c37df", size = 8700452, upload-time = "2025-12-10T22:55:07.47Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/2d5817b0acee3c49b7e7ccfbf5b273f284957cc8e270adf36375db353190/matplotlib-3.10.8-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a48f2b74020919552ea25d222d5cc6af9ca3f4eb43a93e14d068457f545c2a17", size = 9534928, upload-time = "2025-12-10T22:55:10.566Z" }, + { url = "https://files.pythonhosted.org/packages/c9/5b/8e66653e9f7c39cb2e5cab25fce4810daffa2bff02cbf5f3077cea9e942c/matplotlib-3.10.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f254d118d14a7f99d616271d6c3c27922c092dac11112670b157798b89bf4933", size = 9586377, upload-time = "2025-12-10T22:55:12.362Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/fd0bbadf837f81edb0d208ba8f8cb552874c3b16e27cb91a31977d90875d/matplotlib-3.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:f9b587c9c7274c1613a30afabf65a272114cd6cdbe67b3406f818c79d7ab2e2a", size = 8128127, upload-time = "2025-12-10T22:55:14.436Z" }, + { url = "https://files.pythonhosted.org/packages/f8/86/de7e3a1cdcfc941483af70609edc06b83e7c8a0e0dc9ac325200a3f4d220/matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160", size = 8251215, upload-time = "2025-12-10T22:55:16.175Z" }, + { url = "https://files.pythonhosted.org/packages/fd/14/baad3222f424b19ce6ad243c71de1ad9ec6b2e4eb1e458a48fdc6d120401/matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78", size = 8139625, upload-time = "2025-12-10T22:55:17.712Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a0/7024215e95d456de5883e6732e708d8187d9753a21d32f8ddb3befc0c445/matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4", size = 8712614, upload-time = "2025-12-10T22:55:20.8Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f4/b8347351da9a5b3f41e26cf547252d861f685c6867d179a7c9d60ad50189/matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d56a1efd5bfd61486c8bc968fa18734464556f0fb8e51690f4ac25d85cbbbbc2", size = 9540997, upload-time = "2025-12-10T22:55:23.258Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c0/c7b914e297efe0bc36917bf216b2acb91044b91e930e878ae12981e461e5/matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238b7ce5717600615c895050239ec955d91f321c209dd110db988500558e70d6", size = 9596825, upload-time = "2025-12-10T22:55:25.217Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d3/a4bbc01c237ab710a1f22b4da72f4ff6d77eb4c7735ea9811a94ae239067/matplotlib-3.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9", size = 8135090, upload-time = "2025-12-10T22:55:27.162Z" }, + { url = "https://files.pythonhosted.org/packages/89/dd/a0b6588f102beab33ca6f5218b31725216577b2a24172f327eaf6417d5c9/matplotlib-3.10.8-cp311-cp311-win_arm64.whl", hash = "sha256:bab485bcf8b1c7d2060b4fcb6fc368a9e6f4cd754c9c2fea281f4be21df394a2", size = 8012377, upload-time = "2025-12-10T22:55:29.185Z" }, + { url = "https://files.pythonhosted.org/packages/9e/67/f997cdcbb514012eb0d10cd2b4b332667997fb5ebe26b8d41d04962fa0e6/matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a", size = 8260453, upload-time = "2025-12-10T22:55:30.709Z" }, + { url = "https://files.pythonhosted.org/packages/7e/65/07d5f5c7f7c994f12c768708bd2e17a4f01a2b0f44a1c9eccad872433e2e/matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58", size = 8148321, upload-time = "2025-12-10T22:55:33.265Z" }, + { url = "https://files.pythonhosted.org/packages/3e/f3/c5195b1ae57ef85339fd7285dfb603b22c8b4e79114bae5f4f0fcf688677/matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04", size = 8716944, upload-time = "2025-12-10T22:55:34.922Z" }, + { url = "https://files.pythonhosted.org/packages/00/f9/7638f5cc82ec8a7aa005de48622eecc3ed7c9854b96ba15bd76b7fd27574/matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24d50994d8c5816ddc35411e50a86ab05f575e2530c02752e02538122613371f", size = 9550099, upload-time = "2025-12-10T22:55:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/57/61/78cd5920d35b29fd2a0fe894de8adf672ff52939d2e9b43cb83cd5ce1bc7/matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99eefd13c0dc3b3c1b4d561c1169e65fe47aab7b8158754d7c084088e2329466", size = 9613040, upload-time = "2025-12-10T22:55:38.715Z" }, + { url = "https://files.pythonhosted.org/packages/30/4e/c10f171b6e2f44d9e3a2b96efa38b1677439d79c99357600a62cc1e9594e/matplotlib-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:dd80ecb295460a5d9d260df63c43f4afbdd832d725a531f008dad1664f458adf", size = 8142717, upload-time = "2025-12-10T22:55:41.103Z" }, + { url = "https://files.pythonhosted.org/packages/f1/76/934db220026b5fef85f45d51a738b91dea7d70207581063cd9bd8fafcf74/matplotlib-3.10.8-cp312-cp312-win_arm64.whl", hash = "sha256:3c624e43ed56313651bc18a47f838b60d7b8032ed348911c54906b130b20071b", size = 8012751, upload-time = "2025-12-10T22:55:42.684Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6", size = 8261076, upload-time = "2025-12-10T22:55:44.648Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1", size = 8148794, upload-time = "2025-12-10T22:55:46.252Z" }, + { url = "https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486", size = 8718474, upload-time = "2025-12-10T22:55:47.864Z" }, + { url = "https://files.pythonhosted.org/packages/01/be/cd478f4b66f48256f42927d0acbcd63a26a893136456cd079c0cc24fbabf/matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce", size = 9549637, upload-time = "2025-12-10T22:55:50.048Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/8dc289776eae5109e268c4fb92baf870678dc048a25d4ac903683b86d5bf/matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6", size = 9613678, upload-time = "2025-12-10T22:55:52.21Z" }, + { url = "https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149", size = 8142686, upload-time = "2025-12-10T22:55:54.253Z" }, + { url = "https://files.pythonhosted.org/packages/66/52/8d8a8730e968185514680c2a6625943f70269509c3dcfc0dcf7d75928cb8/matplotlib-3.10.8-cp313-cp313-win_arm64.whl", hash = "sha256:c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645", size = 8012917, upload-time = "2025-12-10T22:55:56.268Z" }, + { url = "https://files.pythonhosted.org/packages/b5/27/51fe26e1062f298af5ef66343d8ef460e090a27fea73036c76c35821df04/matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077", size = 8305679, upload-time = "2025-12-10T22:55:57.856Z" }, + { url = "https://files.pythonhosted.org/packages/2c/1e/4de865bc591ac8e3062e835f42dd7fe7a93168d519557837f0e37513f629/matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22", size = 8198336, upload-time = "2025-12-10T22:55:59.371Z" }, + { url = "https://files.pythonhosted.org/packages/c6/cb/2f7b6e75fb4dce87ef91f60cac4f6e34f4c145ab036a22318ec837971300/matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39", size = 8731653, upload-time = "2025-12-10T22:56:01.032Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/bd9c57d6ba670a37ab31fb87ec3e8691b947134b201f881665b28cc039ff/matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565", size = 9561356, upload-time = "2025-12-10T22:56:02.95Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/8b94a481456dfc9dfe6e39e93b5ab376e50998cddfd23f4ae3b431708f16/matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a", size = 9614000, upload-time = "2025-12-10T22:56:05.411Z" }, + { url = "https://files.pythonhosted.org/packages/bd/cd/bc06149fe5585ba800b189a6a654a75f1f127e8aab02fd2be10df7fa500c/matplotlib-3.10.8-cp313-cp313t-win_amd64.whl", hash = "sha256:3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958", size = 8220043, upload-time = "2025-12-10T22:56:07.551Z" }, + { url = "https://files.pythonhosted.org/packages/e3/de/b22cf255abec916562cc04eef457c13e58a1990048de0c0c3604d082355e/matplotlib-3.10.8-cp313-cp313t-win_arm64.whl", hash = "sha256:15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5", size = 8062075, upload-time = "2025-12-10T22:56:09.178Z" }, + { url = "https://files.pythonhosted.org/packages/3c/43/9c0ff7a2f11615e516c3b058e1e6e8f9614ddeca53faca06da267c48345d/matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f", size = 8262481, upload-time = "2025-12-10T22:56:10.885Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ca/e8ae28649fcdf039fda5ef554b40a95f50592a3c47e6f7270c9561c12b07/matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b", size = 8151473, upload-time = "2025-12-10T22:56:12.377Z" }, + { url = "https://files.pythonhosted.org/packages/f1/6f/009d129ae70b75e88cbe7e503a12a4c0670e08ed748a902c2568909e9eb5/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d", size = 9553896, upload-time = "2025-12-10T22:56:14.432Z" }, + { url = "https://files.pythonhosted.org/packages/f5/26/4221a741eb97967bc1fd5e4c52b9aa5a91b2f4ec05b59f6def4d820f9df9/matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008", size = 9824193, upload-time = "2025-12-10T22:56:16.29Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/3abf75f38605772cf48a9daf5821cd4f563472f38b4b828c6fba6fa6d06e/matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c", size = 9615444, upload-time = "2025-12-10T22:56:18.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/a5/de89ac80f10b8dc615807ee1133cd99ac74082581196d4d9590bea10690d/matplotlib-3.10.8-cp314-cp314-win_amd64.whl", hash = "sha256:83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11", size = 8272719, upload-time = "2025-12-10T22:56:20.366Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/b006495c19ccc0a137b48083168a37bd056392dee02f87dba0472f2797fe/matplotlib-3.10.8-cp314-cp314-win_arm64.whl", hash = "sha256:2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8", size = 8144205, upload-time = "2025-12-10T22:56:22.239Z" }, + { url = "https://files.pythonhosted.org/packages/68/d9/b31116a3a855bd313c6fcdb7226926d59b041f26061c6c5b1be66a08c826/matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50", size = 8305785, upload-time = "2025-12-10T22:56:24.218Z" }, + { url = "https://files.pythonhosted.org/packages/1e/90/6effe8103f0272685767ba5f094f453784057072f49b393e3ea178fe70a5/matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908", size = 8198361, upload-time = "2025-12-10T22:56:26.787Z" }, + { url = "https://files.pythonhosted.org/packages/d7/65/a73188711bea603615fc0baecca1061429ac16940e2385433cc778a9d8e7/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a", size = 9561357, upload-time = "2025-12-10T22:56:28.953Z" }, + { url = "https://files.pythonhosted.org/packages/f4/3d/b5c5d5d5be8ce63292567f0e2c43dde9953d3ed86ac2de0a72e93c8f07a1/matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1", size = 9823610, upload-time = "2025-12-10T22:56:31.455Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4b/e7beb6bbd49f6bae727a12b270a2654d13c397576d25bd6786e47033300f/matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c", size = 9614011, upload-time = "2025-12-10T22:56:33.85Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e6/76f2813d31f032e65f6f797e3f2f6e4aab95b65015924b1c51370395c28a/matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b", size = 8362801, upload-time = "2025-12-10T22:56:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/5d/49/d651878698a0b67f23aa28e17f45a6d6dd3d3f933fa29087fa4ce5947b5a/matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f", size = 8192560, upload-time = "2025-12-10T22:56:38.008Z" }, + { url = "https://files.pythonhosted.org/packages/f5/43/31d59500bb950b0d188e149a2e552040528c13d6e3d6e84d0cccac593dcd/matplotlib-3.10.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f97aeb209c3d2511443f8797e3e5a569aebb040d4f8bc79aa3ee78a8fb9e3dd8", size = 8237252, upload-time = "2025-12-10T22:56:39.529Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2c/615c09984f3c5f907f51c886538ad785cf72e0e11a3225de2c0f9442aecc/matplotlib-3.10.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fb061f596dad3a0f52b60dc6a5dec4a0c300dec41e058a7efe09256188d170b7", size = 8124693, upload-time = "2025-12-10T22:56:41.758Z" }, + { url = "https://files.pythonhosted.org/packages/91/e1/2757277a1c56041e1fc104b51a0f7b9a4afc8eb737865d63cababe30bc61/matplotlib-3.10.8-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:12d90df9183093fcd479f4172ac26b322b1248b15729cb57f42f71f24c7e37a3", size = 8702205, upload-time = "2025-12-10T22:56:43.415Z" }, + { url = "https://files.pythonhosted.org/packages/04/30/3afaa31c757f34b7725ab9d2ba8b48b5e89c2019c003e7d0ead143aabc5a/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6da7c2ce169267d0d066adcf63758f0604aa6c3eebf67458930f9d9b79ad1db1", size = 8249198, upload-time = "2025-12-10T22:56:45.584Z" }, + { url = "https://files.pythonhosted.org/packages/48/2f/6334aec331f57485a642a7c8be03cb286f29111ae71c46c38b363230063c/matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9153c3292705be9f9c64498a8872118540c3f4123d1a1c840172edf262c8be4a", size = 8136817, upload-time = "2025-12-10T22:56:47.339Z" }, + { url = "https://files.pythonhosted.org/packages/73/e4/6d6f14b2a759c622f191b2d67e9075a3f56aaccb3be4bb9bb6890030d0a0/matplotlib-3.10.8-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ae029229a57cd1e8fe542485f27e7ca7b23aa9e8944ddb4985d0bc444f1eca2", size = 8713867, upload-time = "2025-12-10T22:56:48.954Z" }, ] [[package]] @@ -2057,7 +2082,7 @@ wheels = [ [[package]] name = "morecantile" -version = "7.0.2" +version = "7.0.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -2076,9 +2101,9 @@ dependencies = [ { name = "pydantic", marker = "python_full_version >= '3.11'" }, { name = "pyproj", version = "3.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/91/4305a53bc20785ec882c9066528d8bbd82782b3a8ec30d4d5f6bc9c9d148/morecantile-7.0.2.tar.gz", hash = "sha256:83aaffab29e63d39a88d78931aaad3659ab5355d500ec843ea136eef976dc717", size = 43076, upload-time = "2026-01-05T20:59:55.844Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/44/fa4f0685481b51e5ce33089ca84e821453593d34f306738515a937934751/morecantile-7.0.3.tar.gz", hash = "sha256:b44419c83f310b411b1f547df2d07c115dc6d194ab7c8a4c318a154490e938c1", size = 43104, upload-time = "2026-02-04T23:03:26.423Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/c3/cb8db47ed1a28b43d498e91b629d69886778ad5d9e91dcb953d411052728/morecantile-7.0.2-py3-none-any.whl", hash = "sha256:f873e435a057e1b61ea91613c297e5a76b2ae854b5ec2ccc8b0c561f9cdde534", size = 50857, upload-time = "2026-01-05T20:59:54.435Z" }, + { url = "https://files.pythonhosted.org/packages/98/1a/f9edb1c167bd8ad214dc87e9ae17fb208d08f7a05e724f74ce29e375c8de/morecantile-7.0.3-py3-none-any.whl", hash = "sha256:747c6b8f3a8029ddaadb04d96c834f10d2796d1898ad893bed47c896a058ddc7", size = 50885, upload-time = "2026-02-04T23:03:27.463Z" }, ] [[package]] @@ -2554,21 +2579,21 @@ wheels = [ [[package]] name = "opencv-python-headless" -version = "4.13.0.90" +version = "4.13.0.92" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/76/38c4cbb5ccfce7aaf36fd9be9fc74a15c85a48ef90bfaca2049b486e10c5/opencv_python_headless-4.13.0.90-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:12a28674f215542c9bf93338de1b5bffd76996d32da9acb9e739fdb9c8bbd738", size = 46020414, upload-time = "2026-01-18T09:07:10.801Z" }, - { url = "https://files.pythonhosted.org/packages/93/c5/4b40daa5003b45aa8397f160324a091ed323733e2446dc0bdf3655e77b84/opencv_python_headless-4.13.0.90-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:32255203040dc98803be96362e13f9e4bce20146898222d2e5c242f80de50da5", size = 32568519, upload-time = "2026-01-18T09:07:52.368Z" }, - { url = "https://files.pythonhosted.org/packages/da/65/920e64a7f03cf5917cd2c6a3046293843c1a16ad89f0ed0f1c683979c9de/opencv_python_headless-4.13.0.90-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e13790342591557050157713af17a7435ac1b50c65282715093c9297fa045d8f", size = 35191272, upload-time = "2026-01-18T09:08:49.235Z" }, - { url = "https://files.pythonhosted.org/packages/fc/13/af150685be342dc09bfb0824e2a280020ccf1c7fc64e15a31d9209016aa9/opencv_python_headless-4.13.0.90-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dbc1f4625e5af3a80ebdbd84380227c0f445228588f2521b11af47710caca1ba", size = 57683677, upload-time = "2026-01-18T09:10:23.588Z" }, - { url = "https://files.pythonhosted.org/packages/cd/47/baab2a3b6d8da8c52e73d00207d1ed3155601c2c332ea855455b3fbc8ff4/opencv_python_headless-4.13.0.90-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eba38bc255d0b7d1969c5bcc90a060ca2b61a3403b613872c750bfa5dfe9e03b", size = 36590019, upload-time = "2026-01-18T09:10:49.053Z" }, - { url = "https://files.pythonhosted.org/packages/81/a1/facfe2801a861b424c4221d66e1281cf19735c00e07f063a337a208c11b5/opencv_python_headless-4.13.0.90-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f46b17ea0aa7e4124ca6ad71143f89233ae9557f61d2326bcdb34329a1ddf9bd", size = 62535926, upload-time = "2026-01-18T09:12:47.229Z" }, - { url = "https://files.pythonhosted.org/packages/06/d2/5e9ee7512306c1caa518be929d1f44bb1c189f342f538f73bea6fb94919f/opencv_python_headless-4.13.0.90-cp37-abi3-win32.whl", hash = "sha256:96060fc57a1abb1144b0b8129e2ff3bfcdd0ccd8e8bd05bd85256ff4ed587d3b", size = 30811665, upload-time = "2026-01-18T09:13:44.517Z" }, - { url = "https://files.pythonhosted.org/packages/a0/09/0a4d832448dccd03b2b1bdee70b9fc2e02c147cc7e06975e9cd729569d90/opencv_python_headless-4.13.0.90-cp37-abi3-win_amd64.whl", hash = "sha256:0e0c8c9f620802fddc4fa7f471a1d263c7b0dca16cd9e7e2f996bb8bd2128c0c", size = 40070035, upload-time = "2026-01-18T09:15:14.652Z" }, + { url = "https://files.pythonhosted.org/packages/79/42/2310883be3b8826ac58c3f2787b9358a2d46923d61f88fedf930bc59c60c/opencv_python_headless-4.13.0.92-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:1a7d040ac656c11b8c38677cc8cccdc149f98535089dbe5b081e80a4e5903209", size = 46247192, upload-time = "2026-02-05T07:01:35.187Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1e/6f9e38005a6f7f22af785df42a43139d0e20f169eb5787ce8be37ee7fcc9/opencv_python_headless-4.13.0.92-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:3e0a6f0a37994ec6ce5f59e936be21d5d6384a4556f2d2da9c2f9c5dc948394c", size = 32568914, upload-time = "2026-02-05T07:01:51.989Z" }, + { url = "https://files.pythonhosted.org/packages/21/76/9417a6aef9def70e467a5bf560579f816148a4c658b7d525581b356eda9e/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c8cfc8e87ed452b5cecb9419473ee5560a989859fe1d10d1ce11ae87b09a2cb", size = 33703709, upload-time = "2026-02-05T10:24:46.469Z" }, + { url = "https://files.pythonhosted.org/packages/92/ce/bd17ff5772938267fd49716e94ca24f616ff4cb1ff4c6be13085108037be/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0525a3d2c0b46c611e2130b5fdebc94cf404845d8fa64d2f3a3b679572a5bd22", size = 56016764, upload-time = "2026-02-05T10:26:48.904Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b4/b7bcbf7c874665825a8c8e1097e93ea25d1f1d210a3e20d4451d01da30aa/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d", size = 35010236, upload-time = "2026-02-05T10:28:11.031Z" }, + { url = "https://files.pythonhosted.org/packages/4b/33/b5db29a6c00eb8f50708110d8d453747ca125c8b805bc437b289dbdcc057/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0bd48544f77c68b2941392fcdf9bcd2b9cdf00e98cb8c29b2455d194763cf99e", size = 60391106, upload-time = "2026-02-05T10:30:14.236Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c3/52cfea47cd33e53e8c0fbd6e7c800b457245c1fda7d61660b4ffe9596a7f/opencv_python_headless-4.13.0.92-cp37-abi3-win32.whl", hash = "sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b", size = 30812232, upload-time = "2026-02-05T07:02:29.594Z" }, + { url = "https://files.pythonhosted.org/packages/4a/90/b338326131ccb2aaa3c2c85d00f41822c0050139a4bfe723cfd95455bd2d/opencv_python_headless-4.13.0.92-cp37-abi3-win_amd64.whl", hash = "sha256:77a82fe35ddcec0f62c15f2ba8a12ecc2ed4207c17b0902c7a3151ae29f37fb6", size = 40070414, upload-time = "2026-02-05T07:02:26.448Z" }, ] [[package]] @@ -3872,7 +3897,7 @@ dependencies = [ { name = "cachetools", marker = "python_full_version >= '3.11'" }, { name = "color-operations", marker = "python_full_version >= '3.11'" }, { name = "httpx", marker = "python_full_version >= '3.11'" }, - { name = "morecantile", version = "7.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "morecantile", version = "7.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "numexpr", marker = "python_full_version >= '3.11'" }, { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pydantic", marker = "python_full_version >= '3.11'" }, @@ -4049,14 +4074,14 @@ wheels = [ [[package]] name = "s3transfer" -version = "0.15.0" +version = "0.16.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/bb/940d6af975948c1cc18f44545ffb219d3c35d78ec972b42ae229e8e37e08/s3transfer-0.15.0.tar.gz", hash = "sha256:d36fac8d0e3603eff9b5bfa4282c7ce6feb0301a633566153cbd0b93d11d8379", size = 152185, upload-time = "2025-11-20T20:28:56.327Z" } +sdist = { url = "https://files.pythonhosted.org/packages/05/04/74127fc843314818edfa81b5540e26dd537353b123a4edc563109d8f17dd/s3transfer-0.16.0.tar.gz", hash = "sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920", size = 153827, upload-time = "2025-12-01T02:30:59.114Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/e1/5ef25f52973aa12a19cf4e1375d00932d7fb354ffd310487ba7d44225c1a/s3transfer-0.15.0-py3-none-any.whl", hash = "sha256:6f8bf5caa31a0865c4081186689db1b2534cef721d104eb26101de4b9d6a5852", size = 85984, upload-time = "2025-11-20T20:28:55.046Z" }, + { url = "https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl", hash = "sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe", size = 86830, upload-time = "2025-12-01T02:30:57.729Z" }, ] [[package]] @@ -5003,71 +5028,74 @@ wheels = [ [[package]] name = "wrapt" -version = "1.17.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/23/bb82321b86411eb51e5a5db3fb8f8032fd30bd7c2d74bfe936136b2fa1d6/wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04", size = 53482, upload-time = "2025-08-12T05:51:44.467Z" }, - { url = "https://files.pythonhosted.org/packages/45/69/f3c47642b79485a30a59c63f6d739ed779fb4cc8323205d047d741d55220/wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2", size = 38676, upload-time = "2025-08-12T05:51:32.636Z" }, - { url = "https://files.pythonhosted.org/packages/d1/71/e7e7f5670c1eafd9e990438e69d8fb46fa91a50785332e06b560c869454f/wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c", size = 38957, upload-time = "2025-08-12T05:51:54.655Z" }, - { url = "https://files.pythonhosted.org/packages/de/17/9f8f86755c191d6779d7ddead1a53c7a8aa18bccb7cea8e7e72dfa6a8a09/wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775", size = 81975, upload-time = "2025-08-12T05:52:30.109Z" }, - { url = "https://files.pythonhosted.org/packages/f2/15/dd576273491f9f43dd09fce517f6c2ce6eb4fe21681726068db0d0467096/wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd", size = 83149, upload-time = "2025-08-12T05:52:09.316Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c4/5eb4ce0d4814521fee7aa806264bf7a114e748ad05110441cd5b8a5c744b/wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05", size = 82209, upload-time = "2025-08-12T05:52:10.331Z" }, - { url = "https://files.pythonhosted.org/packages/31/4b/819e9e0eb5c8dc86f60dfc42aa4e2c0d6c3db8732bce93cc752e604bb5f5/wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418", size = 81551, upload-time = "2025-08-12T05:52:31.137Z" }, - { url = "https://files.pythonhosted.org/packages/f8/83/ed6baf89ba3a56694700139698cf703aac9f0f9eb03dab92f57551bd5385/wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390", size = 36464, upload-time = "2025-08-12T05:53:01.204Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/ee61d36862340ad7e9d15a02529df6b948676b9a5829fd5e16640156627d/wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6", size = 38748, upload-time = "2025-08-12T05:53:00.209Z" }, - { url = "https://files.pythonhosted.org/packages/bd/c3/cefe0bd330d389c9983ced15d326f45373f4073c9f4a8c2f99b50bfea329/wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18", size = 36810, upload-time = "2025-08-12T05:52:51.906Z" }, - { url = "https://files.pythonhosted.org/packages/52/db/00e2a219213856074a213503fdac0511203dceefff26e1daa15250cc01a0/wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7", size = 53482, upload-time = "2025-08-12T05:51:45.79Z" }, - { url = "https://files.pythonhosted.org/packages/5e/30/ca3c4a5eba478408572096fe9ce36e6e915994dd26a4e9e98b4f729c06d9/wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85", size = 38674, upload-time = "2025-08-12T05:51:34.629Z" }, - { url = "https://files.pythonhosted.org/packages/31/25/3e8cc2c46b5329c5957cec959cb76a10718e1a513309c31399a4dad07eb3/wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f", size = 38959, upload-time = "2025-08-12T05:51:56.074Z" }, - { url = "https://files.pythonhosted.org/packages/5d/8f/a32a99fc03e4b37e31b57cb9cefc65050ea08147a8ce12f288616b05ef54/wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311", size = 82376, upload-time = "2025-08-12T05:52:32.134Z" }, - { url = "https://files.pythonhosted.org/packages/31/57/4930cb8d9d70d59c27ee1332a318c20291749b4fba31f113c2f8ac49a72e/wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1", size = 83604, upload-time = "2025-08-12T05:52:11.663Z" }, - { url = "https://files.pythonhosted.org/packages/a8/f3/1afd48de81d63dd66e01b263a6fbb86e1b5053b419b9b33d13e1f6d0f7d0/wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5", size = 82782, upload-time = "2025-08-12T05:52:12.626Z" }, - { url = "https://files.pythonhosted.org/packages/1e/d7/4ad5327612173b144998232f98a85bb24b60c352afb73bc48e3e0d2bdc4e/wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2", size = 82076, upload-time = "2025-08-12T05:52:33.168Z" }, - { url = "https://files.pythonhosted.org/packages/bb/59/e0adfc831674a65694f18ea6dc821f9fcb9ec82c2ce7e3d73a88ba2e8718/wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89", size = 36457, upload-time = "2025-08-12T05:53:03.936Z" }, - { url = "https://files.pythonhosted.org/packages/83/88/16b7231ba49861b6f75fc309b11012ede4d6b0a9c90969d9e0db8d991aeb/wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77", size = 38745, upload-time = "2025-08-12T05:53:02.885Z" }, - { url = "https://files.pythonhosted.org/packages/9a/1e/c4d4f3398ec073012c51d1c8d87f715f56765444e1a4b11e5180577b7e6e/wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a", size = 36806, upload-time = "2025-08-12T05:52:53.368Z" }, - { url = "https://files.pythonhosted.org/packages/9f/41/cad1aba93e752f1f9268c77270da3c469883d56e2798e7df6240dcb2287b/wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0", size = 53998, upload-time = "2025-08-12T05:51:47.138Z" }, - { url = "https://files.pythonhosted.org/packages/60/f8/096a7cc13097a1869fe44efe68dace40d2a16ecb853141394047f0780b96/wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba", size = 39020, upload-time = "2025-08-12T05:51:35.906Z" }, - { url = "https://files.pythonhosted.org/packages/33/df/bdf864b8997aab4febb96a9ae5c124f700a5abd9b5e13d2a3214ec4be705/wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd", size = 39098, upload-time = "2025-08-12T05:51:57.474Z" }, - { url = "https://files.pythonhosted.org/packages/9f/81/5d931d78d0eb732b95dc3ddaeeb71c8bb572fb01356e9133916cd729ecdd/wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828", size = 88036, upload-time = "2025-08-12T05:52:34.784Z" }, - { url = "https://files.pythonhosted.org/packages/ca/38/2e1785df03b3d72d34fc6252d91d9d12dc27a5c89caef3335a1bbb8908ca/wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9", size = 88156, upload-time = "2025-08-12T05:52:13.599Z" }, - { url = "https://files.pythonhosted.org/packages/b3/8b/48cdb60fe0603e34e05cffda0b2a4adab81fd43718e11111a4b0100fd7c1/wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396", size = 87102, upload-time = "2025-08-12T05:52:14.56Z" }, - { url = "https://files.pythonhosted.org/packages/3c/51/d81abca783b58f40a154f1b2c56db1d2d9e0d04fa2d4224e357529f57a57/wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc", size = 87732, upload-time = "2025-08-12T05:52:36.165Z" }, - { url = "https://files.pythonhosted.org/packages/9e/b1/43b286ca1392a006d5336412d41663eeef1ad57485f3e52c767376ba7e5a/wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe", size = 36705, upload-time = "2025-08-12T05:53:07.123Z" }, - { url = "https://files.pythonhosted.org/packages/28/de/49493f962bd3c586ab4b88066e967aa2e0703d6ef2c43aa28cb83bf7b507/wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c", size = 38877, upload-time = "2025-08-12T05:53:05.436Z" }, - { url = "https://files.pythonhosted.org/packages/f1/48/0f7102fe9cb1e8a5a77f80d4f0956d62d97034bbe88d33e94699f99d181d/wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6", size = 36885, upload-time = "2025-08-12T05:52:54.367Z" }, - { url = "https://files.pythonhosted.org/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", size = 54003, upload-time = "2025-08-12T05:51:48.627Z" }, - { url = "https://files.pythonhosted.org/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", size = 39025, upload-time = "2025-08-12T05:51:37.156Z" }, - { url = "https://files.pythonhosted.org/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", size = 39108, upload-time = "2025-08-12T05:51:58.425Z" }, - { url = "https://files.pythonhosted.org/packages/0c/37/6faf15cfa41bf1f3dba80cd3f5ccc6622dfccb660ab26ed79f0178c7497f/wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277", size = 88072, upload-time = "2025-08-12T05:52:37.53Z" }, - { url = "https://files.pythonhosted.org/packages/78/f2/efe19ada4a38e4e15b6dff39c3e3f3f73f5decf901f66e6f72fe79623a06/wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d", size = 88214, upload-time = "2025-08-12T05:52:15.886Z" }, - { url = "https://files.pythonhosted.org/packages/40/90/ca86701e9de1622b16e09689fc24b76f69b06bb0150990f6f4e8b0eeb576/wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa", size = 87105, upload-time = "2025-08-12T05:52:17.914Z" }, - { url = "https://files.pythonhosted.org/packages/fd/e0/d10bd257c9a3e15cbf5523025252cc14d77468e8ed644aafb2d6f54cb95d/wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050", size = 87766, upload-time = "2025-08-12T05:52:39.243Z" }, - { url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" }, - { url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" }, - { url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" }, - { url = "https://files.pythonhosted.org/packages/02/a2/cd864b2a14f20d14f4c496fab97802001560f9f41554eef6df201cd7f76c/wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39", size = 54132, upload-time = "2025-08-12T05:51:49.864Z" }, - { url = "https://files.pythonhosted.org/packages/d5/46/d011725b0c89e853dc44cceb738a307cde5d240d023d6d40a82d1b4e1182/wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235", size = 39091, upload-time = "2025-08-12T05:51:38.935Z" }, - { url = "https://files.pythonhosted.org/packages/2e/9e/3ad852d77c35aae7ddebdbc3b6d35ec8013af7d7dddad0ad911f3d891dae/wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c", size = 39172, upload-time = "2025-08-12T05:51:59.365Z" }, - { url = "https://files.pythonhosted.org/packages/c3/f7/c983d2762bcce2326c317c26a6a1e7016f7eb039c27cdf5c4e30f4160f31/wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b", size = 87163, upload-time = "2025-08-12T05:52:40.965Z" }, - { url = "https://files.pythonhosted.org/packages/e4/0f/f673f75d489c7f22d17fe0193e84b41540d962f75fce579cf6873167c29b/wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa", size = 87963, upload-time = "2025-08-12T05:52:20.326Z" }, - { url = "https://files.pythonhosted.org/packages/df/61/515ad6caca68995da2fac7a6af97faab8f78ebe3bf4f761e1b77efbc47b5/wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7", size = 86945, upload-time = "2025-08-12T05:52:21.581Z" }, - { url = "https://files.pythonhosted.org/packages/d3/bd/4e70162ce398462a467bc09e768bee112f1412e563620adc353de9055d33/wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4", size = 86857, upload-time = "2025-08-12T05:52:43.043Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b8/da8560695e9284810b8d3df8a19396a6e40e7518059584a1a394a2b35e0a/wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10", size = 37178, upload-time = "2025-08-12T05:53:12.605Z" }, - { url = "https://files.pythonhosted.org/packages/db/c8/b71eeb192c440d67a5a0449aaee2310a1a1e8eca41676046f99ed2487e9f/wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6", size = 39310, upload-time = "2025-08-12T05:53:11.106Z" }, - { url = "https://files.pythonhosted.org/packages/45/20/2cda20fd4865fa40f86f6c46ed37a2a8356a7a2fde0773269311f2af56c7/wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58", size = 37266, upload-time = "2025-08-12T05:52:56.531Z" }, - { url = "https://files.pythonhosted.org/packages/77/ed/dd5cf21aec36c80443c6f900449260b80e2a65cf963668eaef3b9accce36/wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a", size = 56544, upload-time = "2025-08-12T05:51:51.109Z" }, - { url = "https://files.pythonhosted.org/packages/8d/96/450c651cc753877ad100c7949ab4d2e2ecc4d97157e00fa8f45df682456a/wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067", size = 40283, upload-time = "2025-08-12T05:51:39.912Z" }, - { url = "https://files.pythonhosted.org/packages/d1/86/2fcad95994d9b572db57632acb6f900695a648c3e063f2cd344b3f5c5a37/wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454", size = 40366, upload-time = "2025-08-12T05:52:00.693Z" }, - { url = "https://files.pythonhosted.org/packages/64/0e/f4472f2fdde2d4617975144311f8800ef73677a159be7fe61fa50997d6c0/wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e", size = 108571, upload-time = "2025-08-12T05:52:44.521Z" }, - { url = "https://files.pythonhosted.org/packages/cc/01/9b85a99996b0a97c8a17484684f206cbb6ba73c1ce6890ac668bcf3838fb/wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f", size = 113094, upload-time = "2025-08-12T05:52:22.618Z" }, - { url = "https://files.pythonhosted.org/packages/25/02/78926c1efddcc7b3aa0bc3d6b33a822f7d898059f7cd9ace8c8318e559ef/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056", size = 110659, upload-time = "2025-08-12T05:52:24.057Z" }, - { url = "https://files.pythonhosted.org/packages/dc/ee/c414501ad518ac3e6fe184753632fe5e5ecacdcf0effc23f31c1e4f7bfcf/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804", size = 106946, upload-time = "2025-08-12T05:52:45.976Z" }, - { url = "https://files.pythonhosted.org/packages/be/44/a1bd64b723d13bb151d6cc91b986146a1952385e0392a78567e12149c7b4/wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977", size = 38717, upload-time = "2025-08-12T05:53:15.214Z" }, - { url = "https://files.pythonhosted.org/packages/79/d9/7cfd5a312760ac4dd8bf0184a6ee9e43c33e47f3dadc303032ce012b8fa3/wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116", size = 41334, upload-time = "2025-08-12T05:53:14.178Z" }, - { url = "https://files.pythonhosted.org/packages/46/78/10ad9781128ed2f99dbc474f43283b13fea8ba58723e98844367531c18e9/wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6", size = 38471, upload-time = "2025-08-12T05:52:57.784Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" }, +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/37/ae31f40bec90de2f88d9597d0b5281e23ffe85b893a47ca5d9c05c63a4f6/wrapt-2.1.1.tar.gz", hash = "sha256:5fdcb09bf6db023d88f312bd0767594b414655d58090fc1c46b3414415f67fac", size = 81329, upload-time = "2026-02-03T02:12:13.786Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/21/293b657a27accfbbbb6007ebd78af0efa2083dac83e8f523272ea09b4638/wrapt-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e927375e43fd5a985b27a8992327c22541b6dede1362fc79df337d26e23604f", size = 60554, upload-time = "2026-02-03T02:11:17.362Z" }, + { url = "https://files.pythonhosted.org/packages/25/e9/96dd77728b54a899d4ce2798d7b1296989ce687ed3c0cb917d6b3154bf5d/wrapt-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c99544b6a7d40ca22195563b6d8bc3986ee8bb82f272f31f0670fe9440c869", size = 61496, upload-time = "2026-02-03T02:12:54.732Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/4c755b45df6ef30c0dd628ecfaa0c808854be147ca438429da70a162833c/wrapt-2.1.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b2be3fa5f4efaf16ee7c77d0556abca35f5a18ad4ac06f0ef3904c3399010ce9", size = 113528, upload-time = "2026-02-03T02:12:26.405Z" }, + { url = "https://files.pythonhosted.org/packages/9f/63/23ce28f7b841217d9a6337a340fbb8d4a7fbd67a89d47f377c8550fa34aa/wrapt-2.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67c90c1ae6489a6cb1a82058902caa8006706f7b4e8ff766f943e9d2c8e608d0", size = 115536, upload-time = "2026-02-03T02:11:54.397Z" }, + { url = "https://files.pythonhosted.org/packages/23/7b/5ca8d3b12768670d16c8329e29960eedd56212770365a02a8de8bf73dc01/wrapt-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:05c0db35ccffd7480143e62df1e829d101c7b86944ae3be7e4869a7efa621f53", size = 114716, upload-time = "2026-02-03T02:12:20.771Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3a/9789ccb14a096d30bb847bf3ee137bf682cc9750c2ce155f4c5ae1962abf/wrapt-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0c2ec9f616755b2e1e0bf4d0961f59bb5c2e7a77407e7e2c38ef4f7d2fdde12c", size = 113200, upload-time = "2026-02-03T02:12:07.688Z" }, + { url = "https://files.pythonhosted.org/packages/cf/e5/4ec3526ce6ce920b267c8d35d2c2f0874d3fad2744c8b7259353f1132baa/wrapt-2.1.1-cp310-cp310-win32.whl", hash = "sha256:203ba6b3f89e410e27dbd30ff7dccaf54dcf30fda0b22aa1b82d560c7f9fe9a1", size = 57876, upload-time = "2026-02-03T02:11:42.61Z" }, + { url = "https://files.pythonhosted.org/packages/d1/4e/661c7c76ecd85375b2bc03488941a3a1078642af481db24949e2b9de01f4/wrapt-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:6f9426d9cfc2f8732922fc96198052e55c09bb9db3ddaa4323a18e055807410e", size = 60224, upload-time = "2026-02-03T02:11:19.096Z" }, + { url = "https://files.pythonhosted.org/packages/5f/b7/53c7252d371efada4cb119e72e774fa2c6b3011fc33e3e552cdf48fb9488/wrapt-2.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:69c26f51b67076b40714cff81bdd5826c0b10c077fb6b0678393a6a2f952a5fc", size = 58645, upload-time = "2026-02-03T02:12:10.396Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a8/9254e4da74b30a105935197015b18b31b7a298bf046e67d8952ef74967bd/wrapt-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c366434a7fb914c7a5de508ed735ef9c133367114e1a7cb91dfb5cd806a1549", size = 60554, upload-time = "2026-02-03T02:11:13.038Z" }, + { url = "https://files.pythonhosted.org/packages/9e/a1/378579880cc7af226354054a2c255f69615b379d8adad482bfe2f22a0dc2/wrapt-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d6a2068bd2e1e19e5a317c8c0b288267eec4e7347c36bc68a6e378a39f19ee7", size = 61491, upload-time = "2026-02-03T02:12:56.077Z" }, + { url = "https://files.pythonhosted.org/packages/dc/72/957b51c56acca35701665878ad31626182199fc4afecfe67dea072210f95/wrapt-2.1.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:891ab4713419217b2aed7dd106c9200f64e6a82226775a0d2ebd6bef2ebd1747", size = 113949, upload-time = "2026-02-03T02:11:04.516Z" }, + { url = "https://files.pythonhosted.org/packages/cd/74/36bbebb4a3d2ae9c3e6929639721f8606cd0710a82a777c371aa69e36504/wrapt-2.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8ef36a0df38d2dc9d907f6617f89e113c5892e0a35f58f45f75901af0ce7d81", size = 115989, upload-time = "2026-02-03T02:12:19.398Z" }, + { url = "https://files.pythonhosted.org/packages/ae/0d/f1177245a083c7be284bc90bddfe5aece32cdd5b858049cb69ce001a0e8d/wrapt-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76e9af3ebd86f19973143d4d592cbf3e970cf3f66ddee30b16278c26ae34b8ab", size = 115242, upload-time = "2026-02-03T02:11:08.111Z" }, + { url = "https://files.pythonhosted.org/packages/62/3e/3b7cf5da27e59df61b1eae2d07dd03ff5d6f75b5408d694873cca7a8e33c/wrapt-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ff562067485ebdeaef2fa3fe9b1876bc4e7b73762e0a01406ad81e2076edcebf", size = 113676, upload-time = "2026-02-03T02:12:41.026Z" }, + { url = "https://files.pythonhosted.org/packages/f7/65/8248d3912c705f2c66f81cb97c77436f37abcbedb16d633b5ab0d795d8cd/wrapt-2.1.1-cp311-cp311-win32.whl", hash = "sha256:9e60a30aa0909435ec4ea2a3c53e8e1b50ac9f640c0e9fe3f21fd248a22f06c5", size = 57863, upload-time = "2026-02-03T02:12:18.112Z" }, + { url = "https://files.pythonhosted.org/packages/6b/31/d29310ab335f71f00c50466153b3dc985aaf4a9fc03263e543e136859541/wrapt-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:7d79954f51fcf84e5ec4878ab4aea32610d70145c5bbc84b3370eabfb1e096c2", size = 60224, upload-time = "2026-02-03T02:12:29.289Z" }, + { url = "https://files.pythonhosted.org/packages/0c/90/a6ec319affa6e2894962a0cb9d73c67f88af1a726d15314bfb5c88b8a08d/wrapt-2.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:d3ffc6b0efe79e08fd947605fd598515aebefe45e50432dc3b5cd437df8b1ada", size = 58643, upload-time = "2026-02-03T02:12:43.022Z" }, + { url = "https://files.pythonhosted.org/packages/df/cb/4d5255d19bbd12be7f8ee2c1fb4269dddec9cef777ef17174d357468efaa/wrapt-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab8e3793b239db021a18782a5823fcdea63b9fe75d0e340957f5828ef55fcc02", size = 61143, upload-time = "2026-02-03T02:11:46.313Z" }, + { url = "https://files.pythonhosted.org/packages/6f/07/7ed02daa35542023464e3c8b7cb937fa61f6c61c0361ecf8f5fecf8ad8da/wrapt-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7c0300007836373d1c2df105b40777986accb738053a92fe09b615a7a4547e9f", size = 61740, upload-time = "2026-02-03T02:12:51.966Z" }, + { url = "https://files.pythonhosted.org/packages/c4/60/a237a4e4a36f6d966061ccc9b017627d448161b19e0a3ab80a7c7c97f859/wrapt-2.1.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2b27c070fd1132ab23957bcd4ee3ba707a91e653a9268dc1afbd39b77b2799f7", size = 121327, upload-time = "2026-02-03T02:11:06.796Z" }, + { url = "https://files.pythonhosted.org/packages/ae/fe/9139058a3daa8818fc67e6460a2340e8bbcf3aef8b15d0301338bbe181ca/wrapt-2.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b0e36d845e8b6f50949b6b65fc6cd279f47a1944582ed4ec8258cd136d89a64", size = 122903, upload-time = "2026-02-03T02:12:48.657Z" }, + { url = "https://files.pythonhosted.org/packages/91/10/b8479202b4164649675846a531763531f0a6608339558b5a0a718fc49a8d/wrapt-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4aeea04a9889370fcfb1ef828c4cc583f36a875061505cd6cd9ba24d8b43cc36", size = 121333, upload-time = "2026-02-03T02:11:32.148Z" }, + { url = "https://files.pythonhosted.org/packages/5f/75/75fc793b791d79444aca2c03ccde64e8b99eda321b003f267d570b7b0985/wrapt-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d88b46bb0dce9f74b6817bc1758ff2125e1ca9e1377d62ea35b6896142ab6825", size = 120458, upload-time = "2026-02-03T02:11:16.039Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8f/c3f30d511082ca6d947c405f9d8f6c8eaf83cfde527c439ec2c9a30eb5ea/wrapt-2.1.1-cp312-cp312-win32.whl", hash = "sha256:63decff76ca685b5c557082dfbea865f3f5f6d45766a89bff8dc61d336348833", size = 58086, upload-time = "2026-02-03T02:12:35.041Z" }, + { url = "https://files.pythonhosted.org/packages/0a/c8/37625b643eea2849f10c3b90f69c7462faa4134448d4443234adaf122ae5/wrapt-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:b828235d26c1e35aca4107039802ae4b1411be0fe0367dd5b7e4d90e562fcbcd", size = 60328, upload-time = "2026-02-03T02:12:45.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/79/56242f07572d5682ba8065a9d4d9c2218313f576e3c3471873c2a5355ffd/wrapt-2.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:75128507413a9f1bcbe2db88fd18fbdbf80f264b82fa33a6996cdeaf01c52352", size = 58722, upload-time = "2026-02-03T02:12:27.949Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ca/3cf290212855b19af9fcc41b725b5620b32f470d6aad970c2593500817eb/wrapt-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ce9646e17fa7c3e2e7a87e696c7de66512c2b4f789a8db95c613588985a2e139", size = 61150, upload-time = "2026-02-03T02:12:50.575Z" }, + { url = "https://files.pythonhosted.org/packages/9d/33/5b8f89a82a9859ce82da4870c799ad11ce15648b6e1c820fec3e23f4a19f/wrapt-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:428cfc801925454395aa468ba7ddb3ed63dc0d881df7b81626cdd433b4e2b11b", size = 61743, upload-time = "2026-02-03T02:11:55.733Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2f/60c51304fbdf47ce992d9eefa61fbd2c0e64feee60aaa439baf42ea6f40b/wrapt-2.1.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5797f65e4d58065a49088c3b32af5410751cd485e83ba89e5a45e2aa8905af98", size = 121341, upload-time = "2026-02-03T02:11:20.461Z" }, + { url = "https://files.pythonhosted.org/packages/ad/03/ce5256e66dd94e521ad5e753c78185c01b6eddbed3147be541f4d38c0cb7/wrapt-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a2db44a71202c5ae4bb5f27c6d3afbc5b23053f2e7e78aa29704541b5dad789", size = 122947, upload-time = "2026-02-03T02:11:33.596Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ae/50ca8854b81b946a11a36fcd6ead32336e6db2c14b6e4a8b092b80741178/wrapt-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8d5350c3590af09c1703dd60ec78a7370c0186e11eaafb9dda025a30eee6492d", size = 121370, upload-time = "2026-02-03T02:11:09.886Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d9/d6a7c654e0043319b4cc137a4caaf7aa16b46b51ee8df98d1060254705b7/wrapt-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d9b076411bed964e752c01b49fd224cc385f3a96f520c797d38412d70d08359", size = 120465, upload-time = "2026-02-03T02:11:37.592Z" }, + { url = "https://files.pythonhosted.org/packages/55/90/65be41e40845d951f714b5a77e84f377a3787b1e8eee6555a680da6d0db5/wrapt-2.1.1-cp313-cp313-win32.whl", hash = "sha256:0bb7207130ce6486727baa85373503bf3334cc28016f6928a0fa7e19d7ecdc06", size = 58090, upload-time = "2026-02-03T02:12:53.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/66/6a09e0294c4fc8c26028a03a15191721c9271672467cc33e6617ee0d91d2/wrapt-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:cbfee35c711046b15147b0ae7db9b976f01c9520e6636d992cd9e69e5e2b03b1", size = 60341, upload-time = "2026-02-03T02:12:36.384Z" }, + { url = "https://files.pythonhosted.org/packages/7a/f0/20ceb8b701e9a71555c87a5ddecbed76ec16742cf1e4b87bbaf26735f998/wrapt-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:7d2756061022aebbf57ba14af9c16e8044e055c22d38de7bf40d92b565ecd2b0", size = 58731, upload-time = "2026-02-03T02:12:01.328Z" }, + { url = "https://files.pythonhosted.org/packages/80/b4/fe95beb8946700b3db371f6ce25115217e7075ca063663b8cca2888ba55c/wrapt-2.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4814a3e58bc6971e46baa910ecee69699110a2bf06c201e24277c65115a20c20", size = 62969, upload-time = "2026-02-03T02:11:51.245Z" }, + { url = "https://files.pythonhosted.org/packages/b8/89/477b0bdc784e3299edf69c279697372b8bd4c31d9c6966eae405442899df/wrapt-2.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:106c5123232ab9b9f4903692e1fa0bdc231510098f04c13c3081f8ad71c3d612", size = 63606, upload-time = "2026-02-03T02:12:02.64Z" }, + { url = "https://files.pythonhosted.org/packages/ed/55/9d0c1269ab76de87715b3b905df54dd25d55bbffd0b98696893eb613469f/wrapt-2.1.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1a40b83ff2535e6e56f190aff123821eea89a24c589f7af33413b9c19eb2c738", size = 152536, upload-time = "2026-02-03T02:11:24.492Z" }, + { url = "https://files.pythonhosted.org/packages/44/18/2004766030462f79ad86efaa62000b5e39b1ff001dcce86650e1625f40ae/wrapt-2.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:789cea26e740d71cf1882e3a42bb29052bc4ada15770c90072cb47bf73fb3dbf", size = 158697, upload-time = "2026-02-03T02:12:32.214Z" }, + { url = "https://files.pythonhosted.org/packages/e1/bb/0a880fa0f35e94ee843df4ee4dd52a699c9263f36881311cfb412c09c3e5/wrapt-2.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ba49c14222d5e5c0ee394495a8655e991dc06cbca5398153aefa5ac08cd6ccd7", size = 155563, upload-time = "2026-02-03T02:11:49.737Z" }, + { url = "https://files.pythonhosted.org/packages/42/ff/cd1b7c4846c8678fac359a6eb975dc7ab5bd606030adb22acc8b4a9f53f1/wrapt-2.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ac8cda531fe55be838a17c62c806824472bb962b3afa47ecbd59b27b78496f4e", size = 150161, upload-time = "2026-02-03T02:12:33.613Z" }, + { url = "https://files.pythonhosted.org/packages/38/ec/67c90a7082f452964b4621e4890e9a490f1add23cdeb7483cc1706743291/wrapt-2.1.1-cp313-cp313t-win32.whl", hash = "sha256:b8af75fe20d381dd5bcc9db2e86a86d7fcfbf615383a7147b85da97c1182225b", size = 59783, upload-time = "2026-02-03T02:11:39.863Z" }, + { url = "https://files.pythonhosted.org/packages/ec/08/466afe4855847d8febdfa2c57c87e991fc5820afbdef01a273683dfd15a0/wrapt-2.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:45c5631c9b6c792b78be2d7352129f776dd72c605be2c3a4e9be346be8376d83", size = 63082, upload-time = "2026-02-03T02:12:09.075Z" }, + { url = "https://files.pythonhosted.org/packages/9a/62/60b629463c28b15b1eeadb3a0691e17568622b12aa5bfa7ebe9b514bfbeb/wrapt-2.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:da815b9263947ac98d088b6414ac83507809a1d385e4632d9489867228d6d81c", size = 60251, upload-time = "2026-02-03T02:11:21.794Z" }, + { url = "https://files.pythonhosted.org/packages/95/a0/1c2396e272f91efe6b16a6a8bce7ad53856c8f9ae4f34ceaa711d63ec9e1/wrapt-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9aa1765054245bb01a37f615503290d4e207e3fd59226e78341afb587e9c1236", size = 61311, upload-time = "2026-02-03T02:12:44.41Z" }, + { url = "https://files.pythonhosted.org/packages/b0/9a/d2faba7e61072a7507b5722db63562fdb22f5a24e237d460d18755627f15/wrapt-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:feff14b63a6d86c1eee33a57f77573649f2550935981625be7ff3cb7342efe05", size = 61805, upload-time = "2026-02-03T02:11:59.905Z" }, + { url = "https://files.pythonhosted.org/packages/db/56/073989deb4b5d7d6e7ea424476a4ae4bda02140f2dbeaafb14ba4864dd60/wrapt-2.1.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:81fc5f22d5fcfdbabde96bb3f5379b9f4476d05c6d524d7259dc5dfb501d3281", size = 120308, upload-time = "2026-02-03T02:12:04.46Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b6/84f37261295e38167a29eb82affaf1dc15948dc416925fe2091beee8e4ac/wrapt-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:951b228ecf66def855d22e006ab9a1fc12535111ae7db2ec576c728f8ddb39e8", size = 122688, upload-time = "2026-02-03T02:11:23.148Z" }, + { url = "https://files.pythonhosted.org/packages/ea/80/32db2eec6671f80c65b7ff175be61bc73d7f5223f6910b0c921bbc4bd11c/wrapt-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ddf582a95641b9a8c8bd643e83f34ecbbfe1b68bc3850093605e469ab680ae3", size = 121115, upload-time = "2026-02-03T02:12:39.068Z" }, + { url = "https://files.pythonhosted.org/packages/49/ef/dcd00383df0cd696614127902153bf067971a5aabcd3c9dcb2d8ef354b2a/wrapt-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fc5c500966bf48913f795f1984704e6d452ba2414207b15e1f8c339a059d5b16", size = 119484, upload-time = "2026-02-03T02:11:48.419Z" }, + { url = "https://files.pythonhosted.org/packages/76/29/0630280cdd2bd8f86f35cb6854abee1c9d6d1a28a0c6b6417cd15d378325/wrapt-2.1.1-cp314-cp314-win32.whl", hash = "sha256:4aa4baadb1f94b71151b8e44a0c044f6af37396c3b8bcd474b78b49e2130a23b", size = 58514, upload-time = "2026-02-03T02:11:58.616Z" }, + { url = "https://files.pythonhosted.org/packages/db/19/5bed84f9089ed2065f6aeda5dfc4f043743f642bc871454b261c3d7d322b/wrapt-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:860e9d3fd81816a9f4e40812f28be4439ab01f260603c749d14be3c0a1170d19", size = 60763, upload-time = "2026-02-03T02:12:24.553Z" }, + { url = "https://files.pythonhosted.org/packages/e4/cb/b967f2f9669e4249b4fe82e630d2a01bc6b9e362b9b12ed91bbe23ae8df4/wrapt-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:3c59e103017a2c1ea0ddf589cbefd63f91081d7ce9d491d69ff2512bb1157e23", size = 59051, upload-time = "2026-02-03T02:11:29.602Z" }, + { url = "https://files.pythonhosted.org/packages/eb/19/6fed62be29f97eb8a56aff236c3f960a4b4a86e8379dc7046a8005901a97/wrapt-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9fa7c7e1bee9278fc4f5dd8275bc8d25493281a8ec6c61959e37cc46acf02007", size = 63059, upload-time = "2026-02-03T02:12:06.368Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1c/b757fd0adb53d91547ed8fad76ba14a5932d83dde4c994846a2804596378/wrapt-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:39c35e12e8215628984248bd9c8897ce0a474be2a773db207eb93414219d8469", size = 63618, upload-time = "2026-02-03T02:12:23.197Z" }, + { url = "https://files.pythonhosted.org/packages/10/fe/e5ae17b1480957c7988d991b93df9f2425fc51f128cf88144d6a18d0eb12/wrapt-2.1.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:94ded4540cac9125eaa8ddf5f651a7ec0da6f5b9f248fe0347b597098f8ec14c", size = 152544, upload-time = "2026-02-03T02:11:43.915Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cc/99aed210c6b547b8a6e4cb9d1425e4466727158a6aeb833aa7997e9e08dd/wrapt-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da0af328373f97ed9bdfea24549ac1b944096a5a71b30e41c9b8b53ab3eec04a", size = 158700, upload-time = "2026-02-03T02:12:30.684Z" }, + { url = "https://files.pythonhosted.org/packages/81/0e/d442f745f4957944d5f8ad38bc3a96620bfff3562533b87e486e979f3d99/wrapt-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4ad839b55f0bf235f8e337ce060572d7a06592592f600f3a3029168e838469d3", size = 155561, upload-time = "2026-02-03T02:11:28.164Z" }, + { url = "https://files.pythonhosted.org/packages/51/ac/9891816280e0018c48f8dfd61b136af7b0dcb4a088895db2531acde5631b/wrapt-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0d89c49356e5e2a50fa86b40e0510082abcd0530f926cbd71cf25bee6b9d82d7", size = 150188, upload-time = "2026-02-03T02:11:57.053Z" }, + { url = "https://files.pythonhosted.org/packages/24/98/e2f273b6d70d41f98d0739aa9a269d0b633684a5fb17b9229709375748d4/wrapt-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:f4c7dd22cf7f36aafe772f3d88656559205c3af1b7900adfccb70edeb0d2abc4", size = 60425, upload-time = "2026-02-03T02:11:35.007Z" }, + { url = "https://files.pythonhosted.org/packages/1e/06/b500bfc38a4f82d89f34a13069e748c82c5430d365d9e6b75afb3ab74457/wrapt-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:f76bc12c583ab01e73ba0ea585465a41e48d968f6d1311b4daec4f8654e356e3", size = 63855, upload-time = "2026-02-03T02:12:15.47Z" }, + { url = "https://files.pythonhosted.org/packages/d9/cc/5f6193c32166faee1d2a613f278608e6f3b95b96589d020f0088459c46c9/wrapt-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7ea74fc0bec172f1ae5f3505b6655c541786a5cabe4bbc0d9723a56ac32eb9b9", size = 60443, upload-time = "2026-02-03T02:11:30.869Z" }, + { url = "https://files.pythonhosted.org/packages/c4/da/5a086bf4c22a41995312db104ec2ffeee2cf6accca9faaee5315c790377d/wrapt-2.1.1-py3-none-any.whl", hash = "sha256:3b0f4629eb954394a3d7c7a1c8cca25f0b07cefe6aa8545e862e9778152de5b7", size = 43886, upload-time = "2026-02-03T02:11:45.048Z" }, ] [[package]] From 8829726e2658c126f7735096eb1d52e6be5b0ada Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 18:35:14 +0100 Subject: [PATCH 06/27] align the actions in CI --- .github/workflows/python-package.yml | 38 +++----- .github/workflows/sync-dependencies.yml | 111 ++++-------------------- 2 files changed, 30 insertions(+), 119 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index e3be464..041b08a 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -3,22 +3,23 @@ name: Python package test on: push: branches: [main] + paths-ignore: + - "uv.lock" + - "conda/meta.yaml" + - "docs/**" pull_request: branches: [main] + paths-ignore: + - "uv.lock" + - "conda/meta.yaml" schedule: - cron: '0 8 * * 1,4' workflow_call: -permissions: - pull-requests: write - contents: read - jobs: test: - # ๐Ÿท๏ธ Fixed naming logic: Simple and clean subdivision name: "๐Ÿ ${{ matrix.python-version }} โ€ข ๐Ÿงฉ Split ${{ matrix.split }} of 4" runs-on: ${{ matrix.os }} - strategy: fail-fast: false matrix: @@ -26,18 +27,13 @@ jobs: os: ["ubuntu-latest"] split: [1, 2, 3, 4] - # Global Job Environment - keeps the individual steps surgical env: CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt - OPENBLAS_NUM_THREADS: 1 - OMP_NUM_THREADS: 1 - MKL_NUM_THREADS: 1 steps: - - name: โฌ‡๏ธ Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: ๐Ÿ“ฆ Download updated dependencies + - name: ๐Ÿ“ฆ Load Updated Lockfile uses: actions/download-artifact@v4 continue-on-error: true with: @@ -48,12 +44,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: ๐Ÿงน Lint Check - run: | - python -m pip install pre-commit - pre-commit run --show-diff-on-failure --all-files - - - name: ๐ŸŒ Install GIS Dependencies + - name: ๐ŸŒ GIS System Deps run: | sudo apt-add-repository -y ppa:ubuntugis/ubuntugis-unstable sudo apt-get -y update @@ -64,14 +55,12 @@ jobs: with: enable-cache: true - - name: ๐Ÿ› ๏ธ Install dependencies - env: - GDAL_CONFIG: /usr/bin/gdal-config + - name: ๐Ÿ› ๏ธ Install run: | uv sync --all-extras uv pip install pytest-split - - name: ๐Ÿงช Run Partitioned Tests + - name: ๐Ÿงช Run Tests env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -85,10 +74,9 @@ jobs: --group ${{ matrix.split }} \ --cov mapchete_eo \ --cov-report xml:coverage.xml \ - --cov-report=term-missing:skip-covered \ --junitxml=pytest-${{ matrix.python-version }}-${{ matrix.split }}.xml - - name: ๐Ÿ“Š Upload to Codecov + - name: ๐Ÿ“Š Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sync-dependencies.yml b/.github/workflows/sync-dependencies.yml index 74949d5..8753163 100644 --- a/.github/workflows/sync-dependencies.yml +++ b/.github/workflows/sync-dependencies.yml @@ -1,58 +1,35 @@ name: sync-dependencies on: - push: - branches: - - main - paths-ignore: - - "docs/**" - - "README.rst" - - "conda/meta.yaml" schedule: - cron: '0 0 * * *' - pull_request: workflow_dispatch: + push: + branches: [main] + paths: + - "pyproject.toml" # โฌ…๏ธ Only trigger when the "source" of deps changes jobs: sync-and-prepare: runs-on: ubuntu-latest outputs: - any_changed: ${{ steps.changed-files.outputs.any_changed }} sync_needed: ${{ steps.check.outputs.changed }} steps: - uses: actions/checkout@v4 with: - # Fetch more than 1 commit so the action can compare branches - fetch-depth: 0 + fetch-depth: 0 ref: ${{ github.event.pull_request.head.ref || github.ref }} - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@v45 - with: - files: | - pyproject.toml - uv.lock - - - name: Install uv + - name: โšก Setup uv uses: astral-sh/setup-uv@v5 - with: - enable-cache: true - cache-dependency-glob: "uv.lock" - - name: Sync and Upgrade + - name: ๐Ÿ› ๏ธ Upgrade & Sync run: | - uv lock || (rm uv.lock && uv lock) uv lock --upgrade - - - name: Sync Conda Recipe - run: | uvx pyproject2conda yaml -f pyproject.toml --output conda/meta.yaml --python-include infer - - name: Check for Changes + - name: ๐Ÿ“‹ Check for Changes id: check - # Only evaluate changes if we actually ran the sync steps above - if: github.event_name != 'pull_request' || steps.changed-files.outputs.any_changed == 'true' run: | if [ -n "$(git status --porcelain)" ]; then echo "changed=true" >> $GITHUB_OUTPUT @@ -60,7 +37,7 @@ jobs: echo "changed=false" >> $GITHUB_OUTPUT fi - - name: Upload artifacts for testing + - name: ๐Ÿ“ค Upload Updated Deps if: steps.check.outputs.changed == 'true' uses: actions/upload-artifact@v4 with: @@ -69,6 +46,7 @@ jobs: uv.lock conda/meta.yaml + # This job runs the full 16-matrix test suite using the new lockfile run-tests: needs: sync-and-prepare if: needs.sync-and-prepare.outputs.sync_needed == 'true' @@ -79,85 +57,30 @@ jobs: needs: [sync-and-prepare, run-tests] if: | always() && - (needs.run-tests.result == 'success' || needs.run-tests.result == 'skipped') && - needs.sync-and-prepare.result == 'success' && + needs.run-tests.result == 'success' && needs.sync-and-prepare.outputs.sync_needed == 'true' runs-on: ubuntu-latest permissions: contents: write - pull-requests: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.ref || github.ref }} - - name: Configure Git + - name: ๐Ÿ› ๏ธ Git Rebase (Clean Tree) run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" + git pull --rebase origin ${{ github.event.pull_request.head.ref || github.ref_name }} - - name: Sync Local Branch with Remote - run: | - BRANCH_NAME="${{ github.event.pull_request.head.ref || github.ref_name }}" - git pull --rebase origin $BRANCH_NAME - - - name: Download updated files + - name: ๐Ÿ“ฅ Apply Verified Artifacts uses: actions/download-artifact@v4 with: name: updated-deps - - name: Push to Existing PR - if: github.event_name == 'pull_request' + - name: ๐Ÿš€ Commit and Push run: | git add uv.lock conda/meta.yaml - if git diff --cached --quiet; then - echo "No changes detected after rebase." - else - git commit -m "chore: sync uv.lock and conda recipe (tests passed)" - git push origin HEAD:${{ github.event.pull_request.head.ref }} - fi - - - name: Create New Pull Request - if: github.event_name != 'pull_request' - uses: peter-evans/create-pull-request@v7 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "chore: update uv.lock and conda recipe" - title: "chore(deps): sync uv and conda" - body: "Automated daily sync." - branch: "automated-dependency-sync" - delete-branch: true - assignees: Scartography - reviewers: ungarj - labels: dependencies, automated-pr - - summary: - name: Final Summary - needs: [sync-and-prepare, run-tests, finalize] - if: always() - runs-on: ubuntu-latest - steps: - - name: Report Status - run: | - function get_status_msg() { - case "$1" in - success) echo "โœ… success" ;; - failure) echo "โŒ failure" ;; - skipped) echo "โญ๏ธ skipped" ;; - *) echo "๐Ÿšซ $1" ;; - esac - } - - echo "### ๐Ÿš€ Sync Workflow Summary" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Job | Result |" >> $GITHUB_STEP_SUMMARY - echo "| :--- | :--- |" >> $GITHUB_STEP_SUMMARY - echo "| **Sync and Prepare** | $(get_status_msg ${{ needs.sync-and-prepare.result }}) |" >> $GITHUB_STEP_SUMMARY - echo "| **Run Tests** | $(get_status_msg ${{ needs.run-tests.result }}) |" >> $GITHUB_STEP_SUMMARY - echo "| **Finalize (Push/PR)** | $(get_status_msg ${{ needs.finalize.result }}) |" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - if [[ "${{ needs.sync-and-prepare.result }}" == "failure" || "${{ needs.run-tests.result }}" == "failure" || "${{ needs.finalize.result }}" == "failure" ]]; then - exit 1 - fi \ No newline at end of file + git commit -m "chore: automated dependency sync (verified)" + git push origin HEAD:${{ github.event.pull_request.head.ref || github.ref_name }} \ No newline at end of file From bf6f87acdb63d9598ed5b65b560c81a12422c3b2 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 18:47:34 +0100 Subject: [PATCH 07/27] try optimize the run of tests --- .github/workflows/python-package.yml | 81 ++++++++++++---------------- 1 file changed, 35 insertions(+), 46 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 041b08a..53ee258 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -6,7 +6,7 @@ on: paths-ignore: - "uv.lock" - "conda/meta.yaml" - - "docs/**" + - "docs/**" pull_request: branches: [main] paths-ignore: @@ -18,67 +18,56 @@ on: jobs: test: - name: "๐Ÿ ${{ matrix.python-version }} โ€ข ๐Ÿงฉ Split ${{ matrix.split }} of 4" - runs-on: ${{ matrix.os }} + # ๐Ÿท๏ธ This keeps the UI clean: Only 4 jobs total + name: "๐Ÿงช Python ${{ matrix.python-version }} (Sequential Splits)" + runs-on: ubuntu-latest strategy: fail-fast: false matrix: + # uv will handle installing these specific versions inside the GDAL container python-version: ["3.10", "3.11", "3.12", "3.13"] - os: ["ubuntu-latest"] - split: [1, 2, 3, 4] - - env: - CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt + + # We use the latest stable GDAL image as our base environment + container: + image: ghcr.io/osgeo/gdal:ubuntu-full-latest steps: - - uses: actions/checkout@v4 - - - name: ๐Ÿ“ฆ Load Updated Lockfile - uses: actions/download-artifact@v4 - continue-on-error: true - with: - name: updated-deps - - - name: ๐Ÿ—๏ธ Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: ๐ŸŒ GIS System Deps - run: | - sudo apt-add-repository -y ppa:ubuntugis/ubuntugis-unstable - sudo apt-get -y update - sudo apt-get install -y gdal-bin libgdal-dev libproj-dev libgeos-dev g++ + - name: โฌ‡๏ธ Checkout + uses: actions/checkout@v4 - name: โšก Setup uv - uses: astral-sh/setup-uv@v5 - with: - enable-cache: true + run: | + apt-get update && apt-get install -y python3-pip + pip install uv + # Force uv to install the specific Python version required for this matrix leg + uv python install ${{ matrix.python-version }} - - name: ๐Ÿ› ๏ธ Install + - name: ๐Ÿ› ๏ธ Install Dependencies run: | - uv sync --all-extras - uv pip install pytest-split + uv sync --all-extras --python ${{ matrix.python-version }} + uv pip install pytest-split pytest-cov - - name: ๐Ÿงช Run Tests + - name: ๐Ÿงช Run Sequential Splits env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REQUEST_PAYER: ${{ vars.AWS_REQUEST_PAYER }} - AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} - CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} - CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} run: | - uv run pytest -v \ - --splits 4 \ - --group ${{ matrix.split }} \ - --cov mapchete_eo \ - --cov-report xml:coverage.xml \ - --junitxml=pytest-${{ matrix.python-version }}-${{ matrix.split }}.xml + # Loop through 4 splits to avoid a "Wall of Tests" in the UI + # --cov-append merges coverage data from each split as we go + for i in {1..4}; do + echo "โ–ถ๏ธ Running Split $i of 4..." + uv run pytest -v \ + --splits 4 \ + --group $i \ + --cov=mapchete_eo \ + --cov-append \ + --cov-report=xml:coverage.xml \ + --junitxml=pytest-split-$i.xml + done - - name: ๐Ÿ“Š Codecov + - name: ๐Ÿ“Š Upload to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - slug: mapchete/mapchete-eo - flags: py${{ matrix.python-version }},split${{ matrix.split }} \ No newline at end of file + file: ./coverage.xml + flags: py${{ matrix.python-version }} \ No newline at end of file From ff7b5cc818b276c90b0314d5d74cedab1f596675 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 18:51:53 +0100 Subject: [PATCH 08/27] mimic other container behaviour --- .github/workflows/python-package.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 53ee258..4795a6b 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -35,15 +35,16 @@ jobs: - name: โฌ‡๏ธ Checkout uses: actions/checkout@v4 - - name: โšก Setup uv + - name: โšก Install uv (Binary Copy) run: | - apt-get update && apt-get install -y python3-pip - pip install uv - # Force uv to install the specific Python version required for this matrix leg - uv python install ${{ matrix.python-version }} + docker create --name uv-exporter ghcr.io/astral-sh/uv:latest + docker cp uv-exporter:/uv /usr/local/bin/uv + docker cp uv-exporter:/uvx /usr/local/bin/uvx + docker rm uv-exporter - - name: ๐Ÿ› ๏ธ Install Dependencies + - name: ๐Ÿ—๏ธ Setup Env run: | + uv python install ${{ matrix.python-version }} uv sync --all-extras --python ${{ matrix.python-version }} uv pip install pytest-split pytest-cov @@ -51,6 +52,11 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REQUEST_PAYER: ${{ vars.AWS_REQUEST_PAYER }} + AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} + CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} + CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} + CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt run: | # Loop through 4 splits to avoid a "Wall of Tests" in the UI # --cov-append merges coverage data from each split as we go From 943b9b66c2600b5b31f27a447519331b154f11d0 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 18:54:08 +0100 Subject: [PATCH 09/27] try installing uv right here and now --- .github/workflows/python-package.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 4795a6b..abcdab7 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -19,7 +19,7 @@ on: jobs: test: # ๐Ÿท๏ธ This keeps the UI clean: Only 4 jobs total - name: "๐Ÿงช Python ${{ matrix.python-version }} (Sequential Splits)" + name: "๐Ÿงช Python ${{ matrix.python-version }}" runs-on: ubuntu-latest strategy: fail-fast: false @@ -35,14 +35,12 @@ jobs: - name: โฌ‡๏ธ Checkout uses: actions/checkout@v4 - - name: โšก Install uv (Binary Copy) + - name: โšก Install uv run: | - docker create --name uv-exporter ghcr.io/astral-sh/uv:latest - docker cp uv-exporter:/uv /usr/local/bin/uv - docker cp uv-exporter:/uvx /usr/local/bin/uvx - docker rm uv-exporter + apt-get update && apt-get install -y curl + curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh - - name: ๐Ÿ—๏ธ Setup Env + - name: ๐Ÿ—๏ธ Setup Python ${{ matrix.python-version }} Env run: | uv python install ${{ matrix.python-version }} uv sync --all-extras --python ${{ matrix.python-version }} From c416797145eb78e5e09c298d3a59361f3b64e8e3 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 18:57:23 +0100 Subject: [PATCH 10/27] make these tests great again --- .github/workflows/python-package.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index abcdab7..c5e12e6 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -19,7 +19,7 @@ on: jobs: test: # ๐Ÿท๏ธ This keeps the UI clean: Only 4 jobs total - name: "๐Ÿงช Python ${{ matrix.python-version }}" + name: "๐Ÿงช Test with Python ${{ matrix.python-version }}" runs-on: ubuntu-latest strategy: fail-fast: false @@ -43,8 +43,7 @@ jobs: - name: ๐Ÿ—๏ธ Setup Python ${{ matrix.python-version }} Env run: | uv python install ${{ matrix.python-version }} - uv sync --all-extras --python ${{ matrix.python-version }} - uv pip install pytest-split pytest-cov + uv sync --frozen --all-extras --python ${{ matrix.python-version }} - name: ๐Ÿงช Run Sequential Splits env: @@ -56,17 +55,17 @@ jobs: CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt run: | - # Loop through 4 splits to avoid a "Wall of Tests" in the UI - # --cov-append merges coverage data from each split as we go + set -e for i in {1..4}; do echo "โ–ถ๏ธ Running Split $i of 4..." uv run pytest -v \ --splits 4 \ - --group $i \ + --group "$i" \ + --splitting-algorithm simple_split \ --cov=mapchete_eo \ --cov-append \ --cov-report=xml:coverage.xml \ - --junitxml=pytest-split-$i.xml + --junitxml="pytest-split-$i.xml" done - name: ๐Ÿ“Š Upload to Codecov From b00a8393e579a612bb996290c8b0e293b819baab Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 18:59:30 +0100 Subject: [PATCH 11/27] try passing a sh loop instead of bash one --- .github/workflows/python-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index c5e12e6..33236d2 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -56,8 +56,8 @@ jobs: CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt run: | set -e - for i in {1..4}; do - echo "โ–ถ๏ธ Running Split $i of 4..." + for i in $(seq 1 4); do + echo "โ–ถ๏ธ Starting Split $i of 4..." uv run pytest -v \ --splits 4 \ --group "$i" \ From 95410541609eaa72932b748d3fc3e918de1c3c37 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:01:10 +0100 Subject: [PATCH 12/27] puh... --- .github/workflows/python-package.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 33236d2..1f281ce 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -61,7 +61,6 @@ jobs: uv run pytest -v \ --splits 4 \ --group "$i" \ - --splitting-algorithm simple_split \ --cov=mapchete_eo \ --cov-append \ --cov-report=xml:coverage.xml \ From 9a6316d7fdecc281480d517a807b6ea71080db3e Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:03:04 +0100 Subject: [PATCH 13/27] dev commit --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 1f281ce..c5703de 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -72,4 +72,4 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.xml - flags: py${{ matrix.python-version }} \ No newline at end of file + flags: py${{ matrix.python-version }} From 9bdcae407bf0af8c9686daa300bdef2a9cb70853 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:10:51 +0100 Subject: [PATCH 14/27] try to setup once per python, but run 4 per python --- .github/workflows/python-package.yml | 77 ++++++++++++++++------------ 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index c5703de..3cbb5c5 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -17,35 +17,53 @@ on: workflow_call: jobs: + setup: + name: "๐Ÿ—๏ธ Build Py${{ matrix.python-version }}" + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13"] + container: ghcr.io/osgeo/gdal:ubuntu-full-latest + steps: + - uses: actions/checkout@v4 + - name: โšก Install uv & Sync + run: | + curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh + uv python install ${{ matrix.python-version }} + uv sync --frozen --all-extras --python ${{ matrix.python-version }} + + - name: ๐Ÿ“ฆ Archive Environment + # We save the .venv and the uv cache so the next job is "ready to go" + run: tar -cf venv.tar .venv .python-version + + - name: ๐Ÿ“ค Upload Environment + uses: actions/upload-artifact@v4 + with: + name: venv-${{ matrix.python-version }} + path: venv.tar test: - # ๐Ÿท๏ธ This keeps the UI clean: Only 4 jobs total - name: "๐Ÿงช Test with Python ${{ matrix.python-version }}" + needs: setup + name: "๐Ÿงช py${{ matrix.python-version }} [${{ matrix.split }}/4]" runs-on: ubuntu-latest strategy: fail-fast: false matrix: - # uv will handle installing these specific versions inside the GDAL container python-version: ["3.10", "3.11", "3.12", "3.13"] - - # We use the latest stable GDAL image as our base environment - container: - image: ghcr.io/osgeo/gdal:ubuntu-full-latest - + split: [1, 2, 3, 4] + container: ghcr.io/osgeo/gdal:ubuntu-full-latest steps: - - name: โฌ‡๏ธ Checkout - uses: actions/checkout@v4 - - - name: โšก Install uv + - uses: actions/checkout@v4 + - name: ๐Ÿ“ฅ Download Environment + uses: actions/download-artifact@v4 + with: + name: venv-${{ matrix.python-version }} + + - name: ๐Ÿ”“ Unpack & Inject uv run: | - apt-get update && apt-get install -y curl + tar -xf venv.tar curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh - - name: ๐Ÿ—๏ธ Setup Python ${{ matrix.python-version }} Env - run: | - uv python install ${{ matrix.python-version }} - uv sync --frozen --all-extras --python ${{ matrix.python-version }} - - - name: ๐Ÿงช Run Sequential Splits + - name: ๐Ÿงช Run Split env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -55,21 +73,14 @@ jobs: CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt run: | - set -e - for i in $(seq 1 4); do - echo "โ–ถ๏ธ Starting Split $i of 4..." - uv run pytest -v \ - --splits 4 \ - --group "$i" \ - --cov=mapchete_eo \ - --cov-append \ - --cov-report=xml:coverage.xml \ - --junitxml="pytest-split-$i.xml" - done + uv run pytest -v \ + --splits 4 \ + --group ${{ matrix.split }} \ + --cov=mapchete_eo \ + --cov-report=xml:coverage.xml - - name: ๐Ÿ“Š Upload to Codecov + - name: ๐Ÿ“Š Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - file: ./coverage.xml - flags: py${{ matrix.python-version }} + flags: py${{ matrix.python-version }},split${{ matrix.split }} From 27513ad5d3eece15bc4e310e2d8e4a2513f34682 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:13:50 +0100 Subject: [PATCH 15/27] dev commit --- .github/workflows/python-package.yml | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 3cbb5c5..508d8a3 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -26,21 +26,28 @@ jobs: container: ghcr.io/osgeo/gdal:ubuntu-full-latest steps: - uses: actions/checkout@v4 - - name: โšก Install uv & Sync + + - name: โšก Install uv run: | + apt-get update && apt-get install -y curl curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh + + - name: ๐Ÿ—๏ธ Create Environment + run: | uv python install ${{ matrix.python-version }} uv sync --frozen --all-extras --python ${{ matrix.python-version }} - - - name: ๐Ÿ“ฆ Archive Environment - # We save the .venv and the uv cache so the next job is "ready to go" - run: tar -cf venv.tar .venv .python-version + # We include the test tools in the lock/sync + + - name: ๐Ÿ“ฆ Archive Venv + # We archive the .venv folder. Using --zstd makes it fast and small. + run: tar -cf venv-${{ matrix.python-version }}.tar .venv .python-version pyproject.toml uv.lock - - name: ๐Ÿ“ค Upload Environment + - name: ๐Ÿ“ค Upload Venv uses: actions/upload-artifact@v4 with: name: venv-${{ matrix.python-version }} - path: venv.tar + path: venv-${{ matrix.python-version }}.tar + retention-days: 1 test: needs: setup name: "๐Ÿงช py${{ matrix.python-version }} [${{ matrix.split }}/4]" @@ -78,9 +85,11 @@ jobs: --group ${{ matrix.split }} \ --cov=mapchete_eo \ --cov-report=xml:coverage.xml + --junitxml="pytest-${{ matrix.split }}.xml" - - name: ๐Ÿ“Š Codecov + - name: ๐Ÿ“Š Upload to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.xml flags: py${{ matrix.python-version }},split${{ matrix.split }} From 0de62011316db07859de286d15ef38079f01218d Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:15:54 +0100 Subject: [PATCH 16/27] dev commit --- .github/workflows/python-package.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 508d8a3..16b9c1f 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -36,11 +36,15 @@ jobs: run: | uv python install ${{ matrix.python-version }} uv sync --frozen --all-extras --python ${{ matrix.python-version }} - # We include the test tools in the lock/sync - name: ๐Ÿ“ฆ Archive Venv - # We archive the .venv folder. Using --zstd makes it fast and small. - run: tar -cf venv-${{ matrix.python-version }}.tar .venv .python-version pyproject.toml uv.lock + run: | + if [ -d ".venv" ]; then + tar -cf venv-${{ matrix.python-version }}.tar .venv pyproject.toml uv.lock + else + echo "โŒ Error: .venv directory not found!" + exit 1 + fi - name: ๐Ÿ“ค Upload Venv uses: actions/upload-artifact@v4 From 2bc93d452191f3da47f1794db1205e7d83ecc25c Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:17:20 +0100 Subject: [PATCH 17/27] dev commit --- .github/workflows/python-package.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 16b9c1f..ce30e8d 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -69,9 +69,10 @@ jobs: with: name: venv-${{ matrix.python-version }} - - name: ๐Ÿ”“ Unpack & Inject uv + - name: ๐Ÿ”“ Restore Env run: | - tar -xf venv.tar + tar -xf venv-${{ matrix.python-version }}.tar + apt-get update && apt-get install -y curl curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh - name: ๐Ÿงช Run Split From 5316b18cf042ef82b32253e07f0b12b2b5c2b8d4 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:23:48 +0100 Subject: [PATCH 18/27] dev commit --- .github/workflows/python-package.yml | 34 +++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index ce30e8d..43bb7be 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -33,6 +33,8 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh - name: ๐Ÿ—๏ธ Create Environment + env: + UV_LINK_MODE: copy run: | uv python install ${{ matrix.python-version }} uv sync --frozen --all-extras --python ${{ matrix.python-version }} @@ -84,13 +86,14 @@ jobs: CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt + UV_LINK_MODE: copy run: | uv run pytest -v \ --splits 4 \ --group ${{ matrix.split }} \ --cov=mapchete_eo \ --cov-report=xml:coverage.xml - --junitxml="pytest-${{ matrix.split }}.xml" + --junitxml="pytest-${{ matrix.python-version }}-${{ matrix.split }}.xml" - name: ๐Ÿ“Š Upload to Codecov uses: codecov/codecov-action@v5 @@ -98,3 +101,32 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.xml flags: py${{ matrix.python-version }},split${{ matrix.split }} + + - name: ๐Ÿ“ค Archive JUnit Results + if: always() + uses: actions/upload-artifact@v4 + with: + name: results-${{ matrix.python-version }}-${{ matrix.split }} + path: pytest-${{ matrix.python-version }}-${{ matrix.split }}.xml + retention-days: 1 + + summary: + name: "๐Ÿ“Š Final Summary" + needs: test + if: always() + runs-on: ubuntu-latest + steps: + - name: ๐Ÿ“ฅ Download All Results + uses: actions/download-artifact@v4 + with: + path: all-results + pattern: results-* + merge-multiple: true + + - name: ๐Ÿ“ Check Matrix Success + run: | + if [[ "${{ needs.test.result }}" != "success" ]]; then + echo "โŒ Some test splits failed." + exit 1 + fi + echo "โœ… All 16 splits passed across all Python versions!" \ No newline at end of file From 79d27c3a33678aecff8048c83b215080e2b41d60 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:28:59 +0100 Subject: [PATCH 19/27] dev commit --- .github/workflows/python-package.yml | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 43bb7be..1fabff3 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -33,27 +33,16 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh - name: ๐Ÿ—๏ธ Create Environment - env: - UV_LINK_MODE: copy run: | uv python install ${{ matrix.python-version }} uv sync --frozen --all-extras --python ${{ matrix.python-version }} - - - name: ๐Ÿ“ฆ Archive Venv - run: | - if [ -d ".venv" ]; then - tar -cf venv-${{ matrix.python-version }}.tar .venv pyproject.toml uv.lock - else - echo "โŒ Error: .venv directory not found!" - exit 1 - fi - - - name: ๐Ÿ“ค Upload Venv + - name: ๐Ÿ“ฆ Archive Workspace + run: tar -cf workspace.tar . + - name: ๐Ÿ“ค Upload venv Workspace uses: actions/upload-artifact@v4 with: - name: venv-${{ matrix.python-version }} - path: venv-${{ matrix.python-version }}.tar - retention-days: 1 + name: workspace-${{ matrix.python-version }} + path: workspace.tar test: needs: setup name: "๐Ÿงช py${{ matrix.python-version }} [${{ matrix.split }}/4]" @@ -73,7 +62,7 @@ jobs: - name: ๐Ÿ”“ Restore Env run: | - tar -xf venv-${{ matrix.python-version }}.tar + tar -xf workspace.tar apt-get update && apt-get install -y curl curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh @@ -87,12 +76,13 @@ jobs: CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt UV_LINK_MODE: copy + UV_PYTHON_PREFERENCE: only-managed run: | - uv run pytest -v \ + uv run --no-sync python -m pytest -v \ --splits 4 \ --group ${{ matrix.split }} \ --cov=mapchete_eo \ - --cov-report=xml:coverage.xml + --cov-report=xml:coverage.xml \ --junitxml="pytest-${{ matrix.python-version }}-${{ matrix.split }}.xml" - name: ๐Ÿ“Š Upload to Codecov From 112b511c930a004da6f2704cf6926e6dceb9008e Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:33:29 +0100 Subject: [PATCH 20/27] dev commit --- .github/workflows/python-package.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 1fabff3..a65802b 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -41,8 +41,10 @@ jobs: - name: ๐Ÿ“ค Upload venv Workspace uses: actions/upload-artifact@v4 with: - name: workspace-${{ matrix.python-version }} + name: venv-artifact-${{ matrix.python-version }} path: workspace.tar + retention-days: 1 + test: needs: setup name: "๐Ÿงช py${{ matrix.python-version }} [${{ matrix.split }}/4]" @@ -58,7 +60,7 @@ jobs: - name: ๐Ÿ“ฅ Download Environment uses: actions/download-artifact@v4 with: - name: venv-${{ matrix.python-version }} + name: venv-artifact-${{ matrix.python-version }} - name: ๐Ÿ”“ Restore Env run: | @@ -75,7 +77,6 @@ jobs: CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt - UV_LINK_MODE: copy UV_PYTHON_PREFERENCE: only-managed run: | uv run --no-sync python -m pytest -v \ From acffcf203537de14c23d26f4b472ff4643fb587c Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:38:36 +0100 Subject: [PATCH 21/27] dev commit --- .github/workflows/python-package.yml | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index a65802b..34d9b2b 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -32,17 +32,15 @@ jobs: apt-get update && apt-get install -y curl curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh - - name: ๐Ÿ—๏ธ Create Environment + - name: ๐Ÿ“ Export Locked Requirements run: | - uv python install ${{ matrix.python-version }} - uv sync --frozen --all-extras --python ${{ matrix.python-version }} - - name: ๐Ÿ“ฆ Archive Workspace - run: tar -cf workspace.tar . - - name: ๐Ÿ“ค Upload venv Workspace + uv export --frozen --all-extras --format requirements-txt > requirements.txt + + - name: ๐Ÿ“ค Upload Requirements uses: actions/upload-artifact@v4 with: - name: venv-artifact-${{ matrix.python-version }} - path: workspace.tar + name: frozen-reqs-${{ matrix.python-version }} + path: requirements.txt retention-days: 1 test: @@ -57,16 +55,18 @@ jobs: container: ghcr.io/osgeo/gdal:ubuntu-full-latest steps: - uses: actions/checkout@v4 - - name: ๐Ÿ“ฅ Download Environment + - name: ๐Ÿ“ฅ Download Requirements uses: actions/download-artifact@v4 with: - name: venv-artifact-${{ matrix.python-version }} + name: frozen-reqs-${{ matrix.python-version }} - - name: ๐Ÿ”“ Restore Env + - name: ๐Ÿ—๏ธ Restore Environment run: | - tar -xf workspace.tar apt-get update && apt-get install -y curl curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh + uv venv --python ${{ matrix.python-version }} + uv pip install -r requirements.txt + uv pip install -e . --no-deps - name: ๐Ÿงช Run Split env: @@ -77,7 +77,6 @@ jobs: CDSE_S3_ACCESS_KEY: ${{ secrets.CDSE_S3_ACCESS_KEY }} CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt - UV_PYTHON_PREFERENCE: only-managed run: | uv run --no-sync python -m pytest -v \ --splits 4 \ From 706d75e8b38c5b63ada6d00171225eabcf039a9f Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:40:23 +0100 Subject: [PATCH 22/27] dev commit --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 34d9b2b..1011a97 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -66,7 +66,7 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh uv venv --python ${{ matrix.python-version }} uv pip install -r requirements.txt - uv pip install -e . --no-deps + uv pip install -e .[test] --no-deps - name: ๐Ÿงช Run Split env: From 74233e143cfe209413cd585c2a62572d64159c1b Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:47:11 +0100 Subject: [PATCH 23/27] dev commit --- .github/workflows/python-package.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 1011a97..87db9c8 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -60,13 +60,16 @@ jobs: with: name: frozen-reqs-${{ matrix.python-version }} - - name: ๐Ÿ—๏ธ Restore Environment + - name: โšก Install uv run: | apt-get update && apt-get install -y curl curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh + + - name: ๐Ÿ—๏ธ Restore Native Env + run: | uv venv --python ${{ matrix.python-version }} uv pip install -r requirements.txt - uv pip install -e .[test] --no-deps + uv pip install -e ".[test]" --no-deps - name: ๐Ÿงช Run Split env: @@ -78,7 +81,7 @@ jobs: CDSE_S3_ACCESS_SECRET: ${{ secrets.CDSE_S3_ACCESS_SECRET }} CURL_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt run: | - uv run --no-sync python -m pytest -v \ + uv run pytest -v \ --splits 4 \ --group ${{ matrix.split }} \ --cov=mapchete_eo \ From 59b4238efe3862cbfa66fd65aca85d93e3710512 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:52:08 +0100 Subject: [PATCH 24/27] install git into the test runners --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 87db9c8..35cbe4f 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -62,7 +62,7 @@ jobs: - name: โšก Install uv run: | - apt-get update && apt-get install -y curl + apt-get update && apt-get install -y curl git curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh - name: ๐Ÿ—๏ธ Restore Native Env From 621f075fc95662bf9203b5c41e7140630fca6338 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 19:53:08 +0100 Subject: [PATCH 25/27] ubuntu small as image --- .github/workflows/python-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 35cbe4f..5c22c50 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13"] - container: ghcr.io/osgeo/gdal:ubuntu-full-latest + container: ghcr.io/osgeo/gdal:ubuntu-small-latest steps: - uses: actions/checkout@v4 @@ -52,7 +52,7 @@ jobs: matrix: python-version: ["3.10", "3.11", "3.12", "3.13"] split: [1, 2, 3, 4] - container: ghcr.io/osgeo/gdal:ubuntu-full-latest + container: ghcr.io/osgeo/gdal:ubuntu-small-latest steps: - uses: actions/checkout@v4 - name: ๐Ÿ“ฅ Download Requirements From 957002ca52b537b082f00bacceb46d01d6731e19 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 20:00:27 +0100 Subject: [PATCH 26/27] code cove better flags and summary a bit more content --- .github/workflows/python-package.yml | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 5c22c50..1fd3a69 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -93,7 +93,8 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.xml - flags: py${{ matrix.python-version }},split${{ matrix.split }} + flags: py${{ matrix.python-version }}-split${{ matrix.split }} + fail_ci_if_error: true - name: ๐Ÿ“ค Archive JUnit Results if: always() @@ -115,11 +116,20 @@ jobs: path: all-results pattern: results-* merge-multiple: true - - - name: ๐Ÿ“ Check Matrix Success + - name: ๐Ÿ“Š Results of the Test Suite run: | - if [[ "${{ needs.test.result }}" != "success" ]]; then - echo "โŒ Some test splits failed." + echo "### ๐Ÿงช Test Results Summary" >> $GITHUB_STEP_SUMMARY + + # Count XML files + COUNT=$(ls all-results/*.xml 2>/dev/null | wc -l || echo "0") + + if [[ "${{ needs.test.result }}" == "success" ]]; then + echo "โœ… **All tests passed!**" >> $GITHUB_STEP_SUMMARY + echo "Successfully collected and verified $COUNT test report files." >> $GITHUB_STEP_SUMMARY + exit 0 + else + echo "โŒ **Some test splits failed.**" >> $GITHUB_STEP_SUMMARY + echo "Review the 'test' matrix for specific logs. Collected $COUNT reports before failure." >> $GITHUB_STEP_SUMMARY + echo "Check the 'Artifacts' section below to download individual JUnit XML reports." >> $GITHUB_STEP_SUMMARY exit 1 - fi - echo "โœ… All 16 splits passed across all Python versions!" \ No newline at end of file + fi \ No newline at end of file From 997a0a887ddb061173199fe380bdcc947b329f70 Mon Sep 17 00:00:00 2001 From: Scartography Date: Thu, 5 Feb 2026 20:02:08 +0100 Subject: [PATCH 27/27] add gpg package into the runners for code cov --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 1fd3a69..3463358 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -62,7 +62,7 @@ jobs: - name: โšก Install uv run: | - apt-get update && apt-get install -y curl git + apt-get update && apt-get install -y curl git gpg curl -LsSf https://astral.sh/uv/install.sh | BINDIR=/usr/local/bin sh - name: ๐Ÿ—๏ธ Restore Native Env