From the @jsbueno user response, I was able to better understand the complexity of the subject I am dealing with.
After many tests and different approaches, I came up with the following code:
def my_deepcopy(data):
if isinstance(data, dict):
result = {}
for key, value in data.items():
result[key] = my_deepcopy(value)
assert id(result) != id(data)
elif isinstance(data, list):
result = []
for item in data:
result.append(my_deepcopy(item))
assert id(result) != id(data)
elif isinstance(data, tuple):
aux = []
for item in data:
aux.append(my_deepcopy(item))
result = tuple(aux)
assert id(result) != id(data)
elif isinstance(data, (int, float, complex, type(None), str, bool )):
result = data
elif isinstance(data, set ):
result = set(data)
assert id(result) != id(data)
elif isinstance(data, bytearray ):
result = bytearray(data)
assert id(result) != id(data)
elif hasattr( data, '__name__' ):
result = data
elif hasattr( data, '__class__'):
aux = {}
result = data.__class__()
for k, v in data.__dict__:
aux[k] = my_deepcopy(v)
assert id(aux[k]) != id(v)
result.__dict__ = aux
assert id(result) != id(data)
else:
raise ValueError("unexpected type")
return result
# Funcao
def FooBar():
return "FooBar"
# Classe
class Xpto:
pass
# Tipos para teste
lst_obj = [ 0, 1.1, 'foo', 'bar' ]
dict_obj = { 'zero' : 0, 'pi' : 3.1415, 'desc' : 'foobar' }
list_list_obj = [ [1,2,3], [4,5,6], [7,8,9] ]
tuple_list_obj = [ (-1,-1), (0,-1,0), (-1,0), (0,0,0,0) ]
dict_list_obj = [ {'zero' : 0}, {'pi' : 3.1415}, {'desc' : 'foobar'} ]
list_set_obj = [ set([1,2,3]), set([1,2,3])]
list_bytearray_obj = [ bytearray([1,2,3]), bytearray([1,2,3]) ]
list_func_obj = [ FooBar, FooBar ]
list_arbitrary_obj = [ Xpto(), Xpto() ]
# Testando
my_deepcopy( lst_obj )
my_deepcopy( dict_obj )
my_deepcopy( list_list_obj )
my_deepcopy( tuple_list_obj )
my_deepcopy( dict_list_obj )
my_deepcopy( list_set_obj )
my_deepcopy( list_bytearray_obj )
my_deepcopy( list_func_obj )
my_deepcopy( list_arbitrary_obj )