From 20a6e95c0caa6671d1e8a87c0fce85f3a6c56451 Mon Sep 17 00:00:00 2001 From: Robin De Schepper Date: Sat, 20 Mar 2021 18:03:11 +0100 Subject: [PATCH] Apply changes only to Python 3.6+ where metaclass alternative is availbl --- share/lib/python/neuron/__init__.py | 5 +++- share/lib/python/neuron/hclass35.py | 40 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 share/lib/python/neuron/hclass35.py diff --git a/share/lib/python/neuron/__init__.py b/share/lib/python/neuron/__init__.py index cbad1d1e56..a608e285f8 100644 --- a/share/lib/python/neuron/__init__.py +++ b/share/lib/python/neuron/__init__.py @@ -242,7 +242,10 @@ def test_rxd(exitOnError=True): from neuron.hclass2 import hclass else: sys.modules["neuron.hclass2"] = types.ModuleType("neuron.hclass2") - from neuron.hclass3 import HocBaseObject, hclass, nonlocal_hclass + if sys.version_info[0] == 3 and sys.version_info[1] < 6: + from neuron.hclass35 import hclass + else: + from neuron.hclass import HocBaseObject, hclass, nonlocal_hclass # global list of paths already loaded by load_mechanisms nrn_dll_loaded = [] diff --git a/share/lib/python/neuron/hclass35.py b/share/lib/python/neuron/hclass35.py new file mode 100644 index 0000000000..98c014f0f1 --- /dev/null +++ b/share/lib/python/neuron/hclass35.py @@ -0,0 +1,40 @@ +#Python 3.0-3.5 only +# ------------------------------------------------------------------------------ +# class factory for subclassing h.anyclass +# h.anyclass methods may be overridden. If so the base method can be called +# using the idiom self.basemethod = self.baseattr('methodname') +# ------------------------------------------------------------------------------ + +from neuron import h, hoc +import nrn + +#avoid syntax error if compiled by python 2 + +class MetaHocObject(type): + """Provides Exception for Inheritance of multiple HocObject""" + def __new__(cls, name, bases, attrs): + #print cls, name, bases + m = [] + for b in bases: + if issubclass(b, hoc.HocObject): + m.append(b.__name__) + if (len(m) > 1): + raise TypeError('Multiple Inheritance of HocObject in %s' % name + + ' through %s not allowed' % ','.join(m)) + #note that join(b.__name__ for b in m) is not valid for Python 2.3 + + return type.__new__(cls, name, bases, attrs) + +def hclass(c): + """Class factory for subclassing h.anyclass. E.g. class MyList(hclass(h.List)):...""" + if c == h.Section : + return nrn.Section + class hc(hoc.HocObject, metaclass=MetaHocObject): + #class hc(hoc.HocObject): + def __new__(cls, *args, **kwds): + kwds2 = {'hocbase': cls.htype} + if 'sec' in kwds: + kwds2['sec'] = kwds['sec'] + return hoc.HocObject.__new__(cls, *args, **kwds2) + setattr(hc, 'htype', c) + return hc