Skip to content

Commit 86f2718

Browse files
author
Christopher Doris
committed
feat: add input validation to PkgSpec
1 parent 5c6fbdf commit 86f2718

File tree

2 files changed

+109
-8
lines changed

2 files changed

+109
-8
lines changed

src/juliapkg/deps.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,53 @@ def save_meta(meta):
5050
class PkgSpec:
5151
def __init__(
5252
self,
53-
name,
54-
uuid,
55-
dev=False,
56-
version=None,
57-
path=None,
58-
subdir=None,
59-
url=None,
60-
rev=None,
53+
name: str,
54+
uuid: str,
55+
dev: bool = False,
56+
version: str | Version | None = None,
57+
path: str | None = None,
58+
subdir: str | None = None,
59+
url: str | None = None,
60+
rev: str | None = None,
6161
):
62+
# Validate name (non-empty string)
63+
if not isinstance(name, str) or not name.strip():
64+
raise ValueError("name must be a non-empty string")
6265
self.name = name
66+
67+
# Validate UUID (non-empty string, could add more specific UUID validation)
68+
if not isinstance(uuid, str) or not uuid.strip():
69+
raise ValueError("uuid must be a non-empty string")
6370
self.uuid = uuid
71+
72+
# Validate dev (boolean)
73+
if not isinstance(dev, bool):
74+
raise TypeError("dev must be a boolean")
6475
self.dev = dev
76+
77+
# Validate version (string, Version, or None)
78+
if version is not None and not isinstance(version, (str, Version)):
79+
raise TypeError("version must be a string, Version, or None")
6580
self.version = version
81+
82+
# Validate path (string or None)
83+
if path is not None and not isinstance(path, str):
84+
raise TypeError("path must be a string or None")
6685
self.path = path
86+
87+
# Validate subdir (string or None)
88+
if subdir is not None and not isinstance(subdir, str):
89+
raise TypeError("subdir must be a string or None")
6790
self.subdir = subdir
91+
92+
# Validate url (string or None)
93+
if url is not None and not isinstance(url, str):
94+
raise TypeError("url must be a string or None")
6895
self.url = url
96+
97+
# Validate rev (string or None)
98+
if rev is not None and not isinstance(rev, str):
99+
raise TypeError("rev must be a string or None")
69100
self.rev = rev
70101

71102
def jlstr(self):

test/test_internals.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import pytest
2+
13
import juliapkg
4+
from juliapkg.deps import PkgSpec
25

36

47
def test_openssl_compat():
@@ -8,3 +11,70 @@ def test_openssl_compat():
811
assert juliapkg.deps.openssl_compat((3, 1, 0)) == "3 - 3.1"
912
assert juliapkg.deps.openssl_compat((3, 1, 2)) == "3 - 3.1"
1013
assert isinstance(juliapkg.deps.openssl_compat(), str)
14+
15+
16+
def test_pkgspec_validation():
17+
# Test valid construction
18+
spec = PkgSpec(name="Example", uuid="123e4567-e89b-12d3-a456-426614174000")
19+
assert spec.name == "Example"
20+
assert spec.uuid == "123e4567-e89b-12d3-a456-426614174000"
21+
assert spec.dev is False
22+
assert spec.version is None
23+
assert spec.path is None
24+
assert spec.subdir is None
25+
assert spec.url is None
26+
assert spec.rev is None
27+
28+
# Test with all parameters
29+
spec = PkgSpec(
30+
name="Example",
31+
uuid="123e4567-e89b-12d3-a456-426614174000",
32+
dev=True,
33+
version="1.0.0",
34+
path="/path/to/pkg",
35+
subdir="subdir",
36+
url="https://example.com/pkg.git",
37+
rev="main",
38+
)
39+
assert spec.dev is True
40+
assert spec.version == "1.0.0"
41+
assert spec.path == "/path/to/pkg"
42+
assert spec.subdir == "subdir"
43+
assert spec.url == "https://example.com/pkg.git"
44+
assert spec.rev == "main"
45+
46+
# Test invalid name
47+
with pytest.raises(ValueError, match="name must be a non-empty string"):
48+
PkgSpec(name="", uuid="0000")
49+
with pytest.raises(ValueError, match="name must be a non-empty string"):
50+
PkgSpec(name=123, uuid="0000")
51+
52+
# Test invalid UUID
53+
with pytest.raises(ValueError, match="uuid must be a non-empty string"):
54+
PkgSpec(name="Example", uuid="")
55+
with pytest.raises(ValueError, match="uuid must be a non-empty string"):
56+
PkgSpec(name="Example", uuid=123)
57+
58+
# Test invalid dev flag
59+
with pytest.raises(TypeError, match="dev must be a boolean"):
60+
PkgSpec(name="Example", uuid="0000", dev="not-a-boolean")
61+
62+
# Test invalid version type
63+
with pytest.raises(TypeError, match="version must be a string, Version, or None"):
64+
PkgSpec(name="Example", uuid="0000", version=123)
65+
66+
# Test invalid path type
67+
with pytest.raises(TypeError, match="path must be a string or None"):
68+
PkgSpec(name="Example", uuid="0000", path=123)
69+
70+
# Test invalid subdir type
71+
with pytest.raises(TypeError, match="subdir must be a string or None"):
72+
PkgSpec(name="Example", uuid="0000", subdir=123)
73+
74+
# Test invalid url type
75+
with pytest.raises(TypeError, match="url must be a string or None"):
76+
PkgSpec(name="Example", uuid="0000", url=123)
77+
78+
# Test invalid rev type
79+
with pytest.raises(TypeError, match="rev must be a string or None"):
80+
PkgSpec(name="Example", uuid="0000", rev=123)

0 commit comments

Comments
 (0)