chtypes 1.1.0__tar.gz → 2.0.0.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/PKG-INFO +6 -2
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/README.md +5 -1
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/pyproject.toml +1 -1
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/__init__.py +9 -1
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/__main__.py +20 -0
- {chtypes-1.1.0/src/chtypes/_abi1 → chtypes-2.0.0.dev0/src/chtypes/_abi2}/__init__.py +5 -3
- {chtypes-1.1.0/src/chtypes/_abi1 → chtypes-2.0.0.dev0/src/chtypes/_abi2}/_decls.py +15 -9
- {chtypes-1.1.0/src/chtypes/_abi1 → chtypes-2.0.0.dev0/src/chtypes/_abi2}/_errmap.py +3 -3
- {chtypes-1.1.0/src/chtypes/_abi1 → chtypes-2.0.0.dev0/src/chtypes/_abi2}/_loader.py +24 -7
- chtypes-2.0.0.dev0/src/chtypes/_abi2/_vocab.py +416 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_decode.py +13 -15
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/__init__.py +6 -0
- chtypes-2.0.0.dev0/src/chtypes/_ocifetch/_channel.py +325 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_ensure.py +36 -9
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_layout.py +25 -14
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_lock.py +5 -3
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/errors.py +1 -1
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/library.py +2 -2
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/registry.py +31 -4
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/results.py +1 -1
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/__init__.py +1 -1
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/conftest.py +28 -11
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/test_conformance.py +6 -6
- chtypes-2.0.0.dev0/tests/abi2/test_dev_fingerprint.py +59 -0
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/test_goldens_runner_stub.py +22 -7
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/test_loader.py +3 -3
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/test_public_library.py +9 -4
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/test_public_open.py +1 -1
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/test_public_registry.py +16 -1
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/test_public_setup_cases.py +3 -3
- chtypes-2.0.0.dev0/tests/abi2/test_reader_rules.py +243 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/api/test_decode.py +37 -13
- chtypes-2.0.0.dev0/tests/api/test_vocab.py +124 -0
- chtypes-2.0.0.dev0/tests/cli/conftest.py +26 -0
- chtypes-2.0.0.dev0/tests/cli/test_devchannel.py +126 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/cli/test_main.py +4 -2
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/conftest.py +1 -1
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/goldens_v1/test_runner.py +25 -5
- chtypes-2.0.0.dev0/tests/ocifetch/conftest.py +28 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_conformance.py +12 -0
- chtypes-2.0.0.dev0/tests/ocifetch/test_devchannel.py +268 -0
- chtypes-2.0.0.dev0/tests/ocifetch/test_seam_gate.py +57 -0
- chtypes-2.0.0.dev0/tests/test_abi_identity.py +24 -0
- chtypes-2.0.0.dev0/tests/test_devchannel_registry.py +98 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/test_fetch_options.py +9 -4
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/uv.lock +1 -1
- chtypes-1.1.0/src/chtypes/_abi1/_vocab.py +0 -254
- chtypes-1.1.0/tests/api/test_vocab.py +0 -90
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/.gitignore +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/CHANGELOG.md +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/LICENSE +0 -0
- {chtypes-1.1.0/src/chtypes/_abi1 → chtypes-2.0.0.dev0/src/chtypes/_abi2}/_errors.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ed25519.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_guard.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_input.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_constants.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_dsse.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_errors.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_faults.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_goldens.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_http.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_oci.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_referrers.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_ocifetch/_unpack.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/_setup.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/src/chtypes/py.typed +0 -0
- {chtypes-1.1.0/tests/abi1 → chtypes-2.0.0.dev0/tests/abi2}/_stub_tree.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/api/__init__.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/api/test_input.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/cli/__init__.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/goldens_v1/__init__.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/goldens_v1/data/stub-goldens.json +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/__init__.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/_bundle_support.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/_registry_support.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/_sign_support.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_cache_roots.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_cache_strict.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_dsse.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_ensure.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_goldens.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_http.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_layout.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_lock.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_oci.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/ocifetch/test_unpack.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/test_ed25519.py +0 -0
- {chtypes-1.1.0 → chtypes-2.0.0.dev0}/tests/test_examples_tour.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: chtypes
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0.dev0
|
|
4
4
|
Summary: Python binding for the chtypes artifacts: ClickHouse's own type system, per version, behind the frozen chs_* C ABI
|
|
5
5
|
Project-URL: Homepage, https://github.com/wave-rf/chtypes
|
|
6
6
|
Project-URL: Repository, https://github.com/wave-rf/chtypes
|
|
@@ -19,6 +19,8 @@ Description-Content-Type: text/markdown
|
|
|
19
19
|
|
|
20
20
|
# chtypes — Python SDK
|
|
21
21
|
|
|
22
|
+
> **2.0.0-dev: UNSTABLE, staging only, not for production.** This is the ABI v2 development binding (public issue #511). It speaks ABI v2's unstable description, pins its dev fingerprint and refuses a library with any other ("update your dev SDK"). It fetches only from the staging dev channel (`https://registry-staging.wavehouse.dev/chtypes/v2-dev`) and trusts only the staging key; `CHTYPES_ARTIFACTS_URL`, `CHTYPES_TRUSTED_KEYS` and `CHTYPES_ALLOW_UNSIGNED`, and the `bases`, `trusted_keys` and `allow_unsigned` fetch options, are ignored, each with one warning; `--lock`, `--frozen` and `--update`, and the `frozen`, `lock_path`, `lock_write` and `update` options, are refused, because a dev build is replaceable and a superseded one expires after 14 days. Its cache is `${XDG_CACHE_HOME:-~/.cache}/chtypes/v2-dev`, or `<CHTYPES_CACHE>/v2-dev` under an explicit cache, which no 1.x SDK reads. Every vocabulary keeps a value it does not list as its `unknown(n)` member (`Outcome("x")`, whose `known` is `False`) instead of failing the document. The rules are r1 to r6 of [`docs/reference/abi-v2.md`](../docs/reference/abi-v2.md). For production, use the 1.x package: `pip install "chtypes<2"`.
|
|
23
|
+
|
|
22
24
|
**If this row were inserted into this table on this ClickHouse version, what would happen?** chtypes answers with ClickHouse's own code: the real C++ type machinery, vendored per release into a native library behind the frozen `chs_*` C ABI and reached here through stdlib `ctypes`. Nothing semantic is reimplemented, so _"what does ClickHouse do with `256` into a `UInt8`?"_ is answered by ClickHouse rather than by a model of it. One peer binding among `{go, python, ts, rust}` — no language is privileged, and all four give one answer.
|
|
23
25
|
|
|
24
26
|
Pure ctypes: no compiler, no build step. The only dependency is a zstd decompressor for the artifact layer, which is the standard library's own from Python 3.14 and the `backports.zstd` package before that.
|
|
@@ -28,9 +30,11 @@ Pure ctypes: no compiler, no build step. The only dependency is a zstd decompres
|
|
|
28
30
|
Two things: this package, and at least one **artifact** — the per-version native library it `dlopen`s at runtime. The registry fetches the artifact on first use when autofetch is on (`Registry(autofetch=True)` or `CHTYPES_AUTOFETCH=1`), after verifying its signature and every byte against the signed statement; with autofetch off it answers only from what is already installed.
|
|
29
31
|
|
|
30
32
|
```sh
|
|
31
|
-
uv add chtypes # or: pip install chtypes
|
|
33
|
+
uv add "chtypes>=2.0.0.dev0" # or: pip install "chtypes>=2.0.0.dev0"
|
|
32
34
|
```
|
|
33
35
|
|
|
36
|
+
`uv add chtypes` and `pip install chtypes` never select a pre-release on their own: the specifier names a dev version, which is what allows one.
|
|
37
|
+
|
|
34
38
|
## Quickstart
|
|
35
39
|
|
|
36
40
|
```python
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# chtypes — Python SDK
|
|
2
2
|
|
|
3
|
+
> **2.0.0-dev: UNSTABLE, staging only, not for production.** This is the ABI v2 development binding (public issue #511). It speaks ABI v2's unstable description, pins its dev fingerprint and refuses a library with any other ("update your dev SDK"). It fetches only from the staging dev channel (`https://registry-staging.wavehouse.dev/chtypes/v2-dev`) and trusts only the staging key; `CHTYPES_ARTIFACTS_URL`, `CHTYPES_TRUSTED_KEYS` and `CHTYPES_ALLOW_UNSIGNED`, and the `bases`, `trusted_keys` and `allow_unsigned` fetch options, are ignored, each with one warning; `--lock`, `--frozen` and `--update`, and the `frozen`, `lock_path`, `lock_write` and `update` options, are refused, because a dev build is replaceable and a superseded one expires after 14 days. Its cache is `${XDG_CACHE_HOME:-~/.cache}/chtypes/v2-dev`, or `<CHTYPES_CACHE>/v2-dev` under an explicit cache, which no 1.x SDK reads. Every vocabulary keeps a value it does not list as its `unknown(n)` member (`Outcome("x")`, whose `known` is `False`) instead of failing the document. The rules are r1 to r6 of [`docs/reference/abi-v2.md`](../docs/reference/abi-v2.md). For production, use the 1.x package: `pip install "chtypes<2"`.
|
|
4
|
+
|
|
3
5
|
**If this row were inserted into this table on this ClickHouse version, what would happen?** chtypes answers with ClickHouse's own code: the real C++ type machinery, vendored per release into a native library behind the frozen `chs_*` C ABI and reached here through stdlib `ctypes`. Nothing semantic is reimplemented, so _"what does ClickHouse do with `256` into a `UInt8`?"_ is answered by ClickHouse rather than by a model of it. One peer binding among `{go, python, ts, rust}` — no language is privileged, and all four give one answer.
|
|
4
6
|
|
|
5
7
|
Pure ctypes: no compiler, no build step. The only dependency is a zstd decompressor for the artifact layer, which is the standard library's own from Python 3.14 and the `backports.zstd` package before that.
|
|
@@ -9,9 +11,11 @@ Pure ctypes: no compiler, no build step. The only dependency is a zstd decompres
|
|
|
9
11
|
Two things: this package, and at least one **artifact** — the per-version native library it `dlopen`s at runtime. The registry fetches the artifact on first use when autofetch is on (`Registry(autofetch=True)` or `CHTYPES_AUTOFETCH=1`), after verifying its signature and every byte against the signed statement; with autofetch off it answers only from what is already installed.
|
|
10
12
|
|
|
11
13
|
```sh
|
|
12
|
-
uv add chtypes # or: pip install chtypes
|
|
14
|
+
uv add "chtypes>=2.0.0.dev0" # or: pip install "chtypes>=2.0.0.dev0"
|
|
13
15
|
```
|
|
14
16
|
|
|
17
|
+
`uv add chtypes` and `pip install chtypes` never select a pre-release on their own: the specifier names a dev version, which is what allows one.
|
|
18
|
+
|
|
15
19
|
## Quickstart
|
|
16
20
|
|
|
17
21
|
```python
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
"""chtypes: ClickHouse's own type system, per version, from Python.
|
|
2
2
|
|
|
3
|
+
2.0.0-dev: UNSTABLE, staging only, not for production. This pre-release speaks
|
|
4
|
+
the ABI v2 dev description (spec/abi-v2/docs.md): it fetches only from the
|
|
5
|
+
staging dev channel and trusts only its key, refuses locks and frozen fetches,
|
|
6
|
+
caches under its own `v2-dev` root, and refuses a library built from any other
|
|
7
|
+
dev fingerprint (rules r5 and r6).
|
|
8
|
+
|
|
3
9
|
One question, exactly: *if this row were inserted into this ClickHouse table on
|
|
4
10
|
this ClickHouse version, what would happen?* The answer comes from ClickHouse's
|
|
5
11
|
real C++ machinery, vendored per release into a shared library behind the frozen
|
|
@@ -40,9 +46,10 @@ from __future__ import annotations
|
|
|
40
46
|
from importlib.metadata import PackageNotFoundError as _PackageNotFound
|
|
41
47
|
from importlib.metadata import version as _package_version
|
|
42
48
|
|
|
43
|
-
from .
|
|
49
|
+
from ._abi2._vocab import (
|
|
44
50
|
EXPORT_NONE,
|
|
45
51
|
DefaultKind,
|
|
52
|
+
DiscoverQueryParam,
|
|
46
53
|
DocFlags,
|
|
47
54
|
FilterOutcome,
|
|
48
55
|
Format,
|
|
@@ -140,6 +147,7 @@ __all__ = [
|
|
|
140
147
|
"Column",
|
|
141
148
|
"Computed",
|
|
142
149
|
"DefaultKind",
|
|
150
|
+
"DiscoverQueryParam",
|
|
143
151
|
"DiscoveredColumn",
|
|
144
152
|
"Discovery",
|
|
145
153
|
"EngineCell",
|
|
@@ -12,6 +12,15 @@ A spelling is `26.8`, `26.8.15` or `26.8.15.10`. Exit statuses come from the
|
|
|
12
12
|
as `ERROR_EXIT_CODES`); a usage error exits 2 and success exits 0. Progress and
|
|
13
13
|
diagnostics go to stderr; `fetch` prints one installed library path per line on
|
|
14
14
|
stdout.
|
|
15
|
+
|
|
16
|
+
2.0.0-dev: UNSTABLE, staging only, not for production. This CLI speaks the ABI
|
|
17
|
+
v2 dev channel (spec/abi-v2/docs.md, rules r5 and r6): it fetches only from
|
|
18
|
+
https://registry-staging.wavehouse.dev/chtypes/v2-dev and trusts only the
|
|
19
|
+
staging key; CHTYPES_ARTIFACTS_URL, CHTYPES_TRUSTED_KEYS and
|
|
20
|
+
CHTYPES_ALLOW_UNSIGNED are ignored, each with one warning; --lock, --frozen and
|
|
21
|
+
--update are refused before any network call; its default cache is
|
|
22
|
+
${XDG_CACHE_HOME:-~/.cache}/chtypes/v2-dev, and an explicit one (--cache,
|
|
23
|
+
CHTYPES_CACHE) is used through its v2-dev subroot.
|
|
15
24
|
"""
|
|
16
25
|
|
|
17
26
|
from __future__ import annotations
|
|
@@ -24,6 +33,7 @@ from collections.abc import Sequence
|
|
|
24
33
|
|
|
25
34
|
from . import __version__ as chtypes_version
|
|
26
35
|
from . import _ocifetch as fetch_layer
|
|
36
|
+
from ._ocifetch import _channel
|
|
27
37
|
from ._ocifetch import _constants as C
|
|
28
38
|
from ._ocifetch._ensure import _translate_transport_error, detect_host_platform, missing_notes
|
|
29
39
|
from ._ocifetch._errors import ArtifactCorruptError, ArtifactMissingError, FetchError
|
|
@@ -67,6 +77,12 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
67
77
|
parser = _Parser(
|
|
68
78
|
prog="chtypes",
|
|
69
79
|
description="Fetch, verify and locate chtypes artifacts (docs/guides/fetch-v1.md).",
|
|
80
|
+
epilog=(
|
|
81
|
+
"2.0.0-dev: UNSTABLE, staging only, not for production. Fetches only from the staging "
|
|
82
|
+
"dev channel and trusts only its key; --lock, --frozen and --update are refused; "
|
|
83
|
+
"CHTYPES_ARTIFACTS_URL, CHTYPES_TRUSTED_KEYS and CHTYPES_ALLOW_UNSIGNED are ignored "
|
|
84
|
+
"(spec/abi-v2/docs.md, rule r6)."
|
|
85
|
+
),
|
|
70
86
|
)
|
|
71
87
|
parser.add_argument("--version", action="version", version=f"chtypes {_display_version()}")
|
|
72
88
|
sub = parser.add_subparsers(dest="command", metavar="<command>")
|
|
@@ -196,6 +212,10 @@ def _published_tags(options) -> list[str]:
|
|
|
196
212
|
|
|
197
213
|
|
|
198
214
|
def _cmd_fetch(args: argparse.Namespace) -> int:
|
|
215
|
+
# A dev SDK pins nothing: the refusal comes before anything else, the
|
|
216
|
+
# network above all (rule r6).
|
|
217
|
+
if (args.lock or args.frozen or args.update) and not _channel.active().pinnable:
|
|
218
|
+
raise ValueError(f"chtypes: {_channel.PINNING_REFUSED}")
|
|
199
219
|
if args.all and args.spellings:
|
|
200
220
|
raise ValueError("chtypes: give spellings or --all, not both")
|
|
201
221
|
if not args.all and not args.spellings and not args.update:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""The ABI
|
|
1
|
+
"""The ABI v2 loader and generated declaration layer (plan
|
|
2
2
|
PLAN-sdk-v1-ffi-2026-10-01.md), private to this binding. Not part of `chtypes`'s
|
|
3
3
|
public surface: the public API (`chtypes.library`, `chtypes.registry`) is built
|
|
4
4
|
over it, and re-exports the vocabularies and errors it defines.
|
|
@@ -7,11 +7,13 @@ over it, and re-exports the vocabularies and errors it defines.
|
|
|
7
7
|
handle classes, the typed call wrappers on `Api`, and the test-only
|
|
8
8
|
`invoke_by_name()` dispatcher.
|
|
9
9
|
- `_vocab`: GENERATED -- `Format`, `Status`, `Outcome`, `Verdict`, `Reason`,
|
|
10
|
-
`Source`, `DefaultKind`, `DocFlags` and the facts the
|
|
10
|
+
`Source`, `DefaultKind`, `DiscoverQueryParam`, `DocFlags` and the facts the
|
|
11
|
+
description attaches, each vocabulary with its unknown(n) member (rule r3).
|
|
11
12
|
- `_errors`: the public `chtypes.errors` classes, re-exported under the names
|
|
12
13
|
`_errmap` uses.
|
|
13
14
|
- `_errmap`: GENERATED -- the sdk.json status/reason -> `_errors` class maps.
|
|
14
|
-
- `_loader`: hand-written -- `open()`/`open_unverified()`, the loader steps
|
|
15
|
+
- `_loader`: hand-written -- `open()`/`open_unverified()`, the loader steps,
|
|
16
|
+
and rule r6's exact refusal of another fingerprint.
|
|
15
17
|
"""
|
|
16
18
|
|
|
17
19
|
from __future__ import annotations
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# GENERATED by scripts/abi-v1/gen.py from spec/abi-
|
|
2
|
-
"""The Python binding's generated ABI
|
|
1
|
+
# GENERATED by scripts/abi-v1/gen.py --major 2 from spec/abi-v2/abi.json (CHS_ABI_FINGERPRINT sha256:8ec0c6941f000aa07bfb9fbfef20205d3ee0a588833856bd12270ba42912bfb3) — DO NOT EDIT # noqa: E501
|
|
2
|
+
"""The Python binding's generated ABI v2 layer: ctypes signatures, the handle
|
|
3
3
|
classes, the two-phase resolve functions and invoke_by_name(), the test-only
|
|
4
|
-
dispatcher the conformance suite drives from tests/fixtures/abi-
|
|
4
|
+
dispatcher the conformance suite drives from tests/fixtures/abi-v2/cases.json.
|
|
5
5
|
See scripts/abi-v1/emit/python.py's module docstring for the design this file
|
|
6
|
-
implements and why. This is the ONLY python/src/chtypes/
|
|
6
|
+
implements and why. This is the ONLY python/src/chtypes/_abi2 file that reads
|
|
7
7
|
a chs_* attribute (scripts/abi-v1/check-no-hand-decls.py exempts it by its
|
|
8
8
|
banner, above); every other file in this package calls the non-chs_-prefixed
|
|
9
9
|
names this module exposes instead.
|
|
@@ -18,8 +18,14 @@ from dataclasses import dataclass, field
|
|
|
18
18
|
|
|
19
19
|
from . import _errmap
|
|
20
20
|
|
|
21
|
-
CHS_ABI_VERSION =
|
|
22
|
-
CHS_ABI_FINGERPRINT = "sha256:
|
|
21
|
+
CHS_ABI_VERSION = 2
|
|
22
|
+
CHS_ABI_FINGERPRINT = "sha256:8ec0c6941f000aa07bfb9fbfef20205d3ee0a588833856bd12270ba42912bfb3"
|
|
23
|
+
|
|
24
|
+
# The description's stability: "unstable" while this generation is being
|
|
25
|
+
# designed, so CHS_ABI_FINGERPRINT moves with every change, and "locked" after
|
|
26
|
+
# (spec/abi-v2/docs.md, rule r6). A dev SDK refuses any other fingerprint with
|
|
27
|
+
# the dev message (_loader.py).
|
|
28
|
+
CHS_ABI_STABILITY = "unstable"
|
|
23
29
|
|
|
24
30
|
# sdk.json's loader.cross_check: (build_info field, predicate field, how to
|
|
25
31
|
# compare), read by _loader.py's step 5 without it ever touching sdk.json
|
|
@@ -516,7 +522,7 @@ class Api:
|
|
|
516
522
|
cls = _errmap.call_error_class(name)
|
|
517
523
|
message = info.message if info else b""
|
|
518
524
|
if name not in STATUS_BY_NAME:
|
|
519
|
-
message = f"status {status} is outside the closed
|
|
525
|
+
message = f"call status unknown({status}) is outside the closed set".encode() + (
|
|
520
526
|
b": " + message if message else b""
|
|
521
527
|
)
|
|
522
528
|
raise cls(
|
|
@@ -927,7 +933,7 @@ def resolve_all(lib: ctypes.CDLL) -> Api:
|
|
|
927
933
|
time step 6 runs, step 3 has already proven it exists). The first symbol
|
|
928
934
|
ctypes cannot dlsym raises MissingSymbol(name); _loader.py's step 6 turns
|
|
929
935
|
that into "missing_symbol:<name>", matching every missing-<sym> stub
|
|
930
|
-
variant (tests/fixtures/abi-
|
|
936
|
+
variant (tests/fixtures/abi-v2/cases.json), chs_build_info and
|
|
931
937
|
chs_clickhouse_version included -- loader step 4 needs chs_build_info
|
|
932
938
|
already resolved, which is exactly why this sweep must run before it."""
|
|
933
939
|
raw: dict = {}
|
|
@@ -1028,7 +1034,7 @@ def invoke_by_name(api: Api, name: str, args: Iterable[object] = ()) -> InvokeRe
|
|
|
1028
1034
|
(or None, where nullable) for handle. Output parameters are never
|
|
1029
1035
|
supplied by the caller: this dispatcher allocates them, and decodes them
|
|
1030
1036
|
into the returned InvokeResult. Test-only: every chs_ spelling below is
|
|
1031
|
-
why this file, alone in python/src/chtypes/
|
|
1037
|
+
why this file, alone in python/src/chtypes/_abi2, carries the generated
|
|
1032
1038
|
banner check-no-hand-decls.py exempts."""
|
|
1033
1039
|
spec = FUNCTIONS[name]
|
|
1034
1040
|
fn = api._raw[name]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# GENERATED by scripts/abi-v1/gen.py from spec/abi-
|
|
2
|
-
"""spec/abi-
|
|
1
|
+
# GENERATED by scripts/abi-v1/gen.py --major 2 from spec/abi-v2/abi.json (CHS_ABI_FINGERPRINT sha256:8ec0c6941f000aa07bfb9fbfef20205d3ee0a588833856bd12270ba42912bfb3) — DO NOT EDIT # noqa: E501
|
|
2
|
+
"""spec/abi-v2/sdk.json's error-mapping tables, as references to the
|
|
3
3
|
public classes (python/src/chtypes/errors.py, re-exported by
|
|
4
|
-
python/src/chtypes/
|
|
4
|
+
python/src/chtypes/_abi2/_errors.py). Only the MAPPING is generated: the
|
|
5
5
|
classes themselves are stable across a regeneration (plan section 3.4), so a
|
|
6
6
|
status renumbering or a new loader refusal reason changes this file, never
|
|
7
7
|
the classes.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""The ABI
|
|
1
|
+
"""The ABI v2 loader, Python half (plan PLAN-sdk-v1-ffi section 3.2/3.3).
|
|
2
2
|
|
|
3
3
|
Decoupled from the fetch PRs on purpose (plan section 3.1): `open()` takes a
|
|
4
4
|
small, loader-owned `predicate` mapping rather than the fetch module's
|
|
@@ -8,13 +8,13 @@ wired up; `predicate` is passed through exactly as that seam promises.
|
|
|
8
8
|
|
|
9
9
|
Every `chs_*` spelling in this module is forbidden by
|
|
10
10
|
scripts/abi-v1/check-no-hand-decls.py (it is not a generated file), so this
|
|
11
|
-
calls ONLY python/src/chtypes/
|
|
11
|
+
calls ONLY python/src/chtypes/_abi2/_decls.py's non-`chs_`-prefixed surface:
|
|
12
12
|
`resolve_abi_version()`, `resolve_all()`, and the `Api` object they return.
|
|
13
13
|
|
|
14
14
|
Steps 1-6 run in the order plan section 3.2 gives (with step 6's full
|
|
15
15
|
resolve-all sweep run right after step 3, BEFORE step 4's
|
|
16
16
|
`chs_build_info()` call -- step 4 needs that symbol already resolved, and
|
|
17
|
-
`tests/fixtures/abi-
|
|
17
|
+
`tests/fixtures/abi-v2/cases.json`'s `missing-chs_build_info` and
|
|
18
18
|
`missing-chs_clickhouse_version` stub variants both expect the step 6
|
|
19
19
|
`missing_symbol:<name>` reason, not a step 4 one, which is only possible if
|
|
20
20
|
the full symbol sweep happens before chs_build_info is ever called). Step 7
|
|
@@ -54,6 +54,25 @@ def _refuse(reason: str, path: str, want: object = None, got: object = None) ->
|
|
|
54
54
|
raise cls(reason=reason, path=path, want=want, got=got)
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
def dev_fingerprint_message(sdk: str, library: str) -> str:
|
|
58
|
+
"""Rule r6's exact refusal of a library whose fingerprint is not this dev
|
|
59
|
+
SDK's (spec/abi-v2/docs.md): `sdk` is the SDK's own fingerprint and
|
|
60
|
+
`library` the library's, both full "sha256:" spellings."""
|
|
61
|
+
return f"this SDK speaks dev fingerprint {sdk}; the library has {library} — update your dev SDK"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _refuse_fingerprint(path: str, got: object) -> None:
|
|
65
|
+
"""Loader step 4's fingerprint refusal: CHTYPES_ARTIFACT_INCOMPATIBLE.
|
|
66
|
+
While this generation's description is unstable (a 2.0.0-dev SDK), its
|
|
67
|
+
message is exactly rule r6's; after the lock it is the ordinary refusal."""
|
|
68
|
+
want = _decls.CHS_ABI_FINGERPRINT
|
|
69
|
+
cls = _errmap.loader_error_class("fingerprint")
|
|
70
|
+
if _decls.CHS_ABI_STABILITY == "unstable":
|
|
71
|
+
message = dev_fingerprint_message(want, str(got))
|
|
72
|
+
raise cls(message, reason="fingerprint", path=path, want=want, got=got)
|
|
73
|
+
raise cls(reason="fingerprint", path=path, want=want, got=got)
|
|
74
|
+
|
|
75
|
+
|
|
57
76
|
def _glibc_version() -> tuple[int, int] | None:
|
|
58
77
|
"""Resolve `gnu_get_libc_version` dynamically from the running process:
|
|
59
78
|
`ctypes.CDLL(None)` is the process image's own global symbols (glibc's,
|
|
@@ -193,9 +212,7 @@ def _open(
|
|
|
193
212
|
info = _parse_build_info(raw, path)
|
|
194
213
|
|
|
195
214
|
if info["abi_fingerprint"] != _decls.CHS_ABI_FINGERPRINT:
|
|
196
|
-
|
|
197
|
-
"fingerprint", path, want=_decls.CHS_ABI_FINGERPRINT, got=info.get("abi_fingerprint")
|
|
198
|
-
)
|
|
215
|
+
_refuse_fingerprint(path, info.get("abi_fingerprint"))
|
|
199
216
|
|
|
200
217
|
if not skip_step5:
|
|
201
218
|
_cross_check(info, predicate, path)
|
|
@@ -231,7 +248,7 @@ def open(
|
|
|
231
248
|
timezone: bytes = b"",
|
|
232
249
|
defaults: bytes = b"",
|
|
233
250
|
) -> LoadResult:
|
|
234
|
-
"""Load and verify
|
|
251
|
+
"""Load and verify an ABI v2 artifact at `path` against its (already verified
|
|
235
252
|
elsewhere) signed `predicate`, then set the image zone (`timezone`, empty
|
|
236
253
|
= UTC) and the default settings (`defaults`, a JSON object of string
|
|
237
254
|
values, empty for none): step 7. Raises an artifact error naming the exact
|