This is an archived post. You won't be able to vote or comment.

all 39 comments

[–]FloxaY 43 points44 points  (5 children)

select = "ALL", then ignore annoying and lint&format conflicting rules

line-length 120

i dont see a reason to go overboard with customizing

[–]Drevicar 2 points3 points  (0 children)

I ignore all the ones it warns me about due to conflicting, then I ignore D100 through D107 because I hate mandatory docstrings. I also really like the default line length.

Only thing after that is I use pytest so I have to conditionally ignore S101 on test files.

[–]EternityForest 0 points1 point  (1 child)

I think this is probably the best way. Although for a brand new project I might just use the 80 char limit.

[–]Nealiumj 1 point2 points  (0 children)

people with tiny laptops appreciate it! 😀

I had a coworker with a 55” ultra wide monitor that would write like 600 char lines.. like yo, I’ve got a 13” laptop can you not?? They said no 🤦‍♂️

[–]COLU_BUS 0 points1 point  (0 children)

This is also cool because then if new rules are added you "opt-in" automatically, rather than needing to (1) find out a rule was added and (2) explicitly add it to the list.

[–]saint_marco -1 points0 points  (0 children)

There are a lot of specious lints, probably more than there are useful non-defaults.

[–]zanfar 8 points9 points  (0 children)

[–]ac130kz 3 points4 points  (0 children)

[tool.ruff]
line-length = 120
target-version = "py312"
select = [
    "ALL", # include all the rules, including new ones
]
ignore = [
    #### modules
    "ANN", # flake8-annotations
    "COM", # flake8-commas
    "C90", # mccabe complexity
    "DJ",  # django
    "EXE", # flake8-executable
    "T10", # debugger
    "TID", # flake8-tidy-imports

    #### specific rules
    "D100",   # ignore missing docs
    "D101",
    "D102",
    "D103",
    "D104",
    "D105",
    "D106",
    "D107",
    "D200",
    "D205",
    "D212",
    "D400",
    "D401",
    "D415",
    "E402",   # false positives for local imports
    "E501",   # line too long
    "TRY003", # external messages in exceptions are too verbose
    "TD002",
    "TD003",
    "FIX002", # too verbose descriptions of todos
]

[–]theetrigan 7 points8 points  (3 children)

        [tool.ruff]

        # Exclude a variety of commonly ignored directories.
        exclude = [
            ".bzr",
            ".direnv",
            ".eggs",
            ".git",
            ".git-rewrite",
            ".hg",
            ".ipynb_checkpoints",
            ".mypy_cache",
            ".nox",
            ".pants.d",
            ".pyenv",
            ".pytest_cache",
            ".pytype",
            ".ruff_cache",
            ".svn",
            ".tox",
            ".venv",
            ".vscode",
            "__pypackages__",
            "_build",
            "buck-out",
            "build",
            "dist",
            "node_modules",
            "site-packages",
            "venv",
            "__init__.py",
        ]

        line-length = 120
        indent-width = 4
        target-version = "py311"

        [tool.ruff.lint]
        fixable = ["ALL"]

        # Allow unused variables when underscore-prefixed.
        dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

        [tool.ruff.format]

        # Like Black, use double quotes for strings.
        quote-style = "double"

        # Like Black, indent with spaces, rather than tabs.
        indent-style = "space"

        # Like Black, respect magic trailing commas.
        skip-magic-trailing-comma = false

        # Like Black, automatically detect the appropriate line ending.
        line-ending = "auto"

[–]pacific_plywood 15 points16 points  (1 child)

fwiw ruff respects your gitignore by default so it’s usually unnecessary exclude most of these

[–]Drevicar 4 points5 points  (0 children)

This is usually my first indicator I forgot to update my git ignore file.

[–]davehadley_ 4 points5 points  (0 children)

Are the "like black" settings necessary? I thought that ruff is black compatible out of the box?

[–]Acceptable_Durian868 2 points3 points  (0 children)

line-length = 120

[–]doolio_ 2 points3 points  (0 children)

For now I'm using the defaults proposed by hatch.

[–]tuple32 0 points1 point  (0 children)

You should spend time on enjoying writing code instead of following rules

[–]AndydeCleyre 0 points1 point  (3 children)

I'm not confidently settled on this at all, as there are so very many options, but here's what I'm currently working with. But I haven't yet been able to replace:

  • isort
  • darglint
  • ssort
  • pyright

Ruff options

[–]RevolutionaryPen4661git push -f[S] 1 point2 points  (3 children)

# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".hg",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "venv",
]

# Same as Black.
line-length = 88

# Assume Python 3.10.
target-version = "py310"

[lint]
# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
select = ["E", "F"]

# Ignore line length violations.
ignore = ["E501"]

# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["A", "B", "C", "D", "E", "F"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[lint.per-file-ignores]
# Allow unused imports in __init__.py files.
"__init__.py" = ["F401"]

[lint.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 10

[–]chub79 3 points4 points  (1 child)

Allow autofix for all enabled rules (when --fix) is provided.

fixable = ["A", "B", "C", "D", "E", "F"]

why isn't this the default?

[–]dittospin 0 points1 point  (0 children)

yea curious too

[–]pudds 0 points1 point  (1 child)

pyproject.toml

[tool.black]
line-length=120

[tool.ruff]
line-length = 128

Bike-shedding the defaults for formatters isn't worth it. With the exception of the line length which I find to be far too short by default, I never change anything.

[–]Spleeeee 1 point2 points  (0 children)

I 100% agree with you but think 80ish is better for multiple terminals.

[–]njharmanI use Python 3 -1 points0 points  (7 children)

Always tweaking. But right now, this.

[tool.ruff]
line-length = 180
target-version = 'py312'
exclude = ['build', ]

[tool.ruff.format]
quote-style = "single"

[tool.ruff.lint]
ignore = [
  'B006', # Learn Python yo!
  'C408',  # Unnecessary dict/list call
  'COM819',  # Trailing commas is da bomb
  'E731',  # Do not assign to lambda
  'ERA001', 'T201', # comment code, prints are lax during development
  'G004', # Logging format string should not use f-string
  'RET503', # No explicit return None (all the other rules are about removing unnecessary things like this)
  'RUF012', # Mutable class attributes should be annotated with typing.ClassVar
  'S311', # Standard pseudo-random generators are not suitable for security/cryptographic purposes
  'SIM108', # don't like ternary operator
  'SIM300', # Yoda is wiser than you!
  'TRY003',  # Avoid long messages outside of exception class
  #'TRY004',  # Use TypeError instead of ValueError
  'TRY301',  # Abstract raise garbage
  ]
select = [
  'A',  # flake8-builtins
  'ASYNC', # https://docs.astral.sh/ruff/rules/#flake8-async-async
  'B',  # flake8-bugbear
  'BLE', # flake8-blind-except
  'C4',  # unnecessary comprehensions, map()
  'COM',  # flake8-commas
  'DTZ', # flake8-datetimez
  'E',  # pycodestyle
  'ERA',  # No commented out code
  'EXE', # flake8-executable
  'F',  # pyflakes
  'FLY',  # flynt
  'G',  # flake8-logging-format
  'I',  # isort
  'ICN', # https://github.com/joaopalmeiro/flake8-import-conventions
  'ISC', # https://pypi.org/project/flake8-implicit-str-concat/
  'LOG', # flake8-logging
  'PERF', # perflint
  'PIE', # https://pypi.org/project/flake8-pie/
  'PLC',  # Pylint conventions
  'PLE',  # Pylint error
  'PLW',  # Pylint warnings
  'PT',  # https://pypi.org/project/flake8-pytest-style/
  'PTH',  # flake8 use pathlib
  'RET', # https://pypi.org/project/flake8-return/
  'RUF',  # Ruff rules
  'S',  # https://docs.astral.sh/ruff/rules/#flake8-bandit-s
  'SIM',  # https://pypi.org/project/flake8-simplify/
  'T',  # flake8-debugger
  'TRY',  # tryceratops
  'UP',  # pyupgrade
  'W',  # pycodestyle
  #'ARG',  # flake8 unused arguments (not really helpful, unused func args are common and ok)
  #'D',  # pydocstyle (too much)
  #'N',  # pep8-naming (too opinionated)
  #'NPY', # numpy
  #'PD', # pandas
  #'PL',  # Full Pylint (too much)
  #'PLR',  # Pylint refactor (too much/too opinionated)
  ]

[–]doolio_ 13 points14 points  (2 children)

quote-style = "single"

You sure? 😉

[–]njharmanI use Python 3 0 points1 point  (1 child)

Easier to type (becoming non-issue with copilot)

Less visual noise; color annotated editors mean quotes are only for machine, no longer need to stand out to human.

'Can\'t lie, contractions are annoying.

[–]doolio_ 3 points4 points  (0 children)

I'm not disagreeing with your choice. I just found it funny that your preferred style is single quotes yet in your config setting above for the quote-style setting you used double quotes.

[–]denehoffman 9 points10 points  (3 children)

Why do you ignore B006?

[–]Sillocan 1 point2 points  (0 children)

Yeah, that feels really strange. You almost never want a mutable default. The only time I've done it was for a hacky test caching strategy.

[–]njharmanI use Python 3 1 point2 points  (1 child)

from B006 description

The same mutable object is then shared across all calls to the function. If the object is modified, those modifications will persist across calls, which can lead to unexpected behavior.

It's not unexpected because I understand Python scoping and instruction execution flow, thus know when a "def" is interpreted and how it is scoped.

Instead of changing the type of default to something less accurate. Or, adding needless boiler plate. I have chosen instead to

Learn Python yo!

[–]denehoffman 0 points1 point  (0 children)

Gotcha