target-version = "py312"
line-length = 320

extend-exclude = [
  "Base/QTGUI/Testing/Data/Input/qSlicerScriptedLoadableModuleSyntaxErrorTest.py",
  "Base/QTGUI/Testing/Data/Input/qSlicerScriptedLoadableModuleSyntaxErrorTestWidget.py",
]

[lint]
select = [
#  "ARG",         # flake8-unused-arguments
#  "ANN",         # flake8-annotations
  "B",           # flake8-bugbear
  "C4",          # flake8-comprehensions
  "COM",         # flake8-commas
  "E", "F", "W", # flake8
  "D",           # pydocstyle
#  "EXE",         # flake8-executable
#  "G",           # flake8-logging-format
  "ICN",         # flake8-import-conventions
  "ISC",         # flake8-implicit-str-concat
  "NPY",         # NumPy specific rules
#  "PERF",        # Perflint
  "PGH",         # pygrep-hooks
#  "PIE",         # flake8-pie
  "PL",          # pylint
  "Q",           # flake8-quote
  "RET",         # flake8-return
  "RUF",         # Ruff-specific
#  "S",           # flake8-bandit
#  "SIM",         # flake8-simplify
  "UP",          # pyupgrade
  "YTT",         # flake8-2020
]
extend-ignore = [
  "E402",    # Module level import not at top of file
  "G004",    # logging-f-string
  "PIE790",  # unnecessary-pass

  "B006",    # Do not use mutable data structures for argument defaults.
  "B007",    # Loop control variable not used within the loop body.
  "B008",    # Do not perform function calls in argument defaults.
  "B009",    # Do not call getattr(x, 'attr'), instead use normal property access: x.attr.
  "B010",    # Do not call setattr with a constant attribute value, it is not any safer than normal property access.\\
  "B018",    # Found useless expression. Either assign it to a variable or remove it.
  "B028",    # No explicit `stacklevel` keyword argument found
  "B904",    # Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None`
             # to distinguish them from errors in exception handling

  "C413",    # Unnecessary `reversed` call around `sorted()`
  "C408",    # Unnecessary `dict` call (rewrite as a literal)
  "C418",    # Unnecessary `dict` literal passed to `dict()` (remove the outer call to `dict()`)
  "C419",    # Unnecessary list comprehension.

  "D10",     # undocumented-public-*
  "D202",    # No blank lines allowed after function docstring"
  "D205",    # 1 blank line required between summary line and description
  "D4",

  "E401",    # Multiple imports on one line
  "E714",    # Test for object identity should be `is not`
  "E713",    # Test for membership should be `not in`
  "E721",    # Do not compare types, use `isinstance()`
  "E722",    # Do not use bare `except`
  "E731",    # Do not assign a `lambda` expression, use a `def`

  "F403",    # 'from module import *' used; unable to detect undefined names
  "F405",    # name may be undefined, or defined from star import
  "F541",    # f-string without any placeholders
  "F811",    # Redefinition of unused `module` from line N
  "F821",    # Undefined name
  "F841",    # Local variable is assigned to but never used

  "G002",    # Logging statement uses `%`
  "G010",    # `warn` is deprecated in favor of `warning`

  "ICN001",  # `numpy` should be imported as `np`
  "ISC002",  # Implicitly concatenated string literals over multiple lines
  "ISC003",  # Explicitly concatenated string should be implicitly concatenated

  "PLC0415", # import outside top level

  "PLR0912", # Too many branche
  "PLR0913", # Too many arguments in function definition
  "PLR0911", # Too many return statements
  "PLR0915", # Too many statements
  "PLR1711", # Useless `return` statement at end of function
  "PLR1714", # Consider merging multiple comparisons
  "PLR1722", # Use `sys.exit()` instead of `exit`
  "PLR2004", # Magic value used in comparison
  "PLR5501", # Use `elif` instead of `else` then `if`, to reduce indentation

  "PLW0120", # `else` clause on loop without a `break` statement; remove the `else` and de-indent all the code inside it
  "PLW0127", # self-assigning-variable 	Self-assignment of variable {name}
  "PLW0602", # Using global for `{name}` but no assignment is done
  "PLW0603", # Using the global statement to update {name} is discouraged
  "PLW1641", # `__eq__` without `__hash__`
  "PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target

  "Q003",    # Change outer quotes to avoid escaping inner quotes

  "RET501", # Do not explicitly return None in function if it is the only possible return value
  "RET502", # Do not implicitly return None in function able to return non-None value
  "RET503", # Missing explicit return at the end of function able to return non-None value
  "RET504", # Unnecessary assignment to {name} before return statement
  "RET505", # Unnecessary {branch} after return statement
  "RET506", # Unnecessary {branch} after raise statement
  "RET508", # Unnecessary {branch} after break statement

  "RUF005",  # Consider {expression} instead of concatenation
  "RUF010",  # Use explicit conversion flag
  "RUF012",  # Mutable class attributes should be annotated with typing.ClassVar
  "RUF013",  # PEP 484 prohibits implicit `Optional`
  "RUF022",  # Unsorted under __all__
  "RUF100",  # Unused `noqa` directive (non-enabled: `F401`)

  "SIM108",  # Use ternary operator
  "SIM101",  # Duplicate isinstance call
  "SIM115",  # Use context handler for opening files

  "UP007",   # non-pep604 annotation union
  "UP018",   # Unnecessary `int` call (rewrite as a literal)
  "UP030",   # Use implicit references for positional format fields
  "UP031",   # Use format specifiers instead of percent format
  "UP032",   # Use f-string instead of `format` call
]

[lint.pydocstyle]
convention = "pep257"

[lint.per-file-ignores]
# Module imported but unused
"Base/Python/mrml.py" = ["F401"]
"Base/Python/slicer/logic.py" = ["F401"]
"Base/Python/slicer/parameterNodeWrapper/__init__.py" = ["F401"]
"Base/Python/vtkAddon.py" = ["F401"]
"Base/Python/vtkITK.py" = ["F401"]
"Base/Python/vtkSegmentationCore.py" = ["F401"]
"Base/Python/vtkTeem.py" = ["F401"]
"Modules/*/__init__.py" = ["F401"]
"Extensions/*/__init__.py" = ["F401"]
"Utilities/*/__init__.py" = ["F401"]
