fix: ComponentMeta.__call__ handles keyword- and positional-only parameters correctly (#6701)

* fix: `ComponentMeta.__call__` handles keyword- and positional-only parameters correctly

* Update release note
This commit is contained in:
Madeesh Kannan 2024-01-12 17:16:03 +01:00 committed by GitHub
parent 0616197b44
commit 4647f2a506
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 1 deletions

View File

@ -139,7 +139,10 @@ class ComponentMeta(type):
instance.__canals_input__ = {}
run_signature = inspect.signature(getattr(cls, "run"))
for param in list(run_signature.parameters)[1:]: # First is 'self' and it doesn't matter.
if run_signature.parameters[param].kind == inspect.Parameter.POSITIONAL_OR_KEYWORD: # ignore `**kwargs`
if run_signature.parameters[param].kind not in (
inspect.Parameter.VAR_POSITIONAL,
inspect.Parameter.VAR_KEYWORD,
): # ignore variable args
socket_kwargs = {"name": param, "type": run_signature.parameters[param].annotation}
if run_signature.parameters[param].default != inspect.Parameter.empty:
socket_kwargs["default_value"] = run_signature.parameters[param].default

View File

@ -0,0 +1,4 @@
---
fixes:
- |
Fix ComponentMeta ignoring keyword-only parameters in the `run` method. ComponentMeta.__call__ handles the creation of InputSockets for the component's inputs when the latter has not explicitly called _Component.set_input_types(). This logic was not correctly handling keyword-only parameters.

View File

@ -176,3 +176,17 @@ def test_input_has_default_value():
comp = MockComponent()
assert comp.__canals_input__["value"].default_value == 42
assert not comp.__canals_input__["value"].is_mandatory
def test_keyword_only_args():
@component
class MockComponent:
def __init__(self):
component.set_output_types(self, value=int)
def run(self, *, arg: int):
return {"value": arg}
comp = MockComponent()
component_inputs = {name: {"type": socket.type} for name, socket in comp.__canals_input__.items()}
assert component_inputs == {"arg": {"type": int}}