0

I have a need to derive a class from int/str that does pretty-printing, however the printing must be parameterised, and therefore would require a slot. This hits a Python limitation that classes derived from int/str cannot have non-empty slots. Can someone suggest a workaround?

class HexDisplayedInteger(int):
    __slots__ = ["length"]

    def __str__(self):
        return format(self, "0%sX" % self.length)

This generates an error:

_______________________________ ERROR collecting tests/lib/test_search.py _______________________________
tests/lib/test_search.py:1: in <module>
    from declarativeunittest import *
tests/declarativeunittest.py:5: in <module>
    from construct import *
construct/__init__.py:22: in <module>
    from construct.core import *
construct/core.py:2905: in <module>
    class HexDisplayedInteger(integertypes[0], object):
E   TypeError: Error when calling the metaclass bases
E       nonempty __slots__ not supported for subtype of 'long'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 13 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ArekBulski
  • 4,520
  • 4
  • 39
  • 61

2 Answers2

1
  1. PyLongObject is a variable-length class in CPython implementation that stores the digits array at the end of its structure.
  2. __slots__ reserves space at the end of the structure and use the offset to retrieve them, this is to avoid the overhead using a dictionary(__dict__).

In summary, those two conflicts, since the PyLongObject and its derivatives are variable lengths, it is impossible to reserve/retrieve the slot with a fixed offset.

lyu.l
  • 282
  • 3
  • 8
0

Ah I found that attributes do not need to be among slots to be added. Now that I am thinking, I already knew that, but for some reason got so accustomed to defining slots that I forgot they are not mandatory.

class HexDisplayedInteger(int):
    def __str__(self):
        return format(self, "0%sX" % self.length)
ArekBulski
  • 4,520
  • 4
  • 39
  • 61