Skip to content

Commit 610ed3f

Browse files
Merge pull request #188 from lsst/tickets/DM-55343
DM-55343: Remove minimum length on description field
2 parents 2119210 + a9fbfdb commit 610ed3f

3 files changed

Lines changed: 125 additions & 25 deletions

File tree

docs/changes/DM-55343.api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Removed restriction on the minimum length of the description field.

python/felis/datamodel.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,6 @@
8181
https://docs.pydantic.dev/2.0/api/config/#pydantic.config.ConfigDict
8282
"""
8383

84-
DESCR_MIN_LENGTH = 3
85-
"""Minimum length for a description field."""
86-
87-
DescriptionStr: TypeAlias = Annotated[str, Field(min_length=DESCR_MIN_LENGTH)]
88-
"""Type for a description, which must be three or more characters long."""
89-
9084

9185
class BaseObject(BaseModel):
9286
"""Base model.
@@ -104,15 +98,17 @@ class BaseObject(BaseModel):
10498
id: str = Field(alias="@id")
10599
"""Unique identifier of the database object."""
106100

107-
description: DescriptionStr | None = None
101+
description: str | None = None
108102
"""Description of the database object."""
109103

110104
votable_utype: str | None = Field(None, alias="votable:utype")
111105
"""VOTable utype (usage-specific or unique type) of the object."""
112106

113107
@model_validator(mode="after")
114108
def check_description(self, info: ValidationInfo) -> BaseObject:
115-
"""Check that the description is present if required.
109+
"""Check that the description is present and contains at least one
110+
non-whitespace character, if the validation context indicates that this
111+
check is enabled. By default, descriptions may be omitted or empty.
116112
117113
Parameters
118114
----------
@@ -129,8 +125,6 @@ def check_description(self, info: ValidationInfo) -> BaseObject:
129125
return self
130126
if self.description is None or self.description == "":
131127
raise ValueError("Description is required and must be non-empty")
132-
if len(self.description) < DESCR_MIN_LENGTH:
133-
raise ValueError(f"Description must be at least {DESCR_MIN_LENGTH} characters long")
134128
return self
135129

136130

tests/test_datamodel.py

Lines changed: 120 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -122,41 +122,146 @@ def test_validation(self) -> None:
122122
with self.assertRaises(ValidationError):
123123
Column(**units_data)
124124

125-
def test_description(self) -> None:
126-
"""Test Pydantic validation of the ``description`` attribute."""
125+
def test_description_unchecked(self) -> None:
126+
"""Test that the ``description`` attribute is optional when the
127+
``check_description`` flag is disabled (the default).
128+
"""
129+
# A missing description should be allowed.
130+
col = Column.model_validate(
131+
{
132+
"name": "testColumn",
133+
"@id": "#test_col_id",
134+
"datatype": "string",
135+
"length": 256,
136+
}
137+
)
138+
self.assertIsNone(col.description)
139+
140+
# An explicit 'None' description should be allowed.
141+
col = Column.model_validate(
142+
{
143+
"name": "testColumn",
144+
"@id": "#test_col_id",
145+
"datatype": "string",
146+
"length": 256,
147+
"description": None,
148+
}
149+
)
150+
self.assertIsNone(col.description)
151+
152+
# An empty description should be allowed.
153+
col = Column.model_validate(
154+
{
155+
"name": "testColumn",
156+
"@id": "#test_col_id",
157+
"datatype": "string",
158+
"length": 256,
159+
"description": "",
160+
}
161+
)
162+
self.assertEqual(col.description, "")
163+
164+
# A description with only whitespace should be allowed.
165+
col = Column.model_validate(
166+
{
167+
"name": "testColumn",
168+
"@id": "#test_col_id",
169+
"datatype": "string",
170+
"length": 256,
171+
"description": " ",
172+
}
173+
)
174+
175+
# Pydantic will strip this automatically.
176+
self.assertEqual(col.description, "")
177+
178+
# A description with one or more non-whitespace characters should be
179+
# allowed.
180+
col = Column.model_validate(
181+
{
182+
"name": "testColumn",
183+
"@id": "#test_col_id",
184+
"datatype": "string",
185+
"length": 256,
186+
"description": "x",
187+
}
188+
)
189+
self.assertEqual(col.description, "x")
190+
191+
def test_description_checked(self) -> None:
192+
"""Test Pydantic validation of the ``description`` attribute when the
193+
``check_description`` flag is enabled.
194+
"""
195+
cxt = {"check_description": True}
196+
127197
# Creating a column with a description of 'None' should throw.
128-
with self.assertRaises(ValueError):
129-
Column(
130-
**{
198+
with self.assertRaises(ValidationError):
199+
Column.model_validate(
200+
{
131201
"name": "testColumn",
132202
"@id": "#test_col_id",
133203
"datatype": "string",
204+
"length": 256,
134205
"description": None,
135-
}
206+
},
207+
context=cxt,
136208
)
137209

138210
# Creating a column with an empty description should throw.
139-
with self.assertRaises(ValueError):
140-
Column(
141-
**{
211+
with self.assertRaises(ValidationError):
212+
Column.model_validate(
213+
{
142214
"name": "testColumn",
143215
"@id": "#test_col_id",
144216
"datatype": "string",
217+
"length": 256,
145218
"description": "",
146-
}
219+
},
220+
context=cxt,
147221
)
148222

149-
# Creating a column with a description that is too short should throw.
223+
# Creating a column with a whitespace-only description should throw,
224+
# since whitespace is stripped before validation.
150225
with self.assertRaises(ValidationError):
151-
Column(
152-
**{
226+
Column.model_validate(
227+
{
153228
"name": "testColumn",
154229
"@id": "#test_col_id",
155230
"datatype": "string",
156-
"description": "xy",
157-
}
231+
"length": 256,
232+
"description": " ",
233+
},
234+
context=cxt,
158235
)
159236

237+
# Creating a column with a single non-whitespace character in the
238+
# description should not throw.
239+
col = Column.model_validate(
240+
{
241+
"name": "testColumn",
242+
"@id": "#test_col_id",
243+
"datatype": "string",
244+
"length": 256,
245+
"description": "x",
246+
},
247+
context=cxt,
248+
)
249+
self.assertEqual(col.description, "x")
250+
251+
# Creating a column with more than one non-whitespace character in the
252+
# description should not throw.
253+
col = Column.model_validate(
254+
{
255+
"name": "testColumn",
256+
"@id": "#test_col_id",
257+
"datatype": "string",
258+
"length": 256,
259+
"description": "test description",
260+
},
261+
context=cxt,
262+
)
263+
self.assertEqual(col.description, "test description")
264+
160265
def test_values(self) -> None:
161266
"""Test Pydantic validation of the ``value`` attribute."""
162267

0 commit comments

Comments
 (0)