Skip to content

Commit c7cde12

Browse files
committed
Unify preflight msg and hint into fix
1 parent cd96c97 commit c7cde12

File tree

18 files changed

+233
-294
lines changed

18 files changed

+233
-294
lines changed

plain-flags/plain/flags/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def get_number(self):
2424
return len(self.flag_errors)
2525

2626
def get_text(self):
27-
return "\n".join(str(e.msg) for e in self.flag_errors)
27+
return "\n".join(str(e.message) for e in self.flag_errors)
2828

2929

3030
@register_viewset

plain-flags/plain/flags/models.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,9 @@ def preflight(cls):
9595
except FlagImportError:
9696
errors.append(
9797
PreflightResult(
98-
f"Flag {flag_name} is not used.",
99-
hint=f"Remove the flag from the database or define it in the {settings.FLAGS_MODULE} module.",
98+
fix=f"Flag {flag_name} is not used. Remove the flag from the database or define it in the {settings.FLAGS_MODULE} module.",
10099
warning=True,
101-
id="plain.flags.I001",
100+
id="flags.unused_flags",
102101
)
103102
)
104103

plain-models/plain/models/backends/mysql/validation.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@ def _check_sql_mode(self):
1414
):
1515
return [
1616
preflight.PreflightResult(
17-
f"{self.connection.display_name} Strict Mode is not set for the database connection",
18-
hint=(
19-
f"{self.connection.display_name}'s Strict Mode fixes many data integrity problems in "
20-
f"{self.connection.display_name}, such as data truncation upon insertion, by "
21-
"escalating warnings into errors. It is strongly "
22-
"recommended you activate it."
23-
),
17+
fix=f"{self.connection.display_name} Strict Mode is not set for the database connection. "
18+
f"{self.connection.display_name}'s Strict Mode fixes many data integrity problems in "
19+
f"{self.connection.display_name}, such as data truncation upon insertion, by "
20+
"escalating warnings into errors. It is strongly "
21+
"recommended you activate it.",
2422
id="mysql.strict_mode_not_enabled",
2523
warning=True,
2624
)
@@ -42,7 +40,7 @@ def check_field_type(self, field, field_type):
4240
):
4341
errors.append(
4442
preflight.PreflightResult(
45-
f"{self.connection.display_name} may not allow unique CharFields to have a max_length "
43+
fix=f"{self.connection.display_name} may not allow unique CharFields to have a max_length "
4644
"> 255.",
4745
obj=field,
4846
id="mysql.unique_charfield_max_length_too_long",

plain-models/plain/models/base.py

Lines changed: 54 additions & 79 deletions
Large diffs are not rendered by default.

plain-models/plain/models/fields/__init__.py

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -232,23 +232,23 @@ def _check_field_name(self):
232232
if self.name.endswith("_"):
233233
return [
234234
PreflightResult(
235-
"Field names must not end with an underscore.",
235+
fix="Field names must not end with an underscore.",
236236
obj=self,
237237
id="fields.name_ends_with_underscore",
238238
)
239239
]
240240
elif LOOKUP_SEP in self.name:
241241
return [
242242
PreflightResult(
243-
f'Field names must not contain "{LOOKUP_SEP}".',
243+
fix=f'Field names must not contain "{LOOKUP_SEP}".',
244244
obj=self,
245245
id="fields.name_contains_lookup_separator",
246246
)
247247
]
248248
elif self.name == "id":
249249
return [
250250
PreflightResult(
251-
"'id' is a reserved word that cannot be used as a field name.",
251+
fix="'id' is a reserved word that cannot be used as a field name.",
252252
obj=self,
253253
id="fields.reserved_field_name_id",
254254
)
@@ -267,7 +267,7 @@ def _check_choices(self):
267267
if not is_iterable(self.choices) or isinstance(self.choices, str):
268268
return [
269269
PreflightResult(
270-
"'choices' must be an iterable (e.g., a list or tuple).",
270+
fix="'choices' must be an iterable (e.g., a list or tuple).",
271271
obj=self,
272272
id="fields.choices_not_iterable",
273273
)
@@ -315,7 +315,7 @@ def _check_choices(self):
315315
if self.max_length is not None and choice_max_length > self.max_length:
316316
return [
317317
PreflightResult(
318-
"'max_length' is too small to fit the longest value " # noqa: UP031
318+
fix="'max_length' is too small to fit the longest value " # noqa: UP031
319319
"in 'choices' (%d characters)." % choice_max_length,
320320
obj=self,
321321
id="fields.max_length_too_small_for_choices",
@@ -325,7 +325,7 @@ def _check_choices(self):
325325

326326
return [
327327
PreflightResult(
328-
"'choices' must be an iterable containing "
328+
fix="'choices' must be an iterable containing "
329329
"(actual value, human readable name) tuples.",
330330
obj=self,
331331
id="fields.choices_invalid_format",
@@ -342,7 +342,7 @@ def _check_db_comment(self):
342342
):
343343
errors.append(
344344
PreflightResult(
345-
f"{db_connection.display_name} does not support comments on "
345+
fix=f"{db_connection.display_name} does not support comments on "
346346
f"columns (db_comment).",
347347
obj=self,
348348
id="fields.db_comment_unsupported",
@@ -358,11 +358,9 @@ def _check_null_allowed_for_primary_keys(self):
358358
# character-based fields a little differently).
359359
return [
360360
PreflightResult(
361-
"Primary keys must not have allow_null=True.",
362-
hint=(
363-
"Set allow_null=False on the field, or "
364-
"remove primary_key=True argument."
365-
),
361+
fix="Primary keys must not have allow_null=True. "
362+
"Set allow_null=False on the field, or "
363+
"remove primary_key=True argument.",
366364
obj=self,
367365
id="fields.primary_key_allows_null",
368366
)
@@ -381,8 +379,8 @@ def _check_validators(self):
381379
if not callable(validator):
382380
errors.append(
383381
PreflightResult(
384-
"All 'validators' must be callable.",
385-
hint=(
382+
fix=(
383+
"All 'validators' must be callable. "
386384
f"validators[{i}] ({repr(validator)}) isn't a function or "
387385
"instance of a validator class."
388386
),
@@ -969,7 +967,7 @@ def _check_max_length_attribute(self, **kwargs):
969967
return []
970968
return [
971969
PreflightResult(
972-
"CharFields must define a 'max_length' attribute.",
970+
fix="CharFields must define a 'max_length' attribute.",
973971
obj=self,
974972
id="fields.charfield_missing_max_length",
975973
)
@@ -981,7 +979,7 @@ def _check_max_length_attribute(self, **kwargs):
981979
):
982980
return [
983981
PreflightResult(
984-
"'max_length' must be a positive integer.",
982+
fix="'max_length' must be a positive integer.",
985983
obj=self,
986984
id="fields.charfield_invalid_max_length",
987985
)
@@ -999,7 +997,7 @@ def _check_db_collation(self):
999997
):
1000998
errors.append(
1001999
PreflightResult(
1002-
f"{db_connection.display_name} does not support a database collation on "
1000+
fix=f"{db_connection.display_name} does not support a database collation on "
10031001
"CharFields.",
10041002
obj=self,
10051003
id="fields.db_collation_unsupported",
@@ -1069,7 +1067,7 @@ def _check_mutually_exclusive_options(self):
10691067
if enabled_options > 1:
10701068
return [
10711069
PreflightResult(
1072-
"The options auto_now, auto_now_add, and default "
1070+
fix="The options auto_now, auto_now_add, and default "
10731071
"are mutually exclusive. Only one of these options "
10741072
"may be present.",
10751073
obj=self,
@@ -1105,13 +1103,11 @@ def _check_if_value_fixed(self, value, now=None):
11051103
if lower <= value <= upper:
11061104
return [
11071105
PreflightResult(
1108-
"Fixed default value provided.",
1109-
hint=(
1110-
"It seems you set a fixed date / time / datetime "
1111-
"value as default for this field. This may not be "
1112-
"what you want. If you want to have the current date "
1113-
"as default, use `plain.utils.timezone.now`"
1114-
),
1106+
fix="Fixed default value provided. "
1107+
"It seems you set a fixed date / time / datetime "
1108+
"value as default for this field. This may not be "
1109+
"what you want. If you want to have the current date "
1110+
"as default, use `plain.utils.timezone.now`",
11151111
obj=self,
11161112
id="fields.datetime_naive_default_value",
11171113
warning=True,
@@ -1395,15 +1391,15 @@ def _check_decimal_places(self):
13951391
except TypeError:
13961392
return [
13971393
PreflightResult(
1398-
"DecimalFields must define a 'decimal_places' attribute.",
1394+
fix="DecimalFields must define a 'decimal_places' attribute.",
13991395
obj=self,
14001396
id="fields.decimalfield_missing_decimal_places",
14011397
)
14021398
]
14031399
except ValueError:
14041400
return [
14051401
PreflightResult(
1406-
"'decimal_places' must be a non-negative integer.",
1402+
fix="'decimal_places' must be a non-negative integer.",
14071403
obj=self,
14081404
id="fields.decimalfield_invalid_decimal_places",
14091405
)
@@ -1419,15 +1415,15 @@ def _check_max_digits(self):
14191415
except TypeError:
14201416
return [
14211417
PreflightResult(
1422-
"DecimalFields must define a 'max_digits' attribute.",
1418+
fix="DecimalFields must define a 'max_digits' attribute.",
14231419
obj=self,
14241420
id="fields.decimalfield_missing_max_digits",
14251421
)
14261422
]
14271423
except ValueError:
14281424
return [
14291425
PreflightResult(
1430-
"'max_digits' must be a positive integer.",
1426+
fix="'max_digits' must be a positive integer.",
14311427
obj=self,
14321428
id="fields.decimalfield_invalid_max_digits",
14331429
)
@@ -1439,7 +1435,7 @@ def _check_decimal_places_and_max_digits(self):
14391435
if int(self.decimal_places) > int(self.max_digits):
14401436
return [
14411437
PreflightResult(
1442-
"'max_digits' must be greater or equal to 'decimal_places'.",
1438+
fix="'max_digits' must be greater or equal to 'decimal_places'.",
14431439
obj=self,
14441440
id="fields.decimalfield_decimal_places_exceeds_max_digits",
14451441
)
@@ -1624,8 +1620,7 @@ def _check_max_length_warning(self):
16241620
if self.max_length is not None:
16251621
return [
16261622
PreflightResult(
1627-
f"'max_length' is ignored when used with {self.__class__.__name__}.",
1628-
hint="Remove 'max_length' from field",
1623+
fix=f"'max_length' is ignored when used with {self.__class__.__name__}. Remove 'max_length' from field.",
16291624
obj=self,
16301625
id="fields.max_length_ignored",
16311626
warning=True,
@@ -1747,7 +1742,7 @@ def _check_required_and_null_values(self):
17471742
):
17481743
return [
17491744
PreflightResult(
1750-
"GenericIPAddressFields cannot have required=False if allow_null=False, "
1745+
fix="GenericIPAddressFields cannot have required=False if allow_null=False, "
17511746
"as blank values are stored as nulls.",
17521747
obj=self,
17531748
id="fields.generic_ip_field_null_blank_config",
@@ -1869,7 +1864,7 @@ def _check_db_collation(self):
18691864
):
18701865
errors.append(
18711866
PreflightResult(
1872-
f"{db_connection.display_name} does not support a database collation on "
1867+
fix=f"{db_connection.display_name} does not support a database collation on "
18731868
"TextFields.",
18741869
obj=self,
18751870
id="fields.db_collation_unsupported",
@@ -2032,7 +2027,7 @@ def _check_str_default_value(self):
20322027
if self.has_default() and isinstance(self.default, str):
20332028
return [
20342029
PreflightResult(
2035-
"BinaryField's default cannot be a string. Use bytes "
2030+
fix="BinaryField's default cannot be a string. Use bytes "
20362031
"content instead.",
20372032
obj=self,
20382033
id="fields.filefield_upload_to_not_callable",

plain-models/plain/models/fields/json.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class JSONField(CheckFieldDefaultMixin, Field):
2323
default_error_messages = {
2424
"invalid": "Value must be valid JSON.",
2525
}
26-
_default_hint = ("dict", "{}")
26+
_default_fix = ("dict", "{}")
2727

2828
def __init__(
2929
self,
@@ -60,7 +60,7 @@ def _check_supported(self):
6060
):
6161
errors.append(
6262
preflight.PreflightResult(
63-
f"{db_connection.display_name} does not support JSONFields.",
63+
fix=f"{db_connection.display_name} does not support JSONFields. Consider using a TextField with JSON serialization or upgrade to a database that supports JSON fields.",
6464
obj=self.model,
6565
id="fields.json_field_unsupported",
6666
)

plain-models/plain/models/fields/mixins.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def delete_cached_value(self, instance):
2929

3030

3131
class CheckFieldDefaultMixin:
32-
_default_hint = ("<valid default>", "<invalid default>")
32+
_default_fix = ("<valid default>", "<invalid default>")
3333

3434
def _check_default(self):
3535
if (
@@ -39,11 +39,11 @@ def _check_default(self):
3939
):
4040
return [
4141
PreflightResult(
42-
f"{self.__class__.__name__} default should be a callable instead of an instance "
43-
"so that it's not shared between all field instances.",
44-
hint=(
42+
fix=(
43+
f"{self.__class__.__name__} default should be a callable instead of an instance "
44+
"so that it's not shared between all field instances. "
4545
"Use a callable instead, e.g., use `{}` instead of "
46-
"`{}`.".format(*self._default_hint)
46+
"`{}`.".format(*self._default_fix)
4747
),
4848
obj=self,
4949
id="fields.invalid_choice_mixin_default",

0 commit comments

Comments
 (0)