Name mangling when using "@patch" of fastcore

Summary:
When using @patch, private methods suffer / no_suffer “name mangling” depending on where they are declared.

Example below.

Import

from dataclasses import dataclass
from fastcore.foundation import patch

Class main body

#| export

@dataclass
class Number:
    "A number."
    num: int
    def __add_private_declared_in_main_body(self):
      self.num+=3
    def add_public_in_main_body(self):
      self.num+=4

Additions to class by using @patch

#| export

@patch
def __add__(self: Number, other):
    "Sum of this and `other`."
    return Number(self.num + other.num)

@patch
def __add_private_declared_out_main_body(self: Number):
    self.num+=3
    self.__add_private_declared_in_main_body()
    self.add_public_in_main_body()

@patch
def add_public_declared_out_main_body(self: Number):
    self.num+=3
    self.__add_private_declared_in_main_body()
    self.add_public_in_main_body()

dir(Number)

['_Number__add_private_declared_in_main_body',
 '__add__',
 '__add_private_declared_out_main_body',
 ...
 'add_public_declared_out_main_body',
 'add_public_in_main_body']

So when running

n=Number(33)
n.add_public_in_main_body()
n.add_public_declared_out_main_body()

We get the error

---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-63-45e4cea7f189> in <cell line: 3>()
      1 n=Number(33)
      2 n.add_public_in_main_body()
----> 3 n.add_public_declared_out_main_body()

<ipython-input-60-c8ec42f26a2b> in add_public_declared_out_main_body(self)
     16 def add_public_declared_out_main_body(self: Number):
     17     self.num+=3
---> 18     self.__add_private_declared_in_main_body()
     19     self.add_public_in_main_body()

AttributeError: 'Number' object has no attribute '__add_private_declared_in_main_body'

I may be doing something wrong, but I don’t think it should matter when a private method is defined (in / out main body).

Is this expected?

Luckily now I know what happens and how to prevent it, but it could be a bit of a nightmare if you don’t bother to do dir(x) and spot the differences.

1 Like