Skip to content

Commit ceb1469

Browse files
committed
Make the tolerance class a singleton
1 parent c2516e9 commit ceb1469

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
* Added `compas.colors.Color.contrast`.
1616
* Added `compas.geometry.Brep.from_plane`.
1717
* Added `compas.tolerance.Tolerance.angulardeflection`.
18+
* Added `compas.tolerance.Tolerance.update_from_dict`.
1819

1920
### Changed
2021

@@ -34,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3435
* Changed use of `compas.geometry.allclose` to `compas.tolerance.TOL.is_allclose`.
3536
* Changed use of `compas.geometry.close` to `compas.tolerance.TOL.is_close`.
3637
* Changed imports of itertools to `compas.itertools` instead of `compas.utilities`.
38+
* Changed `compas.tolerance.Tolerance` to a singleton, to ensure having only library-wide tolerance values.
3739

3840
### Removed
3941

src/compas/tolerance.py

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class Tolerance(Data):
5353
This value is called the "true value".
5454
By convention, the second value is considered the "true value" by the comparison functions of this class.
5555
56+
The :class:`compas.tolerance.Tolerance` class is implemented using a "singleton" pattern and can therefore have only 1 (one) instance per context.
57+
Usage of :attr:`compas.tolerance.TOL` outside of :mod:`compas` internals is therefore deprecated.
58+
5659
Examples
5760
--------
5861
>>> tol = Tolerance()
@@ -67,6 +70,9 @@ class Tolerance(Data):
6770
6871
"""
6972

73+
_instance = None
74+
_is_inited = False
75+
7076
ABSOLUTE = 1e-9
7177
"""float: Determines when a number is small enough to be considered zero.
7278
"""
@@ -108,8 +114,9 @@ class Tolerance(Data):
108114
"""
109115

110116
def __new__(cls, *args, **kwargs):
111-
if not hasattr(cls, "_instance"):
112-
cls._instance = super(Tolerance, cls).__new__(cls)
117+
if not isinstance(cls._instance, cls):
118+
cls._instance = object.__new__(cls, *args, **kwargs)
119+
cls._inited = False
113120
return cls._instance
114121

115122
@property
@@ -151,22 +158,34 @@ def __init__(
151158
name=None,
152159
):
153160
super(Tolerance, self).__init__(name=name)
154-
self._unit = None
155-
self._absolute = None
156-
self._relative = None
157-
self._angular = None
158-
self._approximation = None
159-
self._precision = None
160-
self._lineardeflection = None
161-
self._angulardeflection = None
162-
self.unit = unit
163-
self.absolute = absolute
164-
self.relative = relative
165-
self.angular = angular
166-
self.approximation = approximation
167-
self.precision = precision
168-
self.lineardeflection = lineardflection
169-
self.angulardeflection = angulardflection
161+
if not self._is_inited:
162+
self._unit = None
163+
self._absolute = None
164+
self._relative = None
165+
self._angular = None
166+
self._approximation = None
167+
self._precision = None
168+
self._lineardeflection = None
169+
self._angulardeflection = None
170+
171+
self._is_inited = True
172+
173+
if unit is not None:
174+
self.unit = unit
175+
if absolute is not None:
176+
self.absolute = absolute
177+
if relative is not None:
178+
self.relative = relative
179+
if angular is not None:
180+
self.angular = angular
181+
if approximation is not None:
182+
self.approximation = approximation
183+
if precision is not None:
184+
self.precision = precision
185+
if lineardflection is not None:
186+
self.lineardeflection = lineardflection
187+
if angulardflection is not None:
188+
self.angulardeflection = angulardflection
170189

171190
# this can be autogenerated if we use slots
172191
# __repr__: return f"{__class__.__name__}({', '.join(f'{k}={v!r}' for k, v in self.__dict__.items())})}"
@@ -193,6 +212,23 @@ def reset(self):
193212
self._lineardeflection = None
194213
self._angulardeflection = None
195214

215+
def update_from_dict(self, tolerance):
216+
"""Update the tolerance singleton from the key-value pairs found in a dict.
217+
218+
Parameters
219+
----------
220+
tolerance : dict
221+
A dictionary containing named tolerance values.
222+
223+
Returns
224+
-------
225+
None
226+
227+
"""
228+
for name in tolerance:
229+
if hasattr(self, name):
230+
setattr(self, name, tolerance[name])
231+
196232
@property
197233
def units(self):
198234
return self._unit

0 commit comments

Comments
 (0)