← Back to all posts

August 22, 2022

We've continued to make our custom rules more powerful!

This includes:

  1. A new ... syntax for matching anything in a position. Say you want to write a rule that matches any print statement. You can now write pattern: print(...) and this will find all print statements with any number of positional or keyword arguments.

  2. Fully qualified name recognition. Say you want to transform typing.List into list in line with PEP 585. You can define the following rule:

      - id: convert-typing-list
        pattern: typing.List
        replacement: list
        description: Use `list` rather than `typing.List`

    This will find all occurrences of typing.List and replace them with list, even if they have been imported using from typing import List.


  • Conditions for filtering out captures
  • Match anything ... or nothing !!! in patterns
  • is_identifier public condition to match variables that are valid identifiers
  • statement_count custom rule condition - this lets you count how many statements you matched.


  • Custom rule patterns will now leniently match for type annotations in assignments, parameters and function definitions. This means that the pattern ${target} = ${value} will now match assignments such as i: int = 0.
  • Recognize fully qualified names in custom rule patterns. This means that the pattern os.path.join will match join if it is imported as from os.path import join (and all of the possible variations).
  • Run custom rule conditions on the entire match using the pattern name.
  • Disallow pattern from being used as a regular capture name.
  • Docstring values can now be captured by using any existing syntax inside the string