diff --git a/src/attr/_make.py b/src/attr/_make.py index e4f76beae..88c4c7ce9 100644 --- a/src/attr/_make.py +++ b/src/attr/_make.py @@ -1666,18 +1666,12 @@ def fmt_setter_with_converter(attr_name, value_var): init_hash_cache = "self.%s = %s" lines.append(init_hash_cache % (_hash_cache_field, "None")) - # On Python 2, it's necessary to set self.args for exceptions. We do it on - # *all* versions to keep around defaults. + # For exceptions we rely on BaseException.__init__ for proper + # initialization. if is_exc: - vals = "".join(("(self.", ", self.".join(a.name for a in attrs), ",)")) + vals = ",".join("self." + a.name for a in attrs if a.init) - if frozen: - if slots: - lines.append("_setattr('args', %s)" % (vals,)) - else: - lines.append("object.__setattr__(self, 'args', %s)" % (vals,)) - else: - lines.append("self.args = " + vals) + lines.append("BaseException.__init__(self, %s)" % (vals,)) args = ", ".join(args) if kw_only_args: diff --git a/tests/test_dark_magic.py b/tests/test_dark_magic.py index 6bcc80230..bac2a0168 100644 --- a/tests/test_dark_magic.py +++ b/tests/test_dark_magic.py @@ -6,6 +6,8 @@ import pickle +from copy import deepcopy + import pytest import six @@ -550,13 +552,15 @@ class FooError(Exception): assert e is e assert e == e - assert "(1, 42, 'foo')" == str(e) - # N.B. the default value 42 is preserved by setting args ourselves. - assert (1, 42, "foo") == e.args + assert "(1, 'foo')" == str(e) + assert (1, "foo") == e.args with pytest.raises(TypeError): hash(e) + if not frozen: + deepcopy(e) + @pytest.mark.parametrize("slots", [True, False]) @pytest.mark.parametrize("frozen", [True, False]) def test_auto_exc_one_attrib(self, slots, frozen):