Skip to content

Commit 20be535

Browse files
committed
Explicitly define defaults for terminal range classes
1 parent bdff7ab commit 20be535

File tree

2 files changed

+56
-11
lines changed

2 files changed

+56
-11
lines changed

src/mavedb/view_models/score_range.py

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ class ScoreRange(SavedScoreRange):
8787

8888

8989
class ScoreRangesBase(BaseModel):
90-
title: str = "Score Ranges"
90+
title: str
91+
research_use_only: bool
9192
ranges: Sequence[ScoreRangeBase]
92-
research_use_only: bool = False
9393
source: Optional[Sequence[PublicationIdentifierBase]] = None
9494

9595
@field_validator("ranges")
@@ -193,7 +193,6 @@ class BrnichScoreRange(ScoreRange, SavedBrnichScoreRange):
193193

194194

195195
class BrnichScoreRangesBase(ScoreRangesBase):
196-
title: str = "Brnich functional classes"
197196
baseline_score: Optional[float] = None
198197
baseline_score_description: Optional[str] = None
199198
ranges: Sequence[BrnichScoreRangeBase]
@@ -253,26 +252,54 @@ class BrnichScoreRanges(ScoreRanges, SavedBrnichScoreRanges):
253252
##############################################################################################################
254253

255254

255+
# NOTE: Pydantic takes the first occurence of a field definition in the MRO for default values. It feels most
256+
# natural to define these classes like
257+
# class InvestigatorScoreRangesBase(BrnichScoreRangesBase):
258+
# title: str = "Investigator-provided functional classes"
259+
#
260+
# class InvestigatorScoreRangesModify(BrnichScoreRangesModify, InvestigatorScoreRangesBase):
261+
# pass
262+
#
263+
# however, this does not work because the title field is defined in BrnichScoreRangesBase, and the default
264+
# value from that class is taken instead of the one in InvestigatorScoreRangesBase. Note the opposite problem
265+
# would occur if we defined the classes in the opposite order.
266+
#
267+
# We'd also like to retain the inheritance chain from Base -> Modify -> Create and Base -> Saved -> Full for
268+
# each score range type as this makes it much easier to use these classes in inherited types from other
269+
# modules (like the ScoreSet models). So although a mixin class might seem natural, we can't use one here
270+
# since our MRO resolution wouldn't be linear.
271+
#
272+
# Just duplicating the defaults across each of the classes is the simplest solution for now, despite the
273+
# code duplication.
274+
275+
256276
class InvestigatorScoreRangesBase(BrnichScoreRangesBase):
257277
title: str = "Investigator-provided functional classes"
278+
research_use_only: bool = False
258279

259280

260281
class InvestigatorScoreRangesModify(BrnichScoreRangesModify, InvestigatorScoreRangesBase):
261-
pass
282+
title: str = "Investigator-provided functional classes"
283+
research_use_only: bool = False
262284

263285

264286
class InvestigatorScoreRangesCreate(BrnichScoreRangesCreate, InvestigatorScoreRangesModify):
265-
pass
287+
title: str = "Investigator-provided functional classes"
288+
research_use_only: bool = False
266289

267290

268291
class SavedInvestigatorScoreRanges(SavedBrnichScoreRanges, InvestigatorScoreRangesBase):
269292
record_type: str = None # type: ignore
270293

294+
title: str = "Investigator-provided functional classes"
295+
research_use_only: bool = False
296+
271297
_record_type_factory = record_type_validator()(set_record_type)
272298

273299

274300
class InvestigatorScoreRanges(BrnichScoreRanges, SavedInvestigatorScoreRanges):
275-
pass
301+
title: str = "Investigator-provided functional classes"
302+
research_use_only: bool = False
276303

277304

278305
##############################################################################################################
@@ -282,24 +309,31 @@ class InvestigatorScoreRanges(BrnichScoreRanges, SavedInvestigatorScoreRanges):
282309

283310
class ScottScoreRangesBase(BrnichScoreRangesBase):
284311
title: str = "Scott calibration"
312+
research_use_only: bool = False
285313

286314

287315
class ScottScoreRangesModify(BrnichScoreRangesModify, ScottScoreRangesBase):
288-
pass
316+
title: str = "Scott calibration"
317+
research_use_only: bool = False
289318

290319

291320
class ScottScoreRangesCreate(BrnichScoreRangesCreate, ScottScoreRangesModify):
292-
pass
321+
title: str = "Scott calibration"
322+
research_use_only: bool = False
293323

294324

295325
class SavedScottScoreRanges(SavedBrnichScoreRanges, ScottScoreRangesBase):
296326
record_type: str = None # type: ignore
297327

328+
title: str = "Scott calibration"
329+
research_use_only: bool = False
330+
298331
_record_type_factory = record_type_validator()(set_record_type)
299332

300333

301334
class ScottScoreRanges(BrnichScoreRanges, SavedScottScoreRanges):
302-
pass
335+
title: str = "Scott calibration"
336+
research_use_only: bool = False
303337

304338

305339
##############################################################################################################
@@ -368,29 +402,38 @@ class ZeibergCalibrationParameterSet(BaseModel):
368402

369403
class ZeibergCalibrationScoreRangesBase(ScoreRangesBase):
370404
title: str = "Zeiberg calibration"
405+
research_use_only: bool = True
406+
371407
prior_probability_pathogenicity: Optional[float] = None
372408
parameter_sets: list[ZeibergCalibrationParameterSet] = []
373409
ranges: Sequence[ZeibergCalibrationScoreRangeBase]
374-
research_use_only: bool = True
375410

376411

377412
class ZeibergCalibrationScoreRangesModify(ScoreRangesModify, ZeibergCalibrationScoreRangesBase):
413+
title: str = "Zeiberg calibration"
414+
research_use_only: bool = True
378415
ranges: Sequence[ZeibergCalibrationScoreRangeModify]
379416

380417

381418
class ZeibergCalibrationScoreRangesCreate(ScoreRangesCreate, ZeibergCalibrationScoreRangesModify):
419+
title: str = "Zeiberg calibration"
420+
research_use_only: bool = True
382421
ranges: Sequence[ZeibergCalibrationScoreRangeCreate]
383422

384423

385424
class SavedZeibergCalibrationScoreRanges(SavedScoreRanges, ZeibergCalibrationScoreRangesBase):
386425
record_type: str = None # type: ignore
387426

427+
title: str = "Zeiberg calibration"
428+
research_use_only: bool = True
388429
ranges: Sequence[SavedZeibergCalibrationScoreRange]
389430

390431
_record_type_factory = record_type_validator()(set_record_type)
391432

392433

393434
class ZeibergCalibrationScoreRanges(ScoreRanges, SavedZeibergCalibrationScoreRanges):
435+
title: str = "Zeiberg calibration"
436+
research_use_only: bool = True
394437
ranges: Sequence[ZeibergCalibrationScoreRange]
395438

396439

tests/view_models/test_score_range.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,10 +527,12 @@ def test_score_ranges_ranges_boundaries_may_be_adjacent(
527527
inclusive_upper_bound=not orientation,
528528
)
529529
valid_data = {
530+
"title": "Test Ranges",
531+
"research_use_only": False,
530532
"ranges": [
531533
range_test,
532534
range_check,
533-
]
535+
],
534536
}
535537

536538
ScoreRangesModel(**valid_data)

0 commit comments

Comments
 (0)