From 6fa280b9fdcee87835674242866ab13208803552 Mon Sep 17 00:00:00 2001 From: Ryan Stein Date: Sun, 29 Oct 2017 13:40:30 -0400 Subject: [PATCH] Run 2to3. --- bin/project_rename.py | 24 +- evennia/__init__.py | 4 +- evennia/accounts/accounts.py | 4 +- evennia/accounts/bots.py | 2 +- evennia/accounts/manager.py | 4 +- evennia/accounts/migrations/0001_initial.py | 2 +- .../accounts/migrations/0002_move_defaults.py | 2 +- .../migrations/0003_auto_20150209_2234.py | 2 +- .../migrations/0004_auto_20150403_2339.py | 2 +- .../migrations/0005_auto_20160905_0902.py | 2 +- .../migrations/0006_auto_20170606_1731.py | 2 +- .../migrations/0007_copy_player_to_account.py | 2 +- evennia/accounts/models.py | 2 +- evennia/commands/cmdhandler.py | 8 +- evennia/commands/cmdparser.py | 4 +- evennia/commands/cmdsethandler.py | 8 +- evennia/commands/command.py | 4 +- evennia/commands/default/account.py | 4 +- evennia/commands/default/building.py | 8 +- evennia/commands/default/comms.py | 2 +- evennia/commands/default/system.py | 14 +- evennia/commands/default/tests.py | 8 +- evennia/comms/channelhandler.py | 4 +- evennia/comms/comms.py | 2 +- evennia/comms/managers.py | 8 +- evennia/comms/migrations/0001_initial.py | 2 +- .../0002_msg_db_hide_from_objects.py | 2 +- .../migrations/0003_auto_20140917_0756.py | 2 +- .../migrations/0004_auto_20150118_1631.py | 2 +- .../migrations/0005_auto_20150223_1517.py | 2 +- .../0006_channeldb_db_object_subscriptions.py | 2 +- evennia/comms/migrations/0007_msg_db_tags.py | 2 +- .../migrations/0008_auto_20160905_0902.py | 2 +- .../migrations/0009_auto_20160921_1731.py | 2 +- .../migrations/0010_auto_20161206_1912.py | 2 +- .../migrations/0011_auto_20170217_2039.py | 2 +- .../migrations/0011_auto_20170606_1731.py | 2 +- .../migrations/0012_merge_20170617_2017.py | 2 +- .../migrations/0013_auto_20170705_1726.py | 2 +- .../migrations/0014_auto_20170705_1736.py | 2 +- .../migrations/0015_auto_20170706_2041.py | 2 +- evennia/comms/models.py | 4 +- evennia/contrib/barter.py | 2 +- evennia/contrib/clothing.py | 4 +- evennia/contrib/custom_gametime.py | 4 +- evennia/contrib/egi_client/client.py | 4 +- evennia/contrib/extended_room.py | 4 +- .../contrib/ingame_python/callbackhandler.py | 2 +- evennia/contrib/ingame_python/commands.py | 10 +- evennia/contrib/ingame_python/scripts.py | 10 +- evennia/contrib/ingame_python/tests.py | 6 +- evennia/contrib/ingame_python/utils.py | 6 +- evennia/contrib/mail.py | 2 +- evennia/contrib/mapbuilder.py | 12 +- evennia/contrib/rplanguage.py | 4 +- evennia/contrib/rpsystem.py | 14 +- evennia/contrib/tests.py | 26 +- evennia/contrib/tutorial_world/__init__.py | 2 +- evennia/contrib/tutorial_world/objects.py | 2 +- evennia/contrib/tutorial_world/rooms.py | 2 +- evennia/contrib/wilderness.py | 6 +- evennia/game_template/server/conf/settings.py | 2 +- evennia/help/migrations/0001_initial.py | 2 +- .../migrations/0002_auto_20170606_1731.py | 2 +- evennia/help/models.py | 2 +- evennia/locks/lockfuncs.py | 2 +- evennia/locks/lockhandler.py | 6 +- evennia/locks/tests.py | 36 +- evennia/objects/manager.py | 12 +- evennia/objects/migrations/0001_initial.py | 2 +- .../migrations/0002_auto_20140917_0756.py | 2 +- ...r_defaultexit_defaultobject_defaultroom.py | 2 +- .../migrations/0004_auto_20150118_1622.py | 2 +- .../migrations/0005_auto_20150403_2339.py | 2 +- .../migrations/0006_auto_20170606_1731.py | 2 +- .../migrations/0007_objectdb_db_account.py | 2 +- .../migrations/0008_auto_20170705_1736.py | 2 +- .../0009_remove_objectdb_db_player.py | 2 +- evennia/objects/models.py | 2 +- evennia/objects/objects.py | 8 +- evennia/scripts/manager.py | 4 +- evennia/scripts/migrations/0001_initial.py | 2 +- .../migrations/0002_auto_20150118_1625.py | 2 +- ...techannelhandler_validateidmappercache_.py | 2 +- .../migrations/0004_auto_20150306_1354.py | 12 +- .../migrations/0005_auto_20150306_1441.py | 2 +- .../migrations/0006_auto_20150310_2249.py | 12 +- .../migrations/0007_auto_20150403_2339.py | 2 +- .../migrations/0008_auto_20170606_1731.py | 2 +- .../migrations/0009_scriptdb_db_account.py | 2 +- .../migrations/0010_auto_20170705_1736.py | 2 +- .../0011_remove_scriptdb_db_player.py | 2 +- evennia/scripts/models.py | 2 +- evennia/scripts/monitorhandler.py | 8 +- evennia/scripts/taskhandler.py | 12 +- evennia/scripts/tickerhandler.py | 30 +- evennia/server/amp.py | 6 +- evennia/server/evennia_launcher.py | 20 +- evennia/server/evennia_runner.py | 16 +- evennia/server/initial_setup.py | 2 +- evennia/server/inputfuncs.py | 8 +- evennia/server/migrations/0001_initial.py | 2 +- evennia/server/models.py | 2 +- evennia/server/portal/mssp.py | 2 +- evennia/server/portal/portal.py | 2 +- evennia/server/portal/portalsessionhandler.py | 14 +- evennia/server/portal/ssh.py | 2 +- evennia/server/portal/ssl.py | 2 +- evennia/server/portal/telnet_oob.py | 10 +- evennia/server/portal/webclient_ajax.py | 2 +- evennia/server/profiling/dummyrunner.py | 4 +- evennia/server/profiling/memplot.py | 2 +- evennia/server/profiling/test_queries.py | 2 +- evennia/server/profiling/timetrace.py | 2 +- evennia/server/server.py | 8 +- evennia/server/serversession.py | 4 +- evennia/server/session.py | 4 +- evennia/server/sessionhandler.py | 34 +- evennia/server/webserver.py | 6 +- evennia/settings_default.py | 4 +- evennia/typeclasses/attributes.py | 16 +- evennia/typeclasses/managers.py | 6 +- .../typeclasses/migrations/0001_initial.py | 2 +- .../migrations/0002_auto_20150109_0913.py | 2 +- ...ltplayer_defaultroom_defaultscript_dono.py | 2 +- .../migrations/0004_auto_20151101_1759.py | 2 +- .../migrations/0005_auto_20160625_1812.py | 2 +- ...o_add_dbmodel_value_for_tags_attributes.py | 2 +- .../0007_tag_migrations_may_be_slow.py | 2 +- .../migrations/0008_lock_and_perm_rename.py | 2 +- .../0009_rename_player_cmdsets_typeclasses.py | 2 +- .../0010_delete_old_player_tables.py | 2 +- evennia/typeclasses/models.py | 4 +- evennia/typeclasses/tags.py | 8 +- evennia/utils/__init__.py | 2 +- evennia/utils/ansi.py | 18 +- evennia/utils/batchprocessors.py | 2 +- evennia/utils/create.py | 8 +- evennia/utils/dbserialize.py | 30 +- evennia/utils/eveditor.py | 6 +- evennia/utils/evform.py | 24 +- evennia/utils/evmenu.py | 10 +- evennia/utils/evtable.py | 26 +- evennia/utils/gametime.py | 2 +- evennia/utils/idmapper/models.py | 6 +- evennia/utils/idmapper/tests.py | 10 +- evennia/utils/inlinefuncs.py | 928 +++++++++--------- evennia/utils/logger.py | 2 +- evennia/utils/picklefield.py | 2 +- evennia/utils/spawner.py | 10 +- evennia/utils/tests/test_evform.py | 78 +- evennia/utils/tests/test_evmenu.py | 2 +- evennia/utils/tests/test_tagparsing.py | 52 +- evennia/utils/text2html.py | 4 +- evennia/utils/txws.py | 4 +- evennia/utils/utils.py | 34 +- evennia/web/webclient/views.py | 2 +- 157 files changed, 976 insertions(+), 976 deletions(-) diff --git a/bin/project_rename.py b/bin/project_rename.py index 8f22d75f1c..2d5bcb779e 100644 --- a/bin/project_rename.py +++ b/bin/project_rename.py @@ -6,7 +6,7 @@ Created for the Player->Account renaming Griatch 2017, released under the BSD license. """ -from __future__ import print_function + import re import sys @@ -130,7 +130,7 @@ def rename_in_tree(path, in_list, out_list, excl_list, fileend_list, is_interact replacements in each file. """ - repl_mapping = zip(in_list, out_list) + repl_mapping = list(zip(in_list, out_list)) for root, dirs, files in os.walk(path): @@ -155,13 +155,13 @@ def rename_in_tree(path, in_list, out_list, excl_list, fileend_list, is_interact for src, dst in repl_mapping: new_file = _case_sensitive_replace(new_file, src, dst) if new_file != file: - inp = raw_input(_green("Rename %s\n -> %s\n Y/[N]? > " % (file, new_file))) + inp = input(_green("Rename %s\n -> %s\n Y/[N]? > " % (file, new_file))) if inp.upper() == 'Y': new_full_path = os.path.join(root, new_file) try: os.rename(full_path, new_full_path) except OSError as err: - raw_input(_red("Could not rename - %s (return to skip)" % err)) + input(_red("Could not rename - %s (return to skip)" % err)) else: print("... Renamed.") else: @@ -171,12 +171,12 @@ def rename_in_tree(path, in_list, out_list, excl_list, fileend_list, is_interact for src, dst in repl_mapping: new_root = _case_sensitive_replace(new_root, src, dst) if new_root != root: - inp = raw_input(_green("Dir Rename %s\n -> %s\n Y/[N]? > " % (root, new_root))) + inp = input(_green("Dir Rename %s\n -> %s\n Y/[N]? > " % (root, new_root))) if inp.upper() == 'Y': try: os.rename(root, new_root) except OSError as err: - raw_input(_red("Could not rename - %s (return to skip)" % err)) + input(_red("Could not rename - %s (return to skip)" % err)) else: print("... Renamed.") else: @@ -204,7 +204,7 @@ def rename_in_file(path, in_list, out_list, is_interactive): with open(path, 'r') as fil: org_text = fil.read() - repl_mapping = zip(in_list, out_list) + repl_mapping = list(zip(in_list, out_list)) if not is_interactive: # just replace everything immediately @@ -239,12 +239,12 @@ def rename_in_file(path, in_list, out_list, is_interactive): while True: - for iline, renamed_line in sorted(renamed.items(), key=lambda tup: tup[0]): + for iline, renamed_line in sorted(list(renamed.items()), key=lambda tup: tup[0]): print("%3i orig: %s" % (iline + 1, org_lines[iline])) print(" new : %s" % (_yellow(renamed_line))) print(_green("%s (%i lines changed)" % (path, len(renamed)))) - ret = raw_input(_green("Choose: " + ret = input(_green("Choose: " "[q]uit, " "[h]elp, " "[s]kip file, " @@ -261,7 +261,7 @@ def rename_in_file(path, in_list, out_list, is_interactive): break elif ret == "a": # save result - for iline, renamed_line in renamed.items(): + for iline, renamed_line in list(renamed.items()): org_lines[iline] = renamed_line if FAKE_MODE: @@ -275,12 +275,12 @@ def rename_in_file(path, in_list, out_list, is_interactive): print("Quit renaming program.") sys.exit() elif ret == "h": - raw_input(_HELP_TEXT.format(sources=in_list, targets=out_list)) + input(_HELP_TEXT.format(sources=in_list, targets=out_list)) elif ret.startswith("i"): # ignore one or more lines ignores = [int(ind) - 1 for ind in ret[1:].split(',') if ind.strip().isdigit()] if not ignores: - raw_input("Ignore example: i 2,7,34,133\n (return to continue)") + input("Ignore example: i 2,7,34,133\n (return to continue)") continue for ign in ignores: renamed.pop(ign, None) diff --git a/evennia/__init__.py b/evennia/__init__.py index 6fdc4aaece..92026cb1ec 100644 --- a/evennia/__init__.py +++ b/evennia/__init__.py @@ -17,8 +17,8 @@ to launch such a shell (using python or ipython depending on your install). See www.evennia.com for full documentation. """ -from __future__ import print_function -from __future__ import absolute_import + + from builtins import object # Delayed loading of properties diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 9feed46d2e..aa68524383 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -491,7 +491,7 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)): """ # handle me, self and *me, *self - if isinstance(searchdata, basestring): + if isinstance(searchdata, str): # handle wrapping of common terms if searchdata.lower() in ("me", "*me", "self", "*self",): return self @@ -983,7 +983,7 @@ class DefaultGuest(DefaultAccount): characters = self.db._playable_characters for character in characters: if character: - print "deleting Character:", character + print("deleting Character:", character) character.delete() def at_post_disconnect(self, **kwargs): diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index b0a765fbba..f772e7c4d6 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -3,7 +3,7 @@ Bots are a special child typeclasses of Account that are controlled by the server. """ -from __future__ import print_function + import time from django.conf import settings from evennia.accounts.accounts import DefaultAccount diff --git a/evennia/accounts/manager.py b/evennia/accounts/manager.py index c612cf930d..ade900ea70 100644 --- a/evennia/accounts/manager.py +++ b/evennia/accounts/manager.py @@ -165,9 +165,9 @@ class AccountDBManager(TypedObjectManager, UserManager): if typeclass: # we accept both strings and actual typeclasses if callable(typeclass): - typeclass = u"%s.%s" % (typeclass.__module__, typeclass.__name__) + typeclass = "%s.%s" % (typeclass.__module__, typeclass.__name__) else: - typeclass = u"%s" % typeclass + typeclass = "%s" % typeclass query["db_typeclass_path"] = typeclass if exact: return self.filter(**query) diff --git a/evennia/accounts/migrations/0001_initial.py b/evennia/accounts/migrations/0001_initial.py index d8d267f20c..787eaa79cb 100644 --- a/evennia/accounts/migrations/0001_initial.py +++ b/evennia/accounts/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations import django.utils.timezone diff --git a/evennia/accounts/migrations/0002_move_defaults.py b/evennia/accounts/migrations/0002_move_defaults.py index 461525a4cc..f0b3d6dd51 100644 --- a/evennia/accounts/migrations/0002_move_defaults.py +++ b/evennia/accounts/migrations/0002_move_defaults.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/accounts/migrations/0003_auto_20150209_2234.py b/evennia/accounts/migrations/0003_auto_20150209_2234.py index ccdb2fb897..81bb39abdb 100644 --- a/evennia/accounts/migrations/0003_auto_20150209_2234.py +++ b/evennia/accounts/migrations/0003_auto_20150209_2234.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/accounts/migrations/0004_auto_20150403_2339.py b/evennia/accounts/migrations/0004_auto_20150403_2339.py index 36d8110122..b1412ae9a8 100644 --- a/evennia/accounts/migrations/0004_auto_20150403_2339.py +++ b/evennia/accounts/migrations/0004_auto_20150403_2339.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations import evennia.accounts.manager diff --git a/evennia/accounts/migrations/0005_auto_20160905_0902.py b/evennia/accounts/migrations/0005_auto_20160905_0902.py index 7ceaad2ac0..22f5955c1b 100644 --- a/evennia/accounts/migrations/0005_auto_20160905_0902.py +++ b/evennia/accounts/migrations/0005_auto_20160905_0902.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.9 on 2016-09-05 09:02 -from __future__ import unicode_literals + import django.core.validators from django.db import migrations, models diff --git a/evennia/accounts/migrations/0006_auto_20170606_1731.py b/evennia/accounts/migrations/0006_auto_20170606_1731.py index e48114b23c..c149d8b113 100644 --- a/evennia/accounts/migrations/0006_auto_20170606_1731.py +++ b/evennia/accounts/migrations/0006_auto_20170606_1731.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-06-06 17:31 -from __future__ import unicode_literals + import django.contrib.auth.validators from django.db import migrations, models diff --git a/evennia/accounts/migrations/0007_copy_player_to_account.py b/evennia/accounts/migrations/0007_copy_player_to_account.py index ea1e00448c..0e573f2fa5 100644 --- a/evennia/accounts/migrations/0007_copy_player_to_account.py +++ b/evennia/accounts/migrations/0007_copy_player_to_account.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-03 19:17 -from __future__ import unicode_literals + from django.apps import apps as global_apps from django.db import migrations diff --git a/evennia/accounts/models.py b/evennia/accounts/models.py index bf391b2d82..d9f59a43b0 100644 --- a/evennia/accounts/models.py +++ b/evennia/accounts/models.py @@ -139,7 +139,7 @@ class AccountDB(TypedObject, AbstractUser): return smart_str("%s(account %s)" % (self.name, self.dbid)) def __unicode__(self): - return u"%s(account#%s)" % (self.name, self.dbid) + return "%s(account#%s)" % (self.name, self.dbid) #@property def __username_get(self): diff --git a/evennia/commands/cmdhandler.py b/evennia/commands/cmdhandler.py index 44304b4ea1..b934932352 100644 --- a/evennia/commands/cmdhandler.py +++ b/evennia/commands/cmdhandler.py @@ -190,7 +190,7 @@ def _progressive_cmd_run(cmd, generator, response=None): try: if response is None: - value = generator.next() + value = next(generator) else: value = generator.send(response) except StopIteration: @@ -198,7 +198,7 @@ def _progressive_cmd_run(cmd, generator, response=None): else: if isinstance(value, (int, float)): utils.delay(value, _progressive_cmd_run, cmd, generator) - elif isinstance(value, basestring): + elif isinstance(value, str): _GET_INPUT(cmd.caller, value, _process_input, cmd=cmd, generator=generator) else: raise ValueError("unknown type for a yielded value in command: {}".format(type(value))) @@ -443,7 +443,7 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string) tempmergers[prio] = cmdset # sort cmdsets after reverse priority (highest prio are merged in last) - cmdsets = yield sorted(tempmergers.values(), key=lambda x: x.priority) + cmdsets = yield sorted(list(tempmergers.values()), key=lambda x: x.priority) # Merge all command sets into one, beginning with the lowest-prio one cmdset = cmdsets[0] @@ -567,7 +567,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess returnValue(cmd) # assign custom kwargs to found cmd object - for key, val in kwargs.items(): + for key, val in list(kwargs.items()): setattr(cmd, key, val) _COMMAND_NESTING[called_by] += 1 diff --git a/evennia/commands/cmdparser.py b/evennia/commands/cmdparser.py index e104233e49..c9055db8ca 100644 --- a/evennia/commands/cmdparser.py +++ b/evennia/commands/cmdparser.py @@ -5,7 +5,7 @@ replacing cmdparser function. The replacement parser must accept the same inputs as the default one. """ -from __future__ import division + import re from django.conf import settings @@ -70,7 +70,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None): the `raw_cmdname` is the cmdname unmodified by eventual prefix-stripping. """ - cmdlen, strlen = len(unicode(cmdname)), len(unicode(string)) + cmdlen, strlen = len(str(cmdname)), len(str(string)) mratio = 1 - (strlen - cmdlen) / (1.0 * strlen) args = string[cmdlen:] return (cmdname, args, cmdobj, cmdlen, mratio, raw_cmdname) diff --git a/evennia/commands/cmdsethandler.py b/evennia/commands/cmdsethandler.py index 84eea1fdc5..20b869dc39 100644 --- a/evennia/commands/cmdsethandler.py +++ b/evennia/commands/cmdsethandler.py @@ -422,13 +422,13 @@ class CmdSetHandler(object): it's a 'quirk' that has to be documented. """ - if not (isinstance(cmdset, basestring) or utils.inherits_from(cmdset, CmdSet)): + if not (isinstance(cmdset, str) or utils.inherits_from(cmdset, CmdSet)): string = _("Only CmdSets can be added to the cmdsethandler!") raise Exception(string) if callable(cmdset): cmdset = cmdset(self.obj) - elif isinstance(cmdset, basestring): + elif isinstance(cmdset, str): # this is (maybe) a python path. Try to import from cache. cmdset = self._import_cmdset(cmdset) if cmdset and cmdset.key != '_CMDSET_ERROR': @@ -586,11 +586,11 @@ class CmdSetHandler(object): """ if callable(cmdset) and hasattr(cmdset, 'path'): # try it as a callable - print "Try callable", cmdset + print("Try callable", cmdset) if must_be_default: return self.cmdset_stack and (self.cmdset_stack[0].path == cmdset.path) else: - print [cset.path for cset in self.cmdset_stack], cmdset.path + print([cset.path for cset in self.cmdset_stack], cmdset.path) return any([cset for cset in self.cmdset_stack if cset.path == cmdset.path]) else: diff --git a/evennia/commands/command.py b/evennia/commands/command.py index 48a4b132da..c30c74222e 100644 --- a/evennia/commands/command.py +++ b/evennia/commands/command.py @@ -65,7 +65,7 @@ def _init_command(cls, **kwargs): temp.append(lockstring) cls.lock_storage = ";".join(temp) - if hasattr(cls, 'arg_regex') and isinstance(cls.arg_regex, basestring): + if hasattr(cls, 'arg_regex') and isinstance(cls.arg_regex, str): cls.arg_regex = re.compile(r"%s" % cls.arg_regex, re.I + re.UNICODE) if not hasattr(cls, "auto_help"): cls.auto_help = True @@ -266,7 +266,7 @@ class Command(with_metaclass(CommandMeta, object)): caches are properly updated as well. """ - if isinstance(new_aliases, basestring): + if isinstance(new_aliases, str): new_aliases = new_aliases.split(';') aliases = (str(alias).strip().lower() for alias in make_iter(new_aliases)) self.aliases = list(set(alias for alias in aliases if alias != self.key)) diff --git a/evennia/commands/default/account.py b/evennia/commands/default/account.py index 90c2fdb954..ecde6d8b32 100644 --- a/evennia/commands/default/account.py +++ b/evennia/commands/default/account.py @@ -502,13 +502,13 @@ class CmdOption(COMMAND_DEFAULT_CLASS): options["SCREENWIDTH"] = options["SCREENWIDTH"][0] else: options["SCREENWIDTH"] = " \n".join("%s : %s" % (screenid, size) - for screenid, size in options["SCREENWIDTH"].iteritems()) + for screenid, size in options["SCREENWIDTH"].items()) if "SCREENHEIGHT" in options: if len(options["SCREENHEIGHT"]) == 1: options["SCREENHEIGHT"] = options["SCREENHEIGHT"][0] else: options["SCREENHEIGHT"] = " \n".join("%s : %s" % (screenid, size) - for screenid, size in options["SCREENHEIGHT"].iteritems()) + for screenid, size in options["SCREENHEIGHT"].items()) options.pop("TTYPE", None) header = ("Name", "Value", "Saved") if saved_options else ("Name", "Value") diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index ff487626a1..5b19f2006b 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -1541,7 +1541,7 @@ class CmdSetAttribute(ObjManipCommand): def load(caller): """Called for the editor to load the buffer""" old_value = obj.attributes.get(attr) - if old_value is not None and not isinstance(old_value, basestring): + if old_value is not None and not isinstance(old_value, str): typ = type(old_value).__name__ self.caller.msg("|RWARNING! Saving this buffer will overwrite the " "current attribute (of type %s) with a string!|n" % typ) @@ -1937,7 +1937,7 @@ class CmdExamine(ObjManipCommand): Formats a single attribute line. """ if crop: - if not isinstance(value, basestring): + if not isinstance(value, str): value = utils.to_str(value, force_string=True) value = utils.crop(value) value = utils.to_unicode(value) @@ -2058,7 +2058,7 @@ class CmdExamine(ObjManipCommand): except (TypeError, AttributeError): # an error means we are merging an object without a session pass - all_cmdsets = [cmdset for cmdset in dict(all_cmdsets).values()] + all_cmdsets = [cmdset for cmdset in list(dict(all_cmdsets).values())] all_cmdsets.sort(key=lambda x: x.priority, reverse=True) string += "\n|wMerged Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" % ( cmdset.path, cmdset.key, cmdset.mergetype, cmdset.priority) for cmdset in all_cmdsets)) @@ -2707,7 +2707,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS): self.caller.msg(string) return - if isinstance(prototype, basestring): + if isinstance(prototype, str): # A prototype key keystr = prototype prototype = prototypes.get(prototype, None) diff --git a/evennia/commands/default/comms.py b/evennia/commands/default/comms.py index 53e047a2ac..8ab75f8727 100644 --- a/evennia/commands/default/comms.py +++ b/evennia/commands/default/comms.py @@ -754,7 +754,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS): recobjs = [] for receiver in set(receivers): - if isinstance(receiver, basestring): + if isinstance(receiver, str): pobj = caller.search(receiver) elif hasattr(receiver, 'character'): pobj = receiver diff --git a/evennia/commands/default/system.py b/evennia/commands/default/system.py index fe5efa337d..99879c3b10 100644 --- a/evennia/commands/default/system.py +++ b/evennia/commands/default/system.py @@ -3,7 +3,7 @@ System commands """ -from __future__ import division + import traceback import os @@ -440,7 +440,7 @@ class CmdObjects(COMMAND_DEFAULT_CLASS): typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="table", align="l") typetable.align = 'l' dbtotals = ObjectDB.objects.object_totals() - for path, count in dbtotals.items(): + for path, count in list(dbtotals.items()): typetable.add_row(path, count, "%.2f" % ((float(count) / nobjs) * 100)) # last N table @@ -487,7 +487,7 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS): # typeclass table dbtotals = AccountDB.objects.object_totals() typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l") - for path, count in dbtotals.items(): + for path, count in list(dbtotals.items()): typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100)) # last N table plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim):] @@ -544,7 +544,7 @@ class CmdService(COMMAND_DEFAULT_CLASS): table = EvTable("|wService|n (use @services/start|stop|delete)", "|wstatus", align="l") for service in service_collection.services: table.add_row(service.name, service.running and "|gRunning" or "|rNot Running") - caller.msg(unicode(table)) + caller.msg(str(table)) return # Get the service to start / stop @@ -663,7 +663,7 @@ class CmdTime(COMMAND_DEFAULT_CLASS): table2.add_row("Total time passed:", utils.time_format(gametime.gametime(), 2)) table2.add_row("Current time ", datetime.datetime.fromtimestamp(gametime.gametime(absolute=True))) table2.reformat_column(0, width=30) - self.caller.msg(unicode(table1) + "\n" + unicode(table2)) + self.caller.msg(str(table1) + "\n" + str(table2)) class CmdServerLoad(COMMAND_DEFAULT_CLASS): @@ -799,7 +799,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS): # object cache count (note that sys.getsiseof is not called so this works for pypy too. total_num, cachedict = _IDMAPPER.cache_size() - sorted_cache = sorted([(key, num) for key, num in cachedict.items() if num > 0], + sorted_cache = sorted([(key, num) for key, num in list(cachedict.items()) if num > 0], key=lambda tup: tup[1], reverse=True) memtable = EvTable("entity name", "number", "idmapper %", align="l") for tup in sorted_cache: @@ -841,4 +841,4 @@ class CmdTickers(COMMAND_DEFAULT_CLASS): sub[1] if sub[1] else sub[2], sub[4] or "[Unset]", "*" if sub[5] else "-") - self.caller.msg("|wActive tickers|n:\n" + unicode(table)) + self.caller.msg("|wActive tickers|n:\n" + str(table)) diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index ffb63ef723..7d79e6ad5c 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -78,7 +78,7 @@ class CommandTest(EvenniaTest): cmdobj.parse() ret = cmdobj.func() if isinstance(ret, types.GeneratorType): - ret.next() + next(ret) cmdobj.at_post_cmd() except StopIteration: pass @@ -128,9 +128,9 @@ class TestGeneral(CommandTest): self.call(general.CmdNick(), "testalias = testaliasedstring1", "Nick 'testalias' mapped to 'testaliasedstring1'.") self.call(general.CmdNick(), "/account testalias = testaliasedstring2", "Nick 'testalias' mapped to 'testaliasedstring2'.") self.call(general.CmdNick(), "/object testalias = testaliasedstring3", "Nick 'testalias' mapped to 'testaliasedstring3'.") - self.assertEqual(u"testaliasedstring1", self.char1.nicks.get("testalias")) - self.assertEqual(u"testaliasedstring2", self.char1.nicks.get("testalias", category="account")) - self.assertEqual(u"testaliasedstring3", self.char1.nicks.get("testalias", category="object")) + self.assertEqual("testaliasedstring1", self.char1.nicks.get("testalias")) + self.assertEqual("testaliasedstring2", self.char1.nicks.get("testalias", category="account")) + self.assertEqual("testaliasedstring3", self.char1.nicks.get("testalias", category="object")) def test_get_and_drop(self): self.call(general.CmdGet(), "Obj", "You pick up Obj.") diff --git a/evennia/comms/channelhandler.py b/evennia/comms/channelhandler.py index 02c9e19291..3ed4cc0212 100644 --- a/evennia/comms/channelhandler.py +++ b/evennia/comms/channelhandler.py @@ -271,7 +271,7 @@ class ChannelHandler(object): if channelname: channel = self._cached_channels.get(channelname.lower(), None) return [channel] if channel else [] - return self._cached_channels.values() + return list(self._cached_channels.values()) def get_cmdset(self, source_object): """ @@ -292,7 +292,7 @@ class ChannelHandler(object): else: # create a new cmdset holding all viable channels chan_cmdset = None - chan_cmds = [channelcmd for channel, channelcmd in self._cached_channel_cmds.iteritems() + chan_cmds = [channelcmd for channel, channelcmd in self._cached_channel_cmds.items() if channel.subscriptions.has(source_object) and channelcmd.access(source_object, 'send')] if chan_cmds: diff --git a/evennia/comms/comms.py b/evennia/comms/comms.py index e40de664d1..56cd054720 100644 --- a/evennia/comms/comms.py +++ b/evennia/comms/comms.py @@ -325,7 +325,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)): """ senders = make_iter(senders) if senders else [] - if isinstance(msgobj, basestring): + if isinstance(msgobj, str): # given msgobj is a string - convert to msgobject (always TempMsg) msgobj = TempMsg(senders=senders, header=header, message=msgobj, channels=[self]) # we store the logging setting for use in distribute_message() diff --git a/evennia/comms/managers.py b/evennia/comms/managers.py index f50d813123..af0a3ec1d5 100644 --- a/evennia/comms/managers.py +++ b/evennia/comms/managers.py @@ -3,7 +3,7 @@ These managers define helper methods for accessing the database from Comm system components. """ -from __future__ import print_function + from django.db.models import Q from evennia.typeclasses.managers import (TypedObjectManager, TypeclassManager) @@ -43,9 +43,9 @@ def dbref(inp, reqhash=True): dbref, otherwise `None`. """ - if reqhash and not (isinstance(inp, basestring) and inp.startswith("#")): + if reqhash and not (isinstance(inp, str) and inp.startswith("#")): return None - if isinstance(inp, basestring): + if isinstance(inp, str): inp = inp.lstrip('#') try: if int(inp) < 0: @@ -77,7 +77,7 @@ def identify_object(inp): return inp, "object" elif clsname == "ChannelDB": return inp, "channel" - if isinstance(inp, basestring): + if isinstance(inp, str): return inp, "string" elif dbref(inp): return dbref(inp), "dbref" diff --git a/evennia/comms/migrations/0001_initial.py b/evennia/comms/migrations/0001_initial.py index 611e4061c0..4e502e3145 100644 --- a/evennia/comms/migrations/0001_initial.py +++ b/evennia/comms/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/comms/migrations/0002_msg_db_hide_from_objects.py b/evennia/comms/migrations/0002_msg_db_hide_from_objects.py index 58224b1bde..20e6c1a126 100644 --- a/evennia/comms/migrations/0002_msg_db_hide_from_objects.py +++ b/evennia/comms/migrations/0002_msg_db_hide_from_objects.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/comms/migrations/0003_auto_20140917_0756.py b/evennia/comms/migrations/0003_auto_20140917_0756.py index 1ee5f874da..5f7be96f8f 100644 --- a/evennia/comms/migrations/0003_auto_20140917_0756.py +++ b/evennia/comms/migrations/0003_auto_20140917_0756.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations from django.conf import settings diff --git a/evennia/comms/migrations/0004_auto_20150118_1631.py b/evennia/comms/migrations/0004_auto_20150118_1631.py index 2d4ae99159..2e602f9fad 100644 --- a/evennia/comms/migrations/0004_auto_20150118_1631.py +++ b/evennia/comms/migrations/0004_auto_20150118_1631.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/comms/migrations/0005_auto_20150223_1517.py b/evennia/comms/migrations/0005_auto_20150223_1517.py index a26a6f63e7..b8289f5dea 100644 --- a/evennia/comms/migrations/0005_auto_20150223_1517.py +++ b/evennia/comms/migrations/0005_auto_20150223_1517.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/comms/migrations/0006_channeldb_db_object_subscriptions.py b/evennia/comms/migrations/0006_channeldb_db_object_subscriptions.py index 570d24b136..568da97c7c 100644 --- a/evennia/comms/migrations/0006_channeldb_db_object_subscriptions.py +++ b/evennia/comms/migrations/0006_channeldb_db_object_subscriptions.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/comms/migrations/0007_msg_db_tags.py b/evennia/comms/migrations/0007_msg_db_tags.py index 899d6f946a..e54a058a2b 100644 --- a/evennia/comms/migrations/0007_msg_db_tags.py +++ b/evennia/comms/migrations/0007_msg_db_tags.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/evennia/comms/migrations/0008_auto_20160905_0902.py b/evennia/comms/migrations/0008_auto_20160905_0902.py index cad7637cd3..4a3f2071a7 100644 --- a/evennia/comms/migrations/0008_auto_20160905_0902.py +++ b/evennia/comms/migrations/0008_auto_20160905_0902.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.9 on 2016-09-05 09:02 -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/comms/migrations/0009_auto_20160921_1731.py b/evennia/comms/migrations/0009_auto_20160921_1731.py index 3be041b88a..f803704d3f 100644 --- a/evennia/comms/migrations/0009_auto_20160921_1731.py +++ b/evennia/comms/migrations/0009_auto_20160921_1731.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.9 on 2016-09-21 17:31 -from __future__ import unicode_literals + from django.conf import settings from django.db import migrations, models diff --git a/evennia/comms/migrations/0010_auto_20161206_1912.py b/evennia/comms/migrations/0010_auto_20161206_1912.py index 4da49b8447..b3a10ebe98 100644 --- a/evennia/comms/migrations/0010_auto_20161206_1912.py +++ b/evennia/comms/migrations/0010_auto_20161206_1912.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.11 on 2016-12-06 19:12 -from __future__ import unicode_literals + from django.conf import settings from django.db import migrations, models diff --git a/evennia/comms/migrations/0011_auto_20170217_2039.py b/evennia/comms/migrations/0011_auto_20170217_2039.py index b13e6dcec0..13578b031a 100644 --- a/evennia/comms/migrations/0011_auto_20170217_2039.py +++ b/evennia/comms/migrations/0011_auto_20170217_2039.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.11 on 2017-02-17 20:39 -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/evennia/comms/migrations/0011_auto_20170606_1731.py b/evennia/comms/migrations/0011_auto_20170606_1731.py index f4df669e2d..128e22bd01 100644 --- a/evennia/comms/migrations/0011_auto_20170606_1731.py +++ b/evennia/comms/migrations/0011_auto_20170606_1731.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-06-06 17:31 -from __future__ import unicode_literals + from django.conf import settings from django.db import migrations, models diff --git a/evennia/comms/migrations/0012_merge_20170617_2017.py b/evennia/comms/migrations/0012_merge_20170617_2017.py index a91de6d29c..2c06828618 100644 --- a/evennia/comms/migrations/0012_merge_20170617_2017.py +++ b/evennia/comms/migrations/0012_merge_20170617_2017.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-06-17 20:17 -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/comms/migrations/0013_auto_20170705_1726.py b/evennia/comms/migrations/0013_auto_20170705_1726.py index db42debd2e..b8a863fcb9 100644 --- a/evennia/comms/migrations/0013_auto_20170705_1726.py +++ b/evennia/comms/migrations/0013_auto_20170705_1726.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-05 17:26 -from __future__ import unicode_literals + from django.db import migrations, models, connection diff --git a/evennia/comms/migrations/0014_auto_20170705_1736.py b/evennia/comms/migrations/0014_auto_20170705_1736.py index 474f4b13d6..224aa2dda4 100644 --- a/evennia/comms/migrations/0014_auto_20170705_1736.py +++ b/evennia/comms/migrations/0014_auto_20170705_1736.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-05 17:36 -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/comms/migrations/0015_auto_20170706_2041.py b/evennia/comms/migrations/0015_auto_20170706_2041.py index 62b793646b..58d88eab25 100644 --- a/evennia/comms/migrations/0015_auto_20170706_2041.py +++ b/evennia/comms/migrations/0015_auto_20170706_2041.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-06 20:41 -from __future__ import unicode_literals + from django.db import migrations, connection diff --git a/evennia/comms/models.py b/evennia/comms/models.py index b1a5a37ed9..81555b70ad 100644 --- a/evennia/comms/models.py +++ b/evennia/comms/models.py @@ -166,7 +166,7 @@ class Msg(SharedMemoryModel): for sender in make_iter(senders): if not sender: continue - if isinstance(sender, basestring): + if isinstance(sender, str): self.db_sender_external = sender self.extra_senders.append(sender) self.save(update_fields=["db_sender_external"]) @@ -203,7 +203,7 @@ class Msg(SharedMemoryModel): for sender in make_iter(senders): if not sender: continue - if isinstance(sender, basestring): + if isinstance(sender, str): self.db_sender_external = "" self.save(update_fields=["db_sender_external"]) if not hasattr(sender, "__dbclass__"): diff --git a/evennia/contrib/barter.py b/evennia/contrib/barter.py index 71ea33694b..3171d4e297 100644 --- a/evennia/contrib/barter.py +++ b/evennia/contrib/barter.py @@ -93,7 +93,7 @@ cmdset. This will make the trade (or barter) command available in-game. """ -from __future__ import print_function + from builtins import object from evennia import Command, DefaultScript, CmdSet diff --git a/evennia/contrib/clothing.py b/evennia/contrib/clothing.py index 4e1935c99f..dd61c5f3db 100644 --- a/evennia/contrib/clothing.py +++ b/evennia/contrib/clothing.py @@ -187,7 +187,7 @@ def clothing_type_count(clothes_list): for garment in clothes_list: if garment.db.clothing_type: type = garment.db.clothing_type - if type not in types_count.keys(): + if type not in list(types_count.keys()): types_count[type] = 1 else: types_count[type] += 1 @@ -380,7 +380,7 @@ class CmdWear(MuxCommand): # Apply individual clothing type limits. if clothing.db.clothing_type and not clothing.db.worn: type_count = single_type_count(get_worn_clothes(self.caller), clothing.db.clothing_type) - if clothing.db.clothing_type in CLOTHING_TYPE_LIMIT.keys(): + if clothing.db.clothing_type in list(CLOTHING_TYPE_LIMIT.keys()): if type_count >= CLOTHING_TYPE_LIMIT[clothing.db.clothing_type]: self.caller.msg("You can't wear any more clothes of the type '%s'." % clothing.db.clothing_type) return diff --git a/evennia/contrib/custom_gametime.py b/evennia/contrib/custom_gametime.py index 42a53d1386..1446fcdf13 100644 --- a/evennia/contrib/custom_gametime.py +++ b/evennia/contrib/custom_gametime.py @@ -105,7 +105,7 @@ def gametime_to_realtime(format=False, **kwargs): """ # Dynamically creates the list of units based on kwarg names and UNITs list rtime = 0 - for name, value in kwargs.items(): + for name, value in list(kwargs.items()): # Allow plural names (like mins instead of min) if name not in UNITS and name.endswith("s"): name = name[:-1] @@ -197,7 +197,7 @@ def real_seconds_until(**kwargs): # For each keyword, add in the unit's units.append(1) higher_unit = None - for unit, value in kwargs.items(): + for unit, value in list(kwargs.items()): # Get the unit's index if unit not in UNITS: raise ValueError("unknown unit".format(unit)) diff --git a/evennia/contrib/egi_client/client.py b/evennia/contrib/egi_client/client.py index 6bb49db2e4..c3cb902801 100644 --- a/evennia/contrib/egi_client/client.py +++ b/evennia/contrib/egi_client/client.py @@ -1,4 +1,4 @@ -import urllib +import urllib.request, urllib.parse, urllib.error import platform import warnings @@ -107,7 +107,7 @@ class EvenniaGameIndexClient(object): 'django_version': django.get_version(), 'server_platform': platform.platform(), } - data = urllib.urlencode(values) + data = urllib.parse.urlencode(values) d = agent.request( 'POST', self.report_url, diff --git a/evennia/contrib/extended_room.py b/evennia/contrib/extended_room.py index 6823ede50e..7204fa752e 100644 --- a/evennia/contrib/extended_room.py +++ b/evennia/contrib/extended_room.py @@ -66,7 +66,7 @@ Installation/testing: 3) Use `desc` and `detail` to customize the room, then play around! """ -from __future__ import division + import datetime import re @@ -398,7 +398,7 @@ class CmdExtendedDesc(default_cmds.CmdDesc): # No args given. Return all details on location string = "|wDetails on %s|n:" % location details = "\n".join(" |w%s|n: %s" - % (key, utils.crop(text)) for key, text in location.db.details.items()) + % (key, utils.crop(text)) for key, text in list(location.db.details.items())) caller.msg("%s\n%s" % (string, details) if details else "%s None." % string) return if not self.rhs: diff --git a/evennia/contrib/ingame_python/callbackhandler.py b/evennia/contrib/ingame_python/callbackhandler.py index 625bfa182b..bb0cddc597 100644 --- a/evennia/contrib/ingame_python/callbackhandler.py +++ b/evennia/contrib/ingame_python/callbackhandler.py @@ -36,7 +36,7 @@ class CallbackHandler(object): handler = type(self).script if handler: dicts = handler.get_callbacks(self.obj) - for callback_name, in_list in dicts.items(): + for callback_name, in_list in list(dicts.items()): new_list = [] for callback in in_list: callback = self.format_callback(callback) diff --git a/evennia/contrib/ingame_python/commands.py b/evennia/contrib/ingame_python/commands.py index 138a705297..a8d14ba476 100644 --- a/evennia/contrib/ingame_python/commands.py +++ b/evennia/contrib/ingame_python/commands.py @@ -253,7 +253,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS): row.append("Yes" if callback.get("valid") else "No") table.add_row(*row) - self.msg(unicode(table)) + self.msg(str(table)) else: names = list(set(list(types.keys()) + list(callbacks.keys()))) table = EvTable("Callback name", "Number", "Description", @@ -269,7 +269,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS): description = description.strip("\n").splitlines()[0] table.add_row(name, no, description) - self.msg(unicode(table)) + self.msg(str(table)) def add_callback(self): """Add a callback.""" @@ -457,7 +457,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS): updated_on = "|gUnknown|n" table.add_row(obj.id, type_name, obj, name, by, updated_on) - self.msg(unicode(table)) + self.msg(str(table)) return # An object was specified @@ -503,7 +503,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS): obj = self.obj callback_name = self.callback_name handler = self.handler - tasks = [(k, v[0], v[1], v[2]) for k, v in handler.db.tasks.items()] + tasks = [(k, v[0], v[1], v[2]) for k, v in list(handler.db.tasks.items())] if obj: tasks = [task for task in tasks if task[2] is obj] if callback_name: @@ -518,7 +518,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS): delta = time_format((future - now).total_seconds(), 1) table.add_row(task_id, key, callback_name, delta) - self.msg(unicode(table)) + self.msg(str(table)) # Private functions to handle editing diff --git a/evennia/contrib/ingame_python/scripts.py b/evennia/contrib/ingame_python/scripts.py index 8ffdf172a3..097923878f 100644 --- a/evennia/contrib/ingame_python/scripts.py +++ b/evennia/contrib/ingame_python/scripts.py @@ -3,7 +3,7 @@ Scripts for the in-game Python system. """ from datetime import datetime, timedelta -from Queue import Queue +from queue import Queue import re import sys import traceback @@ -129,7 +129,7 @@ class EventHandler(DefaultScript): while not classes.empty(): typeclass = classes.get() typeclass_name = typeclass.__module__ + "." + typeclass.__name__ - for key, etype in all_events.get(typeclass_name, {}).items(): + for key, etype in list(all_events.get(typeclass_name, {}).items()): if key in invalid: continue if etype[0] is None: # Invalidate @@ -186,7 +186,7 @@ class EventHandler(DefaultScript): """ obj_callbacks = self.db.callbacks.get(obj, {}) callbacks = {} - for callback_name, callback_list in obj_callbacks.items(): + for callback_name, callback_list in list(obj_callbacks.items()): new_list = [] for i, callback in enumerate(callback_list): callback = dict(callback) @@ -436,7 +436,7 @@ class EventHandler(DefaultScript): type(obj), variable, i)) return False else: - locals = {key: value for key, value in locals.items()} + locals = {key: value for key, value in list(locals.items())} callbacks = self.get_callbacks(obj).get(callback_name, []) if event: @@ -576,7 +576,7 @@ class EventHandler(DefaultScript): # Collect and freeze current locals locals = {} - for key, value in self.ndb.current_locals.items(): + for key, value in list(self.ndb.current_locals.items()): try: dbserialize(value) except TypeError: diff --git a/evennia/contrib/ingame_python/tests.py b/evennia/contrib/ingame_python/tests.py index 496c93944d..15a8a45dad 100644 --- a/evennia/contrib/ingame_python/tests.py +++ b/evennia/contrib/ingame_python/tests.py @@ -224,13 +224,13 @@ class TestEventHandler(EvenniaTest): self.assertEqual(callback.code, "pass") self.assertEqual(callback.author, self.char1) self.assertEqual(callback.valid, True) - self.assertIn([callback], self.room1.callbacks.all().values()) + self.assertIn([callback], list(self.room1.callbacks.all().values())) # Edit this very callback new = self.room1.callbacks.edit("dummy", 0, "character.db.say = True", author=self.char1, valid=True) - self.assertIn([new], self.room1.callbacks.all().values()) - self.assertNotIn([callback], self.room1.callbacks.all().values()) + self.assertIn([new], list(self.room1.callbacks.all().values())) + self.assertNotIn([callback], list(self.room1.callbacks.all().values())) # Try to call this callback self.assertTrue(self.room1.callbacks.call("dummy", diff --git a/evennia/contrib/ingame_python/utils.py b/evennia/contrib/ingame_python/utils.py index 71a7c9d4c5..47314f8a88 100644 --- a/evennia/contrib/ingame_python/utils.py +++ b/evennia/contrib/ingame_python/utils.py @@ -50,7 +50,7 @@ def register_events(path_or_typeclass): temporary storage, waiting for the script to be initialized. """ - if isinstance(path_or_typeclass, basestring): + if isinstance(path_or_typeclass, str): typeclass = class_from_module(path_or_typeclass) else: typeclass = path_or_typeclass @@ -65,7 +65,7 @@ def register_events(path_or_typeclass): # If the script is started, add the event directly. # Otherwise, add it to the temporary storage. - for name, tup in getattr(typeclass, "_events", {}).items(): + for name, tup in list(getattr(typeclass, "_events", {}).items()): if len(tup) == 4: variables, help_text, custom_call, custom_add = tup elif len(tup) == 3: @@ -116,7 +116,7 @@ def get_next_wait(format): units = ["min", "hour", "day", "month", "year"] elif calendar == "custom": rsu = custom_rsu - back = dict([(value, name) for name, value in UNITS.items()]) + back = dict([(value, name) for name, value in list(UNITS.items())]) sorted_units = sorted(back.items()) del sorted_units[0] units = [n for v, n in sorted_units] diff --git a/evennia/contrib/mail.py b/evennia/contrib/mail.py index 6e8585136d..a4aee2a4b1 100644 --- a/evennia/contrib/mail.py +++ b/evennia/contrib/mail.py @@ -259,7 +259,7 @@ class CmdMail(default_cmds.MuxCommand): table.reformat_column(4, width=7) self.caller.msg(_HEAD_CHAR * _WIDTH) - self.caller.msg(unicode(table)) + self.caller.msg(str(table)) self.caller.msg(_HEAD_CHAR * _WIDTH) else: self.caller.msg("There are no messages in your inbox.") diff --git a/evennia/contrib/mapbuilder.py b/evennia/contrib/mapbuilder.py index 2b156eb469..3bbf5c72d1 100644 --- a/evennia/contrib/mapbuilder.py +++ b/evennia/contrib/mapbuilder.py @@ -139,7 +139,7 @@ def example1_build_mountains(x, y, **kwargs): room.db.desc = random.choice(room_desc) # Create a random number of objects to populate the room. - for i in xrange(randint(0, 3)): + for i in range(randint(0, 3)): rock = create_object(key="Rock", location=room) rock.db.desc = "An ordinary rock." @@ -286,7 +286,7 @@ def _map_to_list(game_map): """ list_map = game_map.split('\n') - return [character.decode('UTF-8') if isinstance(character, basestring) + return [character.decode('UTF-8') if isinstance(character, str) else character for character in list_map] @@ -321,9 +321,9 @@ def build_map(caller, game_map, legend, iterations=1, build_exits=True): room_dict = {} caller.msg("Creating Landmass...") - for iteration in xrange(iterations): - for y in xrange(len(game_map)): - for x in xrange(len(game_map[y])): + for iteration in range(iterations): + for y in range(len(game_map)): + for x in range(len(game_map[y])): for key in legend: # obs - we must use == for unicode if utils.to_unicode(game_map[y][x]) == utils.to_unicode(key): @@ -336,7 +336,7 @@ def build_map(caller, game_map, legend, iterations=1, build_exits=True): if build_exits: # Creating exits. Assumes single room object in dict entry caller.msg("Connecting Areas...") - for loc_key, location in room_dict.iteritems(): + for loc_key, location in room_dict.items(): x = loc_key[0] y = loc_key[1] diff --git a/evennia/contrib/rplanguage.py b/evennia/contrib/rplanguage.py index 2159719641..4784bb1c08 100644 --- a/evennia/contrib/rplanguage.py +++ b/evennia/contrib/rplanguage.py @@ -232,7 +232,7 @@ class LanguageHandler(DefaultScript): translation = {} if auto_translations: - if isinstance(auto_translations, basestring): + if isinstance(auto_translations, str): # path to a file rather than a list with open(auto_translations, 'r') as f: auto_translations = f.readlines() @@ -254,7 +254,7 @@ class LanguageHandler(DefaultScript): if manual_translations: # update with manual translations - translation.update(dict((key.lower(), value.lower()) for key, value in manual_translations.items())) + translation.update(dict((key.lower(), value.lower()) for key, value in list(manual_translations.items()))) # store data storage = {"translation": translation, diff --git a/evennia/contrib/rpsystem.py b/evennia/contrib/rpsystem.py index a396a18abc..e3ea6b84e4 100644 --- a/evennia/contrib/rpsystem.py +++ b/evennia/contrib/rpsystem.py @@ -511,7 +511,7 @@ def send_emote(sender, receivers, emote, anonymous_add="first"): process_language = receiver.process_language except AttributeError: process_language = _dummy_process - for key, (langname, saytext) in language_mapping.iteritems(): + for key, (langname, saytext) in language_mapping.items(): # color says receiver_lang_mapping[key] = process_language(saytext, sender, langname) # map the language {##num} markers. This will convert the escaped sdesc markers on @@ -531,11 +531,11 @@ def send_emote(sender, receivers, emote, anonymous_add="first"): try: recog_get = receiver.recog.get - receiver_sdesc_mapping = dict((ref, process_recog(recog_get(obj), obj)) for ref, obj in obj_mapping.items()) + receiver_sdesc_mapping = dict((ref, process_recog(recog_get(obj), obj)) for ref, obj in list(obj_mapping.items())) except AttributeError: receiver_sdesc_mapping = dict((ref, process_sdesc(obj.sdesc.get(), obj) if hasattr(obj, "sdesc") else process_sdesc(obj.key, obj)) - for ref, obj in obj_mapping.items()) + for ref, obj in list(obj_mapping.items())) # make sure receiver always sees their real name rkey = "#%i" % receiver.id if rkey in receiver_sdesc_mapping: @@ -684,9 +684,9 @@ class RecogHandler(object): obj2regex = self.obj.attributes.get("_recog_obj2regex", default={}) obj2recog = self.obj.attributes.get("_recog_obj2recog", default={}) self.obj2regex = dict((obj, re.compile(regex, _RE_FLAGS)) - for obj, regex in obj2regex.items() if obj) + for obj, regex in list(obj2regex.items()) if obj) self.obj2recog = dict((obj, recog) - for obj, recog in obj2recog.items() if obj) + for obj, recog in list(obj2recog.items()) if obj) def add(self, obj, recog, max_length=60): """ @@ -981,7 +981,7 @@ class CmdPose(RPCommand): # set current pose and default pose # set the pose. We do one-time ref->sdesc mapping here. parsed, mapping = parse_sdescs_and_recogs(caller, caller.location.contents, pose) mapping = dict((ref, obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key) - for ref, obj in mapping.iteritems()) + for ref, obj in mapping.items()) pose = parsed.format(**mapping) if len(target_name) + len(pose) > 60: @@ -1223,7 +1223,7 @@ class ContribRPObject(DefaultObject): messaging is assumed to be handled by the caller. """ - is_string = isinstance(searchdata, basestring) + is_string = isinstance(searchdata, str) if is_string: # searchdata is a string; wrap some common self-references diff --git a/evennia/contrib/tests.py b/evennia/contrib/tests.py index 1fdd7dde75..cfb7d59ead 100644 --- a/evennia/contrib/tests.py +++ b/evennia/contrib/tests.py @@ -355,14 +355,14 @@ class TestWilderness(EvenniaTest): wilderness.enter_wilderness(self.char1) self.assertIsInstance(self.char1.location, wilderness.WildernessRoom) w = self.get_wilderness_script() - self.assertEquals(w.db.itemcoordinates[self.char1], (0, 0)) + self.assertEqual(w.db.itemcoordinates[self.char1], (0, 0)) def test_enter_wilderness_custom_coordinates(self): wilderness.create_wilderness() wilderness.enter_wilderness(self.char1, coordinates=(1, 2)) self.assertIsInstance(self.char1.location, wilderness.WildernessRoom) w = self.get_wilderness_script() - self.assertEquals(w.db.itemcoordinates[self.char1], (1, 2)) + self.assertEqual(w.db.itemcoordinates[self.char1], (1, 2)) def test_enter_wilderness_custom_name(self): name = "customnname" @@ -381,7 +381,7 @@ class TestWilderness(EvenniaTest): i.access(self.char1, "view") or i.access(self.char1, "traverse"))] - self.assertEquals(len(exits), 3) + self.assertEqual(len(exits), 3) exitsok = ["north", "northeast", "east"] for each_exit in exitsok: self.assertTrue(any([e for e in exits if e.key == each_exit])) @@ -393,7 +393,7 @@ class TestWilderness(EvenniaTest): if i.destination and ( i.access(self.char1, "view") or i.access(self.char1, "traverse"))] - self.assertEquals(len(exits), 8) + self.assertEqual(len(exits), 8) exitsok = ["north", "northeast", "east", "southeast", "south", "southwest", "west", "northwest"] for each_exit in exitsok: @@ -410,25 +410,25 @@ class TestWilderness(EvenniaTest): w = self.get_wilderness_script() # We should have no unused room after moving the first account in. - self.assertEquals(len(w.db.unused_rooms), 0) + self.assertEqual(len(w.db.unused_rooms), 0) w.move_obj(self.char1, (0, 0)) - self.assertEquals(len(w.db.unused_rooms), 0) + self.assertEqual(len(w.db.unused_rooms), 0) # And also no unused room after moving the second one in. w.move_obj(self.char2, (1, 1)) - self.assertEquals(len(w.db.unused_rooms), 0) + self.assertEqual(len(w.db.unused_rooms), 0) # But if char2 moves into char1's room, we should have one unused room # Which should be char2's old room that got created. w.move_obj(self.char2, (0, 0)) - self.assertEquals(len(w.db.unused_rooms), 1) - self.assertEquals(self.char1.location, self.char2.location) + self.assertEqual(len(w.db.unused_rooms), 1) + self.assertEqual(self.char1.location, self.char2.location) # And if char2 moves back out, that unused room should be put back to # use again. w.move_obj(self.char2, (1, 1)) - self.assertNotEquals(self.char1.location, self.char2.location) - self.assertEquals(len(w.db.unused_rooms), 0) + self.assertNotEqual(self.char1.location, self.char2.location) + self.assertEqual(len(w.db.unused_rooms), 0) def test_get_new_coordinates(self): loc = (1, 1) @@ -440,9 +440,9 @@ class TestWilderness(EvenniaTest): "southwest": (0, 0), "west": (0, 1), "northwest": (0, 2)} - for direction, correct_loc in directions.iteritems(): # Not compatible with Python 3 + for direction, correct_loc in directions.items(): # Not compatible with Python 3 new_loc = wilderness.get_new_coordinates(loc, direction) - self.assertEquals(new_loc, correct_loc, direction) + self.assertEqual(new_loc, correct_loc, direction) # Testing chargen contrib diff --git a/evennia/contrib/tutorial_world/__init__.py b/evennia/contrib/tutorial_world/__init__.py index 87f7c7f4cb..45bded2779 100644 --- a/evennia/contrib/tutorial_world/__init__.py +++ b/evennia/contrib/tutorial_world/__init__.py @@ -2,6 +2,6 @@ """ This package holds the demo game of Evennia. """ -from __future__ import absolute_import + from . import mob, objects, rooms diff --git a/evennia/contrib/tutorial_world/objects.py b/evennia/contrib/tutorial_world/objects.py index 3859de7d2d..1e836d5bb1 100644 --- a/evennia/contrib/tutorial_world/objects.py +++ b/evennia/contrib/tutorial_world/objects.py @@ -689,7 +689,7 @@ class CrumblingWall(TutorialObject, DefaultExit): "crisscross the wall, making it hard to clearly see its stony surface. Maybe you could " "try to |wshift|n or |wmove|n them.\n"] # display the root positions to help with the puzzle - for key, pos in self.db.root_pos.items(): + for key, pos in list(self.db.root_pos.items()): result.append("\n" + self._translate_position(key, pos)) self.db.desc = "".join(result) diff --git a/evennia/contrib/tutorial_world/rooms.py b/evennia/contrib/tutorial_world/rooms.py index c16baccff1..e780124609 100644 --- a/evennia/contrib/tutorial_world/rooms.py +++ b/evennia/contrib/tutorial_world/rooms.py @@ -8,7 +8,7 @@ commands needed to control them. Those commands could also have been in a separate module (e.g. if they could have been re-used elsewhere.) """ -from __future__ import print_function + import random from evennia import TICKER_HANDLER diff --git a/evennia/contrib/wilderness.py b/evennia/contrib/wilderness.py index f36dba492d..6d6ebf6649 100644 --- a/evennia/contrib/wilderness.py +++ b/evennia/contrib/wilderness.py @@ -249,10 +249,10 @@ class WildernessScript(DefaultScript): """ Called when the script is started and also after server reloads. """ - for coordinates, room in self.db.rooms.items(): + for coordinates, room in list(self.db.rooms.items()): room.ndb.wildernessscript = self room.ndb.active_coordinates = coordinates - for item in self.db.itemcoordinates.keys(): + for item in list(self.db.itemcoordinates.keys()): # Items deleted from the wilderness leave None type 'ghosts' # that must be cleaned out if item is None: @@ -302,7 +302,7 @@ class WildernessScript(DefaultScript): [Object, ]: list of Objects at coordinates """ result = [] - for item, item_coordinates in self.itemcoordinates.items(): + for item, item_coordinates in list(self.itemcoordinates.items()): # Items deleted from the wilderness leave None type 'ghosts' # that must be cleaned out if item is None: diff --git a/evennia/game_template/server/conf/settings.py b/evennia/game_template/server/conf/settings.py index 7fe163b833..fa314c977a 100644 --- a/evennia/game_template/server/conf/settings.py +++ b/evennia/game_template/server/conf/settings.py @@ -62,4 +62,4 @@ AMP_PORT = 4006 try: from server.conf.secret_settings import * except ImportError: - print "secret_settings.py file not found or failed to import." + print("secret_settings.py file not found or failed to import.") diff --git a/evennia/help/migrations/0001_initial.py b/evennia/help/migrations/0001_initial.py index a8bc6fc91e..6bc0be6b97 100644 --- a/evennia/help/migrations/0001_initial.py +++ b/evennia/help/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/help/migrations/0002_auto_20170606_1731.py b/evennia/help/migrations/0002_auto_20170606_1731.py index 65ab4a5ee1..10f939c18d 100644 --- a/evennia/help/migrations/0002_auto_20170606_1731.py +++ b/evennia/help/migrations/0002_auto_20170606_1731.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-06-06 17:31 -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/evennia/help/models.py b/evennia/help/models.py index 4a81a94099..b19c551f25 100644 --- a/evennia/help/models.py +++ b/evennia/help/models.py @@ -97,7 +97,7 @@ class HelpEntry(SharedMemoryModel): return self.key def __unicode__(self): - return u'%s' % self.key + return '%s' % self.key def access(self, accessing_obj, access_type='read', default=False): """ diff --git a/evennia/locks/lockfuncs.py b/evennia/locks/lockfuncs.py index e30263adbf..c39c82a350 100644 --- a/evennia/locks/lockfuncs.py +++ b/evennia/locks/lockfuncs.py @@ -87,7 +87,7 @@ DefaultLock: Exits: controls who may traverse the exit to Dark/light script ``` """ -from __future__ import print_function + from django.conf import settings from evennia.utils import utils diff --git a/evennia/locks/lockhandler.py b/evennia/locks/lockhandler.py index b8801f9655..3d1787ad9d 100644 --- a/evennia/locks/lockhandler.py +++ b/evennia/locks/lockhandler.py @@ -103,7 +103,7 @@ restricted @perm command sets them, but otherwise they are identical to any other identifier you can use. """ -from __future__ import print_function + from builtins import object import re @@ -269,7 +269,7 @@ class LockHandler(object): """ Store locks to obj """ - self.obj.lock_storage = ";".join([tup[2] for tup in self.locks.values()]) + self.obj.lock_storage = ";".join([tup[2] for tup in list(self.locks.values())]) def cache_lock_bypass(self, obj): """ @@ -302,7 +302,7 @@ class LockHandler(object): error. """ - if isinstance(lockstring, basestring): + if isinstance(lockstring, str): lockdefs = lockstring.split(";") else: lockdefs = [lockdef for locks in lockstring for lockdef in locks.split(";")] diff --git a/evennia/locks/tests.py b/evennia/locks/tests.py index 0c47456ede..29b5810126 100644 --- a/evennia/locks/tests.py +++ b/evennia/locks/tests.py @@ -27,29 +27,29 @@ class TestLockCheck(EvenniaTest): dbref = self.obj2.dbref self.obj1.locks.add("owner:dbref(%s);edit:dbref(%s) or perm(Admin);examine:perm(Builder) and id(%s);delete:perm(Admin);get:all()" % (dbref, dbref, dbref)) self.obj2.permissions.add('Admin') - self.assertEquals(True, self.obj1.locks.check(self.obj2, 'owner')) - self.assertEquals(True, self.obj1.locks.check(self.obj2, 'edit')) - self.assertEquals(True, self.obj1.locks.check(self.obj2, 'examine')) - self.assertEquals(True, self.obj1.locks.check(self.obj2, 'delete')) - self.assertEquals(True, self.obj1.locks.check(self.obj2, 'get')) + self.assertEqual(True, self.obj1.locks.check(self.obj2, 'owner')) + self.assertEqual(True, self.obj1.locks.check(self.obj2, 'edit')) + self.assertEqual(True, self.obj1.locks.check(self.obj2, 'examine')) + self.assertEqual(True, self.obj1.locks.check(self.obj2, 'delete')) + self.assertEqual(True, self.obj1.locks.check(self.obj2, 'get')) self.obj1.locks.add("get:false()") - self.assertEquals(False, self.obj1.locks.check(self.obj2, 'get')) - self.assertEquals(True, self.obj1.locks.check(self.obj2, 'not_exist', default=True)) + self.assertEqual(False, self.obj1.locks.check(self.obj2, 'get')) + self.assertEqual(True, self.obj1.locks.check(self.obj2, 'not_exist', default=True)) class TestLockfuncs(EvenniaTest): def testrun(self): self.obj2.permissions.add('Admin') - self.assertEquals(True, lockfuncs.true(self.obj2, self.obj1)) - self.assertEquals(False, lockfuncs.false(self.obj2, self.obj1)) - self.assertEquals(True, lockfuncs.perm(self.obj2, self.obj1, 'Admin')) - self.assertEquals(True, lockfuncs.perm_above(self.obj2, self.obj1, 'Builder')) + self.assertEqual(True, lockfuncs.true(self.obj2, self.obj1)) + self.assertEqual(False, lockfuncs.false(self.obj2, self.obj1)) + self.assertEqual(True, lockfuncs.perm(self.obj2, self.obj1, 'Admin')) + self.assertEqual(True, lockfuncs.perm_above(self.obj2, self.obj1, 'Builder')) dbref = self.obj2.dbref - self.assertEquals(True, lockfuncs.dbref(self.obj2, self.obj1, '%s' % dbref)) + self.assertEqual(True, lockfuncs.dbref(self.obj2, self.obj1, '%s' % dbref)) self.obj2.db.testattr = 45 - self.assertEquals(True, lockfuncs.attr(self.obj2, self.obj1, 'testattr', '45')) - self.assertEquals(False, lockfuncs.attr_gt(self.obj2, self.obj1, 'testattr', '45')) - self.assertEquals(True, lockfuncs.attr_ge(self.obj2, self.obj1, 'testattr', '45')) - self.assertEquals(False, lockfuncs.attr_lt(self.obj2, self.obj1, 'testattr', '45')) - self.assertEquals(True, lockfuncs.attr_le(self.obj2, self.obj1, 'testattr', '45')) - self.assertEquals(False, lockfuncs.attr_ne(self.obj2, self.obj1, 'testattr', '45')) + self.assertEqual(True, lockfuncs.attr(self.obj2, self.obj1, 'testattr', '45')) + self.assertEqual(False, lockfuncs.attr_gt(self.obj2, self.obj1, 'testattr', '45')) + self.assertEqual(True, lockfuncs.attr_ge(self.obj2, self.obj1, 'testattr', '45')) + self.assertEqual(False, lockfuncs.attr_lt(self.obj2, self.obj1, 'testattr', '45')) + self.assertEqual(True, lockfuncs.attr_le(self.obj2, self.obj1, 'testattr', '45')) + self.assertEqual(False, lockfuncs.attr_ne(self.obj2, self.obj1, 'testattr', '45')) diff --git a/evennia/objects/manager.py b/evennia/objects/manager.py index 3d29768e5a..22ef174636 100644 --- a/evennia/objects/manager.py +++ b/evennia/objects/manager.py @@ -151,7 +151,7 @@ class ObjectDBManager(TypedObjectManager): # This doesn't work if attribute_value is an object. Workaround below - if isinstance(attribute_value, (basestring, int, float, bool)): + if isinstance(attribute_value, (str, int, float, bool)): return self.filter(cand_restriction & type_restriction & Q(db_attributes__db_key=attribute_name, db_attributes__db_value=attribute_value)) else: @@ -196,9 +196,9 @@ class ObjectDBManager(TypedObjectManager): typeclasses (list, optional): List of typeclass-path strings to restrict matches with """ - if isinstance(property_value, basestring): + if isinstance(property_value, str): property_value = to_unicode(property_value) - if isinstance(property_name, basestring): + if isinstance(property_name, str): if not property_name.startswith('db_'): property_name = "db_%s" % property_name querykwargs = {property_name: property_value} @@ -244,7 +244,7 @@ class ObjectDBManager(TypedObjectManager): Returns: matches (list): A list of matches of length 0, 1 or more. """ - if not isinstance(ostring, basestring): + if not isinstance(ostring, str): if hasattr(ostring, "key"): ostring = ostring.key else: @@ -365,9 +365,9 @@ class ObjectDBManager(TypedObjectManager): typeclasses = make_iter(typeclass) for i, typeclass in enumerate(make_iter(typeclasses)): if callable(typeclass): - typeclasses[i] = u"%s.%s" % (typeclass.__module__, typeclass.__name__) + typeclasses[i] = "%s.%s" % (typeclass.__module__, typeclass.__name__) else: - typeclasses[i] = u"%s" % typeclass + typeclasses[i] = "%s" % typeclass typeclass = typeclasses if candidates is not None: diff --git a/evennia/objects/migrations/0001_initial.py b/evennia/objects/migrations/0001_initial.py index bba205bffb..ac528b9fd1 100644 --- a/evennia/objects/migrations/0001_initial.py +++ b/evennia/objects/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations import django.db.models.deletion diff --git a/evennia/objects/migrations/0002_auto_20140917_0756.py b/evennia/objects/migrations/0002_auto_20140917_0756.py index 7483c27268..916671f38e 100644 --- a/evennia/objects/migrations/0002_auto_20140917_0756.py +++ b/evennia/objects/migrations/0002_auto_20140917_0756.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations import django.db.models.deletion diff --git a/evennia/objects/migrations/0003_defaultcharacter_defaultexit_defaultobject_defaultroom.py b/evennia/objects/migrations/0003_defaultcharacter_defaultexit_defaultobject_defaultroom.py index fd72933e43..c69ac070d1 100644 --- a/evennia/objects/migrations/0003_defaultcharacter_defaultexit_defaultobject_defaultroom.py +++ b/evennia/objects/migrations/0003_defaultcharacter_defaultexit_defaultobject_defaultroom.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/objects/migrations/0004_auto_20150118_1622.py b/evennia/objects/migrations/0004_auto_20150118_1622.py index 4626b63c94..640b5e9386 100644 --- a/evennia/objects/migrations/0004_auto_20150118_1622.py +++ b/evennia/objects/migrations/0004_auto_20150118_1622.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/objects/migrations/0005_auto_20150403_2339.py b/evennia/objects/migrations/0005_auto_20150403_2339.py index d8359a909d..4b0521128e 100644 --- a/evennia/objects/migrations/0005_auto_20150403_2339.py +++ b/evennia/objects/migrations/0005_auto_20150403_2339.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/objects/migrations/0006_auto_20170606_1731.py b/evennia/objects/migrations/0006_auto_20170606_1731.py index df56b38745..daf46ed329 100644 --- a/evennia/objects/migrations/0006_auto_20170606_1731.py +++ b/evennia/objects/migrations/0006_auto_20170606_1731.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-06-06 17:31 -from __future__ import unicode_literals + import django.core.validators from django.db import migrations, models diff --git a/evennia/objects/migrations/0007_objectdb_db_account.py b/evennia/objects/migrations/0007_objectdb_db_account.py index 6e40252e8e..b91e315b49 100644 --- a/evennia/objects/migrations/0007_objectdb_db_account.py +++ b/evennia/objects/migrations/0007_objectdb_db_account.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-05 17:27 -from __future__ import unicode_literals + from django.db import migrations, models, connection import django.db.models.deletion diff --git a/evennia/objects/migrations/0008_auto_20170705_1736.py b/evennia/objects/migrations/0008_auto_20170705_1736.py index c2cd711aff..355a339910 100644 --- a/evennia/objects/migrations/0008_auto_20170705_1736.py +++ b/evennia/objects/migrations/0008_auto_20170705_1736.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-05 17:36 -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/objects/migrations/0009_remove_objectdb_db_player.py b/evennia/objects/migrations/0009_remove_objectdb_db_player.py index 10fb2252f4..403b072dfe 100644 --- a/evennia/objects/migrations/0009_remove_objectdb_db_player.py +++ b/evennia/objects/migrations/0009_remove_objectdb_db_player.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-06 20:41 -from __future__ import unicode_literals + from django.db import migrations, connection diff --git a/evennia/objects/models.py b/evennia/objects/models.py index adac6e0a5a..884cc28d80 100644 --- a/evennia/objects/models.py +++ b/evennia/objects/models.py @@ -231,7 +231,7 @@ class ObjectDB(TypedObject): def __location_set(self, location): """Set location, checking for loops and allowing dbref""" - if isinstance(location, (basestring, int)): + if isinstance(location, (str, int)): # allow setting of #dbref dbid = dbref(location, reqhash=False) if dbid: diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index e0fd0dace4..23e65c31bf 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -359,7 +359,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): messaging is assumed to be handled by the caller. """ - is_string = isinstance(searchdata, basestring) + is_string = isinstance(searchdata, str) if is_string: @@ -436,7 +436,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): matching Accounts. """ - if isinstance(searchdata, basestring): + if isinstance(searchdata, str): # searchdata is a string; wrap some common self-references if searchdata.lower() in ("me", "self",): return [self.account] if quiet else self.account @@ -615,7 +615,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): if mapping: substitutions = {t: sub.get_display_name(obj) if hasattr(sub, 'get_display_name') - else str(sub) for t, sub in mapping.items()} + else str(sub) for t, sub in list(mapping.items())} outmessage = inmessage.format(**substitutions) else: outmessage = inmessage @@ -959,7 +959,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)): self.attributes.batch_add(*cdict["attributes"]) if cdict.get("nattributes"): # this should be a dict of nattrname:value - for key, value in cdict["nattributes"].items(): + for key, value in list(cdict["nattributes"].items()): self.nattributes.add(key, value) del self._createdict diff --git a/evennia/scripts/manager.py b/evennia/scripts/manager.py index 1b795b2c3e..8d67b6f966 100644 --- a/evennia/scripts/manager.py +++ b/evennia/scripts/manager.py @@ -240,9 +240,9 @@ class ScriptDBManager(TypedObjectManager): if typeclass: if callable(typeclass): - typeclass = u"%s.%s" % (typeclass.__module__, typeclass.__name__) + typeclass = "%s.%s" % (typeclass.__module__, typeclass.__name__) else: - typeclass = u"%s" % typeclass + typeclass = "%s" % typeclass # not a dbref; normal search obj_restriction = obj and Q(db_obj=obj) or Q() diff --git a/evennia/scripts/migrations/0001_initial.py b/evennia/scripts/migrations/0001_initial.py index 751bd2928e..385e3901e0 100644 --- a/evennia/scripts/migrations/0001_initial.py +++ b/evennia/scripts/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations from django.conf import settings diff --git a/evennia/scripts/migrations/0002_auto_20150118_1625.py b/evennia/scripts/migrations/0002_auto_20150118_1625.py index 272c9b73d0..0022111e2b 100644 --- a/evennia/scripts/migrations/0002_auto_20150118_1625.py +++ b/evennia/scripts/migrations/0002_auto_20150118_1625.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/scripts/migrations/0003_checksessions_defaultscript_donothing_scriptbase_store_validatechannelhandler_validateidmappercache_.py b/evennia/scripts/migrations/0003_checksessions_defaultscript_donothing_scriptbase_store_validatechannelhandler_validateidmappercache_.py index baa3b0d2ee..3d80e56985 100644 --- a/evennia/scripts/migrations/0003_checksessions_defaultscript_donothing_scriptbase_store_validatechannelhandler_validateidmappercache_.py +++ b/evennia/scripts/migrations/0003_checksessions_defaultscript_donothing_scriptbase_store_validatechannelhandler_validateidmappercache_.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/scripts/migrations/0004_auto_20150306_1354.py b/evennia/scripts/migrations/0004_auto_20150306_1354.py index 72bd29a4e7..0c4310ee3d 100644 --- a/evennia/scripts/migrations/0004_auto_20150306_1354.py +++ b/evennia/scripts/migrations/0004_auto_20150306_1354.py @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations def remove_manage_scripts(apps, schema_editor): ScriptDB = apps.get_model("scripts", "ScriptDB") - for script in ScriptDB.objects.filter(db_typeclass_path__in=(u'evennia.scripts.scripts.CheckSessions', - u'evennia.scripts.scripts.ValidateScripts', - u'evennia.scripts.scripts.ValidateChannelHandler', - u'evennia.scripts.scripts.ValidateIdmapperCache', - u'evennia.utils.gametime.GameTime')): + for script in ScriptDB.objects.filter(db_typeclass_path__in=('evennia.scripts.scripts.CheckSessions', + 'evennia.scripts.scripts.ValidateScripts', + 'evennia.scripts.scripts.ValidateChannelHandler', + 'evennia.scripts.scripts.ValidateIdmapperCache', + 'evennia.utils.gametime.GameTime')): script.delete() diff --git a/evennia/scripts/migrations/0005_auto_20150306_1441.py b/evennia/scripts/migrations/0005_auto_20150306_1441.py index 92ab743557..b800c80553 100644 --- a/evennia/scripts/migrations/0005_auto_20150306_1441.py +++ b/evennia/scripts/migrations/0005_auto_20150306_1441.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/scripts/migrations/0006_auto_20150310_2249.py b/evennia/scripts/migrations/0006_auto_20150310_2249.py index d027d49007..80cc25bee0 100644 --- a/evennia/scripts/migrations/0006_auto_20150310_2249.py +++ b/evennia/scripts/migrations/0006_auto_20150310_2249.py @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations def remove_manage_scripts(apps, schema_editor): ScriptDB = apps.get_model("scripts", "ScriptDB") - for script in ScriptDB.objects.filter(db_typeclass_path__in=(u'src.scripts.scripts.CheckSessions', - u'src.scripts.scripts.ValidateScripts', - u'src.scripts.scripts.ValidateChannelHandler', - u'src.scripts.scripts.ValidateIdmapperCache', - u'src.utils.gametime.GameTime')): + for script in ScriptDB.objects.filter(db_typeclass_path__in=('src.scripts.scripts.CheckSessions', + 'src.scripts.scripts.ValidateScripts', + 'src.scripts.scripts.ValidateChannelHandler', + 'src.scripts.scripts.ValidateIdmapperCache', + 'src.utils.gametime.GameTime')): script.delete() diff --git a/evennia/scripts/migrations/0007_auto_20150403_2339.py b/evennia/scripts/migrations/0007_auto_20150403_2339.py index 91fb359dc3..530a93ebb9 100644 --- a/evennia/scripts/migrations/0007_auto_20150403_2339.py +++ b/evennia/scripts/migrations/0007_auto_20150403_2339.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/scripts/migrations/0008_auto_20170606_1731.py b/evennia/scripts/migrations/0008_auto_20170606_1731.py index b4a7f3201c..d8d7700f4e 100644 --- a/evennia/scripts/migrations/0008_auto_20170606_1731.py +++ b/evennia/scripts/migrations/0008_auto_20170606_1731.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-06-06 17:31 -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/evennia/scripts/migrations/0009_scriptdb_db_account.py b/evennia/scripts/migrations/0009_scriptdb_db_account.py index 23f6df92c1..2ad24bf7e2 100644 --- a/evennia/scripts/migrations/0009_scriptdb_db_account.py +++ b/evennia/scripts/migrations/0009_scriptdb_db_account.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-05 17:27 -from __future__ import unicode_literals + from django.db import migrations, models, connection import django.db.models.deletion diff --git a/evennia/scripts/migrations/0010_auto_20170705_1736.py b/evennia/scripts/migrations/0010_auto_20170705_1736.py index 61c9e929ae..c3fbddcafb 100644 --- a/evennia/scripts/migrations/0010_auto_20170705_1736.py +++ b/evennia/scripts/migrations/0010_auto_20170705_1736.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-05 17:36 -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/scripts/migrations/0011_remove_scriptdb_db_player.py b/evennia/scripts/migrations/0011_remove_scriptdb_db_player.py index 20fa63fd50..e5ed4bc915 100644 --- a/evennia/scripts/migrations/0011_remove_scriptdb_db_player.py +++ b/evennia/scripts/migrations/0011_remove_scriptdb_db_player.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.2 on 2017-07-06 20:41 -from __future__ import unicode_literals + from django.db import migrations, connection diff --git a/evennia/scripts/models.py b/evennia/scripts/models.py index d470349964..51fa55cbb7 100644 --- a/evennia/scripts/models.py +++ b/evennia/scripts/models.py @@ -141,7 +141,7 @@ class ScriptDB(TypedObject): except AttributeError: # deprecated ... pass - if isinstance(value, (basestring, int)): + if isinstance(value, (str, int)): from evennia.objects.models import ObjectDB value = to_str(value, force_string=True) if (value.isdigit() or value.startswith("#")): diff --git a/evennia/scripts/monitorhandler.py b/evennia/scripts/monitorhandler.py index af6ae4fd61..c3027ff773 100644 --- a/evennia/scripts/monitorhandler.py +++ b/evennia/scripts/monitorhandler.py @@ -50,8 +50,8 @@ class MonitorHandler(object): if self.monitors: for obj in self.monitors: for fieldname in self.monitors[obj]: - for idstring, (callback, persistent, kwargs) in self.monitors[obj][fieldname].iteritems(): - path = "%s.%s" % (callback.__module__, callback.func_name) + for idstring, (callback, persistent, kwargs) in self.monitors[obj][fieldname].items(): + path = "%s.%s" % (callback.__module__, callback.__name__) savedata.append((obj, fieldname, idstring, path, persistent, kwargs)) savedata = dbserialize(savedata) ServerConfig.objects.conf(key=self.savekey, value=savedata) @@ -97,7 +97,7 @@ class MonitorHandler(object): """ to_delete = [] if obj in self.monitors and fieldname in self.monitors[obj]: - for idstring, (callback, persistent, kwargs) in self.monitors[obj][fieldname].iteritems(): + for idstring, (callback, persistent, kwargs) in self.monitors[obj][fieldname].items(): try: callback(obj=obj, fieldname=fieldname, **kwargs) except Exception: @@ -183,7 +183,7 @@ class MonitorHandler(object): output = [] for obj in self.monitors: for fieldname in self.monitors[obj]: - for idstring, (callback, persistent, kwargs) in self.monitors[obj][fieldname].iteritems(): + for idstring, (callback, persistent, kwargs) in self.monitors[obj][fieldname].items(): output.append((obj, fieldname, idstring, persistent, kwargs)) return output diff --git a/evennia/scripts/taskhandler.py b/evennia/scripts/taskhandler.py index f4819ba076..f4f94e75d0 100644 --- a/evennia/scripts/taskhandler.py +++ b/evennia/scripts/taskhandler.py @@ -41,13 +41,13 @@ class TaskHandler(object): """ to_save = False value = ServerConfig.objects.conf("delayed_tasks", default={}) - if isinstance(value, basestring): + if isinstance(value, str): tasks = dbunserialize(value) else: tasks = value # At this point, `tasks` contains a dictionary of still-serialized tasks - for task_id, value in tasks.items(): + for task_id, value in list(tasks.items()): date, callback, args, kwargs = dbunserialize(value) if isinstance(callback, tuple): # `callback` can be an object and name for instance methods @@ -64,7 +64,7 @@ class TaskHandler(object): def save(self): """Save the tasks in ServerConfig.""" - for task_id, (date, callback, args, kwargs) in self.tasks.items(): + for task_id, (date, callback, args, kwargs) in list(self.tasks.items()): if task_id in self.to_save: continue @@ -111,7 +111,7 @@ class TaskHandler(object): # Choose a free task_id safe_args = [] safe_kwargs = {} - used_ids = self.tasks.keys() + used_ids = list(self.tasks.keys()) task_id = 1 while task_id in used_ids: task_id += 1 @@ -127,7 +127,7 @@ class TaskHandler(object): else: safe_args.append(arg) - for key, value in kwargs.items(): + for key, value in list(kwargs.items()): try: dbserialize(value) except (TypeError, AttributeError): @@ -187,7 +187,7 @@ class TaskHandler(object): """ now = datetime.now() - for task_id, (date, callbac, args, kwargs) in self.tasks.items(): + for task_id, (date, callbac, args, kwargs) in list(self.tasks.items()): seconds = max(0, (date - now).total_seconds()) task.deferLater(reactor, seconds, self.do_task, task_id) diff --git a/evennia/scripts/tickerhandler.py b/evennia/scripts/tickerhandler.py index 36455329a0..5ca5384b76 100644 --- a/evennia/scripts/tickerhandler.py +++ b/evennia/scripts/tickerhandler.py @@ -113,7 +113,7 @@ class Ticker(object): self._to_add = [] self._to_remove = [] self._is_ticking = True - for store_key, (args, kwargs) in self.subscriptions.iteritems(): + for store_key, (args, kwargs) in self.subscriptions.items(): callback = yield kwargs.pop("_callback", "at_tick") obj = yield kwargs.pop("_obj", None) try: @@ -286,7 +286,7 @@ class TickerPool(object): if interval and interval in self.tickers: self.tickers[interval].stop() else: - for ticker in self.tickers.values(): + for ticker in list(self.tickers.values()): ticker.stop() @@ -332,10 +332,10 @@ class TickerHandler(object): outobj, outpath, outcallfunc = None, None, None if callable(callback): if inspect.ismethod(callback): - outobj = callback.im_self - outcallfunc = callback.im_func.func_name + outobj = callback.__self__ + outcallfunc = callback.__func__.__name__ elif inspect.isfunction(callback): - outpath = "%s.%s" % (callback.__module__, callback.func_name) + outpath = "%s.%s" % (callback.__module__, callback.__name__) outcallfunc = callback else: raise TypeError("%s is not a callable function or method." % callback) @@ -371,8 +371,8 @@ class TickerHandler(object): interval = int(interval) persistent = bool(persistent) packed_obj = pack_dbobj(obj) - methodname = callfunc if callfunc and isinstance(callfunc, basestring) else None - outpath = path if path and isinstance(path, basestring) else None + methodname = callfunc if callfunc and isinstance(callfunc, str) else None + outpath = path if path and isinstance(path, str) else None return (packed_obj, methodname, outpath, interval, idstring, persistent) def save(self): @@ -386,16 +386,16 @@ class TickerHandler(object): if self.ticker_storage: # get the current times so the tickers can be restarted with a delay later start_delays = dict((interval, ticker.task.next_call_time()) - for interval, ticker in self.ticker_pool.tickers.items()) + for interval, ticker in list(self.ticker_pool.tickers.items())) # remove any subscriptions that lost its object in the interim - to_save = {store_key: (args, kwargs) for store_key, (args, kwargs) in self.ticker_storage.items() + to_save = {store_key: (args, kwargs) for store_key, (args, kwargs) in list(self.ticker_storage.items()) if ((store_key[1] and ("_obj" in kwargs and kwargs["_obj"].pk) and hasattr(kwargs["_obj"], store_key[1])) or # a valid method with existing obj store_key[2])} # a path given # update the timers for the tickers - for store_key, (args, kwargs) in to_save.items(): + for store_key, (args, kwargs) in list(to_save.items()): interval = store_key[1] # this is a mutable, so it's updated in-place in ticker_storage kwargs["_start_delay"] = start_delays.get(interval, None) @@ -423,7 +423,7 @@ class TickerHandler(object): restored_tickers = dbunserialize(restored_tickers) self.ticker_storage = {} - for store_key, (args, kwargs) in restored_tickers.iteritems(): + for store_key, (args, kwargs) in restored_tickers.items(): try: # at this point obj is the actual object (or None) due to how # the dbunserialize works @@ -431,7 +431,7 @@ class TickerHandler(object): if not persistent and not server_reload: # this ticker will not be restarted continue - if isinstance(callfunc, basestring) and not obj: + if isinstance(callfunc, str) and not obj: # methods must have an existing object continue # we must rebuild the store_key here since obj must not be @@ -562,7 +562,7 @@ class TickerHandler(object): if interval is None: # return dict of all, ordered by interval return dict((interval, ticker.subscriptions) - for interval, ticker in self.ticker_pool.tickers.iteritems()) + for interval, ticker in self.ticker_pool.tickers.items()) else: # get individual interval ticker = self.ticker_pool.tickers.get(interval, None) @@ -579,8 +579,8 @@ class TickerHandler(object): """ store_keys = [] - for ticker in self.ticker_pool.tickers.itervalues(): - for (objtup, callfunc, path, interval, idstring, persistent), (args, kwargs) in ticker.subscriptions.iteritems(): + for ticker in self.ticker_pool.tickers.values(): + for (objtup, callfunc, path, interval, idstring, persistent), (args, kwargs) in ticker.subscriptions.items(): store_keys.append((kwargs.get("_obj", None), callfunc, path, interval, idstring, persistent)) return store_keys diff --git a/evennia/server/amp.py b/evennia/server/amp.py index 9694abd034..615f9b3799 100644 --- a/evennia/server/amp.py +++ b/evennia/server/amp.py @@ -15,16 +15,16 @@ Server - (AMP server) Handles all mud operations. The server holds its own list at startup and when a session connects/disconnects """ -from __future__ import print_function + # imports needed on both server and portal side import os import time from collections import defaultdict, namedtuple from itertools import count -from cStringIO import StringIO +from io import StringIO try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle from twisted.protocols import amp diff --git a/evennia/server/evennia_launcher.py b/evennia/server/evennia_launcher.py index 9ccf664410..559b9358bf 100644 --- a/evennia/server/evennia_launcher.py +++ b/evennia/server/evennia_launcher.py @@ -9,7 +9,7 @@ and portal through the evennia_runner. Run without arguments to get a menu. Run the script with the -h flag to see usage information. """ -from __future__ import print_function + from builtins import input, range import os @@ -535,7 +535,7 @@ def create_settings_file(init=True, secret_settings=False): if not init: # if not --init mode, settings file may already exist from before if os.path.exists(settings_path): - inp = input("%s already exists. Do you want to reset it? y/[N]> " % settings_path) + inp = eval(input("%s already exists. Do you want to reset it? y/[N]> " % settings_path)) if not inp.lower() == 'y': print ("Aborted.") return @@ -601,9 +601,9 @@ def check_database(): # Check so a database exists and is accessible from django.db import connection tables = connection.introspection.get_table_list(connection.cursor()) - if not tables or not isinstance(tables[0], basestring): # django 1.8+ + if not tables or not isinstance(tables[0], str): # django 1.8+ tables = [tableinfo.name for tableinfo in tables] - if tables and u'accounts_accountdb' in tables: + if tables and 'accounts_accountdb' in tables: # database exists and seems set up. Initialize evennia. evennia._init() # Try to get Account#1 @@ -632,7 +632,7 @@ def check_database(): res = "" while res.upper() != "Y": # ask for permission - res = input("Continue [Y]/N: ") + res = eval(input("Continue [Y]/N: ")) if res.upper() == "N": sys.exit() elif not res: @@ -993,9 +993,9 @@ def list_settings(keys): # a specific key table = evtable.EvTable(width=131) keys = [key.upper() for key in keys] - confs = dict((key, var) for key, var in evsettings.__dict__.items() + confs = dict((key, var) for key, var in list(evsettings.__dict__.items()) if key in keys) - for key, val in confs.items(): + for key, val in list(confs.items()): table.add_row(key, str(val)) print(table) @@ -1009,18 +1009,18 @@ def run_menu(): # menu loop print(MENU) - inp = input(" option > ") + inp = eval(input(" option > ")) # quitting and help if inp.lower() == 'q': return elif inp.lower() == 'h': print(HELP_ENTRY) - input("press to continue ...") + eval(input("press to continue ...")) continue elif inp.lower() in ('v', 'i', 'a'): print(show_version_info(about=True)) - input("press to continue ...") + eval(input("press to continue ...")) continue # options diff --git a/evennia/server/evennia_runner.py b/evennia/server/evennia_runner.py index 83e7bf4093..c17dde7045 100644 --- a/evennia/server/evennia_runner.py +++ b/evennia/server/evennia_runner.py @@ -14,13 +14,13 @@ upon returning, or not. A process returning != 0 will always stop, no matter the value of this file. """ -from __future__ import print_function + import os import sys from argparse import ArgumentParser from subprocess import Popen -import Queue -import thread +import queue +import _thread import evennia try: @@ -143,7 +143,7 @@ def start_services(server_argv, portal_argv, doexit=False): and then restarts them when they finish. """ global SERVER, PORTAL - processes = Queue.Queue() + processes = queue.Queue() def server_waiter(queue): try: @@ -167,7 +167,7 @@ def start_services(server_argv, portal_argv, doexit=False): try: if not doexit and get_restart_mode(PORTAL_RESTART) == "True": # start portal as interactive, reloadable thread - PORTAL = thread.start_new_thread(portal_waiter, (processes, )) + PORTAL = _thread.start_new_thread(portal_waiter, (processes, )) else: # normal operation: start portal as a daemon; # we don't care to monitor it for restart @@ -182,7 +182,7 @@ def start_services(server_argv, portal_argv, doexit=False): SERVER = Popen(server_argv, env=getenv()) else: # start server as a reloadable thread - SERVER = thread.start_new_thread(server_waiter, (processes, )) + SERVER = _thread.start_new_thread(server_waiter, (processes, )) except IOError as e: print(PROCESS_IOERROR.format(component="Server", traceback=e)) return @@ -207,14 +207,14 @@ def start_services(server_argv, portal_argv, doexit=False): if (message == "server_stopped" and int(rc) == 0 and get_restart_mode(SERVER_RESTART) in ("True", "reload", "reset")): print(PROCESS_RESTART.format(component="Server")) - SERVER = thread.start_new_thread(server_waiter, (processes, )) + SERVER = _thread.start_new_thread(server_waiter, (processes, )) continue # normally the portal is not reloaded since it's run as a daemon. if (message == "portal_stopped" and int(rc) == 0 and get_restart_mode(PORTAL_RESTART) == "True"): print(PROCESS_RESTART.format(component="Portal")) - PORTAL = thread.start_new_thread(portal_waiter, (processes, )) + PORTAL = _thread.start_new_thread(portal_waiter, (processes, )) continue break except ReactorNotRunning: diff --git a/evennia/server/initial_setup.py b/evennia/server/initial_setup.py index 985a54dc95..bae2cdf534 100644 --- a/evennia/server/initial_setup.py +++ b/evennia/server/initial_setup.py @@ -5,7 +5,7 @@ other things. Everything starts at handle_setup() """ -from __future__ import print_function + import time from django.conf import settings diff --git a/evennia/server/inputfuncs.py b/evennia/server/inputfuncs.py index 3715bb53fe..6d852767af 100644 --- a/evennia/server/inputfuncs.py +++ b/evennia/server/inputfuncs.py @@ -185,11 +185,11 @@ def client_options(session, *args, **kwargs): return {0: int(val)} def validate_bool(val): - if isinstance(val, basestring): + if isinstance(val, str): return True if val.lower() in ("true", "on", "1") else False return bool(val) - for key, value in kwargs.iteritems(): + for key, value in kwargs.items(): key = key.lower() if key == "client": flags["CLIENTNAME"] = to_str(value) @@ -254,7 +254,7 @@ def get_inputfuncs(session, *args, **kwargs): So we get it from the sessionhandler. """ inputfuncsdict = dict((key, func.__doc__) for key, func - in session.sessionhandler.get_inputfuncs().iteritems()) + in session.sessionhandler.get_inputfuncs().items()) session.msg(get_inputfuncs=inputfuncsdict) @@ -463,5 +463,5 @@ def webclient_options(session, *args, **kwargs): session=session) else: # kwargs provided: persist them to the account object - for key, value in kwargs.iteritems(): + for key, value in kwargs.items(): clientoptions[key] = value diff --git a/evennia/server/migrations/0001_initial.py b/evennia/server/migrations/0001_initial.py index bba61366b1..0ca07164ad 100644 --- a/evennia/server/migrations/0001_initial.py +++ b/evennia/server/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/server/models.py b/evennia/server/models.py index 7b4c2e9da8..92cfe88ed6 100644 --- a/evennia/server/models.py +++ b/evennia/server/models.py @@ -11,7 +11,7 @@ manager's conf() method. from builtins import object try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle diff --git a/evennia/server/portal/mssp.py b/evennia/server/portal/mssp.py index f80594c747..29a40ca285 100644 --- a/evennia/server/portal/mssp.py +++ b/evennia/server/portal/mssp.py @@ -191,7 +191,7 @@ class Mssp(object): self.mssp_table.update(MSSPTable_CUSTOM) varlist = '' - for variable, value in self.mssp_table.items(): + for variable, value in list(self.mssp_table.items()): if callable(value): value = value() if utils.is_iter(value): diff --git a/evennia/server/portal/portal.py b/evennia/server/portal/portal.py index 79002c2a0e..75cb77e837 100644 --- a/evennia/server/portal/portal.py +++ b/evennia/server/portal/portal.py @@ -7,7 +7,7 @@ sets up all the networking features. (this is done automatically by game/evennia.py). """ -from __future__ import print_function + from builtins import object import time diff --git a/evennia/server/portal/portalsessionhandler.py b/evennia/server/portal/portalsessionhandler.py index 171216f8d8..032fdfc5bb 100644 --- a/evennia/server/portal/portalsessionhandler.py +++ b/evennia/server/portal/portalsessionhandler.py @@ -1,8 +1,8 @@ """ Sessionhandler for portal sessions """ -from __future__ import print_function -from __future__ import division + + import time from collections import deque, namedtuple @@ -141,7 +141,7 @@ class PortalSessionHandler(SessionHandler): if self.portal.amp_protocol: # we only send sessdata that should not have changed # at the server level at this point - sessdata = dict((key, val) for key, val in sessdata.items() if key in ("protocol_key", + sessdata = dict((key, val) for key, val in list(sessdata.items()) if key in ("protocol_key", "address", "sessid", "csessid", @@ -188,7 +188,7 @@ class PortalSessionHandler(SessionHandler): # we set a watchdog to stop self.disconnect from deleting # sessions while we are looping over them. sessionhandler._disconnect_all = True - for session in sessionhandler.values(): + for session in list(sessionhandler.values()): session.disconnect() del sessionhandler._disconnect_all @@ -253,7 +253,7 @@ class PortalSessionHandler(SessionHandler): reason (str, optional): Motivation for disconnect. """ - for session in self.values(): + for session in list(self.values()): session.disconnect(reason) del session self.clear() @@ -336,7 +336,7 @@ class PortalSessionHandler(SessionHandler): send command. """ - for session in self.values(): + for session in list(self.values()): self.data_out(session, text=[[message], {}]) def data_in(self, session, **kwargs): @@ -412,7 +412,7 @@ class PortalSessionHandler(SessionHandler): # distribute outgoing data to the correct session methods. if session: - for cmdname, (cmdargs, cmdkwargs) in kwargs.iteritems(): + for cmdname, (cmdargs, cmdkwargs) in kwargs.items(): funcname = "send_%s" % cmdname.strip().lower() if hasattr(session, funcname): # better to use hassattr here over try..except diff --git a/evennia/server/portal/ssh.py b/evennia/server/portal/ssh.py index 7dde511637..980839b624 100644 --- a/evennia/server/portal/ssh.py +++ b/evennia/server/portal/ssh.py @@ -8,7 +8,7 @@ login procedure of the game, tracks sessions etc. Using standard ssh client, """ -from __future__ import print_function + from builtins import object import os import re diff --git a/evennia/server/portal/ssl.py b/evennia/server/portal/ssl.py index 209e08696f..761df6766d 100644 --- a/evennia/server/portal/ssl.py +++ b/evennia/server/portal/ssl.py @@ -3,7 +3,7 @@ This is a simple context factory for auto-creating SSL keys and certificates. """ -from __future__ import print_function + import os import sys diff --git a/evennia/server/portal/telnet_oob.py b/evennia/server/portal/telnet_oob.py index 50c8df7713..2d3060ca9c 100644 --- a/evennia/server/portal/telnet_oob.py +++ b/evennia/server/portal/telnet_oob.py @@ -208,7 +208,7 @@ class TelnetOOB(object): msdp_kwargs="".join("%s%s%s%s" % (MSDP_VAR, key, MSDP_VAL, json.dumps(val)) - for key, val in kwargs.iteritems())) + for key, val in kwargs.items())) msdp_string = msdp_args + msdp_kwargs @@ -316,7 +316,7 @@ class TelnetOOB(object): cmds = {} # merge matching table/array/variables together - for key, table in tables.iteritems(): + for key, table in tables.items(): args, kwargs = [], table if key in arrays: args.extend(arrays.pop(key)) @@ -324,13 +324,13 @@ class TelnetOOB(object): args.append(variables.pop(key)) cmds[key] = [args, kwargs] - for key, arr in arrays.iteritems(): + for key, arr in arrays.items(): args, kwargs = arr, {} if key in variables: args.append(variables.pop(key)) cmds[key] = [args, kwargs] - for key, var in variables.iteritems(): + for key, var in variables.items(): cmds[key] = [[var], {}] # print("msdp data in:", cmds) # DEBUG @@ -374,7 +374,7 @@ class TelnetOOB(object): args, kwargs = [], {} if hasattr(structure, "__iter__"): if isinstance(structure, dict): - kwargs = {key: value for key, value in structure.iteritems() if key} + kwargs = {key: value for key, value in structure.items() if key} else: args = list(structure) else: diff --git a/evennia/server/portal/webclient_ajax.py b/evennia/server/portal/webclient_ajax.py index c31f5d8eab..d780feabf7 100644 --- a/evennia/server/portal/webclient_ajax.py +++ b/evennia/server/portal/webclient_ajax.py @@ -87,7 +87,7 @@ class AjaxWebClient(resource.Resource): now = time.time() to_remove = [] keep_alives = ((csessid, remove) for csessid, (t, remove) - in self.last_alive.iteritems() if now - t > _KEEPALIVE) + in self.last_alive.items() if now - t > _KEEPALIVE) for csessid, remove in keep_alives: if remove: # keepalive timeout. Line is dead. diff --git a/evennia/server/profiling/dummyrunner.py b/evennia/server/profiling/dummyrunner.py index 34b6acafba..c008c4432b 100644 --- a/evennia/server/profiling/dummyrunner.py +++ b/evennia/server/profiling/dummyrunner.py @@ -30,8 +30,8 @@ in your settings. See utils.dummyrunner_actions.py for instructions on how to define this module. """ -from __future__ import print_function -from __future__ import division + + from builtins import range import sys diff --git a/evennia/server/profiling/memplot.py b/evennia/server/profiling/memplot.py index e8d7e76b12..5d031baaa3 100644 --- a/evennia/server/profiling/memplot.py +++ b/evennia/server/profiling/memplot.py @@ -6,7 +6,7 @@ the script will append to this file if it already exists. Call this module directly to plot the log (requires matplotlib and numpy). """ -from __future__ import division + import os import sys import time diff --git a/evennia/server/profiling/test_queries.py b/evennia/server/profiling/test_queries.py index 050dd9794a..6c0cf7a207 100644 --- a/evennia/server/profiling/test_queries.py +++ b/evennia/server/profiling/test_queries.py @@ -3,7 +3,7 @@ This is a little routine for viewing the sql queries that are executed by a give query as well as count them for optimization testing. """ -from __future__ import print_function + import sys import os #sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) diff --git a/evennia/server/profiling/timetrace.py b/evennia/server/profiling/timetrace.py index 00a37c3f38..8f4ebb5791 100644 --- a/evennia/server/profiling/timetrace.py +++ b/evennia/server/profiling/timetrace.py @@ -1,7 +1,7 @@ """ Trace a message through the messaging system """ -from __future__ import print_function + import time diff --git a/evennia/server/server.py b/evennia/server/server.py index fb9f753b5c..a68f6d5463 100644 --- a/evennia/server/server.py +++ b/evennia/server/server.py @@ -7,7 +7,7 @@ sets up all the networking features. (this is done automatically by evennia/server/server_runner.py). """ -from __future__ import print_function + from builtins import object import time import sys @@ -131,7 +131,7 @@ def _server_maintenance(): # handle idle timeouts if _IDLE_TIMEOUT > 0: reason = _("idle timeout exceeded") - for session in (sess for sess in SESSIONS.values() + for session in (sess for sess in list(SESSIONS.values()) if (now - sess.cmd_last) > _IDLE_TIMEOUT): if not session.account or not \ session.account.access(session.account, "noidletimeout", default=False): @@ -237,8 +237,8 @@ class Evennia(object): "BASE_EXIT_TYPECLASS", "BASE_SCRIPT_TYPECLASS", "BASE_CHANNEL_TYPECLASS") # get previous and current settings so they can be compared - settings_compare = zip([ServerConfig.objects.conf(name) for name in settings_names], - [settings.__getattr__(name) for name in settings_names]) + settings_compare = list(zip([ServerConfig.objects.conf(name) for name in settings_names], + [settings.__getattr__(name) for name in settings_names])) mismatches = [i for i, tup in enumerate(settings_compare) if tup[0] and tup[1] and tup[0] != tup[1]] if len(mismatches): # can't use any() since mismatches may be [0] which reads as False for any() # we have a changed default. Import relevant objects and diff --git a/evennia/server/serversession.py b/evennia/server/serversession.py index aaaeaaaedd..acd59ad67f 100644 --- a/evennia/server/serversession.py +++ b/evennia/server/serversession.py @@ -141,7 +141,7 @@ class NAttributeHandler(object): """ if return_tuples: - return [(key, value) for (key, value) in self._store.items() if not key.startswith("_")] + return [(key, value) for (key, value) in list(self._store.items()) if not key.startswith("_")] return [key for key in self._store if not key.startswith("_")] @@ -459,7 +459,7 @@ class ServerSession(Session): def __unicode__(self): """Unicode representation""" - return u"%s" % str(self) + return "%s" % str(self) # Dummy API hooks for use during non-loggedin operation diff --git a/evennia/server/session.py b/evennia/server/session.py index 70be0708d7..496d15bfeb 100644 --- a/evennia/server/session.py +++ b/evennia/server/session.py @@ -105,7 +105,7 @@ class Session(object): the keys given by self._attrs_to_sync. """ - return dict((key, value) for key, value in self.__dict__.items() + return dict((key, value) for key, value in list(self.__dict__.items()) if key in self._attrs_to_sync) def load_sync_data(self, sessdata): @@ -117,7 +117,7 @@ class Session(object): sessdata (dict): Session data dictionary. """ - for propname, value in sessdata.items(): + for propname, value in list(sessdata.items()): setattr(self, propname, value) def at_sync(self): diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index 825cf6da30..734e6e0c27 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -26,7 +26,7 @@ from evennia.utils.utils import (variable_from_module, is_iter, from evennia.utils.inlinefuncs import parse_inlinefunc try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle @@ -145,7 +145,7 @@ class SessionHandler(dict): if include_unloggedin: return listvalues(self) else: - return [session for session in self.values() if session.logged_in] + return [session for session in list(self.values()) if session.logged_in] def get_all_sync_data(self): """ @@ -156,7 +156,7 @@ class SessionHandler(dict): syncdata (dict): A dict of sync data. """ - return dict((sessid, sess.get_sync_data()) for sessid, sess in self.items()) + return dict((sessid, sess.get_sync_data()) for sessid, sess in list(self.items())) def clean_senddata(self, session, kwargs): """ @@ -189,12 +189,12 @@ class SessionHandler(dict): "Helper function to convert data to AMP-safe (picketable) values" if isinstance(data, dict): newdict = {} - for key, part in data.items(): + for key, part in list(data.items()): newdict[key] = _validate(part) return newdict elif hasattr(data, "__iter__"): return [_validate(part) for part in data] - elif isinstance(data, basestring): + elif isinstance(data, str): # make sure strings are in a valid encoding try: data = data and to_str(to_unicode(data), encoding=session.protocol_flags["ENCODING"]) @@ -214,12 +214,12 @@ class SessionHandler(dict): elif hasattr(data, "id") and hasattr(data, "db_date_created") \ and hasattr(data, '__dbclass__'): # convert database-object to their string representation. - return _validate(unicode(data)) + return _validate(str(data)) else: return data rkwargs = {} - for key, data in kwargs.iteritems(): + for key, data in kwargs.items(): key = _validate(key) if not data: if key == "text": @@ -347,12 +347,12 @@ class ServerSessionHandler(SessionHandler): delayed_import() global _ServerSession, _AccountDB, _ServerConfig, _ScriptDB - for sess in self.values(): + for sess in list(self.values()): # we delete the old session to make sure to catch eventual # lingering references. del sess - for sessid, sessdict in portalsessionsdata.items(): + for sessid, sessdict in list(portalsessionsdata.items()): sess = _ServerSession() sess.sessionhandler = self sess.load_sync_data(sessdict) @@ -565,7 +565,7 @@ class ServerSessionHandler(SessionHandler): """ uid = curr_session.uid - doublet_sessions = [sess for sess in self.values() + doublet_sessions = [sess for sess in list(self.values()) if sess.logged_in and sess.uid == uid and sess != curr_session] @@ -580,7 +580,7 @@ class ServerSessionHandler(SessionHandler): """ tcurr = time.time() reason = _("Idle timeout exceeded, disconnecting.") - for session in (session for session in self.values() + for session in (session for session in list(self.values()) if session.logged_in and _IDLE_TIMEOUT > 0 and (tcurr - session.cmd_last) > _IDLE_TIMEOUT): self.disconnect(session, reason=reason) @@ -595,7 +595,7 @@ class ServerSessionHandler(SessionHandler): naccount (int): Number of connected accounts """ - return len(set(session.uid for session in self.values() if session.logged_in)) + return len(set(session.uid for session in list(self.values()) if session.logged_in)) def all_connected_accounts(self): """ @@ -606,7 +606,7 @@ class ServerSessionHandler(SessionHandler): amount of Sessions due to multi-playing). """ - return list(set(session.account for session in self.values() if session.logged_in and session.account)) + return list(set(session.account for session in list(self.values()) if session.logged_in and session.account)) def session_from_sessid(self, sessid): """ @@ -653,7 +653,7 @@ class ServerSessionHandler(SessionHandler): """ uid = account.uid - return [session for session in self.values() if session.logged_in and session.uid == uid] + return [session for session in list(self.values()) if session.logged_in and session.uid == uid] def sessions_from_puppet(self, puppet): """ @@ -680,7 +680,7 @@ class ServerSessionHandler(SessionHandler): csessid (str): The session hash """ - return [session for session in self.values() + return [session for session in list(self.values()) if session.csessid and session.csessid == csessid] def announce_all(self, message): @@ -691,7 +691,7 @@ class ServerSessionHandler(SessionHandler): message (str): Message to send. """ - for session in self.values(): + for session in list(self.values()): self.data_out(session, text=message) def data_out(self, session, **kwargs): @@ -754,7 +754,7 @@ class ServerSessionHandler(SessionHandler): # distribute incoming data to the correct receiving methods. if session: input_debug = session.protocol_flags.get("INPUTDEBUG", False) - for cmdname, (cmdargs, cmdkwargs) in kwargs.iteritems(): + for cmdname, (cmdargs, cmdkwargs) in kwargs.items(): cname = cmdname.strip().lower() try: cmdkwargs.pop("options", None) diff --git a/evennia/server/webserver.py b/evennia/server/webserver.py index 260b38071d..a06f537dac 100644 --- a/evennia/server/webserver.py +++ b/evennia/server/webserver.py @@ -11,8 +11,8 @@ application. a great example/aid on how to do this.) """ -import urlparse -from urllib import quote as urlquote +import urllib.parse +from urllib.parse import quote as urlquote from twisted.web import resource, http, server from twisted.internet import reactor from twisted.application import internet @@ -117,7 +117,7 @@ class EvenniaReverseProxyResource(ReverseProxyResource): # RFC 2616 tells us that we can omit the port if it's the default port, # but we have to provide it otherwise request.content.seek(0, 0) - qs = urlparse.urlparse(request.uri)[4] + qs = urllib.parse.urlparse(request.uri)[4] if qs: rest = self.path + '?' + qs else: diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 779d2e3245..f7ce28e72c 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -259,8 +259,8 @@ CONN_MAX_AGE = 3600 * 7 # not be checked for models specified here. If new_natural_key does not exist, # `None` will be returned and stored back as if no replacement was set. ATTRIBUTE_STORED_MODEL_RENAME = [ - ((u"players", u"playerdb"), (u"accounts", u"accountdb")), - ((u"typeclasses", u"defaultplayer"), (u"typeclasses", u"defaultaccount"))] + (("players", "playerdb"), ("accounts", "accountdb")), + (("typeclasses", "defaultplayer"), ("typeclasses", "defaultaccount"))] ###################################################################### diff --git a/evennia/typeclasses/attributes.py b/evennia/typeclasses/attributes.py index 84a21c0c27..2fdbc5d6b7 100644 --- a/evennia/typeclasses/attributes.py +++ b/evennia/typeclasses/attributes.py @@ -168,7 +168,7 @@ class Attribute(SharedMemoryModel): return smart_str("%s(%s)" % (self.db_key, self.id)) def __unicode__(self): - return u"%s(%s)" % (self.db_key, self.id) + return "%s(%s)" % (self.db_key, self.id) def access(self, accessing_obj, access_type='read', default=False, **kwargs): """ @@ -299,7 +299,7 @@ class AttributeHandler(object): # for this category before catkey = "-%s" % category if _TYPECLASS_AGGRESSIVE_CACHE and catkey in self._catcache: - return [attr for key, attr in self._cache.items() if key.endswith(catkey) and attr] + return [attr for key, attr in list(self._cache.items()) if key.endswith(catkey) and attr] else: # we have to query to make this category up-date in the cache query = {"%s__id" % self._model: self._objid, @@ -350,7 +350,7 @@ class AttributeHandler(object): self._cache.pop(cachekey, None) else: self._cache = {key: attrobj for key, attrobj in - self._cache.items() if not key.endswith(catkey)} + list(self._cache.items()) if not key.endswith(catkey)} # mark that the category cache is no longer up-to-date self._catcache.pop(catkey, None) self._cache_complete = False @@ -655,10 +655,10 @@ class AttributeHandler(object): if not self._cache_complete: self._fullcache() if accessing_obj: - [attr.delete() for attr in self._cache.values() + [attr.delete() for attr in list(self._cache.values()) if attr and attr.access(accessing_obj, self._attredit, default=default_access)] else: - [attr.delete() for attr in self._cache.values() if attr and attr.pk] + [attr.delete() for attr in list(self._cache.values()) if attr and attr.pk] self._cache = {} self._catcache = {} self._cache_complete = False @@ -682,7 +682,7 @@ class AttributeHandler(object): """ if not self._cache_complete: self._fullcache() - attrs = sorted([attr for attr in self._cache.values() if attr], + attrs = sorted([attr for attr in list(self._cache.values()) if attr], key=lambda o: o.id) if accessing_obj: return [attr for attr in attrs @@ -903,7 +903,7 @@ class NickHandler(AttributeHandler): for category in make_iter(categories): nicks.update({nick.key: nick for nick in make_iter(self.obj.account.nicks.get( category=category, return_obj=True)) if nick and nick.key}) - for key, nick in nicks.iteritems(): + for key, nick in nicks.items(): nick_regex, template, _, _ = nick.value regex = self._regex_cache.get(nick_regex) if not regex: @@ -1001,5 +1001,5 @@ class NAttributeHandler(object): """ if return_tuples: - return [(key, value) for (key, value) in self._store.items() if not key.startswith("_")] + return [(key, value) for (key, value) in list(self._store.items()) if not key.startswith("_")] return [key for key in self._store if not key.startswith("_")] diff --git a/evennia/typeclasses/managers.py b/evennia/typeclasses/managers.py index 11a84f275a..47293eaa59 100644 --- a/evennia/typeclasses/managers.py +++ b/evennia/typeclasses/managers.py @@ -335,9 +335,9 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): either a string '#N' or an integer N. """ - if reqhash and not (isinstance(dbref, basestring) and dbref.startswith("#")): + if reqhash and not (isinstance(dbref, str) and dbref.startswith("#")): return None - if isinstance(dbref, basestring): + if isinstance(dbref, str): dbref = dbref.lstrip('#') try: if int(dbref) < 0: @@ -438,7 +438,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): if callable(typeclass): cls = typeclass.__class__ typeclass = "%s.%s" % (cls.__module__, cls.__name__) - elif not isinstance(typeclass, basestring) and hasattr(typeclass, "path"): + elif not isinstance(typeclass, str) and hasattr(typeclass, "path"): typeclass = typeclass.path # query objects of exact typeclass diff --git a/evennia/typeclasses/migrations/0001_initial.py b/evennia/typeclasses/migrations/0001_initial.py index 55b1daa7ca..214cc59803 100644 --- a/evennia/typeclasses/migrations/0001_initial.py +++ b/evennia/typeclasses/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations from django.conf import settings diff --git a/evennia/typeclasses/migrations/0002_auto_20150109_0913.py b/evennia/typeclasses/migrations/0002_auto_20150109_0913.py index 66753f4830..75b5e7f558 100644 --- a/evennia/typeclasses/migrations/0002_auto_20150109_0913.py +++ b/evennia/typeclasses/migrations/0002_auto_20150109_0913.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations diff --git a/evennia/typeclasses/migrations/0003_defaultcharacter_defaultexit_defaultguest_defaultobject_defaultplayer_defaultroom_defaultscript_dono.py b/evennia/typeclasses/migrations/0003_defaultcharacter_defaultexit_defaultguest_defaultobject_defaultplayer_defaultroom_defaultscript_dono.py index 8b966bfb86..d308822f70 100644 --- a/evennia/typeclasses/migrations/0003_defaultcharacter_defaultexit_defaultguest_defaultobject_defaultplayer_defaultroom_defaultscript_dono.py +++ b/evennia/typeclasses/migrations/0003_defaultcharacter_defaultexit_defaultguest_defaultobject_defaultplayer_defaultroom_defaultscript_dono.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import models, migrations import evennia.accounts.manager diff --git a/evennia/typeclasses/migrations/0004_auto_20151101_1759.py b/evennia/typeclasses/migrations/0004_auto_20151101_1759.py index 042462318a..a14017f6e6 100644 --- a/evennia/typeclasses/migrations/0004_auto_20151101_1759.py +++ b/evennia/typeclasses/migrations/0004_auto_20151101_1759.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from django.db import migrations, models diff --git a/evennia/typeclasses/migrations/0005_auto_20160625_1812.py b/evennia/typeclasses/migrations/0005_auto_20160625_1812.py index b3fd24f568..98997d89d1 100644 --- a/evennia/typeclasses/migrations/0005_auto_20160625_1812.py +++ b/evennia/typeclasses/migrations/0005_auto_20160625_1812.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.7 on 2016-06-25 18:12 -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/typeclasses/migrations/0006_auto_add_dbmodel_value_for_tags_attributes.py b/evennia/typeclasses/migrations/0006_auto_add_dbmodel_value_for_tags_attributes.py index f2cb9c23cc..33cb0a8640 100644 --- a/evennia/typeclasses/migrations/0006_auto_add_dbmodel_value_for_tags_attributes.py +++ b/evennia/typeclasses/migrations/0006_auto_add_dbmodel_value_for_tags_attributes.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.11 on 2017-01-21 22:30 -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/typeclasses/migrations/0007_tag_migrations_may_be_slow.py b/evennia/typeclasses/migrations/0007_tag_migrations_may_be_slow.py index 443ade55c6..db15e5b54f 100644 --- a/evennia/typeclasses/migrations/0007_tag_migrations_may_be_slow.py +++ b/evennia/typeclasses/migrations/0007_tag_migrations_may_be_slow.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.11 on 2017-01-25 22:30 -from __future__ import unicode_literals + from django.db import migrations diff --git a/evennia/typeclasses/migrations/0008_lock_and_perm_rename.py b/evennia/typeclasses/migrations/0008_lock_and_perm_rename.py index 670a7c8b08..1044c04226 100644 --- a/evennia/typeclasses/migrations/0008_lock_and_perm_rename.py +++ b/evennia/typeclasses/migrations/0008_lock_and_perm_rename.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.11 on 2017-01-25 22:30 -from __future__ import unicode_literals + import re from django.db import migrations diff --git a/evennia/typeclasses/migrations/0009_rename_player_cmdsets_typeclasses.py b/evennia/typeclasses/migrations/0009_rename_player_cmdsets_typeclasses.py index dfbfdcbf6f..84523de9a5 100644 --- a/evennia/typeclasses/migrations/0009_rename_player_cmdsets_typeclasses.py +++ b/evennia/typeclasses/migrations/0009_rename_player_cmdsets_typeclasses.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.3 on 2017-07-09 21:33 -from __future__ import unicode_literals + import re from django.db import migrations diff --git a/evennia/typeclasses/migrations/0010_delete_old_player_tables.py b/evennia/typeclasses/migrations/0010_delete_old_player_tables.py index 30abe534b1..0c9e37364f 100644 --- a/evennia/typeclasses/migrations/0010_delete_old_player_tables.py +++ b/evennia/typeclasses/migrations/0010_delete_old_player_tables.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.3 on 2017-07-13 18:47 -from __future__ import unicode_literals + from django.db import migrations, connection diff --git a/evennia/typeclasses/models.py b/evennia/typeclasses/models.py index c156aa2ac6..dbe48d7705 100644 --- a/evennia/typeclasses/models.py +++ b/evennia/typeclasses/models.py @@ -340,7 +340,7 @@ class TypedObject(SharedMemoryModel): return smart_str("%s" % self.db_key) def __unicode__(self): - return u"%s" % self.db_key + return "%s" % self.db_key #@property def __dbid_get(self): @@ -430,7 +430,7 @@ class TypedObject(SharedMemoryModel): typeclass. """ - if isinstance(typeclass, basestring): + if isinstance(typeclass, str): typeclass = [typeclass] + ["%s.%s" % (prefix, typeclass) for prefix in settings.TYPECLASS_PATHS] else: typeclass = [typeclass.path] diff --git a/evennia/typeclasses/tags.py b/evennia/typeclasses/tags.py index e7c3bfdbb1..e92c0ece42 100644 --- a/evennia/typeclasses/tags.py +++ b/evennia/typeclasses/tags.py @@ -67,7 +67,7 @@ class Tag(models.Model): index_together = (('db_key', 'db_category', 'db_tagtype', 'db_model'),) def __unicode__(self): - return u"" % (self.db_key, "(category:%s)" % self.db_category if self.db_category else "") + return "" % (self.db_key, "(category:%s)" % self.db_category if self.db_category else "") def __str__(self): return str("" % (self.db_key, "(category:%s)" % self.db_category if self.db_category else "")) @@ -166,7 +166,7 @@ class TagHandler(object): # for this category before catkey = "-%s" % category if _TYPECLASS_AGGRESSIVE_CACHE and catkey in self._catcache: - return [tag for key, tag in self._cache.items() if key.endswith(catkey)] + return [tag for key, tag in list(self._cache.items()) if key.endswith(catkey)] else: # we have to query to make this category up-date in the cache query = {"%s__id" % self._model: self._objid, @@ -394,14 +394,14 @@ class TagHandler(object): else: keys[tup[1]].append(tup[0]) data[tup[1]] = tup[2] # overwrite previous - for category, key in keys.iteritems(): + for category, key in keys.items(): self.add(tag=key, category=category, data=data.get(category, None)) def __str__(self): return ",".join(self.all()) def __unicode(self): - return u",".join(self.all()) + return ",".join(self.all()) class AliasHandler(TagHandler): diff --git a/evennia/utils/__init__.py b/evennia/utils/__init__.py index 2672699a7e..a34c39704c 100644 --- a/evennia/utils/__init__.py +++ b/evennia/utils/__init__.py @@ -4,7 +4,7 @@ modules in Evennia. It also holds the idmapper in-memory caching functionality. """ -from __future__ import absolute_import + # simple check to determine if we are currently running under pypy. try: import __pypy__ as is_pypy diff --git a/evennia/utils/ansi.py b/evennia/utils/ansi.py index f4e63cce85..a1a3ebf0e1 100644 --- a/evennia/utils/ansi.py +++ b/evennia/utils/ansi.py @@ -538,7 +538,7 @@ def _spacing_preflight(func): def wrapped(self, width, fillchar=None): if fillchar is None: fillchar = " " - if (len(fillchar) != 1) or (not isinstance(fillchar, basestring)): + if (len(fillchar) != 1) or (not isinstance(fillchar, str)): raise TypeError("must be char, not %s" % type(fillchar)) if not isinstance(width, int): raise TypeError("integer argument expected, got %s" % type(width)) @@ -579,7 +579,7 @@ def _on_raw(func_name): # just skip out if there are no more strings pass result = getattr(self._raw_string, func_name)(*args, **kwargs) - if isinstance(result, basestring): + if isinstance(result, str): return ANSIString(result, decoded=True) return result return wrapped @@ -633,7 +633,7 @@ class ANSIMeta(type): super(ANSIMeta, cls).__init__(*args, **kwargs) -class ANSIString(with_metaclass(ANSIMeta, unicode)): +class ANSIString(with_metaclass(ANSIMeta, str)): """ Unicode-like object that is aware of ANSI codes. @@ -674,7 +674,7 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)): """ string = args[0] - if not isinstance(string, basestring): + if not isinstance(string, str): string = to_str(string, force_string=True) parser = kwargs.get('parser', ANSI_PARSER) decoded = kwargs.get('decoded', False) or hasattr(string, '_raw_string') @@ -705,7 +705,7 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)): # It's a string that has been pre-ansi decoded. clean_string = parser.strip_raw_codes(string) - if not isinstance(string, unicode): + if not isinstance(string, str): string = string.decode('utf-8') ansi_string = super(ANSIString, cls).__new__(ANSIString, to_str(clean_string), "utf-8") @@ -803,7 +803,7 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)): interpreted literally. """ - if not isinstance(other, basestring): + if not isinstance(other, str): return NotImplemented if not isinstance(other, ANSIString): other = ANSIString(other) @@ -814,7 +814,7 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)): Likewise, if we're on the other end. """ - if not isinstance(other, basestring): + if not isinstance(other, str): return NotImplemented if not isinstance(other, ANSIString): other = ANSIString(other) @@ -976,7 +976,7 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)): code_indexes = [] for match in self.parser.ansi_regex.finditer(self._raw_string): - code_indexes.extend(range(match.start(), match.end())) + code_indexes.extend(list(range(match.start(), match.end()))) if not code_indexes: # Plain string, no ANSI codes. return code_indexes, list(range(0, len(self._raw_string))) @@ -1285,7 +1285,7 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)): code_indexes = [i for i in range(0, len(prefix))] length = len(prefix) + len(line) code_indexes.extend([i for i in range(length, length + len(postfix))]) - char_indexes = self._shifter(range(0, len(line)), len(prefix)) + char_indexes = self._shifter(list(range(0, len(line))), len(prefix)) raw_string = prefix + line + postfix return ANSIString( raw_string, clean_string=line, char_indexes=char_indexes, diff --git a/evennia/utils/batchprocessors.py b/evennia/utils/batchprocessors.py index a35e6d37f8..174a296943 100644 --- a/evennia/utils/batchprocessors.py +++ b/evennia/utils/batchprocessors.py @@ -382,7 +382,7 @@ class BatchCodeProcessor(object): """ # define the execution environment environdict = {"settings_module": settings, "DEBUG": debug} - for key, value in extra_environ.items(): + for key, value in list(extra_environ.items()): environdict[key] = value # initializing the django settings at the top of code diff --git a/evennia/utils/create.py b/evennia/utils/create.py index 1404e4caaa..8829bb922e 100644 --- a/evennia/utils/create.py +++ b/evennia/utils/create.py @@ -97,7 +97,7 @@ def create_object(typeclass=None, key=None, location=None, home=None, tags = make_iter(tags) if tags is not None else None - if isinstance(typeclass, basestring): + if isinstance(typeclass, str): # a path is given. Load the actual typeclass typeclass = class_from_module(typeclass, settings.TYPECLASS_PATHS) @@ -181,7 +181,7 @@ def create_script(typeclass=None, key=None, obj=None, account=None, locks=None, typeclass = typeclass if typeclass else settings.BASE_SCRIPT_TYPECLASS - if isinstance(typeclass, basestring): + if isinstance(typeclass, str): # a path is given. Load the actual typeclass typeclass = class_from_module(typeclass, settings.TYPECLASS_PATHS) @@ -353,7 +353,7 @@ def create_channel(key, aliases=None, desc=None, """ typeclass = typeclass if typeclass else settings.BASE_CHANNEL_TYPECLASS - if isinstance(typeclass, basestring): + if isinstance(typeclass, str): # a path is given. Load the actual typeclass typeclass = class_from_module(typeclass, settings.TYPECLASS_PATHS) @@ -418,7 +418,7 @@ def create_account(key, email, password, locks = make_iter(locks) if locks is not None else None permissions = make_iter(permissions) if permissions is not None else None - if isinstance(typeclass, basestring): + if isinstance(typeclass, str): # a path is given. Load the actual typeclass. typeclass = class_from_module(typeclass, settings.TYPECLASS_PATHS) diff --git a/evennia/utils/dbserialize.py b/evennia/utils/dbserialize.py index 80203923e8..dfc184d064 100644 --- a/evennia/utils/dbserialize.py +++ b/evennia/utils/dbserialize.py @@ -24,7 +24,7 @@ from functools import update_wrapper from collections import defaultdict, MutableSequence, MutableSet, MutableMapping from collections import OrderedDict, deque try: - from cPickle import dumps, loads + from pickle import dumps, loads except ImportError: from pickle import dumps, loads from django.core.exceptions import ObjectDoesNotExist @@ -157,7 +157,7 @@ class _SaverMutable(object): self._db_obj = kwargs.pop("_db_obj", None) self._data = None - def __nonzero__(self): + def __bool__(self): """Make sure to evaluate as False if empty""" return bool(self._data) @@ -183,7 +183,7 @@ class _SaverMutable(object): def process_tree(item, parent): """recursively populate the tree, storing parents""" dtype = type(item) - if dtype in (basestring, int, float, bool, tuple): + if dtype in (str, int, float, bool, tuple): return item elif dtype == list: dat = _SaverList(_parent=parent) @@ -191,7 +191,7 @@ class _SaverMutable(object): return dat elif dtype == dict: dat = _SaverDict(_parent=parent) - dat._data.update((key, process_tree(val, dat)) for key, val in item.items()) + dat._data.update((key, process_tree(val, dat)) for key, val in list(item.items())) return dat elif dtype == set: dat = _SaverSet(_parent=parent) @@ -493,18 +493,18 @@ def to_pickle(data): def process_item(item): """Recursive processor and identification of data""" dtype = type(item) - if dtype in (basestring, int, float, bool): + if dtype in (str, int, float, bool): return item elif dtype == tuple: return tuple(process_item(val) for val in item) elif dtype in (list, _SaverList): return [process_item(val) for val in item] elif dtype in (dict, _SaverDict): - return dict((process_item(key), process_item(val)) for key, val in item.items()) + return dict((process_item(key), process_item(val)) for key, val in list(item.items())) elif dtype in (set, _SaverSet): return set(process_item(val) for val in item) elif dtype in (OrderedDict, _SaverOrderedDict): - return OrderedDict((process_item(key), process_item(val)) for key, val in item.items()) + return OrderedDict((process_item(key), process_item(val)) for key, val in list(item.items())) elif dtype in (deque, _SaverDeque): return deque(process_item(val) for val in item) @@ -545,7 +545,7 @@ def from_pickle(data, db_obj=None): def process_item(item): """Recursive processor and identification of data""" dtype = type(item) - if dtype in (basestring, int, float, bool): + if dtype in (str, int, float, bool): return item elif _IS_PACKED_DBOBJ(item): # this must be checked before tuple @@ -555,11 +555,11 @@ def from_pickle(data, db_obj=None): elif dtype == tuple: return tuple(process_item(val) for val in item) elif dtype == dict: - return dict((process_item(key), process_item(val)) for key, val in item.items()) + return dict((process_item(key), process_item(val)) for key, val in list(item.items())) elif dtype == set: return set(process_item(val) for val in item) elif dtype == OrderedDict: - return OrderedDict((process_item(key), process_item(val)) for key, val in item.items()) + return OrderedDict((process_item(key), process_item(val)) for key, val in list(item.items())) elif dtype == deque: return deque(process_item(val) for val in item) elif hasattr(item, '__iter__'): @@ -574,7 +574,7 @@ def from_pickle(data, db_obj=None): def process_tree(item, parent): """Recursive processor, building a parent-tree from iterable data""" dtype = type(item) - if dtype in (basestring, int, float, bool): + if dtype in (str, int, float, bool): return item elif _IS_PACKED_DBOBJ(item): # this must be checked before tuple @@ -588,7 +588,7 @@ def from_pickle(data, db_obj=None): elif dtype == dict: dat = _SaverDict(_parent=parent) dat._data.update((process_item(key), process_tree(val, dat)) - for key, val in item.items()) + for key, val in list(item.items())) return dat elif dtype == set: dat = _SaverSet(_parent=parent) @@ -597,7 +597,7 @@ def from_pickle(data, db_obj=None): elif dtype == OrderedDict: dat = _SaverOrderedDict(_parent=parent) dat._data.update((process_item(key), process_tree(val, dat)) - for key, val in item.items()) + for key, val in list(item.items())) return dat elif dtype == deque: dat = _SaverDeque(_parent=parent) @@ -625,7 +625,7 @@ def from_pickle(data, db_obj=None): elif dtype == dict: dat = _SaverDict(_db_obj=db_obj) dat._data.update((process_item(key), process_tree(val, dat)) - for key, val in data.items()) + for key, val in list(data.items())) return dat elif dtype == set: dat = _SaverSet(_db_obj=db_obj) @@ -634,7 +634,7 @@ def from_pickle(data, db_obj=None): elif dtype == OrderedDict: dat = _SaverOrderedDict(_db_obj=db_obj) dat._data.update((process_item(key), process_tree(val, dat)) - for key, val in data.items()) + for key, val in list(data.items())) return dat elif dtype == deque: dat = _SaverDeque(_db_obj=db_obj) diff --git a/evennia/utils/eveditor.py b/evennia/utils/eveditor.py index 2ec3865eeb..990c826b33 100644 --- a/evennia/utils/eveditor.py +++ b/evennia/utils/eveditor.py @@ -336,7 +336,7 @@ def _load_editor(caller): setattr(eveditor, "_undo_pos", len(saved_undo) - 1) setattr(eveditor, "_unsaved", unsaved) setattr(eveditor, "_indent", indent) - for key, value in saved_options[1].iteritems(): + for key, value in saved_options[1].items(): setattr(eveditor, key, value) else: # something went wrong. Cleanup. @@ -800,7 +800,7 @@ class EvEditor(object): """ try: self._buffer = self._loadfunc(self._caller) - if not isinstance(self._buffer, basestring): + if not isinstance(self._buffer, str): self._buffer = to_str(self._buffer, force_string=True) self._caller.msg("|rNote: input buffer was converted to a string.|n") except Exception as e: @@ -965,7 +965,7 @@ class EvEditor(object): # If the line begins by one of the given keywords indent = self._indent - if any(line.startswith(kw) for kw in keywords.keys()): + if any(line.startswith(kw) for kw in list(keywords.keys())): # Get the keyword and matching begin tags keyword = [kw for kw in keywords if line.startswith(kw)][0] begin_tags = keywords[keyword] diff --git a/evennia/utils/evform.py b/evennia/utils/evform.py index 55fa0ec9e2..44d9f86cf4 100644 --- a/evennia/utils/evform.py +++ b/evennia/utils/evform.py @@ -134,7 +134,7 @@ into (when including its borders and at least one line of text), the form will raise an error. """ -from __future__ import print_function + from builtins import object, range import re @@ -155,12 +155,12 @@ _ANSI_ESCAPE = re.compile(r"\|\|") def _to_ansi(obj, regexable=False): "convert to ANSIString" - if isinstance(obj, basestring): + if isinstance(obj, str): # since ansi will be parsed twice (here and in the normal ansi send), we have to # escape the |-structure twice. obj = _ANSI_ESCAPE.sub(r"||||", obj) if isinstance(obj, dict): - return dict((key, _to_ansi(value, regexable=regexable)) for key, value in obj.items()) + return dict((key, _to_ansi(value, regexable=regexable)) for key, value in list(obj.items())) elif hasattr(obj, "__iter__"): return [_to_ansi(o) for o in obj] else: @@ -196,8 +196,8 @@ class EvForm(object): self.filename = filename self.input_form_dict = form - self.cells_mapping = dict((to_str(key, force_string=True), value) for key, value in cells.items()) if cells else {} - self.tables_mapping = dict((to_str(key, force_string=True), value) for key, value in tables.items()) if tables else {} + self.cells_mapping = dict((to_str(key, force_string=True), value) for key, value in list(cells.items())) if cells else {} + self.tables_mapping = dict((to_str(key, force_string=True), value) for key, value in list(tables.items())) if tables else {} self.cellchar = "x" self.tablechar = "c" @@ -259,7 +259,7 @@ class EvForm(object): break # get rectangles and assign EvCells - for key, (iy, leftix, rightix) in cell_coords.items(): + for key, (iy, leftix, rightix) in list(cell_coords.items()): # scan up to find top of rectangle dy_up = 0 @@ -295,7 +295,7 @@ class EvForm(object): mapping[key] = (iyup, leftix, width, height, EvCell(data, width=width, height=height, **options)) # get rectangles and assign Tables - for key, (iy, leftix, rightix) in table_coords.items(): + for key, (iy, leftix, rightix) in list(table_coords.items()): # scan up to find top of rectangle dy_up = 0 @@ -341,7 +341,7 @@ class EvForm(object): """ form = copy.copy(raw_form) - for key, (iy0, ix0, width, height, cell_or_table) in mapping.items(): + for key, (iy0, ix0, width, height, cell_or_table) in list(mapping.items()): # rect is a list of lines, each wide rect = cell_or_table.get() for il, rectline in enumerate(rect): @@ -368,8 +368,8 @@ class EvForm(object): kwargs.pop("width", None) kwargs.pop("height", None) - new_cells = dict((to_str(key, force_string=True), value) for key, value in cells.items()) if cells else {} - new_tables = dict((to_str(key, force_string=True), value) for key, value in tables.items()) if tables else {} + new_cells = dict((to_str(key, force_string=True), value) for key, value in list(cells.items())) if cells else {} + new_tables = dict((to_str(key, force_string=True), value) for key, value in list(tables.items())) if tables else {} self.cells_mapping.update(new_cells) self.tables_mapping.update(new_tables) @@ -424,7 +424,7 @@ class EvForm(object): def __unicode__(self): "prints the form" - return unicode(ANSIString("\n").join([line for line in self.form])) + return str(ANSIString("\n").join([line for line in self.form])) def _test(): @@ -453,4 +453,4 @@ def _test(): form.map(tables={"A": tableA, "B": tableB}) # unicode is required since the example contains non-ascii characters - return unicode(form) + return str(form) diff --git a/evennia/utils/evmenu.py b/evennia/utils/evmenu.py index a595366f5c..d3cd7ddb64 100644 --- a/evennia/utils/evmenu.py +++ b/evennia/utils/evmenu.py @@ -156,7 +156,7 @@ your default cmdset. Run it with this module, like `testmenu evennia.utils.evmenu`. """ -from __future__ import print_function + import random from builtins import object, range @@ -441,7 +441,7 @@ class EvMenu(object): "cmd_on_exit", "default", "nodetext", "helptext", "options", "cmdset_mergetype", "auto_quit")).intersection(set(kwargs.keys())): raise RuntimeError("One or more of the EvMenu `**kwargs` is reserved by EvMenu for internal use.") - for key, val in kwargs.iteritems(): + for key, val in kwargs.items(): setattr(self, key, val) # @@ -511,7 +511,7 @@ class EvMenu(object): else: # a python path of a module module = mod_import(menudata) - return dict((key, func) for key, func in module.__dict__.items() + return dict((key, func) for key, func in list(module.__dict__.items()) if isfunction(func) and not key.startswith("_")) def _format_node(self, nodetext, optionlist): @@ -663,7 +663,7 @@ class EvMenu(object): logger.log_trace(errmsg) return - if isinstance(ret, basestring): + if isinstance(ret, str): # only return a value if a string (a goto target), ignore all other returns return ret, kwargs return None @@ -934,7 +934,7 @@ class EvMenu(object): table[icol] = [pad(part, width=col_width + colsep, align="l") for part in table[icol]] # format the table into columns - return unicode(EvTable(table=table, border="none")) + return str(EvTable(table=table, border="none")) def node_formatter(self, nodetext, optionstext): """ diff --git a/evennia/utils/evtable.py b/evennia/utils/evtable.py index 31218189ab..b791b9911f 100644 --- a/evennia/utils/evtable.py +++ b/evennia/utils/evtable.py @@ -114,7 +114,7 @@ you need to re-set the color to have it appear on both sides of the table string. """ -from __future__ import print_function + from builtins import object, range from future.utils import listitems @@ -141,7 +141,7 @@ def _to_ansi(obj): return ANSIString(to_unicode(obj)) -_unicode = unicode +_unicode = str _whitespace = '\t\n\x0b\x0c\r ' @@ -810,7 +810,7 @@ class EvCell(object): self.trim_vertical = kwargs.pop("trim_vertical", self.trim_vertical) # fill all other properties - for key, value in kwargs.items(): + for key, value in list(kwargs.items()): setattr(self, key, value) # Handle sizes @@ -841,17 +841,17 @@ class EvCell(object): def __repr__(self): self.formatted = self._reformat() - return unicode(ANSIString("" % self.formatted)) + return str(ANSIString("" % self.formatted)) def __str__(self): "returns cell contents on string form" self.formatted = self._reformat() - return str(unicode(ANSIString("\n").join(self.formatted))) + return str(str(ANSIString("\n").join(self.formatted))) def __unicode__(self): "returns cell contents" self.formatted = self._reformat() - return unicode(ANSIString("\n").join(self.formatted)) + return str(ANSIString("\n").join(self.formatted)) # EvColumn class @@ -1424,7 +1424,7 @@ class EvTable(object): header = kwargs.get("header", None) if header: - column.add_rows(unicode(header), ypos=0, **options) + column.add_rows(str(header), ypos=0, **options) self.header = True elif self.header: # we have a header already. Offset @@ -1519,7 +1519,7 @@ class EvTable(object): """ self.width = kwargs.pop("width", self.width) self.height = kwargs.pop("height", self.height) - for key, value in kwargs.items(): + for key, value in list(kwargs.items()): setattr(self, key, value) hchar = kwargs.pop("header_line_char", self.header_line_char) @@ -1569,10 +1569,10 @@ class EvTable(object): def __str__(self): """print table (this also balances it)""" - return str(unicode(ANSIString("\n").join([line for line in self._generate_lines()]))) + return str(str(ANSIString("\n").join([line for line in self._generate_lines()]))) def __unicode__(self): - return unicode(ANSIString("\n").join([line for line in self._generate_lines()])) + return str(ANSIString("\n").join([line for line in self._generate_lines()])) def _test(): @@ -1580,11 +1580,11 @@ def _test(): table = EvTable("|yHeading1|n", "|gHeading2|n", table=[[1, 2, 3], [4, 5, 6], [7, 8, 9]], border="cells", align="l") table.add_column("|rThis is long data|n", "|bThis is even longer data|n") table.add_row("This is a single row") - print(unicode(table)) + print(str(table)) table.reformat(width=50) - print(unicode(table)) + print(str(table)) table.reformat_column(3, width=30, align='r') - print(unicode(table)) + print(str(table)) return table diff --git a/evennia/utils/gametime.py b/evennia/utils/gametime.py index 793e348143..a6d21907c9 100644 --- a/evennia/utils/gametime.py +++ b/evennia/utils/gametime.py @@ -5,7 +5,7 @@ It also supplies some useful methods to convert between in-mud time and real-world time as well allows to get the total runtime of the server and the current uptime. """ -from __future__ import division + import time from calendar import monthrange from datetime import datetime, timedelta diff --git a/evennia/utils/idmapper/models.py b/evennia/utils/idmapper/models.py index fcda53cdfd..326c387f55 100644 --- a/evennia/utils/idmapper/models.py +++ b/evennia/utils/idmapper/models.py @@ -6,7 +6,7 @@ leave caching unexpectedly (no use of WeakRefs). Also adds `cache_size()` for monitoring the size of the cache. """ -from __future__ import absolute_import, division + from builtins import object from future.utils import listitems, listvalues, with_metaclass @@ -141,7 +141,7 @@ class SharedMemoryModelBase(ModelBase): "Setter only used on foreign key relations, allows setting with #dbref" if _GA(cls, "_is_deleted"): raise ObjectDoesNotExist("Cannot set %s to %s: Hosting object was already deleted!" % (fname, value)) - if isinstance(value, (basestring, int)): + if isinstance(value, (str, int)): value = to_str(value, force_string=True) if (value.isdigit() or value.startswith("#")): # we also allow setting using dbrefs, if so we try to load the matching object. @@ -328,7 +328,7 @@ class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): if force: cls.__dbclass__.__instance_cache__ = {} else: - cls.__dbclass__.__instance_cache__ = dict((key, obj) for key, obj in cls.__dbclass__.__instance_cache__.items() + cls.__dbclass__.__instance_cache__ = dict((key, obj) for key, obj in list(cls.__dbclass__.__instance_cache__.items()) if not obj.at_idmapper_flush()) #flush_instance_cache = classmethod(flush_instance_cache) diff --git a/evennia/utils/idmapper/tests.py b/evennia/utils/idmapper/tests.py index 4647b4a824..374eb0187a 100644 --- a/evennia/utils/idmapper/tests.py +++ b/evennia/utils/idmapper/tests.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import + from builtins import range from django.test import TestCase @@ -44,21 +44,21 @@ class SharedMemorysTest(TestCase): article_list = Article.objects.all().select_related('category') last_article = article_list[0] for article in article_list[1:]: - self.assertEquals(article.category is last_article.category, True) + self.assertEqual(article.category is last_article.category, True) last_article = article def testRegularReferences(self): article_list = RegularArticle.objects.all().select_related('category') last_article = article_list[0] for article in article_list[1:]: - self.assertEquals(article.category2 is last_article.category2, False) + self.assertEqual(article.category2 is last_article.category2, False) last_article = article def testMixedReferences(self): article_list = RegularArticle.objects.all().select_related('category') last_article = article_list[0] for article in article_list[1:]: - self.assertEquals(article.category is last_article.category, True) + self.assertEqual(article.category is last_article.category, True) last_article = article #article_list = Article.objects.all().select_related('category') @@ -74,4 +74,4 @@ class SharedMemorysTest(TestCase): article = Article.objects.all()[0:1].get() pk = article.pk article.delete() - self.assertEquals(pk not in Article.__instance_cache__, True) + self.assertEqual(pk not in Article.__instance_cache__, True) diff --git a/evennia/utils/inlinefuncs.py b/evennia/utils/inlinefuncs.py index e103e217d7..118f4fea5d 100644 --- a/evennia/utils/inlinefuncs.py +++ b/evennia/utils/inlinefuncs.py @@ -1,464 +1,464 @@ -""" -Inline functions (nested form). - -This parser accepts nested inlinefunctions on the form - -``` -$funcname(arg, arg, ...) -``` - -embedded in any text where any arg can be another $funcname{} call. -This functionality is turned off by default - to activate, -`settings.INLINEFUNC_ENABLED` must be set to `True`. - -Each token starts with "$funcname(" where there must be no space -between the $funcname and (. It ends with a matched ending parentesis. -")". - -Inside the inlinefunc definition, one can use `\` to escape. This is -mainly needed for escaping commas in flowing text (which would -otherwise be interpreted as an argument separator), or to escape `}` -when not intended to close the function block. Enclosing text in -matched `\"\"\"` (triple quotes) or `'''` (triple single-quotes) will -also escape *everything* within without needing to escape individual -characters. - -The available inlinefuncs are defined as global-level functions in -modules defined by `settings.INLINEFUNC_MODULES`. They are identified -by their function name (and ignored if this name starts with `_`). They -should be on the following form: - -```python -def funcname (*args, **kwargs): - # ... -``` - -Here, the arguments given to `$funcname(arg1,arg2)` will appear as the -`*args` tuple. This will be populated by the arguments given to the -inlinefunc in-game - the only part that will be available from -in-game. `**kwargs` are not supported from in-game but are only used -internally by Evennia to make details about the caller available to -the function. The kwarg passed to all functions is `session`, the -Sessionobject for the object seeing the string. This may be `None` if -the string is sent to a non-puppetable object. The inlinefunc should -never raise an exception. - -There are two reserved function names: -- "nomatch": This is called if the user uses a functionname that is - not registered. The nomatch function will get the name of the - not-found function as its first argument followed by the normal - arguments to the given function. If not defined the default effect is - to print `` to replace the unknown function. -- "stackfull": This is called when the maximum nested function stack is reached. - When this happens, the original parsed string is returned and the result of - the `stackfull` inlinefunc is appended to the end. By default this is an - error message. - -Error handling: - Syntax errors, notably not completely closing all inlinefunc - blocks, will lead to the entire string remaining unparsed. - -""" - -import re -from django.conf import settings -from evennia.utils import utils - - -# example/testing inline functions - -def pad(*args, **kwargs): - """ - Inlinefunc. Pads text to given width. - - Args: - text (str, optional): Text to pad. - width (str, optional): Will be converted to integer. Width - of padding. - align (str, optional): Alignment of padding; one of 'c', 'l' or 'r'. - fillchar (str, optional): Character used for padding. Defaults to a space. - - Kwargs: - session (Session): Session performing the pad. - - Example: - `$pad(text, width, align, fillchar)` - - """ - text, width, align, fillchar = "", 78, 'c', ' ' - nargs = len(args) - if nargs > 0: - text = args[0] - if nargs > 1: - width = int(args[1]) if args[1].strip().isdigit() else 78 - if nargs > 2: - align = args[2] if args[2] in ('c', 'l', 'r') else 'c' - if nargs > 3: - fillchar = args[3] - return utils.pad(text, width=width, align=align, fillchar=fillchar) - - -def crop(*args, **kwargs): - """ - Inlinefunc. Crops ingoing text to given widths. - - Args: - text (str, optional): Text to crop. - width (str, optional): Will be converted to an integer. Width of - crop in characters. - suffix (str, optional): End string to mark the fact that a part - of the string was cropped. Defaults to `[...]`. - Kwargs: - session (Session): Session performing the crop. - - Example: - `$crop(text, width=78, suffix='[...]')` - - """ - text, width, suffix = "", 78, "[...]" - nargs = len(args) - if nargs > 0: - text = args[0] - if nargs > 1: - width = int(args[1]) if args[1].strip().isdigit() else 78 - if nargs > 2: - suffix = args[2] - return utils.crop(text, width=width, suffix=suffix) - - -def clr(*args, **kwargs): - """ - Inlinefunc. Colorizes nested text. - - Args: - startclr (str, optional): An ANSI color abbreviation without the - prefix `|`, such as `r` (red foreground) or `[r` (red background). - text (str, optional): Text - endclr (str, optional): The color to use at the end of the string. Defaults - to `|n` (reset-color). - Kwargs: - session (Session): Session object triggering inlinefunc. - - Example: - `$clr(startclr, text, endclr)` - - """ - text = "" - nargs = len(args) - if nargs > 0: - color = args[0].strip() - if nargs > 1: - text = args[1] - text = "|" + color + text - if nargs > 2: - text += "|" + args[2].strip() - else: - text += "|n" - return text - - -# we specify a default nomatch function to use if no matching func was -# found. This will be overloaded by any nomatch function defined in -# the imported modules. -_INLINE_FUNCS = {"nomatch": lambda *args, **kwargs: "", - "stackfull": lambda *args, **kwargs: "\n (not parsed: inlinefunc stack size exceeded.)"} - - -# load custom inline func modules. -for module in utils.make_iter(settings.INLINEFUNC_MODULES): - try: - _INLINE_FUNCS.update(utils.callables_from_module(module)) - except ImportError as err: - if module == "server.conf.inlinefuncs": - # a temporary warning since the default module changed name - raise ImportError("Error: %s\nPossible reason: mygame/server/conf/inlinefunc.py should " - "be renamed to mygame/server/conf/inlinefuncs.py (note the S at the end)." % err) - else: - raise - - -# remove the core function if we include examples in this module itself -#_INLINE_FUNCS.pop("inline_func_parse", None) - - -# The stack size is a security measure. Set to <=0 to disable. -try: - _STACK_MAXSIZE = settings.INLINEFUNC_STACK_MAXSIZE -except AttributeError: - _STACK_MAXSIZE = 20 - -# regex definitions - -_RE_STARTTOKEN = re.compile(r"(?.*?)(?.*?)(?(?(?(?\\'|\\"|\\\)|\\$\w+\()| # escaped tokens should re-appear in text - (?P[\w\s.-\/#!%\^&\*;:=\-_`~\|\(}{\[\]]+|\"{1}|\'{1}) # everything else should also be included""", - re.UNICODE + re.IGNORECASE + re.VERBOSE + re.DOTALL) - - -# Cache for function lookups. -_PARSING_CACHE = utils.LimitedSizeOrderedDict(size_limit=1000) - - -class ParseStack(list): - """ - Custom stack that always concatenates strings together when the - strings are added next to one another. Tuples are stored - separately and None is used to mark that a string should be broken - up into a new chunk. Below is the resulting stack after separately - appending 3 strings, None, 2 strings, a tuple and finally 2 - strings: - - [string + string + string, - None - string + string, - tuple, - string + string] - - """ - - def __init__(self, *args, **kwargs): - super(ParseStack, self).__init__(*args, **kwargs) - # always start stack with the empty string - list.append(self, "") - # indicates if the top of the stack is a string or not - self._string_last = True - - def __eq__(self, other): - return (super(ParseStack).__eq__(other) and - hasattr(other, "_string_last") and self._string_last == other._string_last) - - def __ne__(self, other): - return not self.__eq__(other) - - def append(self, item): - """ - The stack will merge strings, add other things as normal - """ - if isinstance(item, basestring): - if self._string_last: - self[-1] += item - else: - list.append(self, item) - self._string_last = True - else: - # everything else is added as normal - list.append(self, item) - self._string_last = False - - -class InlinefuncError(RuntimeError): - pass - - -def parse_inlinefunc(string, strip=False, **kwargs): - """ - Parse the incoming string. - - Args: - string (str): The incoming string to parse. - strip (bool, optional): Whether to strip function calls rather than - execute them. - Kwargs: - session (Session): This is sent to this function by Evennia when triggering - it. It is passed to the inlinefunc. - kwargs (any): All other kwargs are also passed on to the inlinefunc. - - - """ - global _PARSING_CACHE - if string in _PARSING_CACHE: - # stack is already cached - stack = _PARSING_CACHE[string] - elif not _RE_STARTTOKEN.search(string): - # if there are no unescaped start tokens at all, return immediately. - return string - else: - # no cached stack; build a new stack and continue - stack = ParseStack() - - # process string on stack - ncallable = 0 - for match in _RE_TOKEN.finditer(string): - gdict = match.groupdict() - if gdict["singlequote"]: - stack.append(gdict["singlequote"]) - elif gdict["doublequote"]: - stack.append(gdict["doublequote"]) - elif gdict["end"]: - if ncallable <= 0: - stack.append(")") - continue - args = [] - while stack: - operation = stack.pop() - if callable(operation): - if not strip: - stack.append((operation, [arg for arg in reversed(args)])) - ncallable -= 1 - break - else: - args.append(operation) - elif gdict["start"]: - funcname = _RE_STARTTOKEN.match(gdict["start"]).group(1) - try: - # try to fetch the matching inlinefunc from storage - stack.append(_INLINE_FUNCS[funcname]) - except KeyError: - stack.append(_INLINE_FUNCS["nomatch"]) - stack.append(funcname) - ncallable += 1 - elif gdict["escaped"]: - # escaped tokens - token = gdict["escaped"].lstrip("\\") - stack.append(token) - elif gdict["comma"]: - if ncallable > 0: - # commas outside strings and inside a callable are - # used to mark argument separation - we use None - # in the stack to indicate such a separation. - stack.append(None) - else: - # no callable active - just a string - stack.append(",") - else: - # the rest - stack.append(gdict["rest"]) - - if ncallable > 0: - # this means not all inlinefuncs were complete - return string - - if _STACK_MAXSIZE > 0 and _STACK_MAXSIZE < len(stack): - # if stack is larger than limit, throw away parsing - return string + gdict["stackfull"](*args, **kwargs) - else: - # cache the stack - _PARSING_CACHE[string] = stack - - # run the stack recursively - def _run_stack(item, depth=0): - retval = item - if isinstance(item, tuple): - if strip: - return "" - else: - func, arglist = item - args = [""] - for arg in arglist: - if arg is None: - # an argument-separating comma - start a new arg - args.append("") - else: - # all other args should merge into one string - args[-1] += _run_stack(arg, depth=depth + 1) - # execute the inlinefunc at this point or strip it. - kwargs["inlinefunc_stack_depth"] = depth - retval = "" if strip else func(*args, **kwargs) - return utils.to_str(retval, force_string=True) - - # execute the stack from the cache - return "".join(_run_stack(item) for item in _PARSING_CACHE[string]) - -# -# Nick templating -# - - -""" -This supports the use of replacement templates in nicks: - -This happens in two steps: - -1) The user supplies a template that is converted to a regex according - to the unix-like templating language. -2) This regex is tested against nicks depending on which nick replacement - strategy is considered (most commonly inputline). -3) If there is a template match and there are templating markers, - these are replaced with the arguments actually given. - -@desc $1 $2 $3 - -This will be converted to the following regex: - -\@desc (?P<1>\w+) (?P<2>\w+) $(?P<3>\w+) - -Supported template markers (through fnmatch) - * matches anything (non-greedy) -> .*? - ? matches any single character -> - [seq] matches any entry in sequence - [!seq] matches entries not in sequence -Custom arg markers - $N argument position (1-99) - -""" -import fnmatch -_RE_NICK_ARG = re.compile(r"\\(\$)([1-9][0-9]?)") -_RE_NICK_TEMPLATE_ARG = re.compile(r"(\$)([1-9][0-9]?)") -_RE_NICK_SPACE = re.compile(r"\\ ") - - -class NickTemplateInvalid(ValueError): - pass - - -def initialize_nick_templates(in_template, out_template): - """ - Initialize the nick templates for matching and remapping a string. - - Args: - in_template (str): The template to be used for nick recognition. - out_template (str): The template to be used to replace the string - matched by the in_template. - - Returns: - regex (regex): Regex to match against strings - template (str): Template with markers {arg1}, {arg2}, etc for - replacement using the standard .format method. - - Raises: - NickTemplateInvalid: If the in/out template does not have a matching - number of $args. - - """ - # create the regex for in_template - regex_string = fnmatch.translate(in_template) - n_inargs = len(_RE_NICK_ARG.findall(regex_string)) - regex_string = _RE_NICK_SPACE.sub("\s+", regex_string) - regex_string = _RE_NICK_ARG.sub(lambda m: "(?P.+?)" % m.group(2), regex_string) - - # create the out_template - template_string = _RE_NICK_TEMPLATE_ARG.sub(lambda m: "{arg%s}" % m.group(2), out_template) - - # validate the tempaltes - they should at least have the same number of args - n_outargs = len(_RE_NICK_TEMPLATE_ARG.findall(out_template)) - if n_inargs != n_outargs: - print n_inargs, n_outargs - raise NickTemplateInvalid - - return re.compile(regex_string), template_string - - -def parse_nick_template(string, template_regex, outtemplate): - """ - Parse a text using a template and map it to another template - - Args: - string (str): The input string to processj - template_regex (regex): A template regex created with - initialize_nick_template. - outtemplate (str): The template to which to map the matches - produced by the template_regex. This should have $1, $2, - etc to match the regex. - - """ - match = template_regex.match(string) - if match: - return outtemplate.format(**match.groupdict()) - return string +""" +Inline functions (nested form). + +This parser accepts nested inlinefunctions on the form + +``` +$funcname(arg, arg, ...) +``` + +embedded in any text where any arg can be another $funcname{} call. +This functionality is turned off by default - to activate, +`settings.INLINEFUNC_ENABLED` must be set to `True`. + +Each token starts with "$funcname(" where there must be no space +between the $funcname and (. It ends with a matched ending parentesis. +")". + +Inside the inlinefunc definition, one can use `\` to escape. This is +mainly needed for escaping commas in flowing text (which would +otherwise be interpreted as an argument separator), or to escape `}` +when not intended to close the function block. Enclosing text in +matched `\"\"\"` (triple quotes) or `'''` (triple single-quotes) will +also escape *everything* within without needing to escape individual +characters. + +The available inlinefuncs are defined as global-level functions in +modules defined by `settings.INLINEFUNC_MODULES`. They are identified +by their function name (and ignored if this name starts with `_`). They +should be on the following form: + +```python +def funcname (*args, **kwargs): + # ... +``` + +Here, the arguments given to `$funcname(arg1,arg2)` will appear as the +`*args` tuple. This will be populated by the arguments given to the +inlinefunc in-game - the only part that will be available from +in-game. `**kwargs` are not supported from in-game but are only used +internally by Evennia to make details about the caller available to +the function. The kwarg passed to all functions is `session`, the +Sessionobject for the object seeing the string. This may be `None` if +the string is sent to a non-puppetable object. The inlinefunc should +never raise an exception. + +There are two reserved function names: +- "nomatch": This is called if the user uses a functionname that is + not registered. The nomatch function will get the name of the + not-found function as its first argument followed by the normal + arguments to the given function. If not defined the default effect is + to print `` to replace the unknown function. +- "stackfull": This is called when the maximum nested function stack is reached. + When this happens, the original parsed string is returned and the result of + the `stackfull` inlinefunc is appended to the end. By default this is an + error message. + +Error handling: + Syntax errors, notably not completely closing all inlinefunc + blocks, will lead to the entire string remaining unparsed. + +""" + +import re +from django.conf import settings +from evennia.utils import utils + + +# example/testing inline functions + +def pad(*args, **kwargs): + """ + Inlinefunc. Pads text to given width. + + Args: + text (str, optional): Text to pad. + width (str, optional): Will be converted to integer. Width + of padding. + align (str, optional): Alignment of padding; one of 'c', 'l' or 'r'. + fillchar (str, optional): Character used for padding. Defaults to a space. + + Kwargs: + session (Session): Session performing the pad. + + Example: + `$pad(text, width, align, fillchar)` + + """ + text, width, align, fillchar = "", 78, 'c', ' ' + nargs = len(args) + if nargs > 0: + text = args[0] + if nargs > 1: + width = int(args[1]) if args[1].strip().isdigit() else 78 + if nargs > 2: + align = args[2] if args[2] in ('c', 'l', 'r') else 'c' + if nargs > 3: + fillchar = args[3] + return utils.pad(text, width=width, align=align, fillchar=fillchar) + + +def crop(*args, **kwargs): + """ + Inlinefunc. Crops ingoing text to given widths. + + Args: + text (str, optional): Text to crop. + width (str, optional): Will be converted to an integer. Width of + crop in characters. + suffix (str, optional): End string to mark the fact that a part + of the string was cropped. Defaults to `[...]`. + Kwargs: + session (Session): Session performing the crop. + + Example: + `$crop(text, width=78, suffix='[...]')` + + """ + text, width, suffix = "", 78, "[...]" + nargs = len(args) + if nargs > 0: + text = args[0] + if nargs > 1: + width = int(args[1]) if args[1].strip().isdigit() else 78 + if nargs > 2: + suffix = args[2] + return utils.crop(text, width=width, suffix=suffix) + + +def clr(*args, **kwargs): + """ + Inlinefunc. Colorizes nested text. + + Args: + startclr (str, optional): An ANSI color abbreviation without the + prefix `|`, such as `r` (red foreground) or `[r` (red background). + text (str, optional): Text + endclr (str, optional): The color to use at the end of the string. Defaults + to `|n` (reset-color). + Kwargs: + session (Session): Session object triggering inlinefunc. + + Example: + `$clr(startclr, text, endclr)` + + """ + text = "" + nargs = len(args) + if nargs > 0: + color = args[0].strip() + if nargs > 1: + text = args[1] + text = "|" + color + text + if nargs > 2: + text += "|" + args[2].strip() + else: + text += "|n" + return text + + +# we specify a default nomatch function to use if no matching func was +# found. This will be overloaded by any nomatch function defined in +# the imported modules. +_INLINE_FUNCS = {"nomatch": lambda *args, **kwargs: "", + "stackfull": lambda *args, **kwargs: "\n (not parsed: inlinefunc stack size exceeded.)"} + + +# load custom inline func modules. +for module in utils.make_iter(settings.INLINEFUNC_MODULES): + try: + _INLINE_FUNCS.update(utils.callables_from_module(module)) + except ImportError as err: + if module == "server.conf.inlinefuncs": + # a temporary warning since the default module changed name + raise ImportError("Error: %s\nPossible reason: mygame/server/conf/inlinefunc.py should " + "be renamed to mygame/server/conf/inlinefuncs.py (note the S at the end)." % err) + else: + raise + + +# remove the core function if we include examples in this module itself +#_INLINE_FUNCS.pop("inline_func_parse", None) + + +# The stack size is a security measure. Set to <=0 to disable. +try: + _STACK_MAXSIZE = settings.INLINEFUNC_STACK_MAXSIZE +except AttributeError: + _STACK_MAXSIZE = 20 + +# regex definitions + +_RE_STARTTOKEN = re.compile(r"(?.*?)(?.*?)(?(?(?(?\\'|\\"|\\\)|\\$\w+\()| # escaped tokens should re-appear in text + (?P[\w\s.-\/#!%\^&\*;:=\-_`~\|\(}{\[\]]+|\"{1}|\'{1}) # everything else should also be included""", + re.UNICODE + re.IGNORECASE + re.VERBOSE + re.DOTALL) + + +# Cache for function lookups. +_PARSING_CACHE = utils.LimitedSizeOrderedDict(size_limit=1000) + + +class ParseStack(list): + """ + Custom stack that always concatenates strings together when the + strings are added next to one another. Tuples are stored + separately and None is used to mark that a string should be broken + up into a new chunk. Below is the resulting stack after separately + appending 3 strings, None, 2 strings, a tuple and finally 2 + strings: + + [string + string + string, + None + string + string, + tuple, + string + string] + + """ + + def __init__(self, *args, **kwargs): + super(ParseStack, self).__init__(*args, **kwargs) + # always start stack with the empty string + list.append(self, "") + # indicates if the top of the stack is a string or not + self._string_last = True + + def __eq__(self, other): + return (super(ParseStack).__eq__(other) and + hasattr(other, "_string_last") and self._string_last == other._string_last) + + def __ne__(self, other): + return not self.__eq__(other) + + def append(self, item): + """ + The stack will merge strings, add other things as normal + """ + if isinstance(item, str): + if self._string_last: + self[-1] += item + else: + list.append(self, item) + self._string_last = True + else: + # everything else is added as normal + list.append(self, item) + self._string_last = False + + +class InlinefuncError(RuntimeError): + pass + + +def parse_inlinefunc(string, strip=False, **kwargs): + """ + Parse the incoming string. + + Args: + string (str): The incoming string to parse. + strip (bool, optional): Whether to strip function calls rather than + execute them. + Kwargs: + session (Session): This is sent to this function by Evennia when triggering + it. It is passed to the inlinefunc. + kwargs (any): All other kwargs are also passed on to the inlinefunc. + + + """ + global _PARSING_CACHE + if string in _PARSING_CACHE: + # stack is already cached + stack = _PARSING_CACHE[string] + elif not _RE_STARTTOKEN.search(string): + # if there are no unescaped start tokens at all, return immediately. + return string + else: + # no cached stack; build a new stack and continue + stack = ParseStack() + + # process string on stack + ncallable = 0 + for match in _RE_TOKEN.finditer(string): + gdict = match.groupdict() + if gdict["singlequote"]: + stack.append(gdict["singlequote"]) + elif gdict["doublequote"]: + stack.append(gdict["doublequote"]) + elif gdict["end"]: + if ncallable <= 0: + stack.append(")") + continue + args = [] + while stack: + operation = stack.pop() + if callable(operation): + if not strip: + stack.append((operation, [arg for arg in reversed(args)])) + ncallable -= 1 + break + else: + args.append(operation) + elif gdict["start"]: + funcname = _RE_STARTTOKEN.match(gdict["start"]).group(1) + try: + # try to fetch the matching inlinefunc from storage + stack.append(_INLINE_FUNCS[funcname]) + except KeyError: + stack.append(_INLINE_FUNCS["nomatch"]) + stack.append(funcname) + ncallable += 1 + elif gdict["escaped"]: + # escaped tokens + token = gdict["escaped"].lstrip("\\") + stack.append(token) + elif gdict["comma"]: + if ncallable > 0: + # commas outside strings and inside a callable are + # used to mark argument separation - we use None + # in the stack to indicate such a separation. + stack.append(None) + else: + # no callable active - just a string + stack.append(",") + else: + # the rest + stack.append(gdict["rest"]) + + if ncallable > 0: + # this means not all inlinefuncs were complete + return string + + if _STACK_MAXSIZE > 0 and _STACK_MAXSIZE < len(stack): + # if stack is larger than limit, throw away parsing + return string + gdict["stackfull"](*args, **kwargs) + else: + # cache the stack + _PARSING_CACHE[string] = stack + + # run the stack recursively + def _run_stack(item, depth=0): + retval = item + if isinstance(item, tuple): + if strip: + return "" + else: + func, arglist = item + args = [""] + for arg in arglist: + if arg is None: + # an argument-separating comma - start a new arg + args.append("") + else: + # all other args should merge into one string + args[-1] += _run_stack(arg, depth=depth + 1) + # execute the inlinefunc at this point or strip it. + kwargs["inlinefunc_stack_depth"] = depth + retval = "" if strip else func(*args, **kwargs) + return utils.to_str(retval, force_string=True) + + # execute the stack from the cache + return "".join(_run_stack(item) for item in _PARSING_CACHE[string]) + +# +# Nick templating +# + + +""" +This supports the use of replacement templates in nicks: + +This happens in two steps: + +1) The user supplies a template that is converted to a regex according + to the unix-like templating language. +2) This regex is tested against nicks depending on which nick replacement + strategy is considered (most commonly inputline). +3) If there is a template match and there are templating markers, + these are replaced with the arguments actually given. + +@desc $1 $2 $3 + +This will be converted to the following regex: + +\@desc (?P<1>\w+) (?P<2>\w+) $(?P<3>\w+) + +Supported template markers (through fnmatch) + * matches anything (non-greedy) -> .*? + ? matches any single character -> + [seq] matches any entry in sequence + [!seq] matches entries not in sequence +Custom arg markers + $N argument position (1-99) + +""" +import fnmatch +_RE_NICK_ARG = re.compile(r"\\(\$)([1-9][0-9]?)") +_RE_NICK_TEMPLATE_ARG = re.compile(r"(\$)([1-9][0-9]?)") +_RE_NICK_SPACE = re.compile(r"\\ ") + + +class NickTemplateInvalid(ValueError): + pass + + +def initialize_nick_templates(in_template, out_template): + """ + Initialize the nick templates for matching and remapping a string. + + Args: + in_template (str): The template to be used for nick recognition. + out_template (str): The template to be used to replace the string + matched by the in_template. + + Returns: + regex (regex): Regex to match against strings + template (str): Template with markers {arg1}, {arg2}, etc for + replacement using the standard .format method. + + Raises: + NickTemplateInvalid: If the in/out template does not have a matching + number of $args. + + """ + # create the regex for in_template + regex_string = fnmatch.translate(in_template) + n_inargs = len(_RE_NICK_ARG.findall(regex_string)) + regex_string = _RE_NICK_SPACE.sub("\s+", regex_string) + regex_string = _RE_NICK_ARG.sub(lambda m: "(?P.+?)" % m.group(2), regex_string) + + # create the out_template + template_string = _RE_NICK_TEMPLATE_ARG.sub(lambda m: "{arg%s}" % m.group(2), out_template) + + # validate the tempaltes - they should at least have the same number of args + n_outargs = len(_RE_NICK_TEMPLATE_ARG.findall(out_template)) + if n_inargs != n_outargs: + print(n_inargs, n_outargs) + raise NickTemplateInvalid + + return re.compile(regex_string), template_string + + +def parse_nick_template(string, template_regex, outtemplate): + """ + Parse a text using a template and map it to another template + + Args: + string (str): The input string to processj + template_regex (regex): A template regex created with + initialize_nick_template. + outtemplate (str): The template to which to map the matches + produced by the template_regex. This should have $1, $2, + etc to match the regex. + + """ + match = template_regex.match(string) + if match: + return outtemplate.format(**match.groupdict()) + return string diff --git a/evennia/utils/logger.py b/evennia/utils/logger.py index ce3bfe9a15..feb76e949c 100644 --- a/evennia/utils/logger.py +++ b/evennia/utils/logger.py @@ -13,7 +13,7 @@ log_typemsg(). This is for historical, back-compatible reasons. """ -from __future__ import division + import os import time diff --git a/evennia/utils/picklefield.py b/evennia/utils/picklefield.py index bd0a9b1643..61ed452c19 100644 --- a/evennia/utils/picklefield.py +++ b/evennia/utils/picklefield.py @@ -54,7 +54,7 @@ except ImportError: # python 3.x does not have cPickle module try: - from cPickle import loads, dumps # cpython 2.x + from pickle import loads, dumps # cpython 2.x except ImportError: from pickle import loads, dumps # cpython 3.x, other interpreters diff --git a/evennia/utils/spawner.py b/evennia/utils/spawner.py index 6df11985f1..1afff3413d 100644 --- a/evennia/utils/spawner.py +++ b/evennia/utils/spawner.py @@ -87,7 +87,7 @@ otherwise have the same spells as a *goblin wizard* who in turn shares many traits with a normal *goblin*. """ -from __future__ import print_function + import copy from django.conf import settings @@ -235,10 +235,10 @@ def spawn(*prototypes, **kwargs): protmodules = make_iter(settings.PROTOTYPE_MODULES) for prototype_module in protmodules: protparents.update(dict((key, val) for key, val in - all_from_module(prototype_module).items() if isinstance(val, dict))) + list(all_from_module(prototype_module).items()) if isinstance(val, dict))) # overload module's protparents with specifically given protparents protparents.update(kwargs.get("prototype_parents", {})) - for key, prototype in protparents.items(): + for key, prototype in list(protparents.items()): _validate_prototype(key, prototype, protparents, []) if "return_prototypes" in kwargs: @@ -288,11 +288,11 @@ def spawn(*prototypes, **kwargs): # extract ndb assignments nattributes = dict((key.split("_", 1)[1], value() if callable(value) else value) - for key, value in prot.items() if key.startswith("ndb_")) + for key, value in list(prot.items()) if key.startswith("ndb_")) # the rest are attributes simple_attributes = [(key, value()) if callable(value) else (key, value) - for key, value in prot.items() if not key.startswith("ndb_")] + for key, value in list(prot.items()) if not key.startswith("ndb_")] attributes = attributes + simple_attributes attributes = [tup for tup in attributes if not tup[0] in _CREATE_OBJECT_KWARGS] diff --git a/evennia/utils/tests/test_evform.py b/evennia/utils/tests/test_evform.py index e6a0d26049..a02867b221 100644 --- a/evennia/utils/tests/test_evform.py +++ b/evennia/utils/tests/test_evform.py @@ -10,46 +10,46 @@ class TestEvForm(TestCase): def test_form(self): self.maxDiff = None self.assertEqual(evform._test(), - u'.------------------------------------------------.\n' - u'| |\n' - u'| Name: \x1b[0m\x1b[1m\x1b[32mTom\x1b[1m\x1b[32m \x1b' - u'[1m\x1b[32mthe\x1b[1m\x1b[32m \x1b[0m \x1b[0m ' - u'Account: \x1b[0m\x1b[1m\x1b[33mGriatch ' - u'\x1b[0m\x1b[0m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[0m\x1b[0m ' - u'|\n' - u'| \x1b[0m\x1b[1m\x1b[32mBouncer\x1b[0m \x1b[0m |\n' - u'| |\n' - u' >----------------------------------------------<\n' - u'| |\n' - u'| Desc: \x1b[0mA sturdy \x1b[0m \x1b[0m' - u' STR: \x1b[0m12 \x1b[0m\x1b[0m\x1b[0m\x1b[0m' - u' DEX: \x1b[0m10 \x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' - u'| \x1b[0mfellow\x1b[0m \x1b[0m' - u' INT: \x1b[0m5 \x1b[0m\x1b[0m\x1b[0m\x1b[0m' - u' STA: \x1b[0m18 \x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' - u'| \x1b[0m \x1b[0m' - u' LUC: \x1b[0m10 \x1b[0m\x1b[0m\x1b[0m' - u' MAG: \x1b[0m3 \x1b[0m\x1b[0m\x1b[0m |\n' - u'| |\n' - u' >----------.-----------------------------------<\n' - u'| | |\n' - u'| \x1b[0mHP\x1b[0m|\x1b[0mMV \x1b[0m|\x1b[0mMP\x1b[0m ' - u'| \x1b[0mSkill \x1b[0m|\x1b[0mValue \x1b[0m' - u'|\x1b[0mExp \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' - u'| ~~+~~~+~~ | ~~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~~ |\n' - u'| \x1b[0m**\x1b[0m|\x1b[0m***\x1b[0m\x1b[0m|\x1b[0m**\x1b[0m\x1b[0m ' - u'| \x1b[0mShooting \x1b[0m|\x1b[0m12 \x1b[0m' - u'|\x1b[0m550/1200 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' - u'| \x1b[0m \x1b[0m|\x1b[0m**\x1b[0m \x1b[0m|\x1b[0m*\x1b[0m \x1b[0m ' - u'| \x1b[0mHerbalism \x1b[0m|\x1b[0m14 \x1b[0m' - u'|\x1b[0m990/1400 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' - u'| \x1b[0m \x1b[0m|\x1b[0m \x1b[0m|\x1b[0m \x1b[0m ' - u'| \x1b[0mSmithing \x1b[0m|\x1b[0m9 \x1b[0m' - u'|\x1b[0m205/900 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' - u'| | |\n' - u' -----------`-------------------------------------\n') + '.------------------------------------------------.\n' + '| |\n' + '| Name: \x1b[0m\x1b[1m\x1b[32mTom\x1b[1m\x1b[32m \x1b' + '[1m\x1b[32mthe\x1b[1m\x1b[32m \x1b[0m \x1b[0m ' + 'Account: \x1b[0m\x1b[1m\x1b[33mGriatch ' + '\x1b[0m\x1b[0m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[0m\x1b[0m ' + '|\n' + '| \x1b[0m\x1b[1m\x1b[32mBouncer\x1b[0m \x1b[0m |\n' + '| |\n' + ' >----------------------------------------------<\n' + '| |\n' + '| Desc: \x1b[0mA sturdy \x1b[0m \x1b[0m' + ' STR: \x1b[0m12 \x1b[0m\x1b[0m\x1b[0m\x1b[0m' + ' DEX: \x1b[0m10 \x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' + '| \x1b[0mfellow\x1b[0m \x1b[0m' + ' INT: \x1b[0m5 \x1b[0m\x1b[0m\x1b[0m\x1b[0m' + ' STA: \x1b[0m18 \x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' + '| \x1b[0m \x1b[0m' + ' LUC: \x1b[0m10 \x1b[0m\x1b[0m\x1b[0m' + ' MAG: \x1b[0m3 \x1b[0m\x1b[0m\x1b[0m |\n' + '| |\n' + ' >----------.-----------------------------------<\n' + '| | |\n' + '| \x1b[0mHP\x1b[0m|\x1b[0mMV \x1b[0m|\x1b[0mMP\x1b[0m ' + '| \x1b[0mSkill \x1b[0m|\x1b[0mValue \x1b[0m' + '|\x1b[0mExp \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' + '| ~~+~~~+~~ | ~~~~~~~~~~~+~~~~~~~~~~+~~~~~~~~~~~ |\n' + '| \x1b[0m**\x1b[0m|\x1b[0m***\x1b[0m\x1b[0m|\x1b[0m**\x1b[0m\x1b[0m ' + '| \x1b[0mShooting \x1b[0m|\x1b[0m12 \x1b[0m' + '|\x1b[0m550/1200 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' + '| \x1b[0m \x1b[0m|\x1b[0m**\x1b[0m \x1b[0m|\x1b[0m*\x1b[0m \x1b[0m ' + '| \x1b[0mHerbalism \x1b[0m|\x1b[0m14 \x1b[0m' + '|\x1b[0m990/1400 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' + '| \x1b[0m \x1b[0m|\x1b[0m \x1b[0m|\x1b[0m \x1b[0m ' + '| \x1b[0mSmithing \x1b[0m|\x1b[0m9 \x1b[0m' + '|\x1b[0m205/900 \x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m\x1b[0m |\n' + '| | |\n' + ' -----------`-------------------------------------\n') def test_ansi_escape(self): # note that in a msg() call, the result would be the correct |-----, # in a print, ansi only gets called once, so ||----- is the result - self.assertEqual(unicode(evform.EvForm(form={"FORM": "\n||-----"})), "||-----") + self.assertEqual(str(evform.EvForm(form={"FORM": "\n||-----"})), "||-----") diff --git a/evennia/utils/tests/test_evmenu.py b/evennia/utils/tests/test_evmenu.py index 04310c90ed..278bbeec1c 100644 --- a/evennia/utils/tests/test_evmenu.py +++ b/evennia/utils/tests/test_evmenu.py @@ -58,7 +58,7 @@ class TestEvMenu(TestCase): def _debug_output(self, indent, msg): if self.debug_output: - print(" " * indent + msg) + print((" " * indent + msg)) def _test_menutree(self, menu): """ diff --git a/evennia/utils/tests/test_tagparsing.py b/evennia/utils/tests/test_tagparsing.py index a2f07af204..520347a919 100644 --- a/evennia/utils/tests/test_tagparsing.py +++ b/evennia/utils/tests/test_tagparsing.py @@ -15,8 +15,8 @@ class ANSIStringTestCase(TestCase): Verifies the raw and clean strings of an ANSIString match expected output. """ - self.assertEqual(unicode(ansi.clean()), clean) - self.assertEqual(unicode(ansi.raw()), raw) + self.assertEqual(str(ansi.clean()), clean) + self.assertEqual(str(ansi.raw()), raw) def table_check(self, ansi, char, code): """ @@ -29,8 +29,8 @@ class ANSIStringTestCase(TestCase): """ Make sure the ANSIString is always constructed correctly. """ - clean = u'This isA|r testTest' - encoded = u'\x1b[1m\x1b[32mThis is\x1b[1m\x1b[31mA|r test\x1b[0mTest\x1b[0m' + clean = 'This isA|r testTest' + encoded = '\x1b[1m\x1b[32mThis is\x1b[1m\x1b[31mA|r test\x1b[0mTest\x1b[0m' target = ANSIString(r'|gThis is|rA||r test|nTest|n') char_table = [9, 10, 11, 12, 13, 14, 15, 25, 26, 27, 28, 29, 30, 31, 32, 37, 38, 39, 40] code_table = [0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 17, 18, 19, 20, 21, 22, 23, 24, 33, 34, 35, 36, 41, 42, 43, 44] @@ -41,9 +41,9 @@ class ANSIStringTestCase(TestCase): self.checker(ANSIString(encoded, decoded=True), encoded, clean) self.table_check(ANSIString(encoded, decoded=True), char_table, code_table) - self.checker(ANSIString('Test'), u'Test', u'Test') + self.checker(ANSIString('Test'), 'Test', 'Test') self.table_check(ANSIString('Test'), [0, 1, 2, 3], []) - self.checker(ANSIString(''), u'', u'') + self.checker(ANSIString(''), '', '') def test_slice(self): """ @@ -52,24 +52,24 @@ class ANSIStringTestCase(TestCase): """ target = ANSIString(r'|gTest|rTest|n') result = target[:3] - self.checker(result, u'\x1b[1m\x1b[32mTes', u'Tes') + self.checker(result, '\x1b[1m\x1b[32mTes', 'Tes') result = target[:4] - self.checker(result, u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m', u'Test') + self.checker(result, '\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m', 'Test') result = target[:] self.checker( result, - u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTest\x1b[0m', - u'TestTest') + '\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTest\x1b[0m', + 'TestTest') result = target[:-1] self.checker( result, - u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTes', - u'TestTes') + '\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTes', + 'TestTes') result = target[0:0] self.checker( result, - u'', - u'') + '', + '') def test_split(self): """ @@ -77,9 +77,9 @@ class ANSIStringTestCase(TestCase): codes end up where they should. """ target = ANSIString("|gThis is |nA split string|g") - first = (u'\x1b[1m\x1b[32mThis is \x1b[0m', u'This is ') - second = (u'\x1b[1m\x1b[32m\x1b[0m split string\x1b[1m\x1b[32m', - u' split string') + first = ('\x1b[1m\x1b[32mThis is \x1b[0m', 'This is ') + second = ('\x1b[1m\x1b[32m\x1b[0m split string\x1b[1m\x1b[32m', + ' split string') re_split = re.split('A', target) normal_split = target.split('A') self.assertEqual(re_split, normal_split) @@ -97,11 +97,11 @@ class ANSIStringTestCase(TestCase): l = [ANSIString("|gTest|r") for _ in range(0, 3)] # Force the generator to be evaluated. result = "".join(l) - self.assertEqual(unicode(result), u'TestTestTest') + self.assertEqual(str(result), 'TestTestTest') result = ANSIString("").join(l) - self.checker(result, u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m\x1b[1m\x1b' - u'[32mTest\x1b[1m\x1b[31m\x1b[1m\x1b[32mTest' - u'\x1b[1m\x1b[31m', u'TestTestTest') + self.checker(result, '\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m\x1b[1m\x1b' + '[32mTest\x1b[1m\x1b[31m\x1b[1m\x1b[32mTest' + '\x1b[1m\x1b[31m', 'TestTestTest') def test_len(self): """ @@ -116,8 +116,8 @@ class ANSIStringTestCase(TestCase): _transform functions. """ target = ANSIString('|gtest|n') - result = u'\x1b[1m\x1b[32mTest\x1b[0m' - self.checker(target.capitalize(), result, u'Test') + result = '\x1b[1m\x1b[32mTest\x1b[0m' + self.checker(target.capitalize(), result, 'Test') def test_mxp_agnostic(self): """ @@ -131,7 +131,7 @@ class ANSIStringTestCase(TestCase): self.assertEqual(len(ANSIString(mxp1)), len(ANSIString(mxp1).split("\n")[0])) self.assertEqual(len(ANSIString(mxp2)), len(ANSIString(mxp2).split("\n")[0])) self.assertEqual(mxp1, ANSIString(mxp1)) - self.assertEqual(mxp2, unicode(ANSIString(mxp2))) + self.assertEqual(mxp2, str(ANSIString(mxp2))) def test_add(self): """ @@ -140,8 +140,8 @@ class ANSIStringTestCase(TestCase): a = ANSIString("|gTest") b = ANSIString("|cString|n") c = a + b - result = u'\x1b[1m\x1b[32mTest\x1b[1m\x1b[36mString\x1b[0m' - self.checker(c, result, u'TestString') + result = '\x1b[1m\x1b[32mTest\x1b[1m\x1b[36mString\x1b[0m' + self.checker(c, result, 'TestString') char_table = [9, 10, 11, 12, 22, 23, 24, 25, 26, 27] code_table = [0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 29, 30, 31] self.table_check(c, char_table, code_table) diff --git a/evennia/utils/text2html.py b/evennia/utils/text2html.py index 94c5587533..64a25f5742 100644 --- a/evennia/utils/text2html.py +++ b/evennia/utils/text2html.py @@ -8,7 +8,7 @@ snippet #577349 on http://code.activestate.com. (extensively modified by Griatch 2010) """ -from __future__ import absolute_import + from builtins import object import re @@ -52,7 +52,7 @@ class TextToHTMLparser(object): ('color-013', hilite + ANSI_MAGENTA), ('color-014', hilite + ANSI_CYAN), ('color-015', hilite + ANSI_WHITE) # pure white - ] + [("color-%03i" % (i + 16), XTERM256_FG % ("%i" % (i + 16))) for i in xrange(240)] + ] + [("color-%03i" % (i + 16), XTERM256_FG % ("%i" % (i + 16))) for i in range(240)] colorback = [ ('bgcolor-000', ANSI_BACK_BLACK), # pure black diff --git a/evennia/utils/txws.py b/evennia/utils/txws.py index 66be721aec..ef9a4bda8f 100644 --- a/evennia/utils/txws.py +++ b/evennia/utils/txws.py @@ -246,7 +246,7 @@ def make_hybi07_frame_dwim(buf): # TODO: eliminate magic numbers. if isinstance(buf, str): return make_hybi07_frame(buf, opcode=0x2) - elif isinstance(buf, unicode): + elif isinstance(buf, str): return make_hybi07_frame(buf.encode("utf-8"), opcode=0x1) else: raise TypeError("In binary support mode, frame data must be either str or unicode") @@ -510,7 +510,7 @@ class WebSocketProtocol(ProtocolWrapper): elif "Sec-WebSocket-Protocol" in self.headers: protocols = self.headers["Sec-WebSocket-Protocol"] - if isinstance(protocols, basestring): + if isinstance(protocols, str): protocols = [p.strip() for p in protocols.split(',')] for protocol in protocols: diff --git a/evennia/utils/utils.py b/evennia/utils/utils.py index 667f6a209b..fbd9f88fe7 100644 --- a/evennia/utils/utils.py +++ b/evennia/utils/utils.py @@ -6,7 +6,7 @@ They provide some useful string and conversion methods that might be of use when designing your own game. """ -from __future__ import division, print_function + from builtins import object, range from future.utils import viewkeys, raise_ @@ -33,7 +33,7 @@ _EVENNIA_DIR = settings.EVENNIA_DIR _GAME_DIR = settings.GAME_DIR try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle @@ -595,12 +595,12 @@ def dbref(inp, reqhash=True): """ if reqhash: - num = (int(inp.lstrip('#')) if (isinstance(inp, basestring) and + num = (int(inp.lstrip('#')) if (isinstance(inp, str) and inp.startswith("#") and inp.lstrip('#').isdigit()) else None) return num if num > 0 else None - elif isinstance(inp, basestring): + elif isinstance(inp, str): inp = inp.lstrip('#') return int(inp) if inp.isdigit() and int(inp) > 0 else None else: @@ -723,7 +723,7 @@ def to_unicode(obj, encoding='utf-8', force_string=False): """ - if force_string and not isinstance(obj, basestring): + if force_string and not isinstance(obj, str): # some sort of other object. Try to # convert it to a string representation. if hasattr(obj, '__str__'): @@ -734,14 +734,14 @@ def to_unicode(obj, encoding='utf-8', force_string=False): # last resort obj = str(obj) - if isinstance(obj, basestring) and not isinstance(obj, unicode): + if isinstance(obj, str) and not isinstance(obj, str): try: - obj = unicode(obj, encoding) + obj = str(obj, encoding) return obj except UnicodeDecodeError: for alt_encoding in ENCODINGS: try: - obj = unicode(obj, alt_encoding) + obj = str(obj, alt_encoding) return obj except UnicodeDecodeError: # if we still have an error, give up @@ -768,15 +768,15 @@ def to_str(obj, encoding='utf-8', force_string=False): conversion of objects to strings. """ - if force_string and not isinstance(obj, basestring): + if force_string and not isinstance(obj, str): # some sort of other object. Try to # convert it to a string representation. try: obj = str(obj) except Exception: - obj = unicode(obj) + obj = str(obj) - if isinstance(obj, basestring) and isinstance(obj, unicode): + if isinstance(obj, str) and isinstance(obj, str): try: obj = obj.encode(encoding) return obj @@ -872,7 +872,7 @@ def inherits_from(obj, parent): else: obj_paths = ["%s.%s" % (mod.__module__, mod.__name__) for mod in obj.__class__.mro()] - if isinstance(parent, basestring): + if isinstance(parent, str): # a given string path, for direct matching parent_path = parent elif callable(parent): @@ -1266,7 +1266,7 @@ def variable_from_module(module, variable=None, default=None): result.append(mod.__dict__.get(var, default)) else: # get all - result = [val for key, val in mod.__dict__.items() + result = [val for key, val in list(mod.__dict__.items()) if not (key.startswith("_") or ismodule(val))] if len(result) == 1: @@ -1298,7 +1298,7 @@ def string_from_module(module, variable=None, default=None): if variable: return val else: - result = [v for v in make_iter(val) if isinstance(v, basestring)] + result = [v for v in make_iter(val) if isinstance(v, str)] return result if result else default return default @@ -1635,7 +1635,7 @@ def deepsize(obj, max_depth=4): _recurse(ref, dct, depth + 1) sizedict = {} _recurse(obj, sizedict, 0) - size = getsizeof(obj) + sum([p[1] for p in sizedict.values()]) + size = getsizeof(obj) + sum([p[1] for p in list(sizedict.values())]) return size @@ -1682,7 +1682,7 @@ class lazy_property(object): _STRIP_ANSI = None -_RE_CONTROL_CHAR = re.compile('[%s]' % re.escape(''.join([unichr(c) for c in range(0, 32)]))) # + range(127,160)]))) +_RE_CONTROL_CHAR = re.compile('[%s]' % re.escape(''.join([chr(c) for c in range(0, 32)]))) # + range(127,160)]))) def strip_control_sequences(string): @@ -1741,7 +1741,7 @@ def m_len(target): """ # Would create circular import if in module root. from evennia.utils.ansi import ANSI_PARSER - if inherits_from(target, basestring) and "|lt" in target: + if inherits_from(target, str) and "|lt" in target: return len(ANSI_PARSER.strip_mxp(target)) return len(target) diff --git a/evennia/web/webclient/views.py b/evennia/web/webclient/views.py index 94ecffb0e2..1b794b6198 100644 --- a/evennia/web/webclient/views.py +++ b/evennia/web/webclient/views.py @@ -4,7 +4,7 @@ This contains a simple view for rendering the webclient page and serve it eventual static content. """ -from __future__ import print_function + from django.shortcuts import render from django.contrib.auth import login, authenticate