Lying awake at night, existential questions cross your mind. What is my purpose? Is there a god? Can you subclass a Python3 int? Only the last one has an answer. You can indeed subclass an int, but there are a few subtleties.
In short, in Python3 depending on whether the built in type is immutable or mutable, you have to do things slightly differently. For the impatient, here is how you subclass an immutable type like an int or str
class Yint(int): def __new__(cls, value, payload): x = int.__new__(cls, value) x.payload = payload return x # This applies for float and str, but not bool # bool is derived from int, but can't be subclassed itself class Ybool(int): def __new__(cls, value, payload): x = int.__new__(cls, bool(value)) x.payload = payload return x
subclassing a mutable type like a list or dict is much more traditional.
class Ylist(list): def __init__(self, value, payload): list.__init__(self, value) self.payload = payload
While I got good hints from here and here the official Python documentation is pretty helpful if you persist. The Basic Customization section has the detail we need, specifically the sections on __new__ and __init__. I will not copy them here, they are short and explain everything you need to know.
Web searches on this topic bring up very little, perhaps because it’s done less often. Why did I have to do this? It all started because I was looking to get the line numbers for elements in a dictionary parsed from a YAML document.
I ran into ruamel.yaml which was great, except that it’s overhead was pretty high for the documents I needed to parse. I also needed to parse the documents in “user real time” which means a user is typing something and I want to parse what they type as they do it. ruamel.yaml was taking way to long (almost a second) to parse these documents, while bare PyYaml was taking 100ms. For my purposes I was able to lightly shim PyYaml to store the line and column numbers (which PyYaml actually keeps track of) in the data as it was being parsed. I wanted to subclass the leaf elements (which are ints, floats and strs and so on) to store this metadata info.