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

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

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

PyCon APAC 2025

Lee Wei

March 01, 2025
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 ) The requirement
  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

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

    modules Btw, ast took 0.79. seconds (File loading took 0.49 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 black == 24.8.0
  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 black == 24.8.0
  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 black == 24.8.0
  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 black == 24.8.0
  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 black == 24.8.0
  12. 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
  13. 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
  14. wei-lee.me $ cat weilee.py __name__ = 李唯 / Wei Lee

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

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