eu-licence-validator 0.1.18__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.
- eu_licence_validator-0.1.18/PKG-INFO +39 -0
- eu_licence_validator-0.1.18/README.md +18 -0
- eu_licence_validator-0.1.18/eu_licence_validator/__init__.py +73 -0
- eu_licence_validator-0.1.18/eu_licence_validator/wasm/core.wasm +0 -0
- eu_licence_validator-0.1.18/eu_licence_validator.egg-info/PKG-INFO +39 -0
- eu_licence_validator-0.1.18/eu_licence_validator.egg-info/SOURCES.txt +10 -0
- eu_licence_validator-0.1.18/eu_licence_validator.egg-info/dependency_links.txt +1 -0
- eu_licence_validator-0.1.18/eu_licence_validator.egg-info/requires.txt +4 -0
- eu_licence_validator-0.1.18/eu_licence_validator.egg-info/top_level.txt +1 -0
- eu_licence_validator-0.1.18/pyproject.toml +36 -0
- eu_licence_validator-0.1.18/setup.cfg +4 -0
- eu_licence_validator-0.1.18/tests/test_validator.py +37 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eu-licence-validator
|
|
3
|
+
Version: 0.1.18
|
|
4
|
+
Summary: European licence plate validation. Single Go core compiled to WebAssembly, bundled for Python.
|
|
5
|
+
Author: TrueJacobG
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/TrueJacobG/eu-licence-validator
|
|
8
|
+
Project-URL: Repository, https://github.com/TrueJacobG/eu-licence-validator
|
|
9
|
+
Project-URL: Issues, https://github.com/TrueJacobG/eu-licence-validator/issues
|
|
10
|
+
Keywords: licence,license,plate,european,eu,validation,wasm
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: wasmtime>=14.0.0
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
21
|
+
|
|
22
|
+
# eu-licence-validator (Python)
|
|
23
|
+
|
|
24
|
+
European licence plate validation for Python, powered by a shared Go/WebAssembly core.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install eu-licence-validator
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from eu_licence_validator import is_valid
|
|
36
|
+
|
|
37
|
+
is_valid("WPI 1234X", "PL") # True
|
|
38
|
+
is_valid("AA-123-SS", "FR") # False
|
|
39
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# eu-licence-validator (Python)
|
|
2
|
+
|
|
3
|
+
European licence plate validation for Python, powered by a shared Go/WebAssembly core.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install eu-licence-validator
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from eu_licence_validator import is_valid
|
|
15
|
+
|
|
16
|
+
is_valid("WPI 1234X", "PL") # True
|
|
17
|
+
is_valid("AA-123-SS", "FR") # False
|
|
18
|
+
```
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""European licence plate validation (Python binding).
|
|
2
|
+
|
|
3
|
+
Loads the shared Go-compiled WebAssembly core once and exposes
|
|
4
|
+
``is_valid(plate, country_code) -> bool``.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
from functools import lru_cache
|
|
11
|
+
from typing import Tuple
|
|
12
|
+
|
|
13
|
+
from wasmtime import Engine, ExitTrap, Instance, Linker, Module, Store, WasiConfig
|
|
14
|
+
|
|
15
|
+
__all__ = ["is_valid", "isValid"]
|
|
16
|
+
|
|
17
|
+
_WASM_PATH = os.path.join(os.path.dirname(__file__), "wasm", "core.wasm")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@lru_cache(maxsize=1)
|
|
21
|
+
def _instance() -> Tuple[Store, Instance]:
|
|
22
|
+
engine = Engine()
|
|
23
|
+
store = Store(engine)
|
|
24
|
+
store.set_wasi(WasiConfig())
|
|
25
|
+
module = Module.from_file(engine, _WASM_PATH)
|
|
26
|
+
linker = Linker(engine)
|
|
27
|
+
linker.define_wasi()
|
|
28
|
+
instance = linker.instantiate(store, module)
|
|
29
|
+
exports = instance.exports(store)
|
|
30
|
+
|
|
31
|
+
start = exports["_start"]
|
|
32
|
+
if start is not None:
|
|
33
|
+
try:
|
|
34
|
+
start(store)
|
|
35
|
+
except (ExitTrap, SystemExit, RuntimeError):
|
|
36
|
+
pass
|
|
37
|
+
return store, instance
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _write(store: Store, instance: Instance, data: bytes) -> Tuple[int, int]:
|
|
41
|
+
exports = instance.exports(store)
|
|
42
|
+
alloc = exports["alloc"]
|
|
43
|
+
ptr = alloc(store, len(data))
|
|
44
|
+
if ptr == 0 and len(data) > 0:
|
|
45
|
+
raise MemoryError("wasm alloc returned 0")
|
|
46
|
+
mem = exports["memory"]
|
|
47
|
+
raw = mem.data_ptr(store)
|
|
48
|
+
for i, b in enumerate(data):
|
|
49
|
+
raw[ptr + i] = b
|
|
50
|
+
return ptr, len(data)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def is_valid(plate: str, country_code: str) -> bool:
|
|
54
|
+
"""Return True if ``plate`` is a valid licence plate for ``country_code``."""
|
|
55
|
+
store, instance = _instance()
|
|
56
|
+
exports = instance.exports(store)
|
|
57
|
+
|
|
58
|
+
plate_bytes = plate.encode("utf-8")
|
|
59
|
+
country_bytes = country_code.encode("utf-8")
|
|
60
|
+
|
|
61
|
+
p_ptr, p_len = _write(store, instance, plate_bytes)
|
|
62
|
+
c_ptr, c_len = _write(store, instance, country_bytes)
|
|
63
|
+
|
|
64
|
+
validate = exports["validate"]
|
|
65
|
+
result = validate(store, p_ptr, p_len, c_ptr, c_len)
|
|
66
|
+
|
|
67
|
+
dealloc = exports["dealloc"]
|
|
68
|
+
dealloc(store, p_ptr)
|
|
69
|
+
dealloc(store, c_ptr)
|
|
70
|
+
return result == 1
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
isValid = is_valid
|
|
Binary file
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eu-licence-validator
|
|
3
|
+
Version: 0.1.18
|
|
4
|
+
Summary: European licence plate validation. Single Go core compiled to WebAssembly, bundled for Python.
|
|
5
|
+
Author: TrueJacobG
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/TrueJacobG/eu-licence-validator
|
|
8
|
+
Project-URL: Repository, https://github.com/TrueJacobG/eu-licence-validator
|
|
9
|
+
Project-URL: Issues, https://github.com/TrueJacobG/eu-licence-validator/issues
|
|
10
|
+
Keywords: licence,license,plate,european,eu,validation,wasm
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: wasmtime>=14.0.0
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
21
|
+
|
|
22
|
+
# eu-licence-validator (Python)
|
|
23
|
+
|
|
24
|
+
European licence plate validation for Python, powered by a shared Go/WebAssembly core.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install eu-licence-validator
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from eu_licence_validator import is_valid
|
|
36
|
+
|
|
37
|
+
is_valid("WPI 1234X", "PL") # True
|
|
38
|
+
is_valid("AA-123-SS", "FR") # False
|
|
39
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
eu_licence_validator/__init__.py
|
|
4
|
+
eu_licence_validator.egg-info/PKG-INFO
|
|
5
|
+
eu_licence_validator.egg-info/SOURCES.txt
|
|
6
|
+
eu_licence_validator.egg-info/dependency_links.txt
|
|
7
|
+
eu_licence_validator.egg-info/requires.txt
|
|
8
|
+
eu_licence_validator.egg-info/top_level.txt
|
|
9
|
+
eu_licence_validator/wasm/core.wasm
|
|
10
|
+
tests/test_validator.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
eu_licence_validator
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "eu-licence-validator"
|
|
7
|
+
version = "0.1.18"
|
|
8
|
+
description = "European licence plate validation. Single Go core compiled to WebAssembly, bundled for Python."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
authors = [{ name = "TrueJacobG" }]
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
|
+
dependencies = ["wasmtime>=14.0.0"]
|
|
14
|
+
keywords = ["licence", "license", "plate", "european", "eu", "validation", "wasm"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Topic :: Software Development :: Libraries",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.optional-dependencies]
|
|
24
|
+
dev = ["pytest>=7.0.0"]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/TrueJacobG/eu-licence-validator"
|
|
28
|
+
Repository = "https://github.com/TrueJacobG/eu-licence-validator"
|
|
29
|
+
Issues = "https://github.com/TrueJacobG/eu-licence-validator/issues"
|
|
30
|
+
|
|
31
|
+
[tool.setuptools]
|
|
32
|
+
packages = ["eu_licence_validator"]
|
|
33
|
+
include-package-data = true
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.package-data]
|
|
36
|
+
eu_licence_validator = ["wasm/core.wasm"]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from eu_licence_validator import is_valid
|
|
8
|
+
|
|
9
|
+
_CASES_PATH = Path(__file__).resolve().parents[3] / "test_cases.json"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture(scope="module")
|
|
13
|
+
def cases():
|
|
14
|
+
with open(_CASES_PATH) as f:
|
|
15
|
+
data = json.load(f)
|
|
16
|
+
assert data, "test_cases.json is empty"
|
|
17
|
+
return data
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.mark.parametrize("case", [{}]) # replaced dynamically below
|
|
21
|
+
def test_cases_placeholder(case):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _ids(cases):
|
|
26
|
+
return [f"{c['country']}:{c['plate']}" for c in cases]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_all_cases(cases):
|
|
30
|
+
failures = []
|
|
31
|
+
for c in cases:
|
|
32
|
+
got = is_valid(c["plate"], c["country"])
|
|
33
|
+
if got != c["expected"]:
|
|
34
|
+
failures.append(
|
|
35
|
+
f"is_valid({c['plate']!r}, {c['country']!r}) = {got}, want {c['expected']}"
|
|
36
|
+
)
|
|
37
|
+
assert not failures, "\n".join(failures)
|