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

👌 IMPROVE: constructor of base data types #5165

Merged
merged 2 commits into from
Dec 6, 2021

Conversation

mbercx
Copy link
Member

@mbercx mbercx commented Oct 5, 2021

Adapt the constructor of the Dict and List data types so the
value no longer needs to be provided as a keyword argument, but can
simply be passed as the first positional argument.

Remove the *args from the BaseType constructor, instead specifying
the value input argument. Otherwise users could just pass multiple
positional arguments and it would only use the first without raising an
error.

Also fixes two issues with the List class:

  • The remove method was not working as prescribed. Instead of
    removing the first element in the list with the specified value, it
    simply deleted the element with index value.
  • The set_list() method didn't make a copy of the list input, so any
    modification done to the List instance would also affect the original
    list. If the same list is used to initialise several List instances,
    adapting one would affect the other.

Finally, add tests for the List class.

@mbercx
Copy link
Member Author

mbercx commented Oct 6, 2021

Seems there were already some tests for List in tests/test_base_dataclasses.py. Will check why this one fails and move them to tests/orm/data/test_list.py.

I also noticed that these tests use test classes based on AiidaTestCase. Is there a preference between using this setup and separate functions decorated with @pytest.mark.usefixtures('clear_database_before_test')?

@chrisjsewell
Copy link
Member

I also noticed that these tests use test classes based on AiidaTestCase. Is there a preference between using this setup and separate functions decorated with @pytest.mark.usefixtures('clear_database_before_test')?

yep AiidaTestCase is "deprecated", see #4782 for converting

@mbercx mbercx force-pushed the fix/4495/dict-list-constructor branch from 82fc7aa to eb830de Compare October 6, 2021 21:31
@mbercx
Copy link
Member Author

mbercx commented Oct 6, 2021

Alright, refactored the basetype tests. I also moved the data dir in the tests to nodes (renamed from node, to match the package directory tree.

Some things I found out while working on this:

  1. Although adding together a str and bool is perfectly possible:
In [1]: 'a' + 'b'
Out[1]: 'ab'

In [2]: True + False
Out[2]: 1

Doing this for Str or Bool raises a TypeError: unsupported operand type(s).

  1. abs is not implemented for the BaseType classes:
In [3]: abs(Float(-2.0))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-324814f1c59f> in <module>
----> 1 abs(Float(-2.0))

TypeError: bad operand type for abs(): 'Float'
  1. Some interesting inplace addition behaviour:
In [4]: f = Float(2)

In [4]: f += 2.0

In [5]: f
Out[5]: <Float: uuid: 8ee7db38-6a28-442f-8bfb-827de8f9d897 (unstored) value: 4.0>

In [6]: f.store()
Out[6]: <Float: uuid: 8ee7db38-6a28-442f-8bfb-827de8f9d897 (pk: 1) value: 4.0>

In [7]: f += 0.1

In [8]: f
Out[8]: <Float: uuid: cbf4b5ee-1474-46d6-aa48-c11a0639d12f (unstored) value: 4.1>

@codecov
Copy link

codecov bot commented Oct 6, 2021

Codecov Report

Merging #5165 (63e590d) into develop (08ac107) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #5165      +/-   ##
===========================================
+ Coverage    81.31%   81.31%   +0.01%     
===========================================
  Files          529      529              
  Lines        37031    37031              
===========================================
+ Hits         30107    30108       +1     
+ Misses        6924     6923       -1     
Flag Coverage Δ
django 76.81% <100.00%> (+0.01%) ⬆️
sqlalchemy 75.76% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
aiida/orm/nodes/data/base.py 83.34% <100.00%> (-1.96%) ⬇️
aiida/orm/nodes/data/dict.py 87.24% <100.00%> (ø)
aiida/orm/nodes/data/list.py 91.02% <100.00%> (+6.31%) ⬆️
aiida/orm/nodes/data/bool.py 94.12% <0.00%> (-5.88%) ⬇️
aiida/engine/daemon/client.py 75.26% <0.00%> (-1.01%) ⬇️
aiida/transports/plugins/local.py 81.41% <0.00%> (-0.25%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 08ac107...63e590d. Read the comment docs.

@mbercx mbercx force-pushed the fix/4495/dict-list-constructor branch 2 times, most recently from 4b32d62 to 499c4fe Compare October 20, 2021 09:21
unkcpz
unkcpz previously approved these changes Dec 2, 2021
Copy link
Member

@unkcpz unkcpz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @mbercx! Looks good to me.

As for the tests files move to node/data/, I like this new folder refactoring, it has more parallel structure with the code they test.

Comment on lines +49 to +50
def __init__(self, value=None, **kwargs):
"""Initialise a ``Dict`` node instance.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to make sure this will not break any backwards compatibility, correct? We can still use d = orm.Dict(dict={}).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I see a test case for this particular. 👍

Adapt the constructor of the `Dict` and `List` data types so the
value no longer needs to be provided as a keyword argument, but can
simply be passed as the first input.

Remove the `*args` from the `BaseType` constructor, instead specifying
the `value` input argument. Otherwise users could just pass multiple
positional arguments and it would only use the first without raising an
error.

Also fixes two issues with the `List` class:

* The `remove` method was not working as prescribed. Instead of
removing the first element in the list with the specified value, it
simply deleted the element with index `value`.
* The `set_list()` method didn't make a copy of the `list` input, so any
modification done to the `List` instance would also affect the original
`list`. If the same list is used to initialise several `List` instances,
adapting one would affect the other.

Finally, add tests for the `List` class.
@mbercx
Copy link
Member Author

mbercx commented Dec 6, 2021

Thanks for the review @unkcpz! Just rebased, good to merge once the test complete.

@unkcpz unkcpz enabled auto-merge (squash) December 6, 2021 13:56
Copy link
Member

@unkcpz unkcpz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mbercx!

@unkcpz unkcpz merged commit eb73c7d into aiidateam:develop Dec 6, 2021
@mbercx mbercx deleted the fix/4495/dict-list-constructor branch December 6, 2021 14:56
mbercx added a commit to mbercx/aiida-upgrade that referenced this pull request Mar 10, 2022
We recently adapted the constructors of the `Dict` and `List` nodes so
they no longer require the `dict` and `list` keywords, see:

aiidateam/aiida-core#5165

Here we add a transformer that automatically removes these keywords from
`Dict` and `List` constructors if present.
mbercx added a commit to mbercx/aiida-upgrade that referenced this pull request Mar 10, 2022
We recently adapted the constructors of the `Dict` and `List` nodes so
they no longer require the `dict` and `list` keywords, see:

aiidateam/aiida-core#5165

Here we add a transformer that automatically removes these keywords from
`Dict` and `List` constructors if present.
mbercx added a commit to mbercx/aiida-upgrade that referenced this pull request Mar 10, 2022
We recently adapted the constructors of the `Dict` and `List` nodes so
they no longer require the `dict` and `list` keywords, see:

aiidateam/aiida-core#5165

Here we add a transformer that automatically removes these keywords from
`Dict` and `List` constructors if present.
mbercx added a commit to mbercx/aiida-upgrade that referenced this pull request Mar 10, 2022
We recently adapted the constructors of the `Dict` and `List` nodes so
they no longer require the `dict` and `list` keywords, see:

aiidateam/aiida-core#5165

Here we add a transformer that automatically removes these keywords from
`Dict` and `List` constructors if present.
mbercx added a commit to mbercx/aiida-upgrade that referenced this pull request Mar 10, 2022
We recently adapted the constructors of the `Dict` and `List` nodes so
they no longer require the `dict` and `list` keywords, see:

aiidateam/aiida-core#5165

Here we add a transformer that automatically removes these keywords from
`Dict` and `List` constructors if present.
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

Successfully merging this pull request may close these issues.

3 participants