Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deepcopy(frozendict[<key type>, <value type>]) returns empty dict instead of type #29

Closed
JacobHayes opened this issue Sep 5, 2021 · 8 comments
Labels
Priority: Low Not a big problem... Status: Fixed Now it works! Type: Enhancement New feature or request

Comments

@JacobHayes
Copy link

OS version: macOS Big Sur 11.4
Python3 version (python3 -V -V):

Python 3.9.0 (default, Nov 13 2020, 17:57:54)
[Clang 10.0.1 (clang-1001.0.46.4)]

Steps to reproduce:

>>> from copy import copy, deepcopy
>>>
>>> from frozendict import frozendict
>>>
>>> deepcopy(dict)
<class 'dict'>
>>> deepcopy(dict[str, int])
dict[str, int]
>>>
>>> deepcopy(frozendict)
<class 'frozendict.core.frozendict'>
>>> deepcopy(frozendict[str, int])
{}

I don't exactly know why this is happening, but a bit of debugging info:

  • __new__ and __init__ are never called (but did confirm it is called for something like frozendict())
  • __deepcopy__ is called, but only for the deepcopy(frozendict[str, int]) case... and then type(self) is dict, not frozendict which seems weird.
@JacobHayes JacobHayes added the Type: Bug Something isn't working label Sep 5, 2021
@Marco-Sulla
Copy link
Owner

Can you give me the result of:

import frozendict
frozendict.c_ext

@JacobHayes
Copy link
Author

>>> import frozendict
>>> frozendict.c_ext
False

@Marco-Sulla
Copy link
Owner

And this is a problem because....?

@JacobHayes
Copy link
Author

I'm hoping to use frozendict with pydantic (think: dataclasses, but with runtime type checking/parsing - including dict keys and values). The pydantic Models have references to the field types (eg: frozendict[str, int]), but occasionally call deepcopy (eg: when subclassing). After a deepcopy, instead of having model.__fields__['fieldname'] = frozendict[str, int], we end up with model.__fields__['fieldname'] = {}, causing a few other issues.

Small example w/ pydantic if it helps:

from frozendict import frozendict
from pydantic import BaseModel

class Base(BaseModel):
    a: frozendict[str, int]

class Sub(Base):
    pass

print(Sub.__fields__["a"].outer_type_)

@JacobHayes
Copy link
Author

JacobHayes commented Sep 10, 2021

I think this is a bug in python's copy module - when using deepcopy with a GenericAlias and a __deepcopy__ method, the GenericAlias is not considered a type and so copy fetches .__deepcopy__ from the class and calls it with the memo dict (hence type(self) is dict). I'll open a bug upstream.

edit: in case you're interested: https://bugs.python.org/issue45167

@Marco-Sulla Marco-Sulla added Type: Enhancement New feature or request Priority: Low Not a big problem... and removed Type: Bug Something isn't working labels Sep 11, 2021
@Marco-Sulla
Copy link
Owner

I reopen it, since the type hint does not work at all in the C Extension

@Marco-Sulla Marco-Sulla reopened this Sep 11, 2021
@Marco-Sulla
Copy link
Owner

Fixed ecf771c

@JacobHayes
Copy link
Author

Thanks. Btw, the original deepcopy issue was fixed upstream in python/cpython#28324

@Marco-Sulla Marco-Sulla added the Status: Fixed Now it works! label Dec 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: Low Not a big problem... Status: Fixed Now it works! Type: Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants