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

Default Unit registry initialization is not thread safe #2039

Open
Czaki opened this issue Jul 15, 2024 · 0 comments
Open

Default Unit registry initialization is not thread safe #2039

Czaki opened this issue Jul 15, 2024 · 0 comments

Comments

@Czaki
Copy link

Czaki commented Jul 15, 2024

For performance of init, the default registry is created using LazyRegistry

https://github.com/hgrecco/pint/blob/5f2a76a42c44f0077908be212c5445a657da639a/pint/__init__.py#L50C1-L50C18

However, the code for load and initialize register

pint/pint/registry.py

Lines 187 to 192 in 5f2a76a

def __init(self):
args, kwargs = self.__dict__["params"]
kwargs["on_redefinition"] = "raise"
self.__class__ = UnitRegistry
self.__init__(*args, **kwargs)
self._after_init()

is not thread safe, so if two threads try to access to registry it may end with exception like:

  File "napari/utils/transforms/transforms.py", line 477, in __init__
    self._units = (pint.get_application_registry().pixel,) * ndim
  File "pint/registry.py", line 251, in __getattr__
    return getattr(self._registry, name)
  File "pint/facets/plain/registry.py", line 367, in __getattr__
    return self.Unit(item)
  File "pint/facets/plain/unit.py", line 41, in __init__
    self._units = self._REGISTRY.parse_units(units)._units
  File "pint/facets/plain/registry.py", line 1199, in parse_units
    self.parse_units_as_container(input_string, as_delta, case_sensitive)
  File "pint/facets/nonmultiplicative/registry.py", line 69, in parse_units_as_container
    return super().parse_units_as_container(input_string, as_delta, case_sensitive)
  File "pint/facets/plain/registry.py", line 1214, in parse_units_as_container
    return self._parse_units_as_container(input_string, as_delta, case_sensitive)
  File "pint/facets/plain/registry.py", line 1249, in _parse_units_as_container
    cname = self.get_name(name, case_sensitive=case_sensitive)
  File "pint/facets/plain/registry.py", line 658, in get_name
    raise UndefinedUnitError(name_or_alias)

There should be at least information in get_application_registry doc string about this problem or initialization of register should be protected using proper objects from threading library, for example Lock.

I may try to implement such a thing if you wish.

Czaki added a commit to 4DNucleome/PartSeg that referenced this issue Jul 15, 2024
Workaround for hgrecco/pint#2039

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Integrated `pint` library for unit management, improving flexibility
and precision in handling measurements.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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

No branches or pull requests

1 participant