Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

require-subclass option now doesn't flag protocol classes (#130) #131

Merged
merged 1 commit into from Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox tox-gh-actions poetry
pip install tox tox-gh-actions poetry==1.2.2
- name: Test with tox
run: tox

Expand Down
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
239 changes: 109 additions & 130 deletions poetry.lock

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions 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 All @@ -24,9 +24,8 @@ homepage = "https://github.com/ariebovenberg/slotscheck"

[tool.poetry.dependencies]
python = ">=3.7,<4"
importlib-metadata = {version = ">=1,<5", python = "<3.8"}
importlib-metadata = {version = ">=1,<6", python = "<3.8"}
typing-extensions = {version = ">=4.1,<5", python = "<3.10"}
dataclasses = {version = ">=0.6", python = "<3.7"}
click = "^8.0"
tomli = ">=0.2.6,<3.0.0"

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
2 changes: 1 addition & 1 deletion tox.ini
Expand Up @@ -3,7 +3,7 @@ isolated_build = true
envlist = py{37,38,39,310,311},lint,mypy,isort,slots

[testenv]
whitelist_externals =
allowlist_externals =
poetry
commands_pre=
poetry install -n -v --no-root
Expand Down