Misuse of _ (underscore) inside DataSource.sync() #10339

Closed
opened 2025-12-29 21:30:15 +01:00 by adam · 0 comments
Owner

Originally created by @amyasnikov on GitHub (Oct 9, 2024).

Originally assigned to: @arthanson on GitHub.

Deployment Type

Self-hosted

NetBox Version

v4.1.3

Python Version

3.12

Steps to Reproduce

  1. Start two parallel syncs of one particular data source.
  2. Get UnboundLocalError instead of SyncError. Also, the data source has the probability to get stuck in "syncing" state.

It happens due to a common python mistake:

  1. Here _ (underscore) is used as an alias to gettext.
  2. But here inside the same function a value is assigned to _ (underscore).

Python interprets this situation as "reference before assignment". For example, here will happen the same error:

def a(): ...

def b():
   a()
   a = 10

b()  # UnboundLocalError: cannot access local variable 'a' where it is not associated with a value

Here is the full traceback:

"Unhandled error occured: `<class 'UnboundLocalError'>: cannot access local variable '_' where it is not associated with a value`
  File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/scripts/runtests/base.py\", line 40, in terminate_job_on_error
    yield
  File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/scripts/runtests/split.py\", line 109, in __call__
    self.sync_datasources(params.overriding_datasource, device_filter, logger)\n  File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/scripts/runtests/split.py\", line 40, in sync_datasources
    self.datasource_sync_fn(datasources, device_filter)
  File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/utils/misc.py\", line 74, in datasource_sync
    any(tp.map(sync_func, datasources))
  File \"/usr/lib/python3.12/concurrent/futures/_base.py\", line 619, in result_iterator yield _result_or_cancel(fs.pop())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File \"/usr/lib/python3.12/concurrent/futures/_base.py\", line 317, in _result_or_cancel
    return fut.result(timeout)
           ^^^^^^^^^^^^^^^^^^^
  File \"/usr/lib/python3.12/concurrent/futures/_base.py\", line 449, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File \"/usr/lib/python3.12/concurrent/futures/_base.py\", line 401, in __get_result
    raise self._exception
  File \"/usr/lib/python3.12/concurrent/futures/thread.py\", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/utils/misc.py\", line 66, in sync_func
    datasource.sync(device_filter)
  File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/models/data.py\", line 112, in sync
    return super().sync()
           ^^^^^^^^^^^^^^
  File \"/opt/netbox/netbox/core/models/data.py\", line 164, in sync
    raise SyncError(_(\"Cannot initiate sync; syncing already in progress.\"))
                    ^"

Although the traceback is originally generated inside a plugin, I do believe the error is quite clear and not plugin-related. If you disagree, please let me know and I will provide the traceback without plugins.

Expected Behavior

Sync of the data source must generate SyncError if something goes wrong, but not UnboundLocalError

Observed Behavior

UnboundLocalError was raised

Originally created by @amyasnikov on GitHub (Oct 9, 2024). Originally assigned to: @arthanson on GitHub. ### Deployment Type Self-hosted ### NetBox Version v4.1.3 ### Python Version 3.12 ### Steps to Reproduce 1. Start two parallel syncs of one particular data source. 2. Get `UnboundLocalError` instead of `SyncError`. Also, the data source has the probability to get stuck in "syncing" state. It happens due to a common python mistake: 1. [Here](https://github.com/netbox-community/netbox/blob/v4.1.3/netbox/core/models/data.py#L177) `_` (underscore) is used as an alias to gettext. 2. But [here](https://github.com/netbox-community/netbox/blob/v4.1.3/netbox/core/models/data.py#L204) inside the same function a value is assigned to `_` (underscore). Python interprets this situation as "reference before assignment". For example, here will happen the same error: ```python def a(): ... def b(): a() a = 10 b() # UnboundLocalError: cannot access local variable 'a' where it is not associated with a value ``` Here is the full traceback: ``` "Unhandled error occured: `<class 'UnboundLocalError'>: cannot access local variable '_' where it is not associated with a value` File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/scripts/runtests/base.py\", line 40, in terminate_job_on_error yield File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/scripts/runtests/split.py\", line 109, in __call__ self.sync_datasources(params.overriding_datasource, device_filter, logger)\n File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/scripts/runtests/split.py\", line 40, in sync_datasources self.datasource_sync_fn(datasources, device_filter) File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/utils/misc.py\", line 74, in datasource_sync any(tp.map(sync_func, datasources)) File \"/usr/lib/python3.12/concurrent/futures/_base.py\", line 619, in result_iterator yield _result_or_cancel(fs.pop()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File \"/usr/lib/python3.12/concurrent/futures/_base.py\", line 317, in _result_or_cancel return fut.result(timeout) ^^^^^^^^^^^^^^^^^^^ File \"/usr/lib/python3.12/concurrent/futures/_base.py\", line 449, in result return self.__get_result() ^^^^^^^^^^^^^^^^^^^ File \"/usr/lib/python3.12/concurrent/futures/_base.py\", line 401, in __get_result raise self._exception File \"/usr/lib/python3.12/concurrent/futures/thread.py\", line 58, in run result = self.fn(*self.args, **self.kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/utils/misc.py\", line 66, in sync_func datasource.sync(device_filter) File \"/opt/netbox/venv/lib/python3.12/site-packages/validity/models/data.py\", line 112, in sync return super().sync() ^^^^^^^^^^^^^^ File \"/opt/netbox/netbox/core/models/data.py\", line 164, in sync raise SyncError(_(\"Cannot initiate sync; syncing already in progress.\")) ^" ``` Although the traceback is originally generated inside a plugin, I do believe the error is quite clear and not plugin-related. If you disagree, please let me know and I will provide the traceback without plugins. ### Expected Behavior Sync of the data source must generate `SyncError` if something goes wrong, but not `UnboundLocalError` ### Observed Behavior `UnboundLocalError` was raised
adam added the type: bugstatus: acceptedseverity: medium labels 2025-12-29 21:30:15 +01:00
adam closed this issue 2025-12-29 21:30:15 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#10339