Fail with a meaningful error msg on old-style classes

This commit is contained in:
Hynek Schlawack 2015-02-18 20:38:29 +01:00
parent 01cdff398f
commit a44357ad83
2 changed files with 18 additions and 5 deletions

View File

@ -160,6 +160,8 @@ def attributes(maybe_cl=None, these=None,
:type no_init: bool
"""
def wrap(cl):
if getattr(cl, "__class__", None) is None:
raise TypeError("attrs only works with new-style classes.")
_transform_attrs(cl, these)
if not no_repr:
cl = _add_repr(cl)
@ -172,12 +174,11 @@ def attributes(maybe_cl=None, these=None,
return cl
# attrs_or class type depends on the usage of the decorator. It's a class
# if it's used as `@attributes` but ``None`` (or a value passed) if used
# as `@attributes()`.
if isinstance(maybe_cl, type):
return wrap(maybe_cl)
else:
# if it's used as `@attributes` but ``None`` if used # as `@attributes()`.
if maybe_cl is None:
return wrap
else:
return wrap(maybe_cl)
def _attrs_to_tuple(obj, attrs):

View File

@ -9,6 +9,7 @@ from __future__ import absolute_import, division, print_function
import pytest
from . import simple_attr
from attr._compat import PY3
from attr._make import (
Attribute,
NOTHING,
@ -117,6 +118,17 @@ class TestAttributes(object):
"""
Tests for the `attributes` class decorator.
"""
@pytest.mark.skipif(PY3, reason="No old-style classes in Py3")
def test_catches_old_style(self):
"""
Raises TypeError on old-style classes.
"""
with pytest.raises(TypeError) as e:
@attributes
class C:
pass
assert ("attrs only works with new-style classes.",) == e.value.args
def test_sets_attrs(self):
"""
Sets the `__attrs_attrs__` class attribute with a list of `Attribute`s.