astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.
https://docs.astral.sh/ruff
MIT License
32.92k stars 1.1k forks source link

Rule to ensure all code is guarded by functions or __main__ #4757

Open quassy opened 1 year ago

quassy commented 1 year ago

I believe there is a flake8 plugn for this but I can't find it, also not a rule for ruff: Quite often I have to make sure that to avoid unintended side effects of imports all regular code should be guarded by functions, classes or if __name__ == "__main__":

from sqlalchemy import create_engine

engine = create_engine("postgresql+psycopg2://scott:tiger@localhost:5432/mydatabase")

The inspection could look like this:

script.py:3:1: FOO999 Code is not guarded by function or if __name__ == "__main__", importing it may have unindented side effects

I's not safe to autofix because it will certainly change behaviour if you rely on the code being run on import. Manual fixes would be:

from sqlalchemy import create_engine

if __name__ == "__main__":
# or
def get_my_engine():
    engine = create_engine("postgresql+psycopg2://scott:tiger@localhost:5432/mydatabase")
evanrittenhouse commented 1 year ago

@charliermarsh feel free to assign this to me, I can take a look. I'll put it under the RUF linter. Want to get back into the AST, seems like we'll have to keep track of the scope block and ensure that all statements are associated with a scope?

charliermarsh commented 1 year ago

It's probably too restrictive of a lint to include in RUF, another case where we could use some kind of opt-in pedantic category.