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

builder returns wrong values of inputs defaults when namespaces are used in expose_inputs #5263

Closed
bosonie opened this issue Dec 8, 2021 · 5 comments
Labels

Comments

@bosonie
Copy link

bosonie commented Dec 8, 2021

Describe the bug

Several misleading behaviors (fairly weird I would say) have been detected when playing with default of inputs ports that have been exposed inside a namespace. See below to reproduce them.

Steps to reproduce

In verdi shell:

from aiida import orm
from aiida.engine import WorkChain
class ClassA(WorkChain):
    @classmethod
    def define(cls, spec):
        super().define(spec)
        spec.input("www",valid_type=Float,default=lambda: Float(1.0))
        spec.outline(cls.brun)
    def brun(self):
        return None

class ClassB(WorkChain):
    @classmethod
    def define(cls, spec):
        super().define(spec)
        spec.expose_inputs(ClassA,namespace="dddd")
        spec.expose_inputs(ClassA,namespace="aaaa")
        spec.inputs["dddd"]["www"].default = lambda: Float(33.0)
        spec.outline(cls.run)

    def run(self):
        self.report("w")

b=ClassB.get_builder()

First of all, typing b.www() returns something. It shouldn't be since the input is exposed in a namespace.
Second, b.dddd.www() does not return the correct default. Please note that the error is introduced only when the line spec.expose_inputs(ClassA,namespace="aaaa") is present. If removed, the default is correctly returned.

Expected behavior

Should be clear from above

Important node

The bug is only on the value returned by the builder. In fact ClassB.spec().inputs._ports["dddd"]["www"].default() correctly shows the right default. Same for b._process_spec.inputs._ports["dddd"]["www"].default(). And also, when the workchain is launched, the correct inputs are used.
Therefore it only seems a problem of "updating" what is returned by the "getter".

Your environment

  • Operating system [e.g. Linux]: Linux
  • Python version [e.g. 3.7.1]: 3.7.10
  • aiida-core version [e.g. 1.2.1]: 1.6.5
@sphuber
Copy link
Contributor

sphuber commented Dec 9, 2021

Thanks @bosonie . Can you have another look at your example and I cannot reproduce the problem.

In [1]: from aiida import orm
   ...: from aiida.engine import WorkChain
   ...: class ClassA(WorkChain):
   ...:     @classmethod
   ...:     def define(cls, spec):
   ...:         super().define(spec)
   ...:         spec.input("www",valid_type=Float,default=lambda: Float(1.0))
   ...:         spec.outline(cls.brun)
   ...:     def brun(self):
   ...:         return None
   ...: 
   ...: class ClassB(WorkChain):
   ...:     @classmethod
   ...:     def define(cls, spec):
   ...:         super().define(spec)
   ...:         spec.expose_inputs(ClassA,namespace="dddd")
   ...:         spec.expose_inputs(ClassA,namespace="aaaa")
   ...:         spec.inputs["dddd"]["www"].default = lambda: Float(33.0)
   ...:         spec.outline(cls.run)
   ...: 
   ...:     def run(self):
   ...:         self.report("w")
   ...: 
   ...: b=ClassB.get_builder()

In [2]: b
Out[2]: {'metadata': {}, 'dddd': {'metadata': {}}, 'aaaa': {'metadata': {}}}

In [3]: b.www()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-087b93e24a03> in <module>
----> 1 b.www()

AttributeError: 'ProcessBuilder-1051c00d-78f5-4878-8f87-6254f37ee16' object has no attribute 'www'

The resulting namespace looks ok to me. And calling b.www doesn't return anything. I am not sure why you are trying to call a member of the builder anyway? Was this a typo? Thought so initially, but then you do it again later in your post with b.dddd.www().

@bosonie
Copy link
Author

bosonie commented Dec 9, 2021

The fact you call is due to the fact that the default is a lambda, so a function. In any case the same problem can be seen without a lambda, for instance when you have a non_db input port and therefore you define simple python types as defaults.
I confirm my findings. I repeated my example in another machine (fedora) and I get the same problem.

@sphuber
Copy link
Contributor

sphuber commented Dec 9, 2021

After looking at it some more, it is clear that this is a bug in 1.6.5 that was already fixed in develop. This is the same symptom of the bug reported in #4420 which was resolved in #4984

@sphuber
Copy link
Contributor

sphuber commented Dec 9, 2021

Not sure if we want to release a patch 1.6.6 with a backport or we leave it for now since 2.0 is around the corner. Once v2.0 is released we can close this for sure.

@sphuber
Copy link
Contributor

sphuber commented Apr 28, 2022

Closing this since v2.0 has been released

@sphuber sphuber closed this as completed Apr 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants