# Ruff configuration for confluent. # # py37 is the oldest version ruff can target. The oldest interpreter parts of # this tree still run on is 3.6 (el8, sles15) target-version = "py37" line-length = 120 # Ruff discovers *.py only: it does not read shebangs when walking a tree, so # without the patterns below it silently skips every CLI tool in # confluent_client/bin and confluent_server/bin, the osdeploy deploy scripts, # and the loose misc/ utilities. # Some of the osdeploy scripts carry no shebang at all. extend-include = [ "confluent_client/bin/*", "confluent_server/bin/*", # Generated into setup.py at build time by makesetup; #VERSION# only ever # appears inside a string literal, so the template itself is valid Python. "**/setup.py.tmpl", "imgutil/imgutil", "misc/filterpasswd", "misc/getipsfromswitchport", "misc/getusbnicaddr", # confluent_osdeploy: per-profile deploy scripts, matched by name because # each profile directory mixes Python and shell. "**/bfb-autoinstall", "**/nodedeploy-bfb", "**/opt/confluent/bin/apiclient", "**/scripts/add_local_repositories", "**/scripts/autoconsole", "**/scripts/configbmc", "**/scripts/confignet", "**/scripts/getinstalldisk", "**/scripts/makeksnet", "**/scripts/mergetime", "**/scripts/syncfileclient", ] extend-exclude = [ # Shell scripts that live in the directories included wholesale above. "*.sh", ] # Honour exclusions even when CI passes an explicit file list. force-exclude = true # `ruff format` is deliberately not adopted: the tree uses single quotes almost # everywhere and reformatting it would bury real changes. Preserve quotes so an # accidental run does less damage. [format] quote-style = "preserve" [lint] select = [ "E9", # unparseable file "F4", # imports: unused, shadowed by a loop, star import or a name from one, __future__ misuse "F5", # %-format and str.format checked against their arguments: bad conversions, wrong counts "F6", # duplicate dict and set keys, bad starred assignment, `is` against a literal, assert on a tuple "F7", # return outside a function, break outside a loop, an except clause that is not last "F81", # redefinition of an unused name (shadowed def/class) "F82", # undefined name, undefined name in __all__, use before assignment "F541", # f-string with no placeholders "F842", # local that is annotated but never assigned "F901", # `raise NotImplemented`, which raises TypeError rather than NotImplementedError "YTT", # version checks that break on 3.10 and later, such as sys.version[2] or version_info[1] < 7 "E401", # several imports on one line "E701", # several statements on one line "E71", # == against None or True/False, and `not x in y` / `not x is y` written the long way round "PLC0414", # import alias that renames nothing "PLE", # pylint errors: bad string format, invalid returns, ... "PLR0124", # a value compared with itself "PLR1722", # exit() or quit(), which only exist when site.py has run "PLW01", # self-assignment, assert on a literal, unraised exception, NaN compare, else on a breakless loop "PLW0211", # staticmethod whose first argument is named self or cls "PLW0245", # super called without brackets, which yields the class "PLW0406", # a module importing itself "PLW0642", # assignment to self or cls "PLW0711", # `except A + B`, which catches whatever the addition returns "PLW150", # bad open() mode, copy.copy(os.environ), non-string os.environ.get default, Popen preexec_fn "PLW2101", # `with lock:` on a lock created in place, which locks nothing "T100", # forgotten pdb/breakpoint call "W6", # invalid escape sequence in a non-raw string, and future deprecated-construct warnings "B002", # `++x`, which is two unary plus signs, not an increment "B003", # assignment to os.environ, which never reaches the environment "B004", # hasattr(x, '__call__') rather than callable(x) "B005", # .strip() with several characters, which strips a set of them "B008", # function call in a default argument, evaluated once at import "B011", # `assert False`, which disappears under python -O "B012", # break/continue/return in a finally, silently discarding the exception "B013", # single-element tuple in an except clause "B014", # the same exception listed twice in one except clause "B015", # comparison whose result is discarded "B016", # raising something that is not an exception "B017", # assertRaises(Exception), which passes on the wrong error "B019", # lru_cache on a method, which keeps every instance alive "B02", # all of B02x: loop variable overriding its iterable, closure over a loop variable "B03", # all of B03x: non-exception except, groupby reuse, `x: y` for `x = y`, dup set item "ASYNC210", # blocking HTTP call (requests, urllib) inside a coroutine "ASYNC222", # blocking wait on a child process inside a coroutine "ASYNC250", # input() inside a coroutine "ASYNC251", # time.sleep() inside a coroutine "RUF006", # asyncio.create_task result discarded, so the task can be collected while still pending "RUF016", # subscript with a type that cannot index the container "RUF017", # sum() over lists, which is quadratic in the result length "RUF018", # assignment inside an assert, so the side effect disappears under python -O "RUF024", # dict.fromkeys with a mutable value, shared by every key "RUF034", # if-else whose two branches are the same expression "RUF060", # membership test against a collection that is always empty "RUF100", # noqa that suppresses nothing "ISC001", # implicitly concatenated strings on one line, usually a comma missing from a list "LOG", # logging misuse: hand-built Logger, exception() outside a handler, logging.warn, root logger "PGH", # blanket `# noqa` and `# type: ignore`, and assertions on mock attributes that always pass "PIE794", # a class field defined twice, so the first is dead "PIE796", # enum with duplicate values, which silently aliases members "EXE003", # shebang that does not name python "EXE004", # whitespace before the shebang, which stops it working "EXE005", # shebang after the first line, where it does nothing ] # Deliberately not selected, though currently at zero: B905 (zip without an # explicit strict=). It only reports on py310+, so it reads as clean here, and # "fixing" it would mean adding a keyword the oldest supported interpreters # cannot parse. # No ignores and no per-file exemptions: every rule selected above is expected # to stay at zero on its own.