mdomke / schwifty

IBAN parsing and validation

Home Page:https://schwifty.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IBAN object cannot be deepcopied

binaryDiv opened this issue · comments

commented

Currently, when trying a copy.deepcopy() on an IBAN object, an exception is raised. This can happen for example when deepcopying a dictionary that contains an IBAN object.

A simple copy() works perfectly fine, it even returns a new instance:

>>> from schwifty import IBAN
>>> import copy
>>> 
>>> iban = IBAN('DE91100000000123456789')
>>> iban
<IBAN=DE91100000000123456789>
>>> 
>>> iban_copy = copy.copy(iban)
>>> id(iban), id(iban_copy)
(125298528552432, 125298507391216)

However, a deepcopy() results in the following exception:

>>> iban_deepcopy = copy.deepcopy(iban)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.12/copy.py", line 162, in deepcopy
    y = _reconstruct(x, memo, *rv)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/copy.py", line 259, in _reconstruct
    state = deepcopy(state, memo)
            ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/copy.py", line 136, in deepcopy
    y = copier(x, memo)
        ^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/copy.py", line 221, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
                             ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/copy.py", line 162, in deepcopy
    y = _reconstruct(x, memo, *rv)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/copy.py", line 253, in _reconstruct
    y = func(*args)
        ^^^^^^^^^^^
  File "/usr/lib/python3.12/copyreg.py", line 99, in __newobj__
    return cls.__new__(cls, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: BBAN.__new__() missing 1 required positional argument: 'value'

I've tested this on the latest version of schwifty (2024.6.1) and Python 3.12.4.

commented

Adding the following implementation for __deepcopy__ to the BBAN class seems to fix the issue. However, I'm not sure if this is the best solution or if that implementation should be done in the common.Base class.

def __deepcopy__(self, memo):
    cls = type(self)
    return cls(str(self.country_code), str(self))

@binaryDiv Thanks for the heads-up! I added a corresponding implementation to the common.Base-class.