Skip to content

Commit

Permalink
require-subclass option now doesn't flag protocol classes (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
ariebovenberg committed Dec 29, 2022
1 parent e23154f commit 9e555ff
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 145 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
@@ -1,6 +1,12 @@
Changelog
=========

0.16.2 (2022-12-29)
-------------------

- Don't flag ``Protocol`` classes as needing slots if strict
``require-subclass`` option is enabled.

0.16.1 (2022-11-21)
-------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/advanced.rst
Expand Up @@ -18,7 +18,7 @@ Use the following configuration:
repos:
- repo: https://github.com/ariebovenberg/slotscheck
rev: v0.16.1
rev: v0.16.2
hooks:
- id: slotscheck
# If your Python files are not importable from the project root,
Expand Down
237 changes: 108 additions & 129 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "slotscheck"
version = "0.16.1"
version = "0.16.2"
description = "Ensure your __slots__ are working properly."
authors = ["Arie Bovenberg <a.c.bovenberg@gmail.com>"]
license = "MIT"
Expand Down
8 changes: 7 additions & 1 deletion src/slotscheck/cli.py
Expand Up @@ -19,6 +19,7 @@
)

import click
from typing_extensions import Protocol

from . import config
from .checks import (
Expand Down Expand Up @@ -560,7 +561,12 @@ def slot_messages(
yield DuplicateSlots(c)
if require_superclass and has_slots(c) and has_slotless_base(c):
yield BadSlotInheritance(c)
elif require_subclass and not has_slots(c) and not has_slotless_base(c):
elif (
require_subclass
and not has_slots(c)
and not has_slotless_base(c)
and Protocol not in c.__bases__
):
yield ShouldHaveSlots(c)


Expand Down
15 changes: 13 additions & 2 deletions tests/examples/module_not_ok/foo.py
@@ -1,3 +1,6 @@
from typing_extensions import Protocol


class A:
pass

Expand Down Expand Up @@ -93,8 +96,16 @@ class X(RuntimeError):


class Z:
__slots__ = ('a', 'b', 'c', 'b', 'b', 'c')
__slots__ = ("a", "b", "c", "b", "b", "c")


class Za(Z):
__slots__ = ('b', 'c')
__slots__ = ("b", "c")


class MyProto(Protocol):
pass


class Zb(MyProto):
__slots__ = ()
29 changes: 18 additions & 11 deletions tests/src/test_cli.py
Expand Up @@ -205,8 +205,9 @@ def test_errors_with_default_settings(runner: CliRunner):
ERROR: 'module_not_ok.foo:W' defines overlapping slots.
ERROR: 'module_not_ok.foo:Z' has duplicate slots.
ERROR: 'module_not_ok.foo:Za' defines overlapping slots.
ERROR: 'module_not_ok.foo:Zb' has slots but superclass does not.
Oh no, found some problems!
Scanned 4 module(s), 28 class(es).
Scanned 4 module(s), 30 class(es).
"""
)

Expand All @@ -231,8 +232,9 @@ def test_errors_require_slots_subclass(runner: CliRunner):
ERROR: 'module_not_ok.foo:W' defines overlapping slots.
ERROR: 'module_not_ok.foo:Z' has duplicate slots.
ERROR: 'module_not_ok.foo:Za' defines overlapping slots.
ERROR: 'module_not_ok.foo:Zb' has slots but superclass does not.
Oh no, found some problems!
Scanned 4 module(s), 28 class(es).
Scanned 4 module(s), 30 class(es).
"""
)

Expand All @@ -255,8 +257,9 @@ def test_errors_disallow_nonslot_inherit(runner: CliRunner):
ERROR: 'module_not_ok.foo:W' defines overlapping slots.
ERROR: 'module_not_ok.foo:Z' has duplicate slots.
ERROR: 'module_not_ok.foo:Za' defines overlapping slots.
ERROR: 'module_not_ok.foo:Zb' has slots but superclass does not.
Oh no, found some problems!
Scanned 4 module(s), 28 class(es).
Scanned 4 module(s), 30 class(es).
"""
)

Expand All @@ -276,7 +279,7 @@ def test_errors_no_require_superclass(runner: CliRunner):
ERROR: 'module_not_ok.foo:Z' has duplicate slots.
ERROR: 'module_not_ok.foo:Za' defines overlapping slots.
Oh no, found some problems!
Scanned 4 module(s), 28 class(es).
Scanned 4 module(s), 30 class(es).
"""
)

Expand All @@ -297,8 +300,9 @@ def test_errors_with_exclude_classes(runner: CliRunner):
ERROR: 'module_not_ok.foo:U.Ub' defines overlapping slots.
ERROR: 'module_not_ok.foo:Z' has duplicate slots.
ERROR: 'module_not_ok.foo:Za' defines overlapping slots.
ERROR: 'module_not_ok.foo:Zb' has slots but superclass does not.
Oh no, found some problems!
Scanned 4 module(s), 28 class(es).
Scanned 4 module(s), 30 class(es).
"""
)

Expand All @@ -318,7 +322,7 @@ def test_errors_with_include_classes(runner: CliRunner):
ERROR: 'module_not_ok.foo:W' defines overlapping slots.
ERROR: 'module_not_ok.foo:Za' defines overlapping slots.
Oh no, found some problems!
Scanned 4 module(s), 28 class(es).
Scanned 4 module(s), 30 class(es).
"""
)

Expand Down Expand Up @@ -403,16 +407,19 @@ def test_module_not_ok_verbose(runner: CliRunner):
Slots already defined in superclass:
- 'b' (module_not_ok.foo:Z)
- 'c' (module_not_ok.foo:Z)
ERROR: 'module_not_ok.foo:Zb' has slots but superclass does not.
Superclasses without slots:
- 'module_not_ok.foo:MyProto'
Oh no, found some problems!
stats:
modules: 4
checked: 4
excluded: 0
skipped: 0
classes: 28
has slots: 21
no slots: 7
classes: 30
has slots: 22
no slots: 8
n/a: 0
"""
)
Expand Down Expand Up @@ -512,7 +519,7 @@ def test_finds_config(runner: CliRunner, mocker, tmpdir):
ERROR: 'module_not_ok.foo:Z' has duplicate slots.
ERROR: 'module_not_ok.foo:Za' defines overlapping slots.
Oh no, found some problems!
Scanned 4 module(s), 28 class(es).
Scanned 4 module(s), 30 class(es).
"""
)

Expand Down Expand Up @@ -541,7 +548,7 @@ def test_given_config(runner: CliRunner, tmpdir):
ERROR: 'module_not_ok.foo:Z' has duplicate slots.
ERROR: 'module_not_ok.foo:Za' defines overlapping slots.
Oh no, found some problems!
Scanned 4 module(s), 28 class(es).
Scanned 4 module(s), 30 class(es).
"""
)

Expand Down

0 comments on commit 9e555ff

Please sign in to comment.