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

SerialDriver: BindingErrors hidden by AttributeError caused by not (yet) set target #1414

Open
Bastian-Krause opened this issue May 29, 2024 · 1 comment
Labels

Comments

@Bastian-Krause
Copy link
Member

Bastian-Krause commented May 29, 2024

When creating an env config with wrong SerialDriver bindings, a completely unrelated error happens:

$ labgrid-client con                                                                            
Selected role main from configuration file
Traceback (most recent call last):
  File "labgrid/labgrid/remote/client.py", line 1934, in main
    target = session._get_target(place)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "labgrid/labgrid/remote/client.py", line 671, in _get_target
    target = self.env.get_target(self.role)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "labgrid/labgrid/environment.py", line 49, in get_target
    target = target_factory.make_target(role, config, env=self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "labgrid/labgrid/factory.py", line 159, in make_target
    self.make_driver(target, driver, name, args)
  File "labgrid/labgrid/factory.py", line 138, in make_driver
    d = cls(target, name, **args)
        ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<attrs generated init labgrid.driver.serialdriver.SerialDriver>", line 11, in __init__
    self.__attrs_post_init__()
  File "labgrid/labgrid/driver/serialdriver.py", line 26, in __attrs_post_init__
    super().__attrs_post_init__()
  File "labgrid/labgrid/driver/consoleexpectmixin.py", line 18, in __attrs_post_init__
    super().__attrs_post_init__()
  File "labgrid/labgrid/driver/common.py", line 25, in __attrs_post_init__
    super().__attrs_post_init__()
  File "labgrid/labgrid/binding.py", line 55, in __attrs_post_init__
    target.bind(self)
  File "labgrid/labgrid/target.py", line 430, in bind
    return self.bind_driver(bindable)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "labgrid/labgrid/target.py", line 406, in bind_driver
    f"{client} got unexpected bindings: {list(mapping.keys())}"
      ^^^^^^^^
  File "labgrid/labgrid/driver/serialdriver.py", line 116, in __str__
    return f"SerialDriver({self.target.name})"
                           ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'name'

When dropping SerialDriver's __str___() the actual error cause is shown:

$ labgrid-client con
Selected role main from configuration file
Traceback (most recent call last):
  File "labgrid/labgrid/remote/client.py", line 1934, in main
    target = session._get_target(place)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "labgrid/labgrid/remote/client.py", line 671, in _get_target
    target = self.env.get_target(self.role)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "labgrid/labgrid/environment.py", line 49, in get_target
    target = target_factory.make_target(role, config, env=self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "labgrid/labgrid/factory.py", line 159, in make_target
    self.make_driver(target, driver, name, args)
  File "labgrid/labgrid/factory.py", line 138, in make_driver
    d = cls(target, name, **args)
        ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<attrs generated init labgrid.driver.serialdriver.SerialDriver>", line 11, in __init__
    self.__attrs_post_init__()
  File "labgrid/labgrid/driver/serialdriver.py", line 26, in __attrs_post_init__
    super().__attrs_post_init__()
  File "labgrid/labgrid/driver/consoleexpectmixin.py", line 18, in __attrs_post_init__
    super().__attrs_post_init__()
  File "labgrid/labgrid/driver/common.py", line 25, in __attrs_post_init__
    super().__attrs_post_init__()
  File "labgrid/labgrid/binding.py", line 55, in __attrs_post_init__
    target.bind(self)
  File "labgrid/labgrid/target.py", line 430, in bind
    return self.bind_driver(bindable)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "labgrid/labgrid/target.py", line 405, in bind_driver
    raise BindingError(
labgrid.binding.BindingError: SerialDriver() got unexpected bindings: ['serial']

This happens because the target checks if the driver (called client here) consumed all bindings before setting itself to client.target:

labgrid/labgrid/target.py

Lines 403 to 418 in 9e0562e

# make sure drivers consume all given bindings
if mapping and not isinstance(client, Strategy):
raise BindingError(
f"{client} got unexpected bindings: {list(mapping.keys())}"
)
# update relationship in both directions
self.drivers.append(client)
# update lookup table
cls = client.__class__
self._lookup_table[cls.__name__] = cls
for c in cls.mro():
if abc.ABC in c.mro():
self._lookup_table[c.__name__] = c
client.target = self

If that check fails, the driver's __str__() is called. In the case of the SerialDriver, self.target.name is used in this method.

I am not really sure what's the correct fix. Setting client.target = self earlier? I am unsure about the implications.

@Emantor
Copy link
Member

Emantor commented May 29, 2024

IMO we should fix the __str__ call sites as there are only two.

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