flake8-elegant-objects 1.1.0__tar.gz → 1.1.1__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 (48) hide show
  1. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/CHANGELOG.md +6 -0
  2. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/PKG-INFO +1 -1
  3. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/__init__.py +1 -1
  4. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_constructor_code.py +14 -0
  5. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/pyproject.toml +1 -1
  6. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_constructor_code.py +61 -0
  7. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/.claude/settings.local.json +0 -0
  8. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/.github/workflows/lint.yml +0 -0
  9. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/.github/workflows/publish.yml +0 -0
  10. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/.github/workflows/test.yml +0 -0
  11. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/.gitignore +0 -0
  12. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/CLAUDE.md +0 -0
  13. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/LICENSE +0 -0
  14. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/README.md +0 -0
  15. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/docs/EO011.md +0 -0
  16. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/__main__.py +0 -0
  17. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/base.py +0 -0
  18. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_er_name.py +0 -0
  19. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_getters_setters.py +0 -0
  20. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_implementation_inheritance.py +0 -0
  21. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_impure_tests.py +0 -0
  22. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/__init__.py +0 -0
  23. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/base.py +0 -0
  24. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/contract_checker.py +0 -0
  25. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/copy_on_write_checker.py +0 -0
  26. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/core.py +0 -0
  27. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/deep_checker.py +0 -0
  28. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/factory_checker.py +0 -0
  29. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/pattern_detectors.py +0 -0
  30. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_mutable_objects/shared_state_checker.py +0 -0
  31. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_null.py +0 -0
  32. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_orm.py +0 -0
  33. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_public_methods_without_contracts.py +0 -0
  34. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_static.py +0 -0
  35. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/flake8_elegant_objects/no_type_discrimination.py +0 -0
  36. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/__init__.py +0 -0
  37. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_integration.py +0 -0
  38. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_er_name.py +0 -0
  39. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_getters_setters.py +0 -0
  40. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_implementation_inheritance.py +0 -0
  41. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_impure_tests.py +0 -0
  42. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_mutable_objects.py +0 -0
  43. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_null.py +0 -0
  44. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_orm.py +0 -0
  45. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_public_methods_without_contracts.py +0 -0
  46. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_static.py +0 -0
  47. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/tests/test_no_type_discrimination.py +0 -0
  48. {flake8_elegant_objects-1.1.0 → flake8_elegant_objects-1.1.1}/uv.lock +0 -0
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.1] - 2024-06-30
9
+
10
+ ### Minor release
11
+
12
+ - `EO006`: Allow `super()` calls in constructor
13
+
8
14
  ## [1.1.0] - 2024-06-28
9
15
 
10
16
  ### 🚀 Major Enhancements
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flake8-elegant-objects
3
- Version: 1.1.0
3
+ Version: 1.1.1
4
4
  Summary: Flake8 plugin enforcing Elegant Objects principles: no -er naming, no null, no getters/setters, immutable objects
5
5
  Project-URL: Homepage, https://github.com/AntonProkopyev/flake8-elegant-objects
6
6
  Project-URL: Repository, https://github.com/AntonProkopyev/flake8-elegant-objects.git
@@ -17,7 +17,7 @@ class ElegantObjectsPlugin:
17
17
  """Flake8 plugin to check for Elegant Objects violations."""
18
18
 
19
19
  name = "flake8-elegant-objects"
20
- version = "1.0.0"
20
+ version = "1.1.1"
21
21
 
22
22
  def __init__(self, tree: ast.AST) -> None:
23
23
  self.tree = tree
@@ -39,7 +39,21 @@ class NoConstructorCode:
39
39
  violations.extend(violation(stmt, ErrorCodes.EO006))
40
40
  else:
41
41
  violations.extend(violation(stmt, ErrorCodes.EO006))
42
+ elif isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Call):
43
+ if self._is_super_call(stmt.value):
44
+ continue
45
+ violations.extend(violation(stmt, ErrorCodes.EO006))
42
46
  elif not isinstance(stmt, ast.Pass): # Allow pass statements
43
47
  violations.extend(violation(stmt, ErrorCodes.EO006))
44
48
 
45
49
  return violations
50
+
51
+ def _is_super_call(self, call: ast.Call) -> bool:
52
+ """Check if a call is a super() call."""
53
+ if isinstance(call.func, ast.Name) and call.func.id == "super":
54
+ return True
55
+ if isinstance(call.func, ast.Attribute) and isinstance(
56
+ call.func.value, ast.Call
57
+ ):
58
+ return self._is_super_call(call.func.value)
59
+ return False
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "flake8-elegant-objects"
7
- version = "1.1.0"
7
+ version = "1.1.1"
8
8
  description = "Flake8 plugin enforcing Elegant Objects principles: no -er naming, no null, no getters/setters, immutable objects"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -127,6 +127,67 @@ class DataContainer:
127
127
  self.items = items
128
128
  self.count = len(items) # This should trigger violation
129
129
  self.first = items[0] if items else None # This should trigger violation
130
+ """
131
+ violations = self._check_code(code)
132
+ assert len(violations) == 2
133
+ assert all("EO006" in v for v in violations)
134
+
135
+ def test_valid_constructor_with_super_call(self) -> None:
136
+ """Test that super() calls in constructors are allowed."""
137
+ code = """
138
+ class Parent:
139
+ def __init__(self, name):
140
+ self.name = name
141
+
142
+ class Child(Parent):
143
+ def __init__(self, name, age):
144
+ super().__init__(name)
145
+ self.age = age
146
+
147
+ class GrandChild(Child):
148
+ def __init__(self, name, age, grade):
149
+ super().__init__(name, age)
150
+ self.grade = grade
151
+ """
152
+ violations = self._check_code(code)
153
+ assert len(violations) == 0
154
+
155
+ def test_valid_constructor_with_super_call_variations(self) -> None:
156
+ """Test various forms of super() calls are allowed."""
157
+ code = """
158
+ class Base:
159
+ def __init__(self):
160
+ pass
161
+
162
+ class Derived(Base):
163
+ def __init__(self):
164
+ super().__init__()
165
+
166
+ class DerivedWithArgs(Base):
167
+ def __init__(self, value):
168
+ super().__init__()
169
+ self.value = value
170
+
171
+ class ExplicitSuper(Base):
172
+ def __init__(self):
173
+ super(ExplicitSuper, self).__init__()
174
+ """
175
+ violations = self._check_code(code)
176
+ assert len(violations) == 0
177
+
178
+ def test_constructor_with_super_and_invalid_code(self) -> None:
179
+ """Test that super() calls are allowed but other code violations are still detected."""
180
+ code = """
181
+ class Parent:
182
+ def __init__(self, name):
183
+ self.name = name
184
+
185
+ class Child(Parent):
186
+ def __init__(self, name, items):
187
+ super().__init__(name)
188
+ self.items = items
189
+ self.count = len(items) # This should trigger violation
190
+ print("Child initialized") # This should trigger violation
130
191
  """
131
192
  violations = self._check_code(code)
132
193
  assert len(violations) == 2