clinicedc 2.0.28__py3-none-any.whl → 2.0.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of clinicedc might be problematic. Click here for more details.

Files changed (95) hide show
  1. {clinicedc-2.0.28.dist-info → clinicedc-2.0.29.dist-info}/METADATA +2 -2
  2. {clinicedc-2.0.28.dist-info → clinicedc-2.0.29.dist-info}/RECORD +95 -95
  3. edc_auth/admin/fieldsets.py +11 -15
  4. edc_auth/admin/group_admin.py +2 -5
  5. edc_auth/admin/list_filters.py +8 -7
  6. edc_auth/admin/role_admin.py +7 -10
  7. edc_auth/admin/user_admin.py +2 -2
  8. edc_auth/admin/user_profile_admin.py +3 -7
  9. edc_auth/apps.py +2 -2
  10. edc_auth/auth_updater/group_updater.py +4 -4
  11. edc_auth/auth_updater/role_updater.py +1 -3
  12. edc_auth/backends.py +1 -1
  13. edc_auth/export_users.py +6 -5
  14. edc_auth/fix_export_permissions.py +8 -8
  15. edc_auth/forms.py +21 -24
  16. edc_auth/get_app_codenames.py +2 -2
  17. edc_auth/import_users.py +25 -24
  18. edc_auth/management/commands/export_users.py +1 -1
  19. edc_auth/management/commands/fix_export_permissions.py +1 -1
  20. edc_auth/management/commands/import_users.py +1 -1
  21. edc_auth/management/commands/reset_password.py +2 -2
  22. edc_auth/models/signals.py +1 -1
  23. edc_auth/models/user_profile.py +4 -5
  24. edc_auth/password_setter.py +4 -4
  25. edc_auth/post_migrate_signals.py +2 -2
  26. edc_auth/send_new_credentials_to_user.py +1 -1
  27. edc_auth/system_checks.py +7 -6
  28. edc_auth/utils.py +9 -11
  29. edc_consent/consent_definition.py +4 -1
  30. edc_model_admin/mixins/model_admin_form_instructions_mixin.py +9 -3
  31. edc_model_admin/mixins/model_admin_protect_pii_mixin.py +7 -7
  32. edc_pharmacy/admin_mixin.py +1 -1
  33. edc_pharmacy/approve_prescription.py +10 -8
  34. edc_pharmacy/auth_objects.py +1 -1
  35. edc_pharmacy/exceptions.py +7 -7
  36. edc_pharmacy/settings.py +1 -1
  37. edc_pharmacy/views/add_to_storage_bin_view.py +22 -24
  38. edc_pharmacy/views/allocate_to_subject_view.py +10 -18
  39. edc_pharmacy/views/celery_task_status_view.py +1 -2
  40. edc_pharmacy/views/confirm_stock_from_instance_view.py +1 -1
  41. edc_pharmacy/views/confirm_stock_from_queryset_view.py +5 -8
  42. edc_pharmacy/views/dispense_view.py +1 -1
  43. edc_pharmacy/views/move_to_storage_bin_view.py +7 -3
  44. edc_pharmacy/views/prepare_and_review_stock_request_view.py +62 -70
  45. edc_pharmacy/views/print_labels_view.py +1 -1
  46. edc_pharmacy/views/transfer_stock_view.py +1 -1
  47. edc_prn/modelform_mixins.py +8 -9
  48. edc_prn/models.py +3 -1
  49. edc_prn/site_prn_forms.py +2 -2
  50. edc_prn/templatetags/edc_prn_extras.py +1 -1
  51. edc_protocol/middleware.py +1 -1
  52. edc_protocol/research_protocol_config.py +7 -5
  53. edc_protocol_incident/admin/protocol_deviation_violation_admin.py +1 -1
  54. edc_protocol_incident/form_validators/mixins.py +9 -6
  55. edc_protocol_incident/modeladmin_mixins.py +1 -1
  56. edc_pylabels/admin/label_configuration_admin.py +1 -1
  57. edc_pylabels/admin/label_specification_admin.py +1 -1
  58. edc_pylabels/auth_objects.py +1 -1
  59. edc_pylabels/site_label_configs.py +2 -2
  60. edc_qareports/admin/qa_report_log_admin.py +5 -5
  61. edc_qareports/admin/qa_report_log_summary_admin.py +1 -1
  62. edc_qareports/forms/note_form.py +2 -3
  63. edc_qareports/modeladmin_mixins/list_filters.py +23 -19
  64. edc_qareports/modeladmin_mixins/note_modeladmin_mixin.py +7 -7
  65. edc_qareports/modeladmin_mixins/on_study_missing_values_modeladmin_mixin.py +8 -8
  66. edc_qareports/modeladmin_mixins/qa_report_modeladmin_mixin.py +3 -7
  67. edc_qareports/sql_generator/crf_case.py +1 -1
  68. edc_qareports/sql_generator/crf_subquery.py +1 -1
  69. edc_qareports/sql_generator/requisition_subquery.py +1 -1
  70. edc_qareports/sql_generator/sql_view_generator.py +1 -1
  71. edc_qareports/sql_generator/subquery_from_dict.py +39 -39
  72. edc_qareports/utils.py +12 -13
  73. edc_randomization/model_mixins.py +1 -1
  74. edc_randomization/system_checks.py +1 -1
  75. edc_refusal/admin.py +4 -2
  76. edc_registration/modeladmin_mixins.py +18 -20
  77. edc_registration/modelform_mixins.py +2 -2
  78. edc_registration/models/signals.py +1 -1
  79. edc_registration/utils.py +1 -1
  80. edc_reportable/age_evaluator.py +4 -4
  81. edc_reportable/data/grading_data/daids_july_2017.py +3 -3
  82. edc_reportable/evaluator.py +15 -15
  83. edc_reportable/exceptions.py +4 -4
  84. edc_reportable/forms/reportables_form_validator_mixin.py +6 -2
  85. edc_reportable/management/commands/export_reportables.py +1 -1
  86. edc_reportable/models/grading_exception.py +1 -6
  87. edc_reportable/models/normal_data.py +3 -3
  88. edc_reportable/models/reference_range_collection.py +1 -6
  89. edc_reportable/utils/get_grade_for_value.py +15 -15
  90. edc_reportable/utils/get_normal_data_or_raise.py +14 -14
  91. edc_reportable/utils/in_normal_bounds_or_raise.py +6 -6
  92. edc_reportable/utils/load_data.py +1 -1
  93. edc_reportable/utils/update_grading_exceptions.py +5 -5
  94. {clinicedc-2.0.28.dist-info → clinicedc-2.0.29.dist-info}/WHEEL +0 -0
  95. {clinicedc-2.0.28.dist-info → clinicedc-2.0.29.dist-info}/licenses/LICENSE +0 -0
@@ -57,7 +57,7 @@ def randomizationlist_check(app_configs, **kwargs) -> list:
57
57
  ):
58
58
  error_msgs = randomizer.verify_list()
59
59
  for error_msg in error_msgs:
60
- errors.append(error.cls(error_msg, hint=None, obj=None, id=error.id))
60
+ errors.append(error.cls(error_msg, hint=None, obj=None, id=error.id)) # noqa: PERF401
61
61
  if not settings.DEBUG:
62
62
  if not randomizer.get_randomizationlist_path().is_relative_to(settings.ETC_DIR):
63
63
  errors.append(
edc_refusal/admin.py CHANGED
@@ -41,7 +41,7 @@ class SubjectRefusalModelAdminMixin:
41
41
 
42
42
  search_fields = ("screening_identifier",)
43
43
 
44
- radio_fields = {"reason": admin.VERTICAL}
44
+ radio_fields = {"reason": admin.VERTICAL} # noqa: RUF012
45
45
 
46
46
 
47
47
  @admin.register(SubjectRefusal, site=edc_refusal_admin)
@@ -70,5 +70,7 @@ class SubjectRefusalAdmin(
70
70
  if callable(super().view_on_site):
71
71
  url = super().view_on_site(obj)
72
72
  else:
73
- raise NoReverseMatch(f"{e}. See subject_dashboard_url_name for {self!r}.")
73
+ raise NoReverseMatch(
74
+ f"{e}. See subject_dashboard_url_name for {self!r}."
75
+ ) from e
74
76
  return url
@@ -10,7 +10,7 @@ class RegisteredSubjectModelAdminMixin(ModelAdminSubjectDashboardMixin, admin.Mo
10
10
 
11
11
  date_hierarchy = "registration_datetime"
12
12
 
13
- instructions = []
13
+ instructions = ()
14
14
 
15
15
  @staticmethod
16
16
  def show_pii(request) -> bool:
@@ -29,25 +29,23 @@ class RegisteredSubjectModelAdminMixin(ModelAdminSubjectDashboardMixin, admin.Mo
29
29
  def get_readonly_fields(self, request, obj=None) -> tuple[str, ...]:
30
30
  readonly_fields = super().get_readonly_fields(request, obj=obj)
31
31
  return (
32
- readonly_fields
33
- + (
34
- "subject_identifier",
35
- "sid",
36
- "first_name",
37
- "last_name",
38
- "initials",
39
- "dob",
40
- "gender",
41
- "subject_type",
42
- "registration_status",
43
- "identity",
44
- "screening_identifier",
45
- "screening_datetime",
46
- "registration_datetime",
47
- "randomization_datetime",
48
- "consent_datetime",
49
- )
50
- + audit_fields
32
+ *readonly_fields,
33
+ "subject_identifier",
34
+ "sid",
35
+ "first_name",
36
+ "last_name",
37
+ "initials",
38
+ "dob",
39
+ "gender",
40
+ "subject_type",
41
+ "registration_status",
42
+ "identity",
43
+ "screening_identifier",
44
+ "screening_datetime",
45
+ "registration_datetime",
46
+ "randomization_datetime",
47
+ "consent_datetime",
48
+ *audit_fields,
51
49
  )
52
50
 
53
51
  def get_list_display(self, request):
@@ -21,6 +21,6 @@ class ModelFormSubjectIdentifierMixin(SiteModelFormMixin):
21
21
  get_registered_subject_model_cls().objects.get(
22
22
  subject_identifier=subject_identifier
23
23
  )
24
- except ObjectDoesNotExist:
25
- raise forms.ValidationError({"subject_identifier": "Invalid."})
24
+ except ObjectDoesNotExist as e:
25
+ raise forms.ValidationError({"subject_identifier": "Invalid."}) from e
26
26
  return cleaned_data
@@ -18,4 +18,4 @@ def update_registered_subject_from_model_on_post_save(
18
18
  instance.registration_update_or_create()
19
19
  except AttributeError as e:
20
20
  if "registration_update_or_create" not in str(e):
21
- raise AttributeError(str(e))
21
+ raise AttributeError(str(e)) from e
edc_registration/utils.py CHANGED
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
15
15
  from edc_registration.models import RegisteredSubject
16
16
 
17
17
 
18
- class RegisteredSubjectDoesNotExist(Exception):
18
+ class RegisteredSubjectDoesNotExist(Exception): # noqa: N818
19
19
  pass
20
20
 
21
21
 
@@ -13,7 +13,7 @@ class AgeEvaluator(Evaluator):
13
13
  def __init__(
14
14
  self,
15
15
  age_lower: int | None = None,
16
- age_upper: int = None,
16
+ age_upper: int | None = None,
17
17
  age_units: str | None = None,
18
18
  age_lower_inclusive: bool | None = None,
19
19
  age_upper_inclusive: bool | None = None,
@@ -29,15 +29,15 @@ class AgeEvaluator(Evaluator):
29
29
  def __repr__(self) -> str:
30
30
  return f"{self.__class__.__name__}({self.description(show_as_int=True)})"
31
31
 
32
- def description(self, value: int = None, **kwargs):
32
+ def description(self, value: int | None = None, **kwargs):
33
33
  kwargs["show_as_int"] = True
34
34
  kwargs["placeholder"] = "AGE"
35
35
  return super().description(value=value, **kwargs)
36
36
 
37
37
  def in_bounds_or_raise(
38
38
  self,
39
- dob: date = None,
40
- report_datetime: datetime = None,
39
+ dob: date | None = None,
40
+ report_datetime: datetime | None = None,
41
41
  age_units: str | None = None,
42
42
  ) -> bool:
43
43
  report_datetime = report_datetime or timezone.now()
@@ -5,9 +5,9 @@ Creatinine Clearance14 or eGFR, Low
5
5
  *Report only one
6
6
  NA
7
7
  G1 N/A
8
- G2 < 90 to 60 ml/min or ml/min/1.73 m2 OR 10 to < 30% decrease from participants baseline
9
- G3 < 60 to 30 ml/min or ml/min/1.73 m2 OR 30 to < 50% decrease from participants baseline
10
- G4 < 30 ml/min or ml/min/1.73 m2 OR ≥ 50% decrease from participants baseline
8
+ G2 < 90 to 60 ml/min or ml/min/1.73 m2 OR 10 to < 30% decrease from participant's baseline
9
+ G3 < 60 to 30 ml/min or ml/min/1.73 m2 OR 30 to < 50% decrease from participant's baseline
10
+ G4 < 30 ml/min or ml/min/1.73 m2 OR ≥ 50% decrease from participant's baseline
11
11
  """
12
12
 
13
13
  from edc_constants.constants import FEMALE, MALE
@@ -6,40 +6,40 @@ from .constants import HIGH_VALUE
6
6
  from .exceptions import ValueBoundryError
7
7
 
8
8
 
9
- class InvalidUnits(Exception):
9
+ class InvalidUnits(Exception): # noqa: N818
10
10
  pass
11
11
 
12
12
 
13
- class InvalidLowerBound(Exception):
13
+ class InvalidLowerBound(Exception): # noqa: N818
14
14
  pass
15
15
 
16
16
 
17
- class InvalidLowerLimitNormal(Exception):
17
+ class InvalidLowerLimitNormal(Exception): # noqa: N818
18
18
  pass
19
19
 
20
20
 
21
- class InvalidUpperLimitNormal(Exception):
21
+ class InvalidUpperLimitNormal(Exception): # noqa: N818
22
22
  pass
23
23
 
24
24
 
25
- class InvalidUpperBound(Exception):
25
+ class InvalidUpperBound(Exception): # noqa: N818
26
26
  pass
27
27
 
28
28
 
29
- class InvalidCombination(Exception):
29
+ class InvalidCombination(Exception): # noqa: N818
30
30
  pass
31
31
 
32
32
 
33
33
  class Evaluator:
34
34
  def __init__(
35
35
  self,
36
- name: str = None,
37
- lower: int | float = None,
38
- upper: int | float = None,
39
- units: str = None,
36
+ name: str | None = None,
37
+ lower: int | float | None = None,
38
+ upper: int | float | None = None,
39
+ units: str | None = None,
40
40
  lower_inclusive: bool | None = None,
41
41
  upper_inclusive: bool | None = None,
42
- **kwargs,
42
+ **kwargs, # noqa: ARG002
43
43
  ) -> None:
44
44
  self.name = name
45
45
  if lower is not None and not re.match(r"\d+", str(lower)):
@@ -78,8 +78,8 @@ class Evaluator:
78
78
 
79
79
  def description(
80
80
  self,
81
- value: int | float = None,
82
- show_as_int: bool = None,
81
+ value: int | float | None = None,
82
+ show_as_int: bool | None = None,
83
83
  placeholder: str | None = None,
84
84
  ) -> str:
85
85
  placeholder = placeholder or "x"
@@ -98,7 +98,7 @@ class Evaluator:
98
98
  f"{self.upper_operator or ''}{upper} {self.units}"
99
99
  )
100
100
 
101
- def in_bounds_or_raise(self, value: int | float, units: str = None) -> bool:
101
+ def in_bounds_or_raise(self, value: int | float, units: str) -> bool:
102
102
  """Raises a ValueBoundryError exception if condition not met.
103
103
 
104
104
  The condition is evaluated to True or False as a string
@@ -116,6 +116,6 @@ class Evaluator:
116
116
  f"{'' if self.lower is None else self.lower}{self.lower_operator or ''}{value}"
117
117
  f"{self.upper_operator or ''}{'' if self.upper is None else self.upper}"
118
118
  )
119
- if not eval(condition_str): # nosec B307
119
+ if not eval(condition_str): # nosec B307 # noqa: S307
120
120
  raise ValueBoundryError(condition_str)
121
121
  return True
@@ -18,7 +18,7 @@ class SiteReportablesError(Exception):
18
18
  pass
19
19
 
20
20
 
21
- class AlreadyRegistered(Exception):
21
+ class AlreadyRegistered(Exception): # noqa: N818
22
22
  pass
23
23
 
24
24
 
@@ -30,13 +30,13 @@ class ValueBoundryError(Exception):
30
30
  pass
31
31
 
32
32
 
33
- class NotEvaluated(Exception):
33
+ class NotEvaluated(Exception): # noqa: N818
34
34
  pass
35
35
 
36
36
 
37
- class BoundariesOverlap(Exception):
37
+ class BoundariesOverlap(Exception): # noqa: N818
38
38
  pass
39
39
 
40
40
 
41
- class ConversionNotHandled(Exception):
41
+ class ConversionNotHandled(Exception): # noqa: N818
42
42
  pass
@@ -23,7 +23,10 @@ class ReportablesFormValidatorMixin:
23
23
  return {"age_units": "years"}
24
24
 
25
25
  def validate_reportable_fields(
26
- self, reference_range_collection_name: str, **reportables_evaluator_options
26
+ self,
27
+ reference_range_collection_name: str,
28
+ age_units: str | None = None,
29
+ **reportables_evaluator_options,
27
30
  ):
28
31
  """Called in clean() method of the FormValidator.
29
32
 
@@ -47,9 +50,10 @@ class ReportablesFormValidatorMixin:
47
50
  report_datetime=self.report_datetime,
48
51
  value_field_suffix=self.value_field_suffix,
49
52
  )
53
+ age_units = age_units or self.age_units
50
54
  options.update(**reportables_evaluator_options)
51
55
  reference_range_evaluator = self.reference_range_evaluator_cls(
52
- reference_range_collection_name, **options
56
+ reference_range_collection_name, age_units=age_units, **options
53
57
  )
54
58
  try:
55
59
  reference_range_evaluator.validate_reportable_fields()
@@ -50,5 +50,5 @@ class Command(BaseCommand):
50
50
  help="Export path/folder",
51
51
  )
52
52
 
53
- def handle(self, *args, **options):
53
+ def handle(self, *args, **options): # noqa: ARG002
54
54
  export_daids_grading(path=options["path"])
@@ -4,7 +4,6 @@ from edc_model.models import BaseUuidModel
4
4
 
5
5
 
6
6
  class GradingException(BaseUuidModel):
7
-
8
7
  reference_range_collection = models.ForeignKey(
9
8
  "edc_reportable.ReferenceRangeCollection", on_delete=models.PROTECT
10
9
  )
@@ -17,11 +16,7 @@ class GradingException(BaseUuidModel):
17
16
  grade4 = models.BooleanField(default=False)
18
17
 
19
18
  def grades(self) -> list[int]:
20
- grades = []
21
- for i in range(1, 5):
22
- if getattr(self, f"grade{i}"):
23
- grades.append(i)
24
- return grades
19
+ return [i for i in range(1, 5) if getattr(self, f"grade{i}")]
25
20
 
26
21
  class Meta(BaseUuidModel.Meta):
27
22
  verbose_name = "Grading Exception"
@@ -22,8 +22,8 @@ class NormalData(ReferenceModelMixin, BaseUuidModel):
22
22
  def value_in_normal_range_or_raise(
23
23
  self,
24
24
  value: int | float,
25
- dob: date = None,
26
- report_datetime: datetime = None,
25
+ dob: date,
26
+ report_datetime: datetime,
27
27
  age_units: str | None = None,
28
28
  ) -> bool:
29
29
  """Raises a ValueBoundryError exception if condition not met.
@@ -45,7 +45,7 @@ class NormalData(ReferenceModelMixin, BaseUuidModel):
45
45
  value_condition_str = self.get_eval_phrase(value)
46
46
  if not re.match(pattern, value_condition_str):
47
47
  raise ValueError(f"Invalid condition string. Got {value_condition_str}.")
48
- if not eval(value_condition_str): # nosec B307
48
+ if not eval(value_condition_str): # nosec B307 # noqa: S307
49
49
  raise ValueBoundryError(
50
50
  f"{self.label}: {value_condition_str}{self.units} [{self.gender}]"
51
51
  )
@@ -38,11 +38,7 @@ class ReferenceRangeCollection(BaseUuidModel):
38
38
 
39
39
  See also model GradingException.
40
40
  """
41
- grades = []
42
- for i in range(1, 5):
43
- if getattr(self, f"grade{i}"):
44
- grades.append(i)
45
- return grades
41
+ return [i for i in range(1, 5) if getattr(self, f"grade{i}")]
46
42
 
47
43
  def reportable_grades(self, label: str) -> list[int]:
48
44
  if not label:
@@ -96,7 +92,6 @@ class ReferenceRangeCollection(BaseUuidModel):
96
92
  gender: str | None = None,
97
93
  dob: date | None = None,
98
94
  age_units: str | None = None,
99
- site: Site | None = None,
100
95
  ) -> tuple[bool, NormalData]:
101
96
  if subject_identifier:
102
97
  rs_obj = RegisteredSubject.objects.get(subject_identifier=subject_identifier)
@@ -19,12 +19,12 @@ __all__ = ["get_grade_for_value"]
19
19
 
20
20
  def get_grade_for_value(
21
21
  reference_range_collection: ReferenceRangeCollection,
22
- value: float | int = None,
23
- label: str = None,
24
- units: str = None,
25
- gender: str = None,
26
- dob: date = None,
27
- report_datetime: datetime = None,
22
+ value: float | int | None = None,
23
+ label: str | None = None,
24
+ units: str | None = None,
25
+ gender: str | None = None,
26
+ dob: date | None = None,
27
+ report_datetime: datetime | None = None,
28
28
  age_units: str | None = None,
29
29
  site: Site | None = None,
30
30
  create_missing_normal: bool | None = None,
@@ -56,11 +56,11 @@ def get_grade_for_value(
56
56
  upper_limit = get_upper_limit(normal_data, grading_data)
57
57
  value = float(value)
58
58
  condition_str = (
59
- f'{"" if lower_limit is None else lower_limit}'
60
- f'{grading_data.lower_operator or ""}{value}'
61
- f'{grading_data.upper_operator or ""}{"" if upper_limit is None else upper_limit}'
59
+ f"{'' if lower_limit is None else lower_limit}"
60
+ f"{grading_data.lower_operator or ''}{value}"
61
+ f"{grading_data.upper_operator or ''}{'' if upper_limit is None else upper_limit}"
62
62
  )
63
- if eval(condition_str): # nosec B307
63
+ if eval(condition_str): # nosec B307 # noqa: S307
64
64
  if not found_grading_data:
65
65
  found_grading_data = grading_data
66
66
  found_condition_str = (
@@ -104,11 +104,11 @@ def get_upper_limit(
104
104
 
105
105
  def get_grading_data_instances(
106
106
  reference_range_collection: ReferenceRangeCollection,
107
- label: str = None,
108
- units: str = None,
109
- gender: str = None,
110
- dob: date = None,
111
- report_datetime: datetime = None,
107
+ label: str | None = None,
108
+ units: str | None = None,
109
+ gender: str | None = None,
110
+ dob: date | None = None,
111
+ report_datetime: datetime | None = None,
112
112
  age_units: str | None = None,
113
113
  site: Site | None = None,
114
114
  ) -> list[GradingData]:
@@ -25,11 +25,11 @@ __all__ = ["get_normal_data_or_raise"]
25
25
 
26
26
  def get_normal_data_or_raise(
27
27
  reference_range_collection: ReferenceRangeCollection = None,
28
- label: str = None,
29
- units: str = None,
30
- gender: str = None,
31
- dob: date = None,
32
- report_datetime: datetime = None,
28
+ label: str | None = None,
29
+ units: str | None = None,
30
+ gender: str | None = None,
31
+ dob: date | None = None,
32
+ report_datetime: datetime | None = None,
33
33
  age_units: str | None = None,
34
34
  site: Site | None = None,
35
35
  create_missing_normal: bool | None = None,
@@ -48,7 +48,7 @@ def get_normal_data_or_raise(
48
48
  units=units,
49
49
  age_units=age_units,
50
50
  )
51
- except ObjectDoesNotExist:
51
+ except ObjectDoesNotExist as e:
52
52
  if create_missing_normal:
53
53
  opts = dict(
54
54
  reference_range_collection=reference_range_collection,
@@ -68,23 +68,23 @@ def get_normal_data_or_raise(
68
68
  f"age={getattr(age_rdelta, age_units)}{age_units}. "
69
69
  "Perhaps add this to the default normal reference range data or "
70
70
  "pass 'create_missing=True' to convert an existing normal reference."
71
- )
72
- except MultipleObjectsReturned:
71
+ ) from e
72
+ except MultipleObjectsReturned as e:
73
73
  raise NotEvaluated(
74
74
  f"Value not evaluated. "
75
75
  f"Multiple normal references found for `{label}`. "
76
76
  f"Using units={units}, gender={gender}, age={getattr(age_rdelta, age_units)}. "
77
- )
77
+ ) from e
78
78
  return obj
79
79
 
80
80
 
81
81
  def create_obj_for_new_units_or_raise(
82
82
  reference_range_collection: ReferenceRangeCollection = None,
83
- label: str = None,
84
- units: str = None,
85
- gender: str = None,
86
- dob: date = None,
87
- report_datetime: datetime = None,
83
+ label: str | None = None,
84
+ units: str | None = None,
85
+ gender: str | None = None,
86
+ dob: date | None = None,
87
+ report_datetime: datetime | None = None,
88
88
  age_units: str | None = None,
89
89
  ) -> NormalData | None:
90
90
  opts = {}
@@ -14,12 +14,12 @@ __all__ = ["in_normal_bounds_or_raise"]
14
14
 
15
15
  def in_normal_bounds_or_raise(
16
16
  reference_range_collection: ReferenceRangeCollection = None,
17
- label: str = None,
18
- value: int | float = None,
19
- units: str = None,
20
- gender: str = None,
21
- dob: date = None,
22
- report_datetime: datetime = None,
17
+ label: str | None = None,
18
+ value: int | float | None = None,
19
+ units: str | None = None,
20
+ gender: str | None = None,
21
+ dob: date | None = None,
22
+ report_datetime: datetime | None = None,
23
23
  age_units: str | None = None,
24
24
  create_missing_normal: bool | None = None,
25
25
  ) -> bool:
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
18
18
  from ..models import ReferenceRangeCollection
19
19
 
20
20
 
21
- class AlreadyLoaded(Exception):
21
+ class AlreadyLoaded(Exception): # noqa: N818
22
22
  pass
23
23
 
24
24
 
@@ -21,12 +21,12 @@ def update_grading_exceptions(
21
21
  reference_range_collection=reference_range_collection
22
22
  ).delete()
23
23
  for label, grades in reportable_grades_exceptions.items():
24
- grades = [int(g) for g in grades]
24
+ grades = [int(g) for g in grades] # noqa: PLW2901
25
25
  grading_exception_model_cls().objects.get_or_create(
26
26
  reference_range_collection=reference_range_collection,
27
27
  label=label,
28
- grade1=True if 1 in grades else False,
29
- grade2=True if 2 in grades else False,
30
- grade3=True if 3 in grades else False,
31
- grade4=True if 4 in grades else False,
28
+ grade1=1 in grades,
29
+ grade2=2 in grades, # noqa: PLR2004
30
+ grade3=3 in grades, # noqa: PLR2004
31
+ grade4=4 in grades, # noqa: PLR2004
32
32
  )