Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

gh-90562: Support zero argument super with dataclasses when slots=True #124455

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

Merged
Prev Previous commit
Next Next commit
Use assertIs instead of assertEqual for class comparisons. Add a test…
… showing that the original class, if saved, will have in incorrect __class__ value.
  • Loading branch information
ericvsmith committed Sep 24, 2024
commit 97d4f31bb6f79c15f9018c4934b2b38981b6ab09
39 changes: 30 additions & 9 deletions 39 Lib/test/test_dataclasses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4885,15 +4885,15 @@ def _get_foo(slf):
return slf.__class__

def _set_foo(slf, value):
self.assertEqual(__class__, type(slf))
self.assertIs(__class__, type(slf))

def _del_foo(slf):
self.assertEqual(__class__, type(slf))
self.assertIs(__class__, type(slf))

foo = property(_get_foo, _set_foo, _del_foo)

a = A()
self.assertEqual(a.foo, A)
self.assertIs(a.foo, A)
a.foo = 4
del a.foo

Expand All @@ -4906,14 +4906,14 @@ def foo(slf):

@foo.setter
def foo(slf, value):
self.assertEqual(__class__, type(slf))
self.assertIs(__class__, type(slf))

@foo.deleter
def foo(slf):
self.assertEqual(__class__, type(slf))
self.assertIs(__class__, type(slf))

a = A()
self.assertEqual(a.foo, A)
self.assertIs(a.foo, A)
a.foo = 4
del a.foo

Expand All @@ -4926,15 +4926,15 @@ def foo(slf):
return __class__

a = A()
self.assertEqual(a.foo, A)
self.assertIs(a.foo, A)

def test_slots_dunder_class_property_setter(self):
@dataclass(slots=True)
class A:
foo = property()
@foo.setter
def foo(slf, val):
self.assertEqual(__class__, type(slf))
self.assertIs(__class__, type(slf))

a = A()
a.foo = 4
Expand All @@ -4945,7 +4945,7 @@ class A:
foo = property()
@foo.deleter
def foo(slf):
self.assertEqual(__class__, type(slf))
self.assertIs(__class__, type(slf))

a = A()
del a.foo
Expand All @@ -4965,5 +4965,26 @@ def foo(self):

A().foo()

def test_remembered_class(self):
class A:
def cls(self):
return __class__

self.assertIs(A().cls(), A)

B = dataclass(slots=True)(A)
self.assertIs(B().cls(), B)

# This is probably undesirable behavior, but is a function of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can safely remove this "probably" :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh. Will do.

# how modifying __class__ in the closure works. I'm not sure
# this should be tested or not: I don't really want to
# guarantee this behavior, but I don't want to lose the point
# that this is how it works.

# The underlying class is "broken" by changing its __class__
# in A.foo() to B. This normally isn't a problem, because no
# one will be keeping a reference to the underlying class.
self.assertIs(A().cls(), B)

if __name__ == '__main__':
unittest.main()
Morty Proxy This is a proxified and sanitized view of the page, visit original site.