0

I am porting python2 code using old-style classes to python3. The code uses __getattr__ to catch calls to special methods (such as __int__, __str__, __hash__, __repr__) and delegate these calls to other objects. This is a sample code:

class A():
  def __getattr__(self, attr):
    return getattr(self.some_method(), attr)
  def some_method(self):
    return None

class B(A): #in the actual code there are many different subclasses with different some_method implementations
  def __init__(self):
    self.x = C()
  def some_method(self):
    return self.x

class C():
  def __str__(self):
    return "whatever"
  def __int__(self):
    return 5

b = B()

# in the actual code such calls are happening in indirect ways in different modules
print(int(b)) # 5 in python2, TypeError in python3

In python2 I get result 5, in python3, as all classes are new-style by default, I get: TypeError: int() argument must be a string or a number, not 'B'

The question is how to port the code. One way is to define all possible methods (__str__, __int__, etc.) in class A. This will be very time consuming as there is no easy way to find all the possible implicit calls to special methods in this specific code.

Is there a way to force __getattr__ or __getattribute__ to intercept special methods (like it was happening with old style classes)? Or is there any other possibility to intercept these calls?

P.S. I have read these to learn that __getattr__ and __getattribute__ do not get called for new-style classes in case the attribute is a special method:

Community
  • 1
  • 1
Eriks Dobelis
  • 913
  • 7
  • 16
  • And what have you *learned* from what you've read? Have you tried to port to 3.x? What happened? Why do you think `__getattribute__` *doesn't* intercept special methods? – jonrsharpe Jul 15 '15 at 14:13
  • I have learned that call to `__str__` does not get through `__getattr__`. Which leads to a possible solution of implementing `__str__` directly, but as written above for the specific code it will be time consuming. The question is - if there is any alternative way to solve this. – Eriks Dobelis Jul 15 '15 at 14:18
  • @jonrsharpe I have, also, learned from https://docs.python.org/2/reference/datamodel.html#new-style-special-lookup provided in one of the solutions, that `__getattribute__` does not intercept special methods – Eriks Dobelis Jul 15 '15 at 14:28

0 Answers0