diff --git a/evennia/commands/cmdset.py b/evennia/commands/cmdset.py index b3d16d0abd..7d30d4ed1c 100644 --- a/evennia/commands/cmdset.py +++ b/evennia/commands/cmdset.py @@ -30,6 +30,7 @@ Set theory. from weakref import WeakKeyDictionary from django.utils.translation import ugettext as _ from evennia.utils.utils import inherits_from, is_iter +from future.utils import with_metaclass __all__ = ("CmdSet",) @@ -56,7 +57,7 @@ class _CmdSetMeta(type): super(_CmdSetMeta, mcs).__init__(*args, **kwargs) -class CmdSet(object): +class CmdSet(with_metaclass(_CmdSetMeta, object)): """ This class describes a unique cmdset that understands priorities. CmdSets can be merged and made to perform various set operations @@ -138,7 +139,6 @@ class CmdSet(object): """ - __metaclass__ = _CmdSetMeta key = "Unnamed CmdSet" mergetype = "Union" diff --git a/evennia/commands/command.py b/evennia/commands/command.py index 80f9ecd31a..ecd938c06b 100644 --- a/evennia/commands/command.py +++ b/evennia/commands/command.py @@ -8,6 +8,7 @@ All commands in Evennia inherit from the 'Command' class in this module. import re from evennia.locks.lockhandler import LockHandler from evennia.utils.utils import is_iter, fill, lazy_property +from future.utils import with_metaclass def _init_command(mcs, **kwargs): @@ -87,7 +88,7 @@ class CommandMeta(type): # parsing errors. -class Command(object): +class Command(with_metaclass(CommandMeta, object)): """ Base command @@ -127,8 +128,6 @@ class Command(object): system to create the help entry for the command, so it's a good idea to format it similar to this one) """ - # Tie our metaclass, for some convenience cleanup - __metaclass__ = CommandMeta # the main way to call this command (e.g. 'look') key = "command" diff --git a/evennia/comms/comms.py b/evennia/comms/comms.py index c7403f5bec..614edcd9bd 100644 --- a/evennia/comms/comms.py +++ b/evennia/comms/comms.py @@ -8,16 +8,15 @@ from evennia.comms.models import Msg, TempMsg, ChannelDB from evennia.comms.managers import ChannelManager from evennia.utils import logger from evennia.utils.utils import make_iter +from future.utils import with_metaclass -class DefaultChannel(ChannelDB): +class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)): """ This is the base class for all Channel Comms. Inherit from this to create different types of communication channels. """ - # typeclass setup - __metaclass__ = TypeclassBase objects = ChannelManager() def at_first_save(self): diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index e060b9e99e..59ba0073e6 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -20,6 +20,7 @@ from evennia.commands import cmdhandler from evennia.utils import logger from evennia.utils.utils import (variable_from_module, lazy_property, make_iter, to_str, to_unicode) +from future.utils import with_metaclass _MULTISESSION_MODE = settings.MULTISESSION_MODE @@ -120,7 +121,7 @@ class SessidHandler(object): # Base class to inherit from. # -class DefaultObject(ObjectDB): +class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): """ This is the root typeclass object, representing all entities that have an actual presence in-game. DefaultObjects generally have a @@ -133,8 +134,6 @@ class DefaultObject(ObjectDB): without `obj.save()` having to be called explicitly. """ - # typeclass setup - __metaclass__ = TypeclassBase objects = ObjectManager() # on-object properties diff --git a/evennia/players/players.py b/evennia/players/players.py index 0d880f8bfe..a546d6c7db 100644 --- a/evennia/players/players.py +++ b/evennia/players/players.py @@ -28,6 +28,7 @@ from evennia.scripts.scripthandler import ScriptHandler from evennia.commands.cmdsethandler import CmdSetHandler from django.utils.translation import ugettext as _ +from future.utils import with_metaclass __all__ = ("DefaultPlayer",) @@ -38,7 +39,7 @@ _MULTISESSION_MODE = settings.MULTISESSION_MODE _CMDSET_PLAYER = settings.CMDSET_PLAYER _CONNECT_CHANNEL = None -class DefaultPlayer(PlayerDB): +class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)): """ This is the base Typeclass for all Players. Players represent the person playing the game and tracks account info, password @@ -107,8 +108,6 @@ class DefaultPlayer(PlayerDB): """ - __metaclass__ = TypeclassBase - objects = PlayerManager() # properties diff --git a/evennia/scripts/scripts.py b/evennia/scripts/scripts.py index c7ddc8c725..762c8c03a0 100644 --- a/evennia/scripts/scripts.py +++ b/evennia/scripts/scripts.py @@ -12,6 +12,7 @@ from evennia.typeclasses.models import TypeclassBase from evennia.scripts.models import ScriptDB from evennia.scripts.manager import ScriptManager from evennia.utils import logger +from future.utils import with_metaclass __all__ = ["DefaultScript", "DoNothing", "Store"] @@ -132,13 +133,12 @@ class ExtendedLoopingCall(LoopingCall): return interval - (total_runtime % self.interval) return None -class ScriptBase(ScriptDB): +class ScriptBase(with_metaclass(TypeclassBase, ScriptDB)): """ Base class for scripts. Don't inherit from this, inherit from the class `DefaultScript` below instead. """ - __metaclass__ = TypeclassBase objects = ScriptManager() diff --git a/evennia/utils/ansi.py b/evennia/utils/ansi.py index adc0aef82d..0f7e93e2a4 100644 --- a/evennia/utils/ansi.py +++ b/evennia/utils/ansi.py @@ -16,6 +16,7 @@ user. import re from evennia.utils import utils from evennia.utils.utils import to_str, to_unicode +from future.utils import with_metaclass # ANSI definitions @@ -555,7 +556,7 @@ class ANSIMeta(type): super(ANSIMeta, cls).__init__(*args, **kwargs) -class ANSIString(unicode): +class ANSIString(with_metaclass(ANSIMeta, unicode)): """ String-like object that is aware of ANSI codes. @@ -572,7 +573,6 @@ class ANSIString(unicode): for several of the methods that need not be defined directly here. """ - __metaclass__ = ANSIMeta def __new__(cls, *args, **kwargs): """ diff --git a/evennia/utils/idmapper/models.py b/evennia/utils/idmapper/models.py index 005b788a63..e91e49a202 100644 --- a/evennia/utils/idmapper/models.py +++ b/evennia/utils/idmapper/models.py @@ -21,6 +21,7 @@ from evennia.utils import logger from evennia.utils.utils import dbref, get_evennia_pids, to_str from .manager import SharedMemoryManager +from future.utils import with_metaclass AUTO_FLUSH_MIN_INTERVAL = 60.0 * 5 # at least 5 mins between cache flushes @@ -200,13 +201,10 @@ class SharedMemoryModelBase(ModelBase): return super(SharedMemoryModelBase, cls).__new__(cls, name, bases, attrs) -class SharedMemoryModel(Model): +class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): """ Base class for idmapped objects. Inherit from `this`. """ - # CL: setting abstract correctly to allow subclasses to inherit the default - # manager. - __metaclass__ = SharedMemoryModelBase objects = SharedMemoryManager() @@ -415,12 +413,11 @@ class WeakSharedMemoryModelBase(SharedMemoryModelBase): cls._idmapper_recache_protection = False -class WeakSharedMemoryModel(SharedMemoryModel): +class WeakSharedMemoryModel(with_metaclass(WeakSharedMemoryModelBase, SharedMemoryModel)): """ Uses a WeakValue dictionary for caching instead of a regular one """ - __metaclass__ = WeakSharedMemoryModelBase class Meta: abstract = True diff --git a/evennia/utils/picklefield.py b/evennia/utils/picklefield.py index 8bc8576def..7a3ba70cb4 100644 --- a/evennia/utils/picklefield.py +++ b/evennia/utils/picklefield.py @@ -44,6 +44,7 @@ from django.forms.util import flatatt from django.utils.html import format_html from evennia.utils.dbserialize import from_pickle, to_pickle +from future.utils import with_metaclass try: from django.utils.encoding import force_text @@ -167,7 +168,7 @@ class PickledFormField(CharField): raise ValidationError(self.error_messages['invalid']) -class PickledObjectField(_get_subfield_superclass()): +class PickledObjectField(with_metaclass(models.SubfieldBase, _get_subfield_superclass())): """ A field that will accept *any* python object and store it in the database. PickledObjectField will optionally compress its values if @@ -177,7 +178,6 @@ class PickledObjectField(_get_subfield_superclass()): can still do lookups using None). This way, it is still possible to use the ``isnull`` lookup type correctly. """ - __metaclass__ = models.SubfieldBase # for django < 1.3 def __init__(self, *args, **kwargs): self.compress = kwargs.pop('compress', False) diff --git a/requirements.txt b/requirements.txt index 8894232705..eb31de91a8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ twisted >= 15.2.1 mock >= 1.0.1 pillow == 2.9.0 pytz +future >= 0.15.2 diff --git a/win_requirements.txt b/win_requirements.txt index 787d643678..90798c1f86 100644 --- a/win_requirements.txt +++ b/win_requirements.txt @@ -8,3 +8,4 @@ twisted >= 15.2.1 mock >= 1.0.1 pillow == 2.9.0 pytz +future >= 0.15.2