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
12 changes: 0 additions & 12 deletions .coveragerc

This file was deleted.

18 changes: 7 additions & 11 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,15 @@ jobs:

# Bootstrap environment.
source bootstrap.sh

# Run linter.
uv run ruff check .

# Run type testing
uv run mypy


# Report about the test matrix slot.
echo "Invoking tests with CrateDB ${CRATEDB_VERSION}"
uv run coverage run -m pytest

# Set the stage for uploading the coverage report.
uv run coverage xml

# Run linter.
poe lint

# Run tests.
poe test

# https://github.com/codecov/codecov-action
- name: Upload coverage results to Codecov
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ coverage.xml
.installed.cfg
.tox/
*.DS_Store
*.lock
*.pyc
bin/*
!bin/test
Expand Down
9 changes: 2 additions & 7 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@ Changes for crate

Unreleased
==========
- Modernize project to latest practices:
* Use `pyproject.toml` instead of `setup.py`.
* Use hatchling instead of buildout to build project.
* Use pytest instead of unittests and zope runner (decreasing dependencies).
* Make `uv` the recommended tool for local development.
* Simplify versioning when creating a new release.
* Increase the number of tests and overall coverage.
- Modernize project definition to latest Python best practices. Thanks, @surister.
- Exceptions: Exceptions from the BLOB API now include their full names.

2025/01/30 2.0.0
================
Expand Down
4 changes: 2 additions & 2 deletions docs/by-example/http.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Trying to get a non-existing blob throws an exception:
>>> http_client.blob_get('myfiles', '041f06fd774092478d450774f5ba30c5da78acc8')
Traceback (most recent call last):
...
crate.client.exceptions.DigestNotFoundException: myfiles/041f06fd774092478d450774f5ba30c5da78acc8
crate.client.exceptions.DigestNotFoundException: DigestNotFoundException('myfiles/041f06fd774092478d450774f5ba30c5da78acc8')
Copy link
Member Author

@amotl amotl Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: That adjusts for an anomaly because new code now includes the class name into the serialized string representation. I've also reflected it within a changelog item now.


Creating a new blob - this method returns ``True`` if the blob was newly created:

Expand Down Expand Up @@ -173,7 +173,7 @@ Uploading a blob to a table with disabled blob support throws an exception:
... 'locations', '040f06fd774092478d450774f5ba30c5da78acc8', f)
Traceback (most recent call last):
...
crate.client.exceptions.BlobLocationNotFoundException: locations/040f06fd774092478d450774f5ba30c5da78acc8
crate.client.exceptions.BlobLocationNotFoundException: BlobLocationNotFoundException('locations/040f06fd774092478d450774f5ba30c5da78acc8')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dito.


>>> http_client.close()
>>> f.close()
Expand Down
50 changes: 47 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,46 @@ classifiers = [
]
dependencies = [
"orjson>=3.11.3",
"urllib3>=2.5.0",
"urllib3",
"verlib2>=0.3.1",
]

[dependency-groups]
dev = [
"certifi>=2025.10.5",
"coverage<8",
"mypy<1.19",
"poethepoet<1",
"pytest<9",
"pytest-cov<8",
"pytz>=2025.2",
"ruff<0.15",
"setuptools>=80.9.0",
"stopit<1.2",
"urllib3<2.4",
Copy link
Member Author

@amotl amotl Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: This can be removed after tackling #708.

Suggested change
"urllib3<2.4",

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

]


[tool.coverage.run]
branch = false
omit = [
"tests/*",
]
parallel = true
source = [ "src" ]

[tool.coverage.report]
fail_under = 0
show_missing = true
exclude_lines = [
"# pragma: no cover",
"raise NotImplemented",
]
omit = [
"*/.buildout/eggs/*",
"buildout-cache/eggs/*",
"eggs/*",
"parts/*",
"src/crate/client/_pep440.py",
]


Expand All @@ -68,6 +93,20 @@ namespace_packages = true
non_interactive = true


[tool.pytest.ini_options]
addopts = "-rA --verbosity=3"
minversion = "2.0"
log_level = "DEBUG"
log_cli_level = "DEBUG"
testpaths = [
"src",
"tests",
]
xfail_strict = true
markers = [
]


[tool.ruff]
line-length = 80

Expand Down Expand Up @@ -161,5 +200,10 @@ lint = [
]

test = [
{ cmd = "bin/test" },
{ cmd = "coverage erase" },
{ cmd = "coverage run -m pytest" },
{ cmd = "coverage run bin/test" },
{ cmd = "coverage combine" },
{ cmd = "coverage xml" },
{ cmd = "coverage report" },
]
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
setuptools<80.3
urllib3<2.4
zc.buildout==5.1.1
zope.interface==8.1.1
zope.testrunner>=5,<8
2 changes: 1 addition & 1 deletion src/crate/client/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def __init__(self, table, digest):
self.digest = digest

def __str__(self):
return f"{self.__class__.__qualname__}('{self.table}/{self.digest})'"
return f"{self.__class__.__qualname__}('{self.table}/{self.digest}')"
Copy link
Member Author

@amotl amotl Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: That just fixes a little formatting typo discovered when re-enabling doctests.



class DigestNotFoundException(BlobException):
Expand Down
2 changes: 1 addition & 1 deletion tests/client/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ def test_error_with_error_trace():

def test_blob_exception():
err = BlobException(table="sometable", digest="somedigest")
assert str(err) == "BlobException('sometable/somedigest)'"
assert str(err) == "BlobException('sometable/somedigest')"
25 changes: 0 additions & 25 deletions tests/client/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,17 @@
from .layer import (
HttpsTestServerLayer,
ensure_cratedb_layer,
makeSuite,
setUpCrateLayerBaseline,
setUpWithHttps,
tearDownDropEntitiesBaseline,
)
from .test_connection import ConnectionTest
from .test_cursor import CursorTest
from .test_http import (
HttpClientTest,
KeepAliveClientTest,
ParamsTest,
RequestsCaBundleTest,
RetryOnTimeoutServerTest,
TestCrateJsonEncoder,
TestDefaultSchemaHeader,
TestUsernameSentAsHeader,
ThreadSafeHttpClientTest,
)


def test_suite():
suite = unittest.TestSuite()
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS

# Unit tests.
suite.addTest(makeSuite(CursorTest))
suite.addTest(makeSuite(HttpClientTest))
suite.addTest(makeSuite(KeepAliveClientTest))
suite.addTest(makeSuite(ThreadSafeHttpClientTest))
suite.addTest(makeSuite(ParamsTest))
suite.addTest(makeSuite(ConnectionTest))
suite.addTest(makeSuite(RetryOnTimeoutServerTest))
suite.addTest(makeSuite(RequestsCaBundleTest))
suite.addTest(makeSuite(TestUsernameSentAsHeader))
suite.addTest(makeSuite(TestCrateJsonEncoder))
suite.addTest(makeSuite(TestDefaultSchemaHeader))
suite.addTest(doctest.DocTestSuite("crate.client.connection"))
suite.addTest(doctest.DocTestSuite("crate.client.http"))

Expand Down
Loading