Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Unleash the Chaos - Developing a Linter for Un-...

Lee Wei
September 21, 2024

Unleash the Chaos - Developing a Linter for Un-Pythonic Code!

Lee Wei

September 21, 2024
Tweet

More Decks by Lee Wei

Other Decks in Programming

Transcript

  1. wei-lee.me It required default values of argument deferrable in __init__

    methods of any (operator) class to be conf.getboolean( "operators", "default_deferrable", fallback=False )
  2. wei-lee.me What we want to check default values of argument

    deferrable in __init__ methods of any (operator) class to be conf.getboolean( "operators", "default_deferrable", fallback=False )
  3. wei-lee.me What we want to check 1. Search for class

    definitions 2. Search for __init__ methods 3. Search for arguments named as deferrable 4. Check the default value is conf.getboolean( "operators", "default_deferrable", fallback=False ) Formalize it into steps
  4. wei-lee.me What we want to check 1. Search for ClassDef

    node 2. Search for FunctionDef node with name __init__ 3. Search for arguments node with name deferrable 4. Check the default value is conf.getboolean( "operators", "default_deferrable", fallback=False ) Formalize it into ast terms
  5. wei-lee.me Except for it took 9 seconds to process 386

    modules Btw, ast took 1.5 seconds
  6. wei-lee.me What can we do? 1. Use ast to filter

    the modules that might contain an error 2. Use LibCST to fix those modules
  7. wei-lee.me How black works? 1. Sanitize lines 2. Parse the

    source code into a syntax tree (lib2to3_parse) 1. Get grammars in target versions 2. Tokenize 3. Return the syntax tree as Node object 3. Generate Line objects through LineGenerator 4. Transform line into formatted LineBlock In a super high level
  8. wei-lee.me How black works? 1. Sanitize lines 2. Parse the

    source code into a syntax tree (lib2to3_parse) 1. Get grammars in target versions 2. Tokenize 3. Return the syntax tree as Node object 3. Generate Line objects through LineGenerator 4. Transform line into formatted LineBlock In a super high level
  9. wei-lee.me How black works? 1. Sanitize lines 2. Parse the

    source code into a syntax tree (lib2to3_parse) 1. Get grammars in target versions 2. Tokenize 3. Return the syntax tree as Node object 3. Generate Line objects through LineGenerator 4. Transform line into formatted LineBlock In a super high level
  10. wei-lee.me How black works? 1. Sanitize lines 2. Parse the

    source code into a syntax tree (lib2to3_parse) 1. Get grammars in target versions 2. Tokenize 3. Return the syntax tree as Node object 3. Generate Line objects through LineGenerator 4. Transform line into formatted LineBlock In a super high level
  11. wei-lee.me How black works? 1. Sanitize lines 2. Parse the

    source code into a syntax tree (lib2to3_parse) 1. Get grammars in target versions 2. Tokenize 3. Return the syntax tree as Node object 3. Generate Line objects through LineGenerator 4. Transform line into formatted LineBlock In a super high level
  12. wei-lee.me Don't know much about Rust... Sorry.. But looks like

    they're doing something similar How about ruff?
  13. wei-lee.me Setting up the rules 1. Skip builtins, dunder methods,

    and anything imported 2. Change all the top-level variable, class, and function names into numeronyms
  14. wei-lee.me Related PyCon Talks • Charlie Marsh - Ruff: An

    Extremely Fast Python Linter and Code Formatter, Written in Rust • Łukasz Langa - Life Is Better Painted Black, or: How to Stop Worrying and Embrace Auto- Formatting • Cheuk Ting Ho - Reformating your code without AI - let's see how a formatter works
  15. wei-lee.me $ cat weilee.py __name__ = 李唯 / Wei Lee

    __what_i_am_doing__ = [ Volunteer @ PyCon Taiwan, First Time Speaker @ PyCon Taiwan, Member @ PyCon APAC, Maintainer of commitizen-tools, Software Engineer @ Astronomer, Committer @ Apache Airflow, ] __github__ = G Lee-W __linkedin__ = l clleew __site__ = p http://wei-lee.me
  16. wei-lee.me File "weilee.py", line 1 __name__ = 李唯 / Wei

    Lee ^^^ SyntaxError: invalid syntax $ python weilee.py