Skip to content

Commit

Permalink
Add an extra safety measure: slots=True
Browse files Browse the repository at this point in the history
This makes sure that we did not define extra or different
attributes in __init__.
  • Loading branch information
lopuhin committed Nov 7, 2016
1 parent a4a7358 commit 6851e1f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
4 changes: 4 additions & 0 deletions eli5/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
from .base_utils import attrs


# @attrs decorator used in this file calls @attr.s(slots=True),
# creating attr.ib entries based on the signature of __init__.


@attrs
class Explanation(object):
""" An explanation for classifier or regressor,
Expand Down
7 changes: 5 additions & 2 deletions eli5/base_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@


def attrs(class_):
""" Like attr.s, but with attributes extracted from __init__ method signature.
""" Like attr.s with slots=True,
but with attributes extracted from __init__ method signature.
slots=True ensures that signature matches what really happens
(we can't define different attributes on self).
It is useful if we still want __init__ for proper type-checking and
do not want to repeat attribute definitions in the class body.
"""
Expand All @@ -21,4 +24,4 @@ def attrs(class_):
if idx >= defaults_shift:
attrib_kwargs['default'] = init_args.defaults[idx - defaults_shift]
these[arg] = attr.ib(**attrib_kwargs)
return attr.s(class_, these=these, init=False, **attrs_kwargs)
return attr.s(class_, these=these, init=False, slots=True, **attrs_kwargs)
12 changes: 12 additions & 0 deletions tests/test_base_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import attr
import pytest

from eli5.base_utils import attrs

Expand Down Expand Up @@ -48,3 +49,14 @@ def __repr__(self):

assert hash(WithRepr(1)) == hash(WithRepr(1))
assert repr(WithRepr(2)) == 'foo'


def test_bad_init():

@attrs
class BadInit(object):
def __init__(self, x):
self._x = x

with pytest.raises(AttributeError):
BadInit(1)

0 comments on commit 6851e1f

Please sign in to comment.