Skip to content

Commit 375f23a

Browse files
authored
deps: relax dependency constraints (#36)
This commit relaxes our dependency constraints by removing the lockfiles and replacing them by broad ranges for our supported dependency versions. To test that the SDK works with each version, the test matrix was adapted to run each test for each `(python_version,resolution_strategy)` tuple, where `resolution_strategy` is how UV will choose each dependency. - By using `resolution_strategy=lowest`, we will test the lowest version of our dependencies. - By using `resolution_strategy=lowest-direct`, we will test the lowest version of our direct dependencies, and the highest version of transitive dependencies. - By using `resolution_strategy=highest`, we will test the highest version of all dependencies. Due to some transitive dependencies not working in certain Python versions, a new `constraints/` directory was created, which contains `.txt` files that specify our dependency ranges for transitive dependencies. These constraints files are not shipped with the library and are used only for testing. Users are expected to define their transitive constraints themselves depending on the Python version.
1 parent 5e52e1c commit 375f23a

File tree

24 files changed

+127
-300
lines changed

24 files changed

+127
-300
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
kind: Dependencies
2+
body: Relaxed dependency constraints
3+
time: 2024-08-09T17:00:09.507206+02:00

.github/workflows/code-quality.yaml

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ jobs:
1919
- name: fetch server schema
2020
run: "hatch run dev:fetch-schema"
2121

22+
- name: show env info
23+
run: "hatch run test:uv pip freeze"
24+
2225
- name: unit tests
2326
run: "hatch run test:unit"
2427

2528
- name: integration tests
26-
run: "hatch run test.py3.12:integration"
29+
run: "hatch run test:integration"
2730
env:
2831
SL_HOST: ${{ secrets.TEST_HOST }}
2932
SL_ENV_ID: ${{ secrets.TEST_ENV_ID }}

CONTRIBUTING.md

+19-3
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ Hatch will manage your environments for you. Check out the list of available env
2828

2929
For most use cases, you probably want to use the `dev` environment by running `hatch shell dev`.
3030

31+
If you're having problems with your environment, check out the [troubleshooting](#troubleshooting) section.
32+
3133

3234
### Upgrading dependencies
3335

34-
We use locked `requirements.txt` files for dependency management. If you want to upgrade, remove or add a dependency, change the `deps/*.in` files and run `hatch run lock`. Don't edit `.txt` files manually, since those are autogenerated by [uv](https://github.com/astral-sh/uv/).
36+
If you want to upgrade, remove or add a dependency, change the `pyproject.toml` file. Make sure to include a reasonable min/max version range to facilitate installation by end users. Also make sure the entire test matrix passes.
3537

3638

3739
### Making code changes
@@ -43,9 +45,9 @@ We use [changie](https://changie.dev/) to manage our [`CHANGELOG.md`](./CHANGELO
4345

4446
### Running tests
4547

46-
Run tests by using `hatch run test:all`. This will run all our tests in all supported Python versions. Make sure they pass before you submit a PR.
48+
Run tests by using `hatch run test:all`. This will run all our tests in all supported Python versions and with a variety of dependency versions. Make sure they pass before you submit a PR.
4749

48-
If you want to run unit test separately, run `hatch run test:unit`. For integration tests, run `hatch run test.py3.12:integration` to avoid running slow tests in all python versions.
50+
If you want to run unit test separately, run `hatch run test:unit`. For integration tests, run `hatch run test.py3.12-highest:integration` to avoid running slow tests in all python versions.
4951

5052
The unit test suite requires a `tests/server_schema.gql` file to exist, since it checks that all GraphQL queries from the SDK will work against the server. That file must contain the schema of the GraphQL API, and you can obtain it by running our introspection script with `hatch run dev:fetch-schema`.
5153

@@ -63,3 +65,17 @@ We don't require every commit to be perfect, but your pull-request as a whole mu
6365

6466
If you think you've found a security vulnerability (i.e something that could leak customer data, compromise API keys, gain access to unauthorized resources), **do not open an issue in GitHub**. In that case, contact us directly at `[email protected]`, and wait until the vulnerability has been patched before publicly disclosing it.
6567

68+
69+
## Troubleshooting
70+
71+
Here's a non-exhaustive list of problems that might occur during development.
72+
73+
### `clang: error: the clang compiler does not support 'faltivec', please use -maltivec and include altivec.h explicitly`
74+
75+
For compatibility issues, we support older versions of libraries such as PyArrow. However, those older versions might not compile properly in MacOS with the error above. This issue might arise especially when running tests in the environment with older versions.
76+
77+
To solve it, you need to install [OpenBLAS](https://www.openblas.net/) and tell the compiler where it is:
78+
```
79+
brew install openblas
80+
export OPENBLAS=$(brew --prefix openblas)
81+
```

constraints/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Dependency constraints and overrides
2+
3+
All files in this directory specify transitive dependency constraints for usage in our test environments. The files in this directory are _not_ shipped with the package, and users should specify those constraints themselves, according to what works in their own system. Learn more about pip constraints [here](https://pip.pypa.io/en/stable/user_guide/#constraints-files).
4+
5+
This is useful for specifying different minimum versions of a package for Python 3.12 and 3.9, since older versions might not support the newest Python and vice-versa.
6+
7+
For direct dependencies, we solve this by using the `python_version` [environment marker](https://peps.python.org/pep-0508/#environment-markers) in our dependencies.
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
cython>=3.0.11
2+
setuptools>=72.1.0
3+
wheel>=0.43.0

constraints/constraints/py312.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
numpy>=1.26.0
2+
requests>=2.32.0
3+
urllib3>=1.26.8
4+
yarl>=1.9.3
5+
frozenlist>=1.4.0
6+
aiohttp>=3.9.0

constraints/overrides/py312.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pyarrow>=0.14.0

constraints/py310.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
numpy>=1.21.3,<2.0.0
2+
requests>=2.27.0
3+
urllib3>=1.26.0

constraints/py311.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
numpy>=1.24.0,<2.0.0
2+
requests>=2.28.0
3+
urllib3>=1.26.8
4+
yarl>=1.8.2
5+
frozenlist>=1.3.1
6+
aiohttp>=3.8.2

constraints/py312.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
numpy>=1.26.0,<2.0.0
2+
requests>=2.32.0
3+
urllib3>=1.26.8
4+
yarl>=1.9.3
5+
frozenlist>=1.4.0
6+
aiohttp>=3.9.0

constraints/py39.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
numpy>=1.21.0,<2.0.0

dbtsl/models/base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from dataclasses import field as dc_field
44
from functools import cache
55
from types import MappingProxyType
6-
from typing import List, Set, Type, Union
6+
from typing import Any, List, Set, Type, Union
77
from typing import get_args as get_type_args
88
from typing import get_origin as get_type_origin
99

@@ -62,11 +62,11 @@ def gql_model_name(cls) -> str:
6262
# If we do that, we need to modify this method to memoize what fragments were already created
6363
# so that we exit the recursion gracefully
6464
@staticmethod
65-
def _get_fragments_for_field(type: Type, field_name: str) -> Union[str, List[GraphQLFragment]]:
65+
def _get_fragments_for_field(type: Union[Type[Any], str], field_name: str) -> Union[str, List[GraphQLFragment]]:
6666
if inspect.isclass(type) and issubclass(type, GraphQLFragmentMixin):
6767
return type.gql_fragments()
6868

69-
if get_type_origin(type) == list:
69+
if get_type_origin(type) is list:
7070
inner_type = get_type_args(type)[0]
7171
return GraphQLFragmentMixin._get_fragments_for_field(inner_type, field_name)
7272

deps/async.in

-1
This file was deleted.

deps/async.txt

-34
This file was deleted.

deps/common.in

-4
This file was deleted.

deps/common.txt

-19
This file was deleted.

deps/dev.in

-7
This file was deleted.

deps/dev.txt

-77
This file was deleted.

deps/sync.in

-1
This file was deleted.

deps/sync.txt

-33
This file was deleted.

deps/test.in

-7
This file was deleted.

deps/test.txt

-69
This file was deleted.

0 commit comments

Comments
 (0)