python: Make meta class declarations Python 3 safe
Python 2.x and Python 3 use different meta class syntax. Fix this by implementing meta classes using the add_metaclass decorator in the six Python library. Due to the way meta classes are implemented in six, MetaParamValue.__new__ seems to be called twice for some classes. This triggers an assertion which when param that checks that Param types have only been registered once. I have turned this assertion into a warning. The assertion was triggered in params.CheckedInt and params.Enum. It seems like the cause of the issue is that these classes have their own meta classes (CheckedIntType and MetaEnum) that inherit from MetaParamValue and a base class (ParamValue) that also inherits from MetaParamValue. Change-Id: I5dea08bf0558cfca57897a124cb131c78114e59e Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26083 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
committed by
Giacomo Travaglini
parent
ee9a360c60
commit
5d70afd3a9
@@ -40,6 +40,7 @@
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from six import add_metaclass
|
||||
import six
|
||||
if six.PY3:
|
||||
long = int
|
||||
@@ -1073,10 +1074,10 @@ class SimObjectCliWrapper(object):
|
||||
# The SimObject class is the root of the special hierarchy. Most of
|
||||
# the code in this class deals with the configuration hierarchy itself
|
||||
# (parent/child node relationships).
|
||||
@add_metaclass(MetaSimObject)
|
||||
class SimObject(object):
|
||||
# Specify metaclass. Any class inheriting from SimObject will
|
||||
# get this metaclass.
|
||||
__metaclass__ = MetaSimObject
|
||||
type = 'SimObject'
|
||||
abstract = True
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#####################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
from six import add_metaclass
|
||||
import six
|
||||
if six.PY3:
|
||||
long = int
|
||||
@@ -87,15 +88,17 @@ allParams = {}
|
||||
class MetaParamValue(type):
|
||||
def __new__(mcls, name, bases, dct):
|
||||
cls = super(MetaParamValue, mcls).__new__(mcls, name, bases, dct)
|
||||
assert name not in allParams
|
||||
if name in allParams:
|
||||
warn("%s already exists in allParams. This may be caused by the " \
|
||||
"Python 2.7 compatibility layer." % (name, ))
|
||||
allParams[name] = cls
|
||||
return cls
|
||||
|
||||
|
||||
# Dummy base class to identify types that are legitimate for SimObject
|
||||
# parameters.
|
||||
@add_metaclass(MetaParamValue)
|
||||
class ParamValue(object):
|
||||
__metaclass__ = MetaParamValue
|
||||
cmd_line_settable = False
|
||||
|
||||
# Generate the code needed as a prerequisite for declaring a C++
|
||||
@@ -233,8 +236,8 @@ class ParamDesc(object):
|
||||
# that the value is a vector (list) of the specified type instead of a
|
||||
# single value.
|
||||
|
||||
@add_metaclass(MetaParamValue)
|
||||
class VectorParamValue(list):
|
||||
__metaclass__ = MetaParamValue
|
||||
def __setattr__(self, attr, value):
|
||||
raise AttributeError("Not allowed to set %s on '%s'" % \
|
||||
(attr, type(self).__name__))
|
||||
@@ -585,8 +588,8 @@ class CheckedIntType(MetaParamValue):
|
||||
# class is subclassed to generate parameter classes with specific
|
||||
# bounds. Initialization of the min and max bounds is done in the
|
||||
# metaclass CheckedIntType.__init__.
|
||||
@add_metaclass(CheckedIntType)
|
||||
class CheckedInt(NumericParamValue):
|
||||
__metaclass__ = CheckedIntType
|
||||
cmd_line_settable = True
|
||||
|
||||
def _check(self):
|
||||
@@ -1294,7 +1297,6 @@ allEnums = {}
|
||||
# Metaclass for Enum types
|
||||
class MetaEnum(MetaParamValue):
|
||||
def __new__(mcls, name, bases, dict):
|
||||
assert name not in allEnums
|
||||
|
||||
cls = super(MetaEnum, mcls).__new__(mcls, name, bases, dict)
|
||||
allEnums[name] = cls
|
||||
@@ -1445,8 +1447,8 @@ module_init(py::module &m_internal)
|
||||
|
||||
|
||||
# Base class for enum types.
|
||||
@add_metaclass(MetaEnum)
|
||||
class Enum(ParamValue):
|
||||
__metaclass__ = MetaEnum
|
||||
vals = []
|
||||
cmd_line_settable = True
|
||||
|
||||
@@ -1499,8 +1501,8 @@ class Enum(ParamValue):
|
||||
return self.value
|
||||
|
||||
# This param will generate a scoped c++ enum and its python bindings.
|
||||
@add_metaclass(MetaEnum)
|
||||
class ScopedEnum(Enum):
|
||||
__metaclass__ = MetaEnum
|
||||
vals = []
|
||||
cmd_line_settable = True
|
||||
|
||||
@@ -1787,8 +1789,8 @@ class MemoryBandwidth(float,ParamValue):
|
||||
# make_param_value() above that lets these be assigned where a
|
||||
# SimObject is required.
|
||||
# only one copy of a particular node
|
||||
@add_metaclass(Singleton)
|
||||
class NullSimObject(object):
|
||||
__metaclass__ = Singleton
|
||||
_name = 'Null'
|
||||
|
||||
def __call__(cls):
|
||||
@@ -2155,9 +2157,8 @@ VectorSlavePort = VectorResponsePort
|
||||
# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of
|
||||
# proxy objects (via set_param_desc()) so that proxy error messages
|
||||
# make sense.
|
||||
@add_metaclass(Singleton)
|
||||
class PortParamDesc(object):
|
||||
__metaclass__ = Singleton
|
||||
|
||||
ptype_str = 'Port'
|
||||
ptype = Port
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from __future__ import print_function
|
||||
from six import add_metaclass
|
||||
|
||||
try:
|
||||
import builtins
|
||||
@@ -112,9 +113,8 @@ class code_formatter_meta(type):
|
||||
}
|
||||
cls.pattern = re.compile(pat, re.VERBOSE | re.DOTALL | re.MULTILINE)
|
||||
|
||||
@add_metaclass(code_formatter_meta)
|
||||
class code_formatter(object):
|
||||
__metaclass__ = code_formatter_meta
|
||||
|
||||
delim = r'$'
|
||||
ident = r'[_A-z]\w*'
|
||||
pos = r'[0-9]+'
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from six import add_metaclass
|
||||
|
||||
from abc import *
|
||||
|
||||
@add_metaclass(ABCMeta)
|
||||
class PyBindExport(object):
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@abstractmethod
|
||||
def export(self, code, cname):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user