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
18 changes: 9 additions & 9 deletions tests/models/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,19 @@ def test_from_toml_config(config_params: dict[str, list[str]]):
)


@given(st.lists(st.from_regex(VALIDATION_NAMESPACE_REGEX)))
@given(st.lists(st.from_regex(VALIDATION_NAMESPACE_REGEX, fullmatch=True)))
def test_namespace_priorities_validation(namespaces: list[str]):
config = VariantConfiguration(namespace_priorities=namespaces)
assert config.namespace_priorities == namespaces


@given(
st.lists(st.from_regex(VALIDATION_NAMESPACE_REGEX)),
st.lists(st.from_regex(VALIDATION_NAMESPACE_REGEX, fullmatch=True)),
st.lists(
st.builds(
VariantFeature,
namespace=st.just("OmniCorp"),
feature=st.from_regex(VALIDATION_FEATURE_REGEX),
feature=st.from_regex(VALIDATION_FEATURE_REGEX, fullmatch=True),
)
),
)
Expand All @@ -77,20 +77,20 @@ def test_feature_priorities_validation(


@given(
st.lists(st.from_regex(VALIDATION_NAMESPACE_REGEX)),
st.lists(st.from_regex(VALIDATION_NAMESPACE_REGEX, fullmatch=True)),
st.lists(
st.builds(
VariantFeature,
namespace=st.from_regex(VALIDATION_NAMESPACE_REGEX),
feature=st.from_regex(VALIDATION_FEATURE_REGEX),
namespace=st.from_regex(VALIDATION_NAMESPACE_REGEX, fullmatch=True),
feature=st.from_regex(VALIDATION_FEATURE_REGEX, fullmatch=True),
)
),
st.lists(
st.builds(
VariantProperty,
namespace=st.from_regex(VALIDATION_NAMESPACE_REGEX),
feature=st.from_regex(VALIDATION_FEATURE_REGEX),
value=st.from_regex(VALIDATION_VALUE_REGEX),
namespace=st.from_regex(VALIDATION_NAMESPACE_REGEX, fullmatch=True),
feature=st.from_regex(VALIDATION_FEATURE_REGEX, fullmatch=True),
value=st.from_regex(VALIDATION_VALUE_REGEX, fullmatch=True),
)
),
)
Expand Down
21 changes: 7 additions & 14 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
from variantlib.api import get_variant_hashes_by_priority
from variantlib.api import set_variant_metadata
from variantlib.api import validate_variant
from variantlib.constants import VALIDATION_FEATURE_REGEX
from variantlib.constants import VALIDATION_NAMESPACE_REGEX
from variantlib.constants import VALIDATION_VALUE_REGEX
from variantlib.constants import VARIANTS_JSON_VARIANT_DATA_KEY
from variantlib.loader import PluginLoader
from variantlib.models import provider as pconfig
Expand Down Expand Up @@ -70,7 +73,7 @@ def test_get_variant_hashes_by_priority_roundtrip(mocker, configs):
]


@settings(deadline=1000, suppress_health_check=[HealthCheck.function_scoped_fixture])
@settings(deadline=None, suppress_health_check=[HealthCheck.function_scoped_fixture])
@example(
[
ProviderConfig(
Expand All @@ -95,29 +98,19 @@ def test_get_variant_hashes_by_priority_roundtrip(mocker, configs):
unique_by=lambda provider_cfg: provider_cfg.namespace,
elements=st.builds(
ProviderConfig,
namespace=st.text(
string.ascii_letters + string.digits + "_", min_size=1, max_size=64
),
namespace=st.from_regex(VALIDATION_NAMESPACE_REGEX, fullmatch=True),
configs=st.lists(
min_size=1,
max_size=2,
unique_by=lambda vfeat_cfg: vfeat_cfg.name,
elements=st.builds(
VariantFeatureConfig,
name=st.text(
alphabet=string.ascii_letters + string.digits + "_",
min_size=1,
max_size=64,
),
name=st.from_regex(VALIDATION_FEATURE_REGEX, fullmatch=True),
values=st.lists(
min_size=1,
max_size=3,
unique=True,
elements=st.text(
alphabet=string.ascii_letters + string.digits + "_.",
min_size=1,
max_size=64,
),
elements=st.from_regex(VALIDATION_VALUE_REGEX, fullmatch=True),
),
),
),
Expand Down
2 changes: 1 addition & 1 deletion variantlib/commands/analyze_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def analyze_wheel(args: list[str]) -> None:
raise TypeError(f"File must have a `.whl` extension: `{input_file.name}`")

# Checking if the wheel file is a valid wheel file
if (wheel_info := WHEEL_NAME_VALIDATION_REGEX.match(input_file.name)) is None:
if (wheel_info := WHEEL_NAME_VALIDATION_REGEX.fullmatch(input_file.name)) is None:
raise TypeError(
f"The file is not a valid python wheel filename: `{input_file.name}`"
)
Expand Down
2 changes: 1 addition & 1 deletion variantlib/commands/make_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def make_variant(args: list[str]) -> None:
)

# Input Validation - Wheel Filename is valid and non variant already.
wheel_info = WHEEL_NAME_VALIDATION_REGEX.match(input_filepath.name)
wheel_info = WHEEL_NAME_VALIDATION_REGEX.fullmatch(input_filepath.name)
if wheel_info is None:
raise ValueError(f"{input_filepath.name!r} is not a valid wheel filename.")

Expand Down
11 changes: 5 additions & 6 deletions variantlib/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@
VARIANTS_JSON_PROVIDER_DATA_KEY = "providers"
VARIANTS_JSON_VARIANT_DATA_KEY = "variants"

VALIDATION_VARIANT_HASH_REGEX = re.compile(rf"^[0-9a-f]{{{VARIANT_HASH_LEN}}}$")
VALIDATION_NAMESPACE_REGEX = re.compile(r"^[A-Za-z0-9_]+$")
VALIDATION_FEATURE_REGEX = re.compile(r"^[A-Za-z0-9_]+$")
VALIDATION_VALUE_REGEX = re.compile(r"^[A-Za-z0-9_.]+$")
VALIDATION_VARIANT_HASH_REGEX = re.compile(rf"[0-9a-f]{{{VARIANT_HASH_LEN}}}")
VALIDATION_NAMESPACE_REGEX = re.compile(r"[A-Za-z0-9_]+")
VALIDATION_FEATURE_REGEX = re.compile(r"[A-Za-z0-9_]+")
VALIDATION_VALUE_REGEX = re.compile(r"[A-Za-z0-9_.]+")

METADATA_VARIANT_HASH_HEADER = "Variant-hash"
METADATA_VARIANT_PROPERTY_HEADER = "Variant"
METADATA_VARIANT_PROVIDER_HEADER = "Variant-provider"

WHEEL_NAME_VALIDATION_REGEX = re.compile(
r"^ "
r"(?P<base_wheel_name> " # <base_wheel_name> group (without variant)
r" (?P<namever> " # "namever" group contains <name>-<ver>
r" (?P<name>[^\s-]+?) " # <name>
Expand All @@ -34,6 +33,6 @@
r" ) "
r")? "
r"\.whl " # ".whl" suffix
r"$ ",
r" ",
re.VERBOSE,
)
18 changes: 9 additions & 9 deletions variantlib/models/variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,15 @@ def deserialize(cls, data: dict[str, str]) -> Self:
@classmethod
def from_str(cls, input_str: str) -> Self:
# removing starting `^` and trailing `$`
pttn_nmspc = VALIDATION_NAMESPACE_REGEX.pattern[1:-1]
pttn_feature = VALIDATION_FEATURE_REGEX.pattern[1:-1]
pttn_nmspc = VALIDATION_NAMESPACE_REGEX.pattern
pttn_feature = VALIDATION_FEATURE_REGEX.pattern

pattern = re.compile(
rf"^(?P<namespace>{pttn_nmspc})\s*::\s*(?P<feature>{pttn_feature})$"
rf"(?P<namespace>{pttn_nmspc})\s*::\s*(?P<feature>{pttn_feature})"
)

# Try matching the input string with the regex pattern
match = pattern.match(input_str.strip())
match = pattern.fullmatch(input_str.strip())

if match is None:
raise ValidationError(
Expand Down Expand Up @@ -130,16 +130,16 @@ def to_str(self) -> str:
@classmethod
def from_str(cls, input_str: str) -> Self:
# removing starting `^` and trailing `$`
pttn_nmspc = VALIDATION_NAMESPACE_REGEX.pattern[1:-1]
pttn_feature = VALIDATION_FEATURE_REGEX.pattern[1:-1]
pttn_value = VALIDATION_VALUE_REGEX.pattern[1:-1]
pttn_nmspc = VALIDATION_NAMESPACE_REGEX.pattern
pttn_feature = VALIDATION_FEATURE_REGEX.pattern
pttn_value = VALIDATION_VALUE_REGEX.pattern

pattern = re.compile(
rf"^(?P<namespace>{pttn_nmspc})\s*::\s*(?P<feature>{pttn_feature})\s*::\s*(?P<value>{pttn_value})$"
rf"(?P<namespace>{pttn_nmspc})\s*::\s*(?P<feature>{pttn_feature})\s*::\s*(?P<value>{pttn_value})"
)

# Try matching the input string with the regex pattern
match = pattern.match(input_str.strip())
match = pattern.fullmatch(input_str.strip())

if match is None:
raise ValidationError(
Expand Down
10 changes: 5 additions & 5 deletions variantlib/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


def validate_matches_re(value: str, pattern: str | re.Pattern) -> None:
if not re.match(pattern, value):
if not re.fullmatch(pattern, value):
raise ValidationError(f"Value `{value}` must match regex {pattern}")


Expand Down Expand Up @@ -184,7 +184,7 @@ def validate_variants_json(data: dict) -> None:
raise ValidationError(
f"Invalid `variant_hash` type: `{variant_hash}` in data (expected str)"
)
if VALIDATION_VARIANT_HASH_REGEX.match(variant_hash) is None:
if VALIDATION_VARIANT_HASH_REGEX.fullmatch(variant_hash) is None:
raise ValidationError(f"Invalid variant hash `{variant_hash}` in data")

# Check the Variant Data
Expand All @@ -204,7 +204,7 @@ def validate_variants_json(data: dict) -> None:
raise ValidationError(
f"Invalid variant namespace `{namespace}` for hash `{variant_hash}`"
)
if VALIDATION_NAMESPACE_REGEX.match(namespace) is None:
if VALIDATION_NAMESPACE_REGEX.fullmatch(namespace) is None:
raise ValidationError(
f"Invalid variant namespace `{namespace}` for hash `{variant_hash}`"
)
Expand All @@ -229,7 +229,7 @@ def validate_variants_json(data: dict) -> None:
f"Invalid variant feature name `{feature_name}` for hash "
f"`{variant_hash}`"
)
if VALIDATION_FEATURE_REGEX.match(feature_name) is None:
if VALIDATION_FEATURE_REGEX.fullmatch(feature_name) is None:
raise ValidationError(
f"Invalid variant feature name `{feature_name}` for hash "
f"`{variant_hash}`"
Expand All @@ -242,7 +242,7 @@ def validate_variants_json(data: dict) -> None:
f"`{variant_hash}` - Type received: `{type(feature_value)}`, "
"expected: `str`."
)
if VALIDATION_VALUE_REGEX.match(feature_value) is None:
if VALIDATION_VALUE_REGEX.fullmatch(feature_value) is None:
raise ValidationError(
f"Invalid variant value `{feature_value}` for hash "
f"`{variant_hash}`"
Expand Down
Loading