sarj-python-lint 0.67.4__tar.gz → 0.67.6__tar.gz

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.
Files changed (99) hide show
  1. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/PKG-INFO +1 -1
  2. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/pyproject.toml +1 -1
  3. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/kwarg_heavy_construction_in_test.py +24 -2
  4. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_library_fake.py +10 -1
  5. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_timedelta_for_durations.py +7 -0
  6. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/.gitignore +0 -0
  7. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/LICENSE +0 -0
  8. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/README.md +0 -0
  9. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/__init__.py +0 -0
  10. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/__main__.py +0 -0
  11. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/_filesystem.py +0 -0
  12. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/_ratchet_cli.py +0 -0
  13. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/_secret_names.py +0 -0
  14. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/_version.py +0 -0
  15. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/py.typed +0 -0
  16. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/ratchet.py +0 -0
  17. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rule_base.py +0 -0
  18. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/__init__.py +0 -0
  19. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_ast_index.py +0 -0
  20. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_comments.py +0 -0
  21. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_docstrings.py +0 -0
  22. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_fastapi.py +0 -0
  23. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_first_party.py +0 -0
  24. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_imports.py +0 -0
  25. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_logging.py +0 -0
  26. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_paths.py +0 -0
  27. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_prose_budget.py +0 -0
  28. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_pytest.py +0 -0
  29. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_registry.py +0 -0
  30. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_sql.py +0 -0
  31. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_suppression_comments.py +0 -0
  32. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/_test_assertions.py +0 -0
  33. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/defect_xfail_requires_strict.py +0 -0
  34. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/docstring_args_restate_signature.py +0 -0
  35. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/docstring_returns_restate_signature.py +0 -0
  36. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/duplicate_test_body.py +0 -0
  37. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/duplicated_override_docstring.py +0 -0
  38. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/fastapi_openapi_contract.py +0 -0
  39. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/fixture_returns_bare_tuple.py +0 -0
  40. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/invalid_pydantic_field_default.py +0 -0
  41. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/mock_without_spec.py +0 -0
  42. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_aggregation_in_store_query.py +0 -0
  43. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_comment_cruft.py +0 -0
  44. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_cors_wildcard_with_credentials.py +0 -0
  45. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_duplicate_dunder_all_entry.py +0 -0
  46. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_file_level_escape_hatch_noqa.py +0 -0
  47. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_file_level_suppression.py +0 -0
  48. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_first_party_private_import.py +0 -0
  49. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_frozen_after_validator_field_write.py +0 -0
  50. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_gen_random_uuid_in_sql.py +0 -0
  51. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_generic_single_export_module.py +0 -0
  52. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_hidden_constructor_fallback.py +0 -0
  53. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_isinstance_union_chain.py +0 -0
  54. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_long_comment.py +0 -0
  55. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_offset_pagination.py +0 -0
  56. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_optional_tenant_predicate.py +0 -0
  57. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_query_with_many_joins.py +0 -0
  58. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_repeated_string_literal.py +0 -0
  59. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_restated_comment.py +0 -0
  60. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_secret_in_log.py +0 -0
  61. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_select_star.py +0 -0
  62. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_sentinel_return_on_except.py +0 -0
  63. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_stdlib_logging.py +0 -0
  64. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_string_concat_in_loop.py +0 -0
  65. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_tautological_expect.py +0 -0
  66. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/no_typed_doc_sections.py +0 -0
  67. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/opaque_parametrize_case_needs_id.py +0 -0
  68. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/over_mocked_test.py +0 -0
  69. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/phase_label_comment.py +0 -0
  70. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_class_row.py +0 -0
  71. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_constant_time_secret_compare.py +0 -0
  72. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_fstring_over_concat.py +0 -0
  73. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_immutable_module_constant.py +0 -0
  74. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_match_assert_never.py +0 -0
  75. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_match_type_dispatch.py +0 -0
  76. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_module_level_constant.py +0 -0
  77. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_namedtuple_over_tuple_return.py +0 -0
  78. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_nominal_id_types.py +0 -0
  79. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_non_nullable_collection.py +0 -0
  80. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_or_pattern.py +0 -0
  81. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_self_documenting_constant.py +0 -0
  82. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_self_type_annotation.py +0 -0
  83. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_str_enum.py +0 -0
  84. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_struct_over_namedtuple.py +0 -0
  85. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_walrus_comprehension_filter.py +0 -0
  86. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_walrus_regex_match.py +0 -0
  87. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/prefer_walrus_stream_loop.py +0 -0
  88. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/pydantic_at_boundaries.py +0 -0
  89. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/redundant_class_docstring.py +0 -0
  90. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/redundant_docstring.py +0 -0
  91. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/redundant_module_docstring.py +0 -0
  92. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/require_keyword_only_swap_prone_params.py +0 -0
  93. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/require_port_for_service.py +0 -0
  94. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/restated_test_docstring.py +0 -0
  95. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/stepdown.py +0 -0
  96. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/store_insert_requires_on_conflict.py +0 -0
  97. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/trailing_value_narration.py +0 -0
  98. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/trivially_true_assertion.py +0 -0
  99. {sarj_python_lint-0.67.4 → sarj_python_lint-0.67.6}/src/sarj_python_lint/rules/unused_mock_setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sarj-python-lint
3
- Version: 0.67.4
3
+ Version: 0.67.6
4
4
  Summary: Custom Python lint rules — AST-based, pre-commit-friendly, hypermodern defaults
5
5
  Project-URL: Homepage, https://code-standards.sarj.ai/rules/python/
6
6
  Project-URL: Documentation, https://code-standards.sarj.ai/rules/python/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sarj-python-lint"
3
- version = "0.67.4"
3
+ version = "0.67.6"
4
4
  description = "Custom Python lint rules — AST-based, pre-commit-friendly, hypermodern defaults"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "sarj-ai" }]
@@ -65,7 +65,18 @@ class KwargHeavyConstructionInTest(Rule):
65
65
  files=(
66
66
  ExampleFile.python(
67
67
  "tests/test_call.py",
68
- "def test_first():\n assert Call(a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8, i=9)\n\ndef test_second():\n assert Call(a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8, i=9)\n",
68
+ "def test_style():\n"
69
+ " style = Style(\n"
70
+ ' color="red", bgcolor="black", bold=True, dim=True, italic=True,\n'
71
+ " underline=True, blink=True, blink2=True, reverse=True,\n"
72
+ " )\n"
73
+ " assert str(style)\n\n"
74
+ "def test_style_again():\n"
75
+ " other = Style(\n"
76
+ ' color="blue", bgcolor="white", bold=False, dim=True, italic=True,\n'
77
+ " underline=True, blink=True, blink2=True, reverse=True,\n"
78
+ " )\n"
79
+ " assert str(other)\n",
69
80
  ),
70
81
  ),
71
82
  focus_path=PurePosixPath("tests/test_call.py"),
@@ -79,7 +90,18 @@ class KwargHeavyConstructionInTest(Rule):
79
90
  files=(
80
91
  ExampleFile.python(
81
92
  "tests/test_call.py",
82
- "def build_call(**overrides):\n return Call(**overrides)\n\ndef test_first():\n assert build_call(a=1)\n",
93
+ "def build_style(**overrides):\n"
94
+ " defaults = dict(\n"
95
+ " dim=True, italic=True, underline=True,\n"
96
+ " blink=True, blink2=True, reverse=True,\n"
97
+ " )\n"
98
+ " return Style(**(defaults | overrides))\n\n"
99
+ "def test_style():\n"
100
+ ' style = build_style(color="red", bgcolor="black", bold=True)\n'
101
+ " assert str(style)\n\n"
102
+ "def test_style_again():\n"
103
+ ' other = build_style(color="blue", bgcolor="white", bold=False)\n'
104
+ " assert str(other)\n",
83
105
  ),
84
106
  ),
85
107
  focus_path=PurePosixPath("tests/test_call.py"),
@@ -297,7 +297,16 @@ class PreferLibraryFake(Rule):
297
297
  files=(
298
298
  ExampleFile.python(
299
299
  "tests/fakes/s3.py",
300
- "class FakeS3Client:\n def put_object(self, **kwargs):\n return kwargs\n\n def get_object(self, **kwargs):\n return kwargs\n\n def delete_object(self, **kwargs):\n return kwargs\n",
300
+ "class FakeS3Client:\n"
301
+ " def __init__(self):\n"
302
+ " self.objects = {}\n\n"
303
+ " def put_object(self, Bucket, Key, Body):\n"
304
+ " self.objects[(Bucket, Key)] = Body\n"
305
+ ' return {"ResponseMetadata": {"HTTPStatusCode": 200}}\n\n'
306
+ " def get_object(self, Bucket, Key):\n"
307
+ ' return {"Body": self.objects[(Bucket, Key)]}\n\n'
308
+ " def delete_object(self, Bucket, Key):\n"
309
+ " self.objects.pop((Bucket, Key), None)\n",
301
310
  ),
302
311
  ),
303
312
  focus_path=PurePosixPath("tests/fakes/s3.py"),
@@ -46,6 +46,11 @@ _EXCLUDE_RE = re.compile(
46
46
  re.IGNORECASE,
47
47
  )
48
48
 
49
+ # Standard HTTP status symbols describe integer protocol codes, even when the
50
+ # reason phrase contains a duration-shaped word (for example, 408 Request
51
+ # Timeout). Requiring ``timedelta`` here would change the public wire value.
52
+ _HTTP_STATUS_CONSTANT_RE = re.compile(r"^HTTP_[1-5]\d{2}(?:_|$)", re.IGNORECASE)
53
+
49
54
  _NUMERIC_NAMES = frozenset({"int", "float"})
50
55
  _BARE_UNIT_NAMES = frozenset(
51
56
  {
@@ -181,6 +186,8 @@ class PreferTimedeltaForDurations(Rule):
181
186
  ) -> None:
182
187
  if annotation is None:
183
188
  return
189
+ if _HTTP_STATUS_CONSTANT_RE.search(name):
190
+ return
184
191
  if name.lower() in _BARE_UNIT_NAMES or name.lower().endswith(("_worked", "_elapsed")):
185
192
  return
186
193
  if not _UNIT_RE.search(name) or _EXCLUDE_RE.search(name):