Skip to content

Commit 29d68ae

Browse files
authored
refactor: update IfStatement references and add annotated version (#57)
1 parent fa2dfbb commit 29d68ae

File tree

3 files changed

+101
-27
lines changed

3 files changed

+101
-27
lines changed

conda_recipe_v2_schema/model.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pydantic import (
77
AnyHttpUrl,
88
BaseModel,
9+
ConfigDict,
910
Field,
1011
TypeAdapter,
1112
conint,
@@ -20,8 +21,7 @@
2021

2122

2223
class StrictBaseModel(BaseModel):
23-
class Config:
24-
extra = "forbid"
24+
model_config = ConfigDict(extra="forbid")
2525

2626

2727
###########################
@@ -81,8 +81,12 @@ class ComplexPackage(StrictBaseModel):
8181
SHA256Str = constr(min_length=64, max_length=64, pattern=r"[a-fA-F0-9]{64}") | JinjaExpr
8282

8383

84+
# We will use a type for patches that doesn't allow standalone if statements so they must be inside a list
85+
PatchesList = Union[PathNoBackslash, list[Union[PathNoBackslash, "IfStatement[PathNoBackslash]"]]]
86+
87+
8488
class BaseSource(StrictBaseModel):
85-
patches: ConditionalList[PathNoBackslash] = Field(
89+
patches: PatchesList = Field(
8690
[], description="A list of patches to apply after fetching the source"
8791
)
8892
target_directory: NonEmptyStr | None = Field(

schema.json

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,6 @@
159159
"pattern": "^[^\\\\]+$",
160160
"type": "string"
161161
},
162-
{
163-
"$ref": "#/$defs/IfStatement"
164-
},
165162
{
166163
"items": {
167164
"anyOf": [
@@ -170,7 +167,7 @@
170167
"type": "string"
171168
},
172169
{
173-
"$ref": "#/$defs/IfStatement"
170+
"$ref": "#/$defs/IfStatement_Annotated_str__StringConstraints__"
174171
}
175172
]
176173
},
@@ -1445,9 +1442,6 @@
14451442
"pattern": "^[^\\\\]+$",
14461443
"type": "string"
14471444
},
1448-
{
1449-
"$ref": "#/$defs/IfStatement"
1450-
},
14511445
{
14521446
"items": {
14531447
"anyOf": [
@@ -1456,7 +1450,7 @@
14561450
"type": "string"
14571451
},
14581452
{
1459-
"$ref": "#/$defs/IfStatement"
1453+
"$ref": "#/$defs/IfStatement_Annotated_str__StringConstraints__"
14601454
}
14611455
]
14621456
},
@@ -1538,9 +1532,6 @@
15381532
"pattern": "^[^\\\\]+$",
15391533
"type": "string"
15401534
},
1541-
{
1542-
"$ref": "#/$defs/IfStatement"
1543-
},
15441535
{
15451536
"items": {
15461537
"anyOf": [
@@ -1549,7 +1540,7 @@
15491540
"type": "string"
15501541
},
15511542
{
1552-
"$ref": "#/$defs/IfStatement"
1543+
"$ref": "#/$defs/IfStatement_Annotated_str__StringConstraints__"
15531544
}
15541545
]
15551546
},
@@ -1631,9 +1622,6 @@
16311622
"pattern": "^[^\\\\]+$",
16321623
"type": "string"
16331624
},
1634-
{
1635-
"$ref": "#/$defs/IfStatement"
1636-
},
16371625
{
16381626
"items": {
16391627
"anyOf": [
@@ -1642,7 +1630,7 @@
16421630
"type": "string"
16431631
},
16441632
{
1645-
"$ref": "#/$defs/IfStatement"
1633+
"$ref": "#/$defs/IfStatement_Annotated_str__StringConstraints__"
16461634
}
16471635
]
16481636
},
@@ -1819,6 +1807,57 @@
18191807
"title": "IfStatement",
18201808
"type": "object"
18211809
},
1810+
"IfStatement_Annotated_str__StringConstraints__": {
1811+
"additionalProperties": false,
1812+
"properties": {
1813+
"if": {
1814+
"title": "If",
1815+
"type": "string"
1816+
},
1817+
"then": {
1818+
"anyOf": [
1819+
{
1820+
"pattern": "^[^\\\\]+$",
1821+
"type": "string"
1822+
},
1823+
{
1824+
"items": {
1825+
"pattern": "^[^\\\\]+$",
1826+
"type": "string"
1827+
},
1828+
"type": "array"
1829+
}
1830+
],
1831+
"title": "Then"
1832+
},
1833+
"else": {
1834+
"anyOf": [
1835+
{
1836+
"pattern": "^[^\\\\]+$",
1837+
"type": "string"
1838+
},
1839+
{
1840+
"items": {
1841+
"pattern": "^[^\\\\]+$",
1842+
"type": "string"
1843+
},
1844+
"type": "array"
1845+
},
1846+
{
1847+
"type": "null"
1848+
}
1849+
],
1850+
"default": null,
1851+
"title": "Else"
1852+
}
1853+
},
1854+
"required": [
1855+
"if",
1856+
"then"
1857+
],
1858+
"title": "IfStatement[Annotated[str, StringConstraints]]",
1859+
"type": "object"
1860+
},
18221861
"IfStatement_Union_ScriptTestElement__PythonTestElement__DownstreamTestElement__PackageContentTest__": {
18231862
"additionalProperties": false,
18241863
"properties": {
@@ -2146,9 +2185,6 @@
21462185
"pattern": "^[^\\\\]+$",
21472186
"type": "string"
21482187
},
2149-
{
2150-
"$ref": "#/$defs/IfStatement"
2151-
},
21522188
{
21532189
"items": {
21542190
"anyOf": [
@@ -2157,7 +2193,7 @@
21572193
"type": "string"
21582194
},
21592195
{
2160-
"$ref": "#/$defs/IfStatement"
2196+
"$ref": "#/$defs/IfStatement_Annotated_str__StringConstraints__"
21612197
}
21622198
]
21632199
},
@@ -4085,9 +4121,6 @@
40854121
"pattern": "^[^\\\\]+$",
40864122
"type": "string"
40874123
},
4088-
{
4089-
"$ref": "#/$defs/IfStatement"
4090-
},
40914124
{
40924125
"items": {
40934126
"anyOf": [
@@ -4096,7 +4129,7 @@
40964129
"type": "string"
40974130
},
40984131
{
4099-
"$ref": "#/$defs/IfStatement"
4132+
"$ref": "#/$defs/IfStatement_Annotated_str__StringConstraints__"
41004133
}
41014134
]
41024135
},

tests/test_recipy.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import yaml
55
from jsonschema import validate
66
from jsonschema.exceptions import ValidationError
7+
from pydantic import ValidationError as PydanticValidationError
78

89
from conda_recipe_v2_schema.model import Recipe
910

@@ -53,3 +54,39 @@ def test_recipe_schema_invalid(recipe_schema, invalid_recipe):
5354

5455
def test_recipe_schema_not_changed(recipe_schema):
5556
assert recipe_schema == Recipe.json_schema()
57+
58+
59+
def test_patches_valid_conditional():
60+
"""Test that patches with conditionals inside a list pass validation."""
61+
recipe_yaml = """
62+
package:
63+
name: test
64+
version: 1.0.0
65+
source:
66+
url: https://example.com/test.tar.gz
67+
patches:
68+
- file.patch
69+
- if: target_platform == 'win-64'
70+
then: windows.patch
71+
"""
72+
recipe_dict = yaml.safe_load(recipe_yaml)
73+
# This should not raise an exception
74+
Recipe.validate_python(recipe_dict)
75+
76+
77+
def test_patches_invalid_conditional():
78+
"""Test that patches with standalone conditionals fail validation."""
79+
recipe_yaml = """
80+
package:
81+
name: test
82+
version: 1.0.0
83+
source:
84+
url: https://example.com/test.tar.gz
85+
patches:
86+
if: target_platform == 'win-64'
87+
then: windows.patch
88+
"""
89+
recipe_dict = yaml.safe_load(recipe_yaml)
90+
# This should raise a validation error
91+
with pytest.raises(PydanticValidationError):
92+
Recipe.validate_python(recipe_dict)

0 commit comments

Comments
 (0)