Skip to content

int and set subclass __sizeof__ under-reports the instance dictionary pointer #101266

Closed
@ionite34

Description

@ionite34

Bug report

Most built-in types, when subclassed, will have a __sizeof__ that is 8 (pointer size) larger than the parent object, due to having an instance dictionary.

class UserFloat(float): pass assert UserFloat().__sizeof__() - (0.0).__sizeof__() == 8 class UserTuple(tuple): pass assert UserTuple().__sizeof__() - ().__sizeof__() == 8 class UserList(list): pass assert UserList().__sizeof__() - [].__sizeof__() == 8 class UserDict(dict): pass assert UserDict().__sizeof__() - {}.__sizeof__() == 8

This is unexpectedly, not the case for int and set, which exactly match the original __sizeof__

class UserSet(set): pass print(UserSet().__sizeof__(), set().__sizeof__()) # 200 200 class UserInt(int): pass print(UserInt().__sizeof__(), (0).__sizeof__()) # 24 24

As a result this makes __dictoffset__ usages incorrect as well

from ctypes import py_object class UserTuple(tuple): pass x = UserTuple() x.a = 5 print(x.__dict__) >> {'a': 5} py_object.from_address(id(x) + x.__sizeof__() + UserTuple.__dictoffset__) >> py_object({'a': 5})
from ctypes import py_object class UserInt(int): pass x = UserInt() x.a = 5 print(x.__dict__) >> {'a': 5} py_object.from_address(id(x) + x.__sizeof__() + UserInt.__dictoffset__) >> py_object(<NULL>)

Your environment

  • CPython versions tested on: 3.11, 3.12.0a3

Linked PRs

Metadata

Metadata

Assignees

Labels

type-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions