First stab at correcting object lifetime issue

This is a minimal change which re-orders some bits of CompositeDevice's
constructor to ensure that all exceptions get raised *before* we store a
reference to the contained devices. Hopefully this'll be enough to sort
out 2.x but I'm not sure it will be for pypy (might still require an
explicit close there).
This commit is contained in:
Dave Jones
2017-06-25 21:17:55 +01:00
parent 56f2152daf
commit 12cbd5ae09

View File

@@ -321,16 +321,16 @@ class CompositeDevice(Device):
for missing_name in set(kwargs.keys()) - set(self._order): for missing_name in set(kwargs.keys()) - set(self._order):
raise CompositeDeviceBadOrder('%s missing from _order' % missing_name) raise CompositeDeviceBadOrder('%s missing from _order' % missing_name)
self._order = tuple(self._order) self._order = tuple(self._order)
super(CompositeDevice, self).__init__()
for name in set(self._order) & set(dir(self)): for name in set(self._order) & set(dir(self)):
raise CompositeDeviceBadName('%s is a reserved name' % name) raise CompositeDeviceBadName('%s is a reserved name' % name)
self._all = args + tuple(kwargs[v] for v in self._order) for dev in chain(args, kwargs.values()):
for dev in self._all:
if not isinstance(dev, Device): if not isinstance(dev, Device):
raise CompositeDeviceBadDevice("%s doesn't inherit from Device" % dev) raise CompositeDeviceBadDevice("%s doesn't inherit from Device" % dev)
self._named = frozendict(kwargs) self._named = frozendict(kwargs)
self._namedtuple = namedtuple('%sValue' % self.__class__.__name__, chain( self._namedtuple = namedtuple('%sValue' % self.__class__.__name__, chain(
('device_%d' % i for i in range(len(args))), self._order)) ('device_%d' % i for i in range(len(args))), self._order))
self._all = args + tuple(kwargs[v] for v in self._order)
super(CompositeDevice, self).__init__()
def __getattr__(self, name): def __getattr__(self, name):
# if _named doesn't exist yet, pretend it's an empty dict # if _named doesn't exist yet, pretend it's an empty dict