super() in injected methods

Andras Tantos python-list at andras.tantosonline.com
Thu Feb 11 21:39:41 EST 2021


On 2/11/21 1:43 PM, Greg Ewing wrote:
> On 12/02/21 7:05 am, Andras Tantos wrote:
>
>>      a = B()
>>      a.m(41)
>>      a.m = MethodType(method, a)
>>      a.m(42)
>
> Are you sure you really need to inject methods into instances
> like this? What problem are you trying to solve by doing so?
> There's almost certainly a better way to approach it.
>
Greg,

This is going to be a long a convoluted story, but since, you've asked...

I'm developing a library to describe hardware (RTL) in Python and 
convert it into Verilog (or potentially other languages).

In this project, I have two concepts:

1. Ports, which are the connection points on the various netlist 
entities. These would be the inputs and outputs of an AND gate for example

2. NetTypes, which describe the type of data that can travel through a 
net (and thus through a Port). One such type would be an 8-bit signed 
integer, or a simple logic signal.

There are derived types of the Port object (for inputs and outputs etc.) 
as well as of NetType (for signed integers, structs, etc.)

An interesting aspect of the problem is that most ports don't need to 
have a type initially: it can be deduced from the connectivity (netlist) 
of the circuit described. So, for example the above mentioned AND gate 
can handle any input as long as they are of the same NetType and produce 
an output of the same NetType. This is to say, that Ports have an 
optional NetType, the association between Port and NetType is dynamic 
and changes during the lifetime of the Port instance.

There are two ways I can think of modelling this in Python:

1. A (derived) Port instance uses multiple-inheritance to also inherit 
from it's (derived) NetType

2. A (derived) Port instance has a member of a (derived) NetType instance

I went with #2 in my current implementation.

Now, when a Port gets assigned a NetType, it needs to gain all sorts of 
new features. It for example should have a 'length' attribute that tells 
how many bits are needed to represent its possible values. The list of 
these new features (attributes, methods, properties) are known to the 
NetType and should be injected into the Port when the NetType is 
assigned to the Port.

With #1, the situation is different, but not any less complicated: now, 
the features are automatically appear in the Port instance (maybe even 
too much so) but we dynamically mess with the inheritance tree of the 
type of the Port instance.

The example I've written up deals with the problems when I try to inject 
these new features into the Port instance (say a new method) and the 
method implementation intends to call back the base-class behavior for 
some reason.

I believe even #1 could have similar problems in different ways though: 
since I manipulate the inheritance chain dynamically, I don't think 
there's a guarantee that the statically determined '__class__' cell will 
be the same as the dynamically expected one.

Andras




More information about the Python-list mailing list