joseph-bergin opened a new pull request, #72119:
URL: https://github.com/apache/airflow/pull/72119
Migrates the exasol provider to pyexasol 2.x and removes the
`pyexasol>=0.26.0,<2` cap added in #68933.
### What the cap was hiding
pyexasol 2.x ships type information, so mypy now checks these calls. Against
pyexasol 2.3.2 the hook reports 6 errors:
- `ExaConnection.execute` / `export_to_pandas` are typed `query_params: dict
| None`, but the hook forwarded `Iterable | Mapping[str, Any] | None` (lines
148, 191, 208, 337).
- `execute` is typed `query: str`, but `get_records` / `get_first` forwarded
the `str | list[str]` that `DbApiHook` accepts (lines 191, 208).
`get_conn` also reused one local for both the Airflow `Connection` and the
`ExaConnection` returned by `pyexasol.connect`; that one only surfaces with
Airflow's own sources on `mypy_path`, and is fixed here too.
### Changes
- `get_conn` uses separate locals (`airflow_conn` and the returned
connection).
- `_to_query_params` passes `None` through, copies any mapping into a
`dict`, and rejects sequences.
- `_to_single_statement` unwraps the `str` and rejects a list.
- Cap removed from `providers/exasol/pyproject.toml`.
### On the two rejected paths
Both were already broken against a real Exasol, so only the error message
changes:
- `ExaStatement._format_query` does `self.connection.format.format(query,
**query_params)`. A tuple or list there raises `TypeError: argument after **
must be a mapping, not tuple`, so positional parameters have never reached the
driver intact.
- `ExaConnection.execute` runs exactly one statement, so a `list[str]` was
never executable in `get_records` / `get_first`. `run()` is the method that
splits and loops, and the new message points there.
`test_run_with_parameters` passed `("param1", "param2")` and passed only
because the connection is a `MagicMock`. It now uses a mapping, with new
coverage for mapping normalization and for both rejections.
If you would rather keep those paths permissive and satisfy mypy with `cast`
instead, I am happy to switch — I went with explicit errors because the status
quo is a confusing failure deep inside the driver.
### Verification
Against pyexasol 2.3.2, Python 3.11:
- `mypy providers/exasol/src/` — 6 errors before, 0 after
- `pytest providers/exasol/tests/unit/exasol/` — 58 passed (previously 53
passed with 1 failing after the migration)
- `ruff check` and `ruff format --check` at the pinned 0.16.3 — clean
closes: #69123
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes (please specify the tool below)
Generated-by: Claude Code (Opus 5) following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]