Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Changed:
- `AsyncioDispatcher cleanup tasks atexit <../../pull/138>`_
- `Ensure returned numpy arrays are not writeable <../../pull/164>`_
- `Ensure records do not get stuck in processing state <../../pull/175>`_
- `Remove __super attribute <../../pull/187>`_

Fixed:

Expand Down
12 changes: 6 additions & 6 deletions softioc/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class ProcessDeviceSupportCore(DeviceSupportCore, RecordLookup):
def __init__(self, name, **kargs):
autosave_fields = kargs.pop("autosave", None)
autosave.add_pv_to_autosave(self, name, autosave_fields)
self.__super.__init__(name, **kargs)
super().__init__(name, **kargs)

# Most subclasses (all except waveforms) define a ctypes constructor for the
# underlying EPICS compatible value.
Expand Down Expand Up @@ -127,7 +127,7 @@ def __init__(self, name, **kargs):
# The tuple contains everything needed to be written: the value,
# severity, alarm and optional timestamp.
self._value = (value, alarm.NO_ALARM, alarm.UDF_ALARM, None)
self.__super.__init__(name, **kargs)
super().__init__(name, **kargs)

def _process(self, record):
# For input process we copy the value stored in the instance to the
Expand Down Expand Up @@ -197,7 +197,7 @@ def __init__(self, name, **kargs):
if self._blocking:
self._callback = create_callback_capsule()

self.__super.__init__(name, **kargs)
super().__init__(name, **kargs)

def init_record(self, record):
'''Special record initialisation for out records only: implements
Expand Down Expand Up @@ -385,7 +385,7 @@ def _process(self, record):
# Because we're returning NO_CONVERT we need to do the .UDF updating
# ourself (otherwise the record support layer does this).
record.UDF = int(numpy.isnan(self._value[0]))
return self.__super._process(record)
return super()._process(record)

class ao(ProcessDeviceSupportOut):
_record_type_ = 'ao'
Expand Down Expand Up @@ -439,11 +439,11 @@ class WaveformBase(ProcessDeviceSupportCore):
def __init__(self, name, _wf_nelm, _wf_dtype, **kargs):
self._dtype = _wf_dtype
self._nelm = _wf_nelm
self.__super.__init__(name, **kargs)
super().__init__(name, **kargs)

def init_record(self, record):
self._dbf_type_ = record.FTVL
return self.__super.init_record(record)
return super().init_record(record)

def _read_value(self, record):
nord = record.NORD
Expand Down
49 changes: 5 additions & 44 deletions softioc/device_core.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,11 @@
from __future__ import print_function

import sys
from . import imports
from .fields import RecordFactory
from ctypes import *


# Black magic lifted from six.py (http://pypi.python.org/pypi/six/) to replace
# use of __metaclass__ for metaclass definition
def with_metaclass(meta, *bases):
class metaclass(meta):
def __new__(cls, name, this_bases, d):
return meta(name, bases, d)
return type.__new__(metaclass, 'temporary_class', (), {})


class InitClass(type):
def __new__(cls, name, bases, dict):
if '__init_class__' in dict:
dict['__init_class__'] = classmethod(dict['__init_class__'])
return type.__new__(cls, name, bases, dict)

def __init__(cls, name, bases, dict):
type.__init__(cls, name, bases, dict)
# Binds self.__super.method to the appropriate superclass method
setattr(cls, '_%s__super' % name.lstrip('_'), super(cls))
# Binds cls.__super_cls().method to the appropriate superclass
# class method. Unfortunately the .__super form doesn't work
# with class methods, only instance methods.
setattr(
cls, '_%s__super_cls' % name,
classmethod(lambda child: super(cls, child)))
# Finally call the class initialisatio nmethod.
cls.__init_class__()

class DeviceCommon(with_metaclass(InitClass)):
'''Adds support for an __init_class__ method called when the class or any
of its subclasses is constructed. Also adds auto-super functionality
(see iocbuilder.support.autosuper).'''

def __init_class__(cls): pass

class DeviceCommon:
# By requiring that DeviceCommon be a common base class for the entire
# Python device hierarchy, we can use this __init__ to test for unused
# keyword arguments.
Expand Down Expand Up @@ -83,20 +48,16 @@ class DeviceSupportCore(DeviceCommon):
# treatment) are then bound to the appropriate class instance and the
# appropriate method is invoked.

def __init_class__(cls):
def __init_subclass__(cls):
'''Record support initialisation, called once during class
initialisation for each sub-class. This registers record support for
the specified device name.'''

if not hasattr(cls, '_record_type_'):
# If no record type has been specified then we're a base class
# with nothing to do.
return

# Create an empty device directory.
# (Potentially this belongs in a mix-in for resolving the linkage
# between record and instances, but for now this is hard-wired here.)
cls.__device_directory = {}

Comment on lines -95 to -99
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting: I can find no trace of this symbol anywhere else (even using git log -S)! I guess this was an idea that either never happened or has been erased.

# Convert the list of fields into a dictionary suitable for record
# lookup.
fields = set([cls._link_] + cls.__preset_fields + cls._fields_)
Expand Down Expand Up @@ -194,7 +155,7 @@ def __init__(self, name, **kargs):
# a call to get_ioinit_info. This is only a trivial attempt to
# reduce resource consumption.
self.__ioscanpvt = imports.IOSCANPVT()
self.__super.__init__(name, **kargs)
super().__init__(name, **kargs)


def init_record(self, record):
Expand Down Expand Up @@ -245,7 +206,7 @@ def __init__(self, name, **kargs):
'Record %s already registered' % name
self._name = name
self._RecordDirectory[name] = self
self.__super.__init__(name, **kargs)
super().__init__(name, **kargs)


LookupRecord = RecordLookup.LookupRecord
Expand Down
Loading