@@ -29,9 +29,363 @@ dependencies = ["homeassistant", "plugwise"]
2929"Source Code" = " https://github.com/plugwise/plugwise-beta"
3030"Bug Reports" = " https://github.com/plugwise/plugwise-beta/issues"
3131
32- [tool .black ]
33- target-version = [" py312" ]
34- exclude = ' generated'
32+ [tool .pylint .MAIN ]
33+ py-version = " 3.12"
34+ # Use a conservative default here; 2 should speed up most setups and not hurt
35+ # any too bad. Override on command line as appropriate.
36+ jobs = 2
37+ init-hook = """ \
38+ from pathlib import Path; \
39+ import sys; \
40+
41+ from pylint.config import find_default_config_files; \
42+
43+ sys.path.append( \
44+ str(Path(next(find_default_config_files())).parent.joinpath('pylint/plugins'))
45+ ) \
46+ """
47+ load-plugins = [
48+ " pylint.extensions.code_style" ,
49+ " pylint.extensions.typing" ,
50+ " hass_enforce_class_module" ,
51+ " hass_enforce_sorted_platforms" ,
52+ " hass_enforce_super_call" ,
53+ " hass_enforce_type_hints" ,
54+ " hass_inheritance" ,
55+ " hass_imports" ,
56+ " hass_logger" ,
57+ " pylint_per_file_ignores" ,
58+ ]
59+ persistent = false
60+ extension-pkg-allow-list = [
61+ " av.audio.stream" ,
62+ " av.logging" ,
63+ " av.stream" ,
64+ " ciso8601" ,
65+ " orjson" ,
66+ " cv2" ,
67+ ]
68+ fail-on = [
69+ " I" ,
70+ ]
71+
72+ [tool .pylint .BASIC ]
73+ class-const-naming-style = " any"
74+
75+ [tool .pylint ."MESSAGES CONTROL" ]
76+ # Reasons disabled:
77+ # format - handled by ruff
78+ # locally-disabled - it spams too much
79+ # duplicate-code - unavoidable
80+ # cyclic-import - doesn't test if both import on load
81+ # abstract-class-little-used - prevents from setting right foundation
82+ # unused-argument - generic callbacks and setup methods create a lot of warnings
83+ # too-many-* - are not enforced for the sake of readability
84+ # too-few-* - same as too-many-*
85+ # abstract-method - with intro of async there are always methods missing
86+ # inconsistent-return-statements - doesn't handle raise
87+ # too-many-ancestors - it's too strict.
88+ # wrong-import-order - isort guards this
89+ # possibly-used-before-assignment - too many errors / not necessarily issues
90+ # ---
91+ # Pylint CodeStyle plugin
92+ # consider-using-namedtuple-or-dataclass - too opinionated
93+ # consider-using-assignment-expr - decision to use := better left to devs
94+ disable = [
95+ " format" ,
96+ " abstract-method" ,
97+ " cyclic-import" ,
98+ " duplicate-code" ,
99+ " inconsistent-return-statements" ,
100+ " locally-disabled" ,
101+ " not-context-manager" ,
102+ " too-few-public-methods" ,
103+ " too-many-ancestors" ,
104+ " too-many-arguments" ,
105+ " too-many-instance-attributes" ,
106+ " too-many-lines" ,
107+ " too-many-locals" ,
108+ " too-many-public-methods" ,
109+ " too-many-boolean-expressions" ,
110+ " too-many-positional-arguments" ,
111+ " wrong-import-order" ,
112+ " consider-using-namedtuple-or-dataclass" ,
113+ " consider-using-assignment-expr" ,
114+ " possibly-used-before-assignment" ,
115+
116+ # Handled by ruff
117+ # Ref: <https://github.com/astral-sh/ruff/issues/970>
118+ " await-outside-async" , # PLE1142
119+ " bad-str-strip-call" , # PLE1310
120+ " bad-string-format-type" , # PLE1307
121+ " bidirectional-unicode" , # PLE2502
122+ " continue-in-finally" , # PLE0116
123+ " duplicate-bases" , # PLE0241
124+ " misplaced-bare-raise" , # PLE0704
125+ " format-needs-mapping" , # F502
126+ " function-redefined" , # F811
127+ # Needed because ruff does not understand type of __all__ generated by a function
128+ # "invalid-all-format", # PLE0605
129+ " invalid-all-object" , # PLE0604
130+ " invalid-character-backspace" , # PLE2510
131+ " invalid-character-esc" , # PLE2513
132+ " invalid-character-nul" , # PLE2514
133+ " invalid-character-sub" , # PLE2512
134+ " invalid-character-zero-width-space" , # PLE2515
135+ " logging-too-few-args" , # PLE1206
136+ " logging-too-many-args" , # PLE1205
137+ " missing-format-string-key" , # F524
138+ " mixed-format-string" , # F506
139+ " no-method-argument" , # N805
140+ " no-self-argument" , # N805
141+ " nonexistent-operator" , # B002
142+ " nonlocal-without-binding" , # PLE0117
143+ " not-in-loop" , # F701, F702
144+ " notimplemented-raised" , # F901
145+ " return-in-init" , # PLE0101
146+ " return-outside-function" , # F706
147+ " syntax-error" , # E999
148+ " too-few-format-args" , # F524
149+ " too-many-format-args" , # F522
150+ " too-many-star-expressions" , # F622
151+ " truncated-format-string" , # F501
152+ " undefined-all-variable" , # F822
153+ " undefined-variable" , # F821
154+ " used-prior-global-declaration" , # PLE0118
155+ " yield-inside-async-function" , # PLE1700
156+ " yield-outside-function" , # F704
157+ " anomalous-backslash-in-string" , # W605
158+ " assert-on-string-literal" , # PLW0129
159+ " assert-on-tuple" , # F631
160+ " bad-format-string" , # W1302, F
161+ " bad-format-string-key" , # W1300, F
162+ " bare-except" , # E722
163+ " binary-op-exception" , # PLW0711
164+ " cell-var-from-loop" , # B023
165+ # "dangerous-default-value", # B006, ruff catches new occurrences, needs more work
166+ " duplicate-except" , # B014
167+ " duplicate-key" , # F601
168+ " duplicate-string-formatting-argument" , # F
169+ " duplicate-value" , # F
170+ " eval-used" , # S307
171+ " exec-used" , # S102
172+ " expression-not-assigned" , # B018
173+ " f-string-without-interpolation" , # F541
174+ " forgotten-debug-statement" , # T100
175+ " format-string-without-interpolation" , # F
176+ # "global-statement", # PLW0603, ruff catches new occurrences, needs more work
177+ " global-variable-not-assigned" , # PLW0602
178+ " implicit-str-concat" , # ISC001
179+ " import-self" , # PLW0406
180+ " inconsistent-quotes" , # Q000
181+ " invalid-envvar-default" , # PLW1508
182+ " keyword-arg-before-vararg" , # B026
183+ " logging-format-interpolation" , # G
184+ " logging-fstring-interpolation" , # G
185+ " logging-not-lazy" , # G
186+ " misplaced-future" , # F404
187+ " named-expr-without-context" , # PLW0131
188+ " nested-min-max" , # PLW3301
189+ " pointless-statement" , # B018
190+ " raise-missing-from" , # B904
191+ " redefined-builtin" , # A001
192+ " try-except-raise" , # TRY302
193+ " unused-argument" , # ARG001, we don't use it
194+ " unused-format-string-argument" , # F507
195+ " unused-format-string-key" , # F504
196+ " unused-import" , # F401
197+ " unused-variable" , # F841
198+ " useless-else-on-loop" , # PLW0120
199+ " wildcard-import" , # F403
200+ " bad-classmethod-argument" , # N804
201+ " consider-iterating-dictionary" , # SIM118
202+ " empty-docstring" , # D419
203+ " invalid-name" , # N815
204+ " line-too-long" , # E501, disabled globally
205+ " missing-class-docstring" , # D101
206+ " missing-final-newline" , # W292
207+ " missing-function-docstring" , # D103
208+ " missing-module-docstring" , # D100
209+ " multiple-imports" , # E401
210+ " singleton-comparison" , # E711, E712
211+ " subprocess-run-check" , # PLW1510
212+ " superfluous-parens" , # UP034
213+ " ungrouped-imports" , # I001
214+ " unidiomatic-typecheck" , # E721
215+ " unnecessary-direct-lambda-call" , # PLC3002
216+ " unnecessary-lambda-assignment" , # PLC3001
217+ " unnecessary-pass" , # PIE790
218+ " unneeded-not" , # SIM208
219+ " useless-import-alias" , # PLC0414
220+ " wrong-import-order" , # I001
221+ " wrong-import-position" , # E402
222+ " comparison-of-constants" , # PLR0133
223+ " comparison-with-itself" , # PLR0124
224+ " consider-alternative-union-syntax" , # UP007
225+ " consider-merging-isinstance" , # PLR1701
226+ " consider-using-alias" , # UP006
227+ " consider-using-dict-comprehension" , # C402
228+ " consider-using-generator" , # C417
229+ " consider-using-get" , # SIM401
230+ " consider-using-set-comprehension" , # C401
231+ " consider-using-sys-exit" , # PLR1722
232+ " consider-using-ternary" , # SIM108
233+ " literal-comparison" , # F632
234+ " property-with-parameters" , # PLR0206
235+ " super-with-arguments" , # UP008
236+ " too-many-branches" , # PLR0912
237+ " too-many-return-statements" , # PLR0911
238+ " too-many-statements" , # PLR0915
239+ " trailing-comma-tuple" , # COM818
240+ " unnecessary-comprehension" , # C416
241+ " use-a-generator" , # C417
242+ " use-dict-literal" , # C406
243+ " use-list-literal" , # C405
244+ " useless-object-inheritance" , # UP004
245+ " useless-return" , # PLR1711
246+ " no-else-break" , # RET508
247+ " no-else-continue" , # RET507
248+ " no-else-raise" , # RET506
249+ " no-else-return" , # RET505
250+ " broad-except" , # BLE001
251+ " protected-access" , # SLF001
252+ " broad-exception-raised" , # TRY002
253+ " consider-using-f-string" , # PLC0209
254+ # "no-self-use", # PLR6301 # Optional plugin, not enabled
255+
256+ # Handled by mypy
257+ # Ref: <https://github.com/antonagestam/pylint-mypy-overlap>
258+ " abstract-class-instantiated" ,
259+ " arguments-differ" ,
260+ " assigning-non-slot" ,
261+ " assignment-from-no-return" ,
262+ " assignment-from-none" ,
263+ " bad-exception-cause" ,
264+ " bad-format-character" ,
265+ " bad-reversed-sequence" ,
266+ " bad-super-call" ,
267+ " bad-thread-instantiation" ,
268+ " catching-non-exception" ,
269+ " comparison-with-callable" ,
270+ " deprecated-class" ,
271+ " dict-iter-missing-items" ,
272+ " format-combined-specification" ,
273+ " global-variable-undefined" ,
274+ " import-error" ,
275+ " inconsistent-mro" ,
276+ " inherit-non-class" ,
277+ " init-is-generator" ,
278+ " invalid-class-object" ,
279+ " invalid-enum-extension" ,
280+ " invalid-envvar-value" ,
281+ " invalid-format-returned" ,
282+ " invalid-hash-returned" ,
283+ " invalid-metaclass" ,
284+ " invalid-overridden-method" ,
285+ " invalid-repr-returned" ,
286+ " invalid-sequence-index" ,
287+ " invalid-slice-index" ,
288+ " invalid-slots-object" ,
289+ " invalid-slots" ,
290+ " invalid-star-assignment-target" ,
291+ " invalid-str-returned" ,
292+ " invalid-unary-operand-type" ,
293+ " invalid-unicode-codec" ,
294+ " isinstance-second-argument-not-valid-type" ,
295+ " method-hidden" ,
296+ " misplaced-format-function" ,
297+ " missing-format-argument-key" ,
298+ " missing-format-attribute" ,
299+ " missing-kwoa" ,
300+ " no-member" ,
301+ " no-value-for-parameter" ,
302+ " non-iterator-returned" ,
303+ " non-str-assignment-to-dunder-name" ,
304+ " nonlocal-and-global" ,
305+ " not-a-mapping" ,
306+ " not-an-iterable" ,
307+ " not-async-context-manager" ,
308+ " not-callable" ,
309+ " not-context-manager" ,
310+ " overridden-final-method" ,
311+ " raising-bad-type" ,
312+ " raising-non-exception" ,
313+ " redundant-keyword-arg" ,
314+ " relative-beyond-top-level" ,
315+ " self-cls-assignment" ,
316+ " signature-differs" ,
317+ " star-needs-assignment-target" ,
318+ " subclassed-final-class" ,
319+ " super-without-brackets" ,
320+ " too-many-function-args" ,
321+ " typevar-double-variance" ,
322+ " typevar-name-mismatch" ,
323+ " unbalanced-dict-unpacking" ,
324+ " unbalanced-tuple-unpacking" ,
325+ " unexpected-keyword-arg" ,
326+ " unhashable-member" ,
327+ " unpacking-non-sequence" ,
328+ " unsubscriptable-object" ,
329+ " unsupported-assignment-operation" ,
330+ " unsupported-binary-operation" ,
331+ " unsupported-delete-operation" ,
332+ " unsupported-membership-test" ,
333+ " used-before-assignment" ,
334+ " using-final-decorator-in-unsupported-version" ,
335+ " wrong-exception-operation" ,
336+ ]
337+ enable = [
338+ # "useless-suppression", # temporarily every now and then to clean them up
339+ " use-symbolic-message-instead" ,
340+ ]
341+ per-file-ignores = [
342+ # redefined-outer-name: Tests reference fixtures in the test function
343+ # use-implicit-booleaness-not-comparison: Tests need to validate that a list
344+ # or a dict is returned
345+ " /tests/:redefined-outer-name,use-implicit-booleaness-not-comparison" ,
346+ ]
347+
348+ [tool .pylint .REPORTS ]
349+ score = false
350+
351+ [tool .pylint .TYPECHECK ]
352+ ignored-classes = [
353+ " _CountingAttr" , # for attrs
354+ ]
355+ mixin-class-rgx = " .*[Mm]ix[Ii]n"
356+
357+ [tool .pylint .FORMAT ]
358+ expected-line-ending-format = " LF"
359+
360+ [tool .pylint .EXCEPTIONS ]
361+ overgeneral-exceptions = [
362+ " builtins.BaseException" ,
363+ " builtins.Exception" ,
364+ # "homeassistant.exceptions.HomeAssistantError", # too many issues
365+ ]
366+
367+ [tool .pylint .TYPING ]
368+ runtime-typing = false
369+
370+ [tool .pylint .CODE_STYLE ]
371+ max-line-length-suggestions = 72
372+
373+ [tool .coverage .run ]
374+ source = [" plugwise-beta" ]
375+
376+ [tool .coverage .report ]
377+ exclude_lines = [
378+ # Have to re-enable the standard pragma
379+ " pragma: no cover" ,
380+ # Don't complain about missing debug-only code:
381+ " def __repr__" ,
382+ # Don't complain if tests don't hit defensive assertion code:
383+ " raise AssertionError" ,
384+ " raise NotImplementedError" ,
385+ # TYPE_CHECKING and @overload blocks are never executed during pytest run
386+ " if TYPE_CHECKING:" ,
387+ " @overload" ,
388+ ]
35389
36390[tool .ruff ]
37391required-version = " >=0.5.3"
@@ -65,6 +419,7 @@ select = [
65419 " DTZ004" , # Use datetime.fromtimestamp(ts, tz=) instead of datetime.utcfromtimestamp(ts)
66420 " E" , # pycodestyle
67421 " F" , # pyflakes/autoflake
422+ " F541" , # f-string without any placeholders
68423 " FLY" , # flynt
69424 " FURB" , # refurb
70425 " G" , # flake8-logging-format
@@ -117,9 +472,11 @@ select = [
117472 " T100" , # Trace found: {name} used
118473 " T20" , # flake8-print
119474 " TCH" , # flake8-type-checking
120- " TID251 " , # Banned imports
475+ " TID " , # Tidy imports
121476 " TRY" , # tryceratops
122477 " UP" , # pyupgrade
478+ " UP031" , # Use format specifiers instead of percent format
479+ " UP032" , # Use f-string instead of `format` call
123480 " W" , # pycodestyle
124481]
125482
0 commit comments