Skip to content

Implement flake8-pie #1543

@sbdchd

Description

@sbdchd

There might be some overlap with these rules and pylint / flake8-simplify, but I think I eliminated most of the dupes / unnecessary rules:

  • PIE810: single-starts-ends-with
    Instead of calling startswith or endswith on the same string for multiple prefixes, pass the prefixes as a tuple in a single startswith or endswith call.
# error
foo.startswith("foo") or foo.startswith("bar")

# error
foo.endswith("foo") or foo.endswith("bar")

# error
foo.startswith("foo") or str.startswith(foo, "bar")

# ok
foo.startswith(("foo",  "bar"))

# ok
foo.endswith(("foo",  "bar"))

# ok
foo.startswith("foo") or foo.endswith("bar")

pass is unnecessary when definining a class or function with an empty body.

# error
class BadError(Exception):
    """
    some doc comment
    """
    pass

def foo() -> None:
    """
    some function
    """
    pass

# ok
class BadError(Exception):
    """
    some doc comment
    """

def foo() -> None:
    """
    some function
    """

Finds duplicate definitions for the same field, which can occur in large ORM model definitions.

# error
class User(BaseModel):
    email = fields.EmailField()
    # ...80 more properties...
    email = fields.EmailField()

# ok
class User(BaseModel):
    email = fields.EmailField()
    # ...80 more properties...

By default the stdlib enum allows multiple field names to map to the same value, this lint requires each enum value be unique.

# error
class Foo(enum.Enum):
    A = "A"
    B = "B"
    C = "C"
    D = "C"

# ok
class Foo(enum.Enum):
    A = "A"
    B = "B"
    C = "C"
    D = "D"

Check for unnecessary dict unpacking.

# error
{**foo, **{"bar": 10}}

# ok
{**foo, "bar": 10}

As long as the keys of the dict are valid Python identifier names, we can safely remove the surrounding dict.

# error
foo(**{"bar": True})

# ok
foo(bar=True)
foo(**buzz)
foo(**{"bar foo": True})

lambda: [] is equivalent to the builtin list

# error
@dataclass
class Foo:
    foo: List[str] = field(default_factory=lambda: [])

# ok
@dataclass
class Foo:
    foo: List[str] = field(default_factory=list)

Do these all sound good / are there any I should leave out? I skipped a few different ones from the original package that were too specific / awkward.

Also skipped rules that overlapped with:

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueGood for newcomerspluginImplementing a known but unsupported plugin

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions