Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,51 @@ jobs:
name: coverage-report
path: coverage.xml

# run unit tests against older pandas versions, since the test job installs only the newest pandas in the supported range
test-pandas-versions:
needs: [pre-commit]
timeout-minutes: 60

strategy:
fail-fast: false
matrix:
include:
# pandas < 2.2.2 is not compatible with numpy 2, so those entries pin numpy 1.26.4 (the last 1.x release)
# pandas 1.5 is the lower bound in setup.cfg and installs only on Python 3.11
- python: '3.11'
pandas: 'pandas==1.5.3'
numpy: 'numpy==1.26.4'
# pandas 2.1 is the first version with DataFrame.map and the first to support Python 3.12
- python: '3.12'
pandas: 'pandas==2.1.4'
numpy: 'numpy==1.26.4'
# pandas 2.2.3 is the first version to support Python 3.13
- python: '3.13'
pandas: 'pandas==2.2.3'
numpy: 'numpy==2.5.4'

runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}

- name: Install py-dependencies
shell: bash
run: |
python -m pip install --upgrade pip

pip install -e ".[boto3,pandas,pysftp,tests,curator]" "${{ matrix.pandas }}" "${{ matrix.numpy }}"

- name: run-unit-tests
shell: bash
run: |
python -c "import numpy, pandas; print(f'pandas {pandas.__version__}, numpy {numpy.__version__}')"
pytest -sv tests/unit

sonarcloud:
needs: [test]
if: ${{ always() && !cancelled()}}
Expand Down Expand Up @@ -350,7 +395,7 @@ jobs:

# on a GitHub release, build the pip package and upload it as a GitHub release asset
package:
needs: [test, pre-commit]
needs: [test, test-pandas-versions, pre-commit]

runs-on: ubuntu-22.04

Expand Down
8 changes: 8 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Synapse Python Client — official Python SDK and CLI for Synapse (synapse.org),
- Python 3.11–3.14 (`setup.cfg`: `python_requires = >=3.11, <3.15`)
- HTTP: httpx (async), requests (sync/legacy)
- Models: stdlib dataclasses (NOT Pydantic)
- pandas (optional): `pandas>=1.5,<4.0` (`setup.cfg`, 4 places)
- Tests: pytest 9.0.3, pytest-asyncio, pytest-socket, pytest-xdist
- Docs: MkDocs with Material theme, mkdocstrings
- Linting: ruff, black (line-length 88), isort (profile=black), bandit
Expand Down Expand Up @@ -107,6 +108,12 @@ pandas, boto3, pysftp, and other optional extras must never be imported at the t

For type annotations referencing pandas types, use `DATA_FRAME_TYPE` and `SERIES_TYPE` from `core/typing_utils.py` rather than `pd.DataFrame` or `pd.Series`. These aliases resolve correctly at type-check time without requiring pandas at runtime.

### pandas version compatibility
Code must work on every pandas version from 1.5 to 3.x. Use one code path that works on all supported versions. Use a feature check only when no such code path exists. Known pandas 3 traps:
- Text columns have the `str` dtype, not `object`. Use `pd.api.types.is_string_dtype()` instead of comparing to `object`.
- `DataFrame.applymap` is replaced by `DataFrame.map`, but `DataFrame.map` is not in pandas < 2.1. Use `df.apply(lambda col: col.map(func))` instead.
- `iterrows()` gives a `str`-dtype row when all values in the row are strings or missing, and `None` becomes `NaN`. Check each value, not only the column dtype.

## Constraints

- Do not use Pydantic for models — the codebase uses stdlib dataclasses with custom serialization. Mixing would break the `@async_to_sync` decorator and `fill_from_dict()` pattern.
Expand All @@ -126,6 +133,7 @@ For type annotations referencing pandas types, use `DATA_FRAME_TYPE` and `SERIES
- Integration fixtures create per-worker Synapse projects; use `schedule_for_cleanup()` for teardown
- Auth env vars: `SYNAPSE_AUTH_TOKEN` (bearer token), `SYNAPSE_PROFILE` (config file profile, default: `"default"`), `SYNAPSE_TOKEN_AWS_SSM_PARAMETER_NAME` (AWS SSM path)
- CI runs integration tests only on Python 3.11 and 3.14 (oldest + newest) to limit Synapse server load
- CI job `test-pandas-versions` (`.github/workflows/build.yml`) runs the unit tests on older pandas versions: 1.5.3 on Python 3.11, 2.1.4 on Python 3.12, 2.2.3 on Python 3.13 (ubuntu only). The `package` job needs it. pandas < 2.2.2 requires `numpy<2`, so each matrix entry pins its own numpy version (1.26.4, 1.26.4, 2.5.4).

## Maintenance

Expand Down
Loading
Loading