From bd33886cc0c870740d1a1f1f80101eb724af38d0 Mon Sep 17 00:00:00 2001 From: Greg Taylor Date: Sat, 14 Sep 2019 23:47:00 -0700 Subject: [PATCH] Remove uses of the 'future' py2->3 module This is no longer needed, now that we are Py3.7+ only. One layer of indirection removed, and one less dependency. --- evennia/accounts/accounts.py | 3 +-- evennia/commands/cmdset.py | 6 ++---- evennia/commands/cmdsethandler.py | 13 ++++++------- evennia/commands/command.py | 4 +--- evennia/comms/comms.py | 4 ++-- evennia/contrib/tutorial_world/objects.py | 3 +-- evennia/objects/objects.py | 3 +-- evennia/scripts/scripts.py | 3 +-- evennia/server/inputfuncs.py | 1 - evennia/server/portal/irc.py | 7 +++---- evennia/server/sessionhandler.py | 3 +-- evennia/utils/ansi.py | 3 +-- evennia/utils/evtable.py | 6 ++---- evennia/utils/idmapper/models.py | 9 ++++----- requirements.txt | 1 - win_requirements.txt | 1 - 16 files changed, 26 insertions(+), 44 deletions(-) diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 4920f734a7..5214a58fe2 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -37,7 +37,6 @@ from evennia.commands.cmdsethandler import CmdSetHandler from evennia.utils.optionhandler import OptionHandler from django.utils.translation import ugettext as _ -from future.utils import with_metaclass from random import getrandbits __all__ = ("DefaultAccount",) @@ -113,7 +112,7 @@ class AccountSessionHandler(object): return len(self.get()) -class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)): +class DefaultAccount(AccountDB, metaclass=TypeclassBase): """ This is the base Typeclass for all Accounts. Accounts represent the person playing the game and tracks account info, password diff --git a/evennia/commands/cmdset.py b/evennia/commands/cmdset.py index 95bbf9da22..596c01f745 100644 --- a/evennia/commands/cmdset.py +++ b/evennia/commands/cmdset.py @@ -26,8 +26,6 @@ Set theory. to affect the low-priority cmdset. Ex: A1,A3 + B1,B2,B4,B5 = B2,B4,B5 """ -from future.utils import listvalues, with_metaclass - from weakref import WeakKeyDictionary from django.utils.translation import ugettext as _ from evennia.utils.utils import inherits_from, is_iter @@ -57,7 +55,7 @@ class _CmdSetMeta(type): super().__init__(*args, **kwargs) -class CmdSet(with_metaclass(_CmdSetMeta, object)): +class CmdSet(object, metaclass=_CmdSetMeta): """ This class describes a unique cmdset that understands priorities. CmdSets can be merged and made to perform various set operations @@ -585,7 +583,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)): unique[cmd.key] = cmd else: unique[cmd.key] = cmd - self.commands = listvalues(unique) + self.commands = list(unique.values()) def get_all_cmd_keys_and_aliases(self, caller=None): """ diff --git a/evennia/commands/cmdsethandler.py b/evennia/commands/cmdsethandler.py index d332c7fcd2..bc0b759031 100644 --- a/evennia/commands/cmdsethandler.py +++ b/evennia/commands/cmdsethandler.py @@ -64,7 +64,6 @@ example, you can have a 'On a boat' set, onto which you then tack on the 'Fishing' set. Fishing from a boat? No problem! """ from builtins import object -from future.utils import raise_ import sys from traceback import format_exc from importlib import import_module @@ -172,22 +171,22 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False): if not cmdsetclass: try: module = import_module(modpath, package="evennia") - except ImportError: + except ImportError as exc: if len(trace()) > 2: # error in module, make sure to not hide it. - exc = sys.exc_info() - raise_(exc[1], None, exc[2]) + _, _, tb = sys.exc_info() + raise exc.with_traceback(tb) else: # try next suggested path errstring += _("\n(Unsuccessfully tried '%s')." % python_path) continue try: cmdsetclass = getattr(module, classname) - except AttributeError: + except AttributeError as exc: if len(trace()) > 2: # Attribute error within module, don't hide it - exc = sys.exc_info() - raise_(exc[1], None, exc[2]) + _, _, tb = sys.exc_info() + raise exc.with_traceback(tb) else: errstring += _("\n(Unsuccessfully tried '%s')." % python_path) continue diff --git a/evennia/commands/command.py b/evennia/commands/command.py index ce9fbb1885..6858d24671 100644 --- a/evennia/commands/command.py +++ b/evennia/commands/command.py @@ -16,8 +16,6 @@ from evennia.utils.utils import is_iter, fill, lazy_property, make_iter from evennia.utils.evtable import EvTable from evennia.utils.ansi import ANSIString -from future.utils import with_metaclass - def _init_command(cls, **kwargs): """ @@ -99,7 +97,7 @@ class CommandMeta(type): # parsing errors. -class Command(with_metaclass(CommandMeta, object)): +class Command(object, metaclass=CommandMeta): """ Base command diff --git a/evennia/comms/comms.py b/evennia/comms/comms.py index 8c885d3458..309f3cd9ae 100644 --- a/evennia/comms/comms.py +++ b/evennia/comms/comms.py @@ -11,11 +11,11 @@ from evennia.comms.models import TempMsg, ChannelDB from evennia.comms.managers import ChannelManager from evennia.utils import create, logger from evennia.utils.utils import make_iter -from future.utils import with_metaclass + _CHANNEL_HANDLER = None -class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)): +class DefaultChannel(ChannelDB, metaclass=TypeclassBase): """ This is the base class for all Channel Comms. Inherit from this to create different types of communication channels. diff --git a/evennia/contrib/tutorial_world/objects.py b/evennia/contrib/tutorial_world/objects.py index 7a9fe096ba..a4580fb518 100644 --- a/evennia/contrib/tutorial_world/objects.py +++ b/evennia/contrib/tutorial_world/objects.py @@ -18,7 +18,6 @@ Weapon WeaponRack """ -from future.utils import listvalues import random @@ -528,7 +527,7 @@ class CmdShiftRoot(Command): self.obj.db.root_pos = root_pos # Check victory condition - if listvalues(root_pos).count(0) == 0: # no roots in middle position + if list(root_pos.values()).count(0) == 0: # no roots in middle position # This will affect the cmd: lock of CmdPressButton self.obj.db.button_exposed = True self.caller.msg("Holding aside the root you think you notice something behind it ...") diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index fd76fae645..61dd3aed44 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -8,7 +8,6 @@ entities. import time import inflect from builtins import object -from future.utils import with_metaclass from collections import defaultdict from django.conf import settings @@ -179,7 +178,7 @@ class ObjectSessionHandler(object): # Base class to inherit from. -class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): +class DefaultObject(ObjectDB, metaclass=TypeclassBase): """ This is the root typeclass object, representing all entities that have an actual presence in-game. DefaultObjects generally have a diff --git a/evennia/scripts/scripts.py b/evennia/scripts/scripts.py index b7e3296319..72f46d8e21 100644 --- a/evennia/scripts/scripts.py +++ b/evennia/scripts/scripts.py @@ -13,7 +13,6 @@ from evennia.typeclasses.models import TypeclassBase from evennia.scripts.models import ScriptDB from evennia.scripts.manager import ScriptManager from evennia.utils import create, logger -from future.utils import with_metaclass __all__ = ["DefaultScript", "DoNothing", "Store"] @@ -144,7 +143,7 @@ class ExtendedLoopingCall(LoopingCall): return None -class ScriptBase(with_metaclass(TypeclassBase, ScriptDB)): +class ScriptBase(ScriptDB, metaclass=TypeclassBase): """ Base class for scripts. Don't inherit from this, inherit from the class `DefaultScript` below instead. diff --git a/evennia/server/inputfuncs.py b/evennia/server/inputfuncs.py index 4eee991188..08427658b9 100644 --- a/evennia/server/inputfuncs.py +++ b/evennia/server/inputfuncs.py @@ -19,7 +19,6 @@ Evennia knows which modules to use for inputfuncs by settings.INPUT_FUNC_MODULES. """ -from future.utils import viewkeys import importlib from codecs import lookup as codecs_lookup diff --git a/evennia/server/portal/irc.py b/evennia/server/portal/irc.py index 2b616f2ce1..e4273e4cc5 100644 --- a/evennia/server/portal/irc.py +++ b/evennia/server/portal/irc.py @@ -3,7 +3,6 @@ This connects to an IRC network/channel and launches an 'bot' onto it. The bot then pipes what is being said between the IRC channel and one or more Evennia channels. """ -from future.utils import viewkeys, viewvalues, viewitems import re from twisted.application import internet @@ -90,15 +89,15 @@ IRC_COLOR_MAP = dict(( )) # ansi->irc RE_ANSI_COLOR = re.compile(r"|".join( - [re.escape(key) for key in viewkeys(IRC_COLOR_MAP)]), re.DOTALL) + [re.escape(key) for key in IRC_COLOR_MAP.keys()]), re.DOTALL) RE_MXP = re.compile(r'\|lc(.*?)\|lt(.*?)\|le', re.DOTALL) RE_ANSI_ESCAPES = re.compile(r"(%s)" % "|".join(("{{", "%%", "\\\\")), re.DOTALL) # irc->ansi _CLR_LIST = [re.escape(val) - for val in sorted(viewvalues(IRC_COLOR_MAP), key=len, reverse=True) if val.strip()] + for val in sorted(IRC_COLOR_MAP.values(), key=len, reverse=True) if val.strip()] _CLR_LIST = _CLR_LIST[-2:] + _CLR_LIST[:-2] RE_IRC_COLOR = re.compile(r"|".join(_CLR_LIST), re.DOTALL) -ANSI_COLOR_MAP = dict((tup[1], tup[0]) for tup in viewitems(IRC_COLOR_MAP) if tup[1].strip()) +ANSI_COLOR_MAP = dict((tup[1], tup[0]) for tup in IRC_COLOR_MAP.items() if tup[1].strip()) def parse_ansi_to_irc(string): diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index cdb9a1ab1d..cfded91906 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -14,7 +14,6 @@ There are two similar but separate stores of sessions: """ import time from builtins import object -from future.utils import listvalues from django.conf import settings from evennia.commands.cmdhandler import CMD_LOGINSTART @@ -148,7 +147,7 @@ class SessionHandler(dict): """ if include_unloggedin: - return listvalues(self) + return list(self.values()) else: return [session for session in self.values() if session.logged_in] diff --git a/evennia/utils/ansi.py b/evennia/utils/ansi.py index a10c6a4e2c..7eec5f95b3 100644 --- a/evennia/utils/ansi.py +++ b/evennia/utils/ansi.py @@ -25,7 +25,6 @@ from evennia.utils import utils from evennia.utils import logger from evennia.utils.utils import to_str -from future.utils import with_metaclass # ANSI definitions @@ -631,7 +630,7 @@ class ANSIMeta(type): super().__init__(*args, **kwargs) -class ANSIString(with_metaclass(ANSIMeta, str)): +class ANSIString(str, metaclass=ANSIMeta): """ Unicode-like object that is aware of ANSI codes. diff --git a/evennia/utils/evtable.py b/evennia/utils/evtable.py index 29c4340d00..90cf1d2f44 100644 --- a/evennia/utils/evtable.py +++ b/evennia/utils/evtable.py @@ -111,8 +111,6 @@ table string. """ -from future.utils import listitems - from django.conf import settings from textwrap import TextWrapper from copy import deepcopy, copy @@ -1464,7 +1462,7 @@ class EvTable(object): """ # this will replace default options with new ones without changing default - options = dict(listitems(self.options) + listitems(kwargs)) + options = dict(list(self.options.items()) + list(kwargs.items())) xpos = kwargs.get("xpos", None) column = EvColumn(*args, **options) @@ -1529,7 +1527,7 @@ class EvTable(object): """ # this will replace default options with new ones without changing default row = list(args) - options = dict(listitems(self.options) + listitems(kwargs)) + options = dict(list(self.options.items()) + list(kwargs.items())) ypos = kwargs.get("ypos", None) wtable = self.ncols diff --git a/evennia/utils/idmapper/models.py b/evennia/utils/idmapper/models.py index 57a7cbaacd..b8f2db0444 100644 --- a/evennia/utils/idmapper/models.py +++ b/evennia/utils/idmapper/models.py @@ -8,7 +8,6 @@ Also adds `cache_size()` for monitoring the size of the cache. """ from builtins import object -from future.utils import listitems, listvalues, with_metaclass import os import threading @@ -197,7 +196,7 @@ class SharedMemoryModelBase(ModelBase): return # dynamically create the wrapper properties for all fields not already handled # (manytomanyfields are always handlers) - for fieldname, field in ((fname, field) for fname, field in listitems(attrs) + for fieldname, field in ((fname, field) for fname, field in list(attrs.items()) if fname.startswith("db_") and type(field).__name__ != "ManyToManyField"): foreignkey = type(field).__name__ == "ForeignKey" wrappername = "dbid" if fieldname == "id" else fieldname.replace("db_", "", 1) @@ -208,7 +207,7 @@ class SharedMemoryModelBase(ModelBase): return super().__new__(cls, name, bases, attrs) -class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): +class SharedMemoryModel(Model, metaclass=SharedMemoryModelBase): """ Base class for idmapped objects. Inherit from `this`. """ @@ -291,7 +290,7 @@ class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): Return the objects so far cached by idmapper for this class. """ - return listvalues(cls.__dbclass__.__instance_cache__) + return list(cls.__dbclass__.__instance_cache__.values()) @classmethod def _flush_cached_by_key(cls, key, force=True): @@ -457,7 +456,7 @@ class WeakSharedMemoryModelBase(SharedMemoryModelBase): cls.__dbclass__.__instance_cache__ = WeakValueDictionary() -class WeakSharedMemoryModel(with_metaclass(WeakSharedMemoryModelBase, SharedMemoryModel)): +class WeakSharedMemoryModel(SharedMemoryModel, metaclass=WeakSharedMemoryModelBase): """ Uses a WeakValue dictionary for caching instead of a regular one diff --git a/requirements.txt b/requirements.txt index 4e3e79ab8a..63e7bdc70c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,6 @@ django >= 2.2.4, < 2.3 twisted >= 19.2.1, < 20.0.0 pillow == 5.2.0 pytz -future >= 0.15.2 django-sekizai inflect autobahn >= 17.9.3 diff --git a/win_requirements.txt b/win_requirements.txt index ea3bb46fb7..895da341bc 100644 --- a/win_requirements.txt +++ b/win_requirements.txt @@ -8,7 +8,6 @@ django >= 2.2.4, < 2.3 twisted >= 19.2.1, < 20.0.0 pillow == 5.2.0 pytz -future >= 0.15.2 django-sekizai autobahn >= 17.9.3 inflect