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

Prodict semantic broken #50

Open
adm271828 opened this issue Dec 13, 2024 · 0 comments
Open

Prodict semantic broken #50

adm271828 opened this issue Dec 13, 2024 · 0 comments

Comments

@adm271828
Copy link

Hi,

I just discover that setting a value using attribute setter is different, in a very counter intuitive way, than setting a value using item setter.

Let's start again with #42 example. When given a regular dict, Prodict does not perform a deep transformation in order to convert nested dict into nested Prodict:

>>> from prodict import Prodict
>>> a = {'x': 100, 'y': 200, 'foo': {'z': 300}}
>>> d=Prodict(a)
>>> d
{'x': 100, 'y': 200, 'foo': {'z': 300}}
>>> type(d.foo)
<class 'dict'>

On the other hand, when intialized with a keyword arg, a deep conversion is done... which is not consistent with previous exemple:

>>> d = Prodict(a=a)
>>> d
{'a': {'x': 100, 'y': 200, 'foo': {'z': 300}}}
>>> type(d.a)
<class 'prodict.Prodict'>
>>> type(d.a.foo)
<class 'prodict.Prodict'>

When starting with an empty dict and setting a, the result differ if we use an item setter or an attribute setter. Still not really consistent:

>>> d=Prodict()
>>> d['a']=a           # <-- No conversion
>>> type(d.a)
<class 'dict'>
>>> d.a is a
True

>>> d=Prodict()
>>> d.a=a              # <-- Deep copy and conversion
>>> type(d.a)
<class 'prodict.Prodict'>
>>> type(d.a.foo)
<class 'prodict.Prodict'>

>>> d=Prodict()
>>> d.update(a=a)      # <-- No conversion
>>> type(d.a)
<class 'dict'>
>>> type(d.a)
>>> d.a is a
True

And when value is already a Prodict a deep copy is made even if it seems unnecessary:

>>> a=Prodict(x=100,y=200,foo={'z':300})
>>> a
{'x': 100, 'y': 200, 'foo': {'z': 300}}
>>> type(a.foo)
<class 'prodict.Prodict'>
>>> d=Prodict()
>>> d.a=a
>>> d.a is a            # <-- expected to be True, why perform a deep copy?
False
>>> d.a.foo is a.foo
False

So, what would be a clean semantic?

  • At least, attribute setter (d.a=...), item setter (d['a']=...), update (d.update(a=...)) and kwargs initialization (Prodict(a=...) or Prodict((('a',...),))) should behave the very same way
  • Whether a deep copy is made or not (design choice, I'd go for a deep conversion), it should be documented
  • Instances of Prodict should not be copied (and possibly not inspected more deeply if a deep conversion is performed)

Best regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant