summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Grapentin <andreas@grapentin.org>2019-02-09 15:17:27 +0100
committerAndreas Grapentin <andreas@grapentin.org>2019-02-09 15:17:27 +0100
commit8f3733a26fae6667355988269731d62dfba294e1 (patch)
tree6f927cedf37fdb087549d1fdb876227a6c19d71b
parentb3cc9ec36120a1438f496ab6aa247490f2411a8b (diff)
downloadabslibre-8f3733a26fae6667355988269731d62dfba294e1.tar.gz
abslibre-8f3733a26fae6667355988269731d62dfba294e1.tar.bz2
abslibre-8f3733a26fae6667355988269731d62dfba294e1.zip
pcr/renpy-python3: unmaintained, unbuilt. removed
-rw-r--r--pcr/renpy-python3/PKGBUILD82
-rw-r--r--pcr/renpy-python3/python3.patch5504
-rw-r--r--pcr/renpy-python3/renpy3
-rw-r--r--pcr/renpy-python3/renpy-ffmpeg30.patch94
-rw-r--r--pcr/renpy-python3/renpy.desktop9
-rw-r--r--pcr/renpy-python3/renpy.pngbin18422 -> 0 bytes
6 files changed, 0 insertions, 5692 deletions
diff --git a/pcr/renpy-python3/PKGBUILD b/pcr/renpy-python3/PKGBUILD
deleted file mode 100644
index c5fd8922e..000000000
--- a/pcr/renpy-python3/PKGBUILD
+++ /dev/null
@@ -1,82 +0,0 @@
-# $Id: PKGBUILD 161858 2016-02-16 17:48:18Z alucryd $
-# Maintainer (Arch): Maxime Gauduin <alucryd@archlinux.org>
-# Contributor (Arch): Cravix <dr.neemous@gmail.com>
-# Contributor (Arch): AlexanderR <rvacheva@nxt.ru>
-# Contributor (Arch): zhn <zhangn1985@gmail.com>
-# Maintainer: Márcio Silva <coadde@hyperbola.info>
-
-pkgbase=renpy
-pkgname=('renpy-python3' 'renpy-python3-demos')
-pkgver=6.99.8
-pkgrel=3
-pkgdesc="The Ren'Py Visual Novel Engine, with Python 3 support"
-arch=('i686' 'x86_64' 'armv7h')
-url='http://www.renpy.org'
-license=('MIT')
-depends=('ffmpeg' 'glew' 'python-pygame-sdl2')
-makedepends=('cython')
-source=("http://www.renpy.org/dl/${pkgver}/renpy-${pkgver}-source.tar.bz2"
- 'renpy'
- 'renpy.desktop'
- 'renpy.png'
- 'renpy-ffmpeg30.patch'
- 'python3.patch')
-sha256sums=('0eb0c763bf7e977db06039c69751f1ed5e69c4b738f7f6d975e99e8729eff58e'
- '993046143826c74f15ad3990d662878952594545eb315e3f1857ffe32e62399b'
- 'fccde3461617a098a78d938d9db782d403eda410a84ab52825a597498ab95834'
- '611edc07a40ccb8e04e8858847fc1d2a066d29c2ed54e5b357880a0605818dc5'
- 'c2d27a3f6b74f874a790ce6c12e9d4b718784478d8a8aa23c879d186f60a25ab'
- 'e2250ce41ea5f42d882de0fbcc0d3057ce8da8e755f150294e447e05340edaa9')
-
-prepare() {
- cd renpy-${pkgver}-source
-
- patch -Np1 -i ../renpy-ffmpeg30.patch
- patch -Np1 -i ../python3.patch # use "2to3" to convert all .py file to Python 3
-}
-
-build() {
- cd renpy-${pkgver}-source
-
- export RENPY_CYTHON='cython'
-
- python module/setup.py build
-}
-
-package_renpy-python3() {
- optdepends=('renpy-demos: Tutorial and The Question demos'
- 'tk: Set projects directory')
- conflicts=('renpy')
-
- cd renpy-${pkgver}-source
-
- python module/setup.py install --root="${pkgdir}" --prefix='/usr' --optimize='1'
-
- install -dm 755 "${pkgdir}"/usr/{bin,share/{applications,pixmaps,renpy,doc}}
-
- cp -dr --no-preserve='ownership' doc launcher renpy renpy.py templates "${pkgdir}"/usr/share/renpy/
- ln -s /usr/share/renpy/doc "${pkgdir}"/usr/share/doc/renpy
-
- install -m 755 ../renpy "${pkgdir}"/usr/bin/
- install -m 644 ../renpy.desktop "${pkgdir}"/usr/share/applications/
- install -m 644 ../renpy.png "${pkgdir}"/usr/share/pixmaps/
-
- install -dm 755 "${pkgdir}"/usr/share/licenses/renpy
- install -m 644 LICENSE.txt "${pkgdir}"/usr/share/licenses/renpy/
-}
-
-package_renpy-python3-demos() {
- depends=('renpy-python3')
- conflicts=('renpy-python3-demos')
-
- cd renpy-${pkgver}-source
-
- install -dm 755 "${pkgdir}"/usr/share/renpy
-
- cp -dr --no-preserve='ownership' the_question tutorial "${pkgdir}"/usr/share/renpy/
-
- install -dm 755 "${pkgdir}"/usr/share/licenses
- ln -s renpy "${pkgdir}"/usr/share/licenses/renpy-demos
-}
-
-# vim: ts=2 sw=2 et:
diff --git a/pcr/renpy-python3/python3.patch b/pcr/renpy-python3/python3.patch
deleted file mode 100644
index aa25f7772..000000000
--- a/pcr/renpy-python3/python3.patch
+++ /dev/null
@@ -1,5504 +0,0 @@
-diff --git a/launcher/game/EasyDialogsWin.py b/launcher/game/EasyDialogsWin.py
-index aea17ed..f63c883 100644
---- a/launcher/game/EasyDialogsWin.py
-+++ b/launcher/game/EasyDialogsWin.py
-@@ -19,8 +19,6 @@ This module uses DLOG resources 260 and on.
- Based upon STDWIN dialogs with the same names and functions.
- """
-
--from __future__ import division
--
- import os
-
- import ctypes
-@@ -606,7 +604,7 @@ def AskFileForOpen(
- ofn.lpstrTitle = windowTitle
- ofn.lpstrInitialDir = defaultLocation
-
-- if typeList and filter(None, typeList):
-+ if typeList and [_f for _f in typeList if _f]:
- lpstrFilter = ''
- for typeSpec in typeList:
- try:
-@@ -672,10 +670,10 @@ def AskFileForOpen(
- ofn.lpfnHook = LPOFNHOOKPROC(hookProc)
-
- if fn(ctypes.byref(ofn)):
-- filenames = filter(None, filename.split('\0'))
-+ filenames = [_f for _f in filename.split('\0') if _f]
- if len(filenames) > 1:
- dir, filenames = filenames[0], filenames[1:]
-- return map(lambda fn: os.path.join(dir, fn), filenames)
-+ return [os.path.join(dir, fn) for fn in filenames]
- elif multiple:
- return filenames
- else:
-@@ -771,7 +769,7 @@ def AskFolder(
- def BrowseCallback(hwnd, uMsg, lParam, lpData):
- if uMsg == BFFM_INITIALIZED:
- if actionButtonLabel:
-- label = unicode(actionButtonLabel, errors='replace')
-+ label = str(actionButtonLabel, errors='replace')
- user32.SendMessageW(hwnd, BFFM_SETOKTEXT, 0, label)
- if cancelButtonLabel:
- cancelButton = user32.GetDlgItem(hwnd, IDCANCEL)
-@@ -995,14 +993,14 @@ def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfo
- if item[0] == '"':
- while item[-1] != '"':
- if not tmplist:
-- raise RuntimeError, "Unterminated quoted argument"
-+ raise RuntimeError("Unterminated quoted argument")
- item = item + ' ' + tmplist[0]
- del tmplist[0]
- item = item[1:-1]
- if item[0] == "'":
- while item[-1] != "'":
- if not tmplist:
-- raise RuntimeError, "Unterminated quoted argument"
-+ raise RuntimeError("Unterminated quoted argument")
- item = item + ' ' + tmplist[0]
- del tmplist[0]
- item = item[1:-1]
-@@ -1029,7 +1027,7 @@ def test():
- argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
- Message("Command line: %s"%' '.join(argv))
- for i in range(len(argv)):
-- print 'arg[%d] = %r' % (i, argv[i])
-+ print('arg[%d] = %r' % (i, argv[i]))
- ok = AskYesNoCancel("Do you want to proceed?")
- ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
- if ok > 0:
-@@ -1053,11 +1051,11 @@ def test():
- try:
- if hasattr(MacOS, 'SchedParams'):
- appsw = MacOS.SchedParams(1, 0)
-- for i in xrange(20):
-+ for i in range(20):
- bar.inc()
- time.sleep(0.05)
- bar.set(0,100)
-- for i in xrange(100):
-+ for i in range(100):
- bar.set(i)
- time.sleep(0.05)
- if i % 10 == 0:
-diff --git a/launcher/game/change_icon.py b/launcher/game/change_icon.py
-index 900cff6..23caaab 100644
---- a/launcher/game/change_icon.py
-+++ b/launcher/game/change_icon.py
-@@ -62,9 +62,9 @@ class BinFile(object):
- def name(self):
- c = self.u16()
-
-- rv = u""
-+ rv = ""
- for _i in range(c):
-- rv += unichr(self.u16())
-+ rv += chr(self.u16())
-
- return rv
-
-@@ -143,11 +143,11 @@ def parse_directory(bf, offset):
- def show_resources(d, prefix):
-
- if not isinstance(d, dict):
-- print prefix, "Codepage", d[0], "length", len(d[1])
-+ print(prefix, "Codepage", d[0], "length", len(d[1]))
- return
-
- for k in d:
-- print prefix, k
-+ print(prefix, k)
- show_resources(d[k], prefix + " ")
-
- ##############################################################################
-@@ -201,8 +201,8 @@ class Packer(object):
- return rv
-
- def pack_dict(self, d, offset):
-- name_entries = sorted((a, b) for a, b in d.iteritems() if isinstance(a, unicode))
-- id_entries = sorted((a, b) for a, b in d.iteritems() if isinstance(a, int))
-+ name_entries = sorted((a, b) for a, b in d.items() if isinstance(a, str))
-+ id_entries = sorted((a, b) for a, b in d.items() if isinstance(a, int))
-
- rv = struct.pack("<IIHHHH", 0, 0, 4, 0, len(name_entries), len(id_entries))
-
-@@ -211,7 +211,7 @@ class Packer(object):
- rest = ""
-
- for (name, value) in name_entries + id_entries:
-- if isinstance(name, unicode):
-+ if isinstance(name, str):
- name = 0x80000000 | self.pack_name(name)
-
- if isinstance(value, dict):
-@@ -230,7 +230,7 @@ class Packer(object):
- # This loads in an icon file, and returns a dictionary that is suitable for
- # use in the resources of an exe file.
- def load_icon(fn):
-- f = BinFile(file(fn, "rb").read())
-+ f = BinFile(open(fn, "rb").read())
-
- f.seek(0)
- f.u16()
-@@ -291,7 +291,7 @@ def change_icons(oldexe, icofn):
- physize = rsrc_section.SizeOfRawData
- virsize = rsrc_section.Misc_VirtualSize
-
-- f = file(oldexe, "rb")
-+ f = open(oldexe, "rb")
- f.seek(base)
- data = f.read(physize)
- f.close()
-@@ -343,7 +343,7 @@ def change_icons(oldexe, icofn):
-
- if __name__ == "__main__":
-
-- f = file(sys.argv[3], "wb")
-+ f = open(sys.argv[3], "wb")
- f.write(change_icons(sys.argv[1], sys.argv[2]))
- f.close()
-
-diff --git a/launcher/game/pefile.py b/launcher/game/pefile.py
-index 9fd10a5..5e20cd3 100644
---- a/launcher/game/pefile.py
-+++ b/launcher/game/pefile.py
-@@ -83,8 +83,8 @@ IMAGE_OS2_SIGNATURE_LE = 0x454C
- IMAGE_VXD_SIGNATURE = 0x454C
- IMAGE_NT_SIGNATURE = 0x00004550
- IMAGE_NUMBEROF_DIRECTORY_ENTRIES= 16
--IMAGE_ORDINAL_FLAG = 0x80000000L
--IMAGE_ORDINAL_FLAG64 = 0x8000000000000000L
-+IMAGE_ORDINAL_FLAG = 0x80000000
-+IMAGE_ORDINAL_FLAG64 = 0x8000000000000000
- OPTIONAL_HEADER_MAGIC_PE = 0x10b
- OPTIONAL_HEADER_MAGIC_PE_PLUS = 0x20b
-
-@@ -167,7 +167,7 @@ section_characteristics = [
- ('IMAGE_SCN_MEM_SHARED', 0x10000000),
- ('IMAGE_SCN_MEM_EXECUTE', 0x20000000),
- ('IMAGE_SCN_MEM_READ', 0x40000000),
-- ('IMAGE_SCN_MEM_WRITE', 0x80000000L) ]
-+ ('IMAGE_SCN_MEM_WRITE', 0x80000000) ]
-
- SECTION_CHARACTERISTICS = dict([(e[1], e[0]) for e in
- section_characteristics]+section_characteristics)
-@@ -574,7 +574,7 @@ class UnicodeStringWrapperPostProcessor:
-
- try:
- data = self.pe.get_data(self.rva_ptr, 2)
-- except PEFormatError, e:
-+ except PEFormatError as e:
- return False
-
- if len(data)<2:
-@@ -646,7 +646,7 @@ class Dump:
- The text can be indented with the optional argument 'indent'.
- """
-
-- if isinstance(txt, unicode):
-+ if isinstance(txt, str):
- try:
- txt = str(txt)
- except UnicodeEncodeError:
-@@ -768,7 +768,7 @@ class Structure:
- self.__all_zeroes__ = True
-
- self.__unpacked_data_elms__ = struct.unpack(self.__format__, data)
-- for i in xrange(len(self.__unpacked_data_elms__)):
-+ for i in range(len(self.__unpacked_data_elms__)):
- for key in self.__keys__[i]:
- #self.values[key] = self.__unpacked_data_elms__[i]
- setattr(self, key, self.__unpacked_data_elms__[i])
-@@ -778,7 +778,7 @@ class Structure:
-
- new_values = []
-
-- for i in xrange(len(self.__unpacked_data_elms__)):
-+ for i in range(len(self.__unpacked_data_elms__)):
-
- for key in self.__keys__[i]:
- new_val = getattr(self, key)
-@@ -814,15 +814,15 @@ class Structure:
- for key in keys:
-
- val = getattr(self, key)
-- if isinstance(val, int) or isinstance(val, long):
-+ if isinstance(val, int):
- val_str = '0x%-8X' % (val)
- if key == 'TimeDateStamp' or key == 'dwTimeStamp':
- try:
- val_str += ' [%s UTC]' % time.asctime(time.gmtime(val))
-- except exceptions.ValueError, e:
-+ except exceptions.ValueError as e:
- val_str += ' [INVALID TIME]'
- else:
-- val_str = ''.join(filter(lambda c:c != '\0', str(val)))
-+ val_str = ''.join([c for c in str(val) if c != '\0'])
-
- dump.append('%-30s %s' % (key+':', val_str))
-
-@@ -957,7 +957,7 @@ class DataContainer:
- """Generic data container."""
-
- def __init__(self, **args):
-- for key, value in args.items():
-+ for key, value in list(args.items()):
- setattr(self, key, value)
-
-
-@@ -1371,7 +1371,7 @@ class PE:
-
- try:
- structure.__unpack__(data)
-- except PEFormatError, err:
-+ except PEFormatError as err:
- self.__warnings.append(
- 'Corrupt header "%s" at file offset %d. Exception: %s' % (
- format[0], file_offset, str(err)) )
-@@ -1390,7 +1390,7 @@ class PE:
- """
-
- if fname:
-- fd = file(fname, 'rb')
-+ fd = open(fname, 'rb')
- self.__data__ = fd.read()
- fd.close()
- elif data:
-@@ -1555,7 +1555,7 @@ class PE:
- 'Normal values are never larger than 0x10, the value is: 0x%x' %
- self.OPTIONAL_HEADER.NumberOfRvaAndSizes )
-
-- for i in xrange(int(0x7fffffffL & self.OPTIONAL_HEADER.NumberOfRvaAndSizes)):
-+ for i in range(int(0x7fffffff & self.OPTIONAL_HEADER.NumberOfRvaAndSizes)):
-
- if len(self.__data__[offset:]) == 0:
- break
-@@ -1668,7 +1668,7 @@ class PE:
- """
-
- for warning in self.__warnings:
-- print '>', warning
-+ print('>', warning)
-
-
- def full_load(self):
-@@ -1705,7 +1705,7 @@ class PE:
- for entry in self.FileInfo:
- if hasattr(entry, 'StringTable'):
- for st_entry in entry.StringTable:
-- for key, entry in st_entry.entries.items():
-+ for key, entry in list(st_entry.entries.items()):
-
- offsets = st_entry.entries_offsets[key]
- lengths = st_entry.entries_lengths[key]
-@@ -1738,12 +1738,12 @@ class PE:
- file_data[
- offsets[1] + len(entry)*2 :
- offsets[1] + lengths[1]*2 ] = [
-- u'\0' ] * remainder*2
-+ '\0' ] * remainder*2
-
- new_file_data = ''.join( [ chr(ord(c)) for c in file_data] )
-
- if filename:
-- f = file(filename, 'wb+')
-+ f = open(filename, 'wb+')
- f.write(new_file_data)
- f.close()
- else:
-@@ -1767,7 +1767,7 @@ class PE:
-
- self.sections = []
-
-- for i in xrange(self.FILE_HEADER.NumberOfSections):
-+ for i in range(self.FILE_HEADER.NumberOfSections):
- section = SectionStructure(self.__IMAGE_SECTION_HEADER_format__)
- if not section:
- break
-@@ -1846,7 +1846,7 @@ class PE:
- matching the filter "flag_filter".
- """
-
-- return [(f[0], f[1]) for f in flag_dict.items() if
-+ return [(f[0], f[1]) for f in list(flag_dict.items()) if
- isinstance(f[0], str) and f[0].startswith(flag_filter)]
-
-
-@@ -1956,7 +1956,7 @@ class PE:
- rva += bnd_descr.sizeof()
-
- forwarder_refs = []
-- for idx in xrange(bnd_descr.NumberOfModuleForwarderRefs):
-+ for idx in range(bnd_descr.NumberOfModuleForwarderRefs):
- # Both structures IMAGE_BOUND_IMPORT_DESCRIPTOR and
- # IMAGE_BOUND_FORWARDER_REF have the same size.
- bnd_frwd_ref = self.__unpack_data__(
-@@ -2092,7 +2092,7 @@ class PE:
- data = self.get_data(data_rva, size)
-
- entries = []
-- for idx in xrange(len(data)/2):
-+ for idx in range(len(data)/2):
- word = struct.unpack('<H', data[idx*2:(idx+1)*2])[0]
- reloc_type = (word>>12)
- reloc_offset = (word&0x0fff)
-@@ -2110,10 +2110,10 @@ class PE:
- dbg_size = Structure(self.__IMAGE_DEBUG_DIRECTORY_format__).sizeof()
-
- debug = []
-- for idx in xrange(size/dbg_size):
-+ for idx in range(size/dbg_size):
- try:
- data = self.get_data(rva+dbg_size*idx, dbg_size)
-- except PEFormatError, e:
-+ except PEFormatError as e:
- self.__warnings.append(
- 'Invalid debug information. Can\'t read ' +
- 'data at RVA: 0x%x' % rva)
-@@ -2167,7 +2167,7 @@ class PE:
- # If the RVA is invalid all would blow up. Some EXEs seem to be
- # specially nasty and have an invalid RVA.
- data = self.get_data(rva, Structure(self.__IMAGE_RESOURCE_DIRECTORY_format__).sizeof() )
-- except PEFormatError, e:
-+ except PEFormatError as e:
- self.__warnings.append(
- 'Invalid resources directory. Can\'t read ' +
- 'directory data at RVA: 0x%x' % rva)
-@@ -2201,7 +2201,7 @@ class PE:
-
- strings_to_postprocess = list()
-
-- for idx in xrange(number_of_entries):
-+ for idx in range(number_of_entries):
-
- res = self.parse_resource_entry(rva)
- if res is None:
-@@ -2227,7 +2227,7 @@ class PE:
- entry_name = UnicodeStringWrapperPostProcessor(self, ustr_offset)
- strings_to_postprocess.append(entry_name)
-
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing the resources directory, ' +
- 'attempting to read entry name. ' +
-@@ -2328,7 +2328,7 @@ class PE:
- # If the RVA is invalid all would blow up. Some EXEs seem to be
- # specially nasty and have an invalid RVA.
- data = self.get_data(rva, Structure(self.__IMAGE_RESOURCE_DATA_ENTRY_format__).sizeof() )
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing a resource directory data entry, ' +
- 'the RVA is invalid: 0x%x' % ( rva ) )
-@@ -2353,13 +2353,13 @@ class PE:
- return None
-
- #resource.NameIsString = (resource.Name & 0x80000000L) >> 31
-- resource.NameOffset = resource.Name & 0x7FFFFFFFL
-+ resource.NameOffset = resource.Name & 0x7FFFFFFF
-
-- resource.__pad = resource.Name & 0xFFFF0000L
-- resource.Id = resource.Name & 0x0000FFFFL
-+ resource.__pad = resource.Name & 0xFFFF0000
-+ resource.Id = resource.Name & 0x0000FFFF
-
-- resource.DataIsDirectory = (resource.OffsetToData & 0x80000000L) >> 31
-- resource.OffsetToDirectory = resource.OffsetToData & 0x7FFFFFFFL
-+ resource.DataIsDirectory = (resource.OffsetToData & 0x80000000) >> 31
-+ resource.OffsetToDirectory = resource.OffsetToData & 0x7FFFFFFF
-
- return resource
-
-@@ -2407,7 +2407,7 @@ class PE:
- ustr_offset = version_struct.OffsetToData + versioninfo_struct.sizeof()
- try:
- versioninfo_string = self.get_string_u_at_rva( ustr_offset )
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing the version information, ' +
- 'attempting to read VS_VERSION_INFO string. Can\'t ' +
-@@ -2418,7 +2418,7 @@ class PE:
-
- # If the structure does not contain the expected name, it's assumed to be invalid
- #
-- if versioninfo_string != u'VS_VERSION_INFO':
-+ if versioninfo_string != 'VS_VERSION_INFO':
-
- self.__warnings.append('Invalid VS_VERSION_INFO block')
- return
-@@ -2487,7 +2487,7 @@ class PE:
- stringfileinfo_offset + versioninfo_struct.sizeof() )
- try:
- stringfileinfo_string = self.get_string_u_at_rva( ustr_offset )
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing the version information, ' +
- 'attempting to read StringFileInfo string. Can\'t ' +
-@@ -2506,7 +2506,7 @@ class PE:
-
- # Parse a StringFileInfo entry
- #
-- if stringfileinfo_string.startswith(u'StringFileInfo'):
-+ if stringfileinfo_string.startswith('StringFileInfo'):
-
- if stringfileinfo_struct.Type == 1 and stringfileinfo_struct.ValueLength == 0:
-
-@@ -2533,7 +2533,7 @@ class PE:
- stringtable_struct.sizeof() )
- try:
- stringtable_string = self.get_string_u_at_rva( ustr_offset )
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing the version information, ' +
- 'attempting to read StringTable string. Can\'t ' +
-@@ -2568,7 +2568,7 @@ class PE:
- try:
- key = self.get_string_u_at_rva( ustr_offset )
- key_offset = self.get_offset_from_rva( ustr_offset )
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing the version information, ' +
- 'attempting to read StringTable Key string. Can\'t ' +
-@@ -2584,7 +2584,7 @@ class PE:
- value = self.get_string_u_at_rva( ustr_offset,
- max_length = string_struct.ValueLength )
- value_offset = self.get_offset_from_rva( ustr_offset )
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing the version information, ' +
- 'attempting to read StringTable Value string. ' +
-@@ -2629,7 +2629,7 @@ class PE:
-
- # Parse a VarFileInfo entry
- #
-- elif stringfileinfo_string.startswith( u'VarFileInfo' ):
-+ elif stringfileinfo_string.startswith( 'VarFileInfo' ):
-
- varfileinfo_struct = stringfileinfo_struct
- varfileinfo_struct.name = 'VarFileInfo'
-@@ -2659,7 +2659,7 @@ class PE:
- var_struct.sizeof() )
- try:
- var_string = self.get_string_u_at_rva( ustr_offset )
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing the version information, ' +
- 'attempting to read VarFileInfo Var string. ' +
-@@ -2681,7 +2681,7 @@ class PE:
- raw_data[varword_offset+2:varword_offset+4], 0)
- varword_offset += 4
-
-- if isinstance(word1, (int, long)) and isinstance(word1, (int, long)):
-+ if isinstance(word1, int) and isinstance(word1, int):
- var_struct.entry = {var_string: '0x%04x 0x%04x' % (word1, word2)}
-
- var_offset = self.dword_align(
-@@ -2750,7 +2750,7 @@ class PE:
-
- exports = []
-
-- for i in xrange(export_dir.NumberOfNames):
-+ for i in range(export_dir.NumberOfNames):
-
-
- symbol_name = self.get_string_at_rva(
-@@ -2787,7 +2787,7 @@ class PE:
-
- ordinals = [exp.ordinal for exp in exports]
-
-- for idx in xrange(export_dir.NumberOfFunctions):
-+ for idx in range(export_dir.NumberOfFunctions):
-
- if not idx+export_dir.Base in ordinals:
- symbol_address = self.get_dword_from_data(
-@@ -2828,7 +2828,7 @@ class PE:
- # If the RVA is invalid all would blow up. Some PEs seem to be
- # specially nasty and have an invalid RVA.
- data = self.get_data( rva, Structure(self.__IMAGE_DELAY_IMPORT_DESCRIPTOR_format__).sizeof() )
-- except PEFormatError, e:
-+ except PEFormatError as e:
- self.__warnings.append(
- 'Error parsing the Delay import directory at RVA: 0x%x' % ( rva ) )
- break
-@@ -2850,7 +2850,7 @@ class PE:
- import_desc.pINT,
- import_desc.pIAT,
- None)
-- except PEFormatError, e:
-+ except PEFormatError as e:
- self.__warnings.append(
- 'Error parsing the Delay import directory. ' +
- 'Invalid import data at RVA: 0x%x' % ( rva ) )
-@@ -2881,7 +2881,7 @@ class PE:
- # If the RVA is invalid all would blow up. Some EXEs seem to be
- # specially nasty and have an invalid RVA.
- data = self.get_data(rva, Structure(self.__IMAGE_IMPORT_DESCRIPTOR_format__).sizeof() )
-- except PEFormatError, e:
-+ except PEFormatError as e:
- self.__warnings.append(
- 'Error parsing the Import directory at RVA: 0x%x' % ( rva ) )
- break
-@@ -2901,7 +2901,7 @@ class PE:
- import_desc.OriginalFirstThunk,
- import_desc.FirstThunk,
- import_desc.ForwarderChain)
-- except PEFormatError, excp:
-+ except PEFormatError as excp:
- self.__warnings.append(
- 'Error parsing the Import directory. ' +
- 'Invalid Import data at RVA: 0x%x' % ( rva ) )
-@@ -2934,7 +2934,7 @@ class PE:
- imported_symbols = []
- imports_section = self.get_section_by_rva(first_thunk)
- if not imports_section:
-- raise PEFormatError, 'Invalid/corrupt imports.'
-+ raise PEFormatError('Invalid/corrupt imports.')
-
-
- # Import Lookup Table. Contains ordinals or pointers to strings.
-@@ -2961,7 +2961,7 @@ class PE:
- return None
-
-
-- for idx in xrange(len(table)):
-+ for idx in range(len(table)):
-
- imp_ord = None
- imp_hint = None
-@@ -2989,7 +2989,7 @@ class PE:
- # Get the Hint
- imp_hint = self.get_word_from_data(data, 0)
- imp_name = self.get_string_at_rva(table[idx].AddressOfData+2)
-- except PEFormatError, e:
-+ except PEFormatError as e:
- pass
-
- imp_address = first_thunk+self.OPTIONAL_HEADER.ImageBase+idx*4
-@@ -3030,7 +3030,7 @@ class PE:
-
- try:
- data = self.get_data( rva, Structure(format).sizeof() )
-- except PEFormatError, e:
-+ except PEFormatError as e:
- self.__warnings.append(
- 'Error parsing the import table. ' +
- 'Invalid data at RVA: 0x%x' % ( rva ) )
-@@ -3135,7 +3135,7 @@ class PE:
- end = None
- return self.header[rva:end]
-
-- raise PEFormatError, 'data at RVA can\'t be fetched. Corrupt header?'
-+ raise PEFormatError('data at RVA can\'t be fetched. Corrupt header?')
-
- return s.get_data(rva, length)
-
-@@ -3158,7 +3158,7 @@ class PE:
- s = self.get_section_by_rva(rva)
- if not s:
-
-- raise PEFormatError, 'data at RVA can\'t be fetched. Corrupt header?'
-+ raise PEFormatError('data at RVA can\'t be fetched. Corrupt header?')
-
- return s.get_offset_from_rva(rva)
-
-@@ -3205,21 +3205,21 @@ class PE:
- # If the RVA is invalid all would blow up. Some EXEs seem to be
- # specially nasty and have an invalid RVA.
- self.get_data(rva, 2)
-- except PEFormatError, e:
-+ except PEFormatError as e:
- return None
-
- #length = struct.unpack('<H', data)[0]
-
-- s = u''
-- for idx in xrange(max_length):
-+ s = ''
-+ for idx in range(max_length):
- try:
- uchr = struct.unpack('<H', self.get_data(rva+2*idx, 2))[0]
- except struct.error:
- break
-
-- if unichr(uchr) == u'\0':
-+ if chr(uchr) == '\0':
- break
-- s += unichr(uchr)
-+ s += chr(uchr)
-
- return s
-
-@@ -3251,7 +3251,7 @@ class PE:
-
- def print_info(self):
- """Print all the PE header information in a human readable from."""
-- print self.dump_info()
-+ print(self.dump_info())
-
-
- def dump_info(self, dump=None):
-@@ -3334,7 +3334,7 @@ class PE:
- hasattr(self.OPTIONAL_HEADER, 'DATA_DIRECTORY') ):
-
- dump.add_header('Directories')
-- for idx in xrange(len(self.OPTIONAL_HEADER.DATA_DIRECTORY)):
-+ for idx in range(len(self.OPTIONAL_HEADER.DATA_DIRECTORY)):
- directory = self.OPTIONAL_HEADER.DATA_DIRECTORY[idx]
- dump.add_lines(directory.dump())
- dump.add_newline()
-@@ -3368,7 +3368,7 @@ class PE:
- [dump.add_line(' '+line) for line in st_entry.dump()]
- dump.add_line(' LangID: '+st_entry.LangID)
- dump.add_newline()
-- for str_entry in st_entry.entries.items():
-+ for str_entry in list(st_entry.entries.items()):
- dump.add_line( ' ' +
- convert_to_printable(str_entry[0]) + ': ' +
- convert_to_printable(str_entry[1]) )
-@@ -3380,8 +3380,8 @@ class PE:
- [dump.add_line(' '+line) for line in var_entry.dump()]
- dump.add_line(
- ' ' +
-- convert_to_printable(var_entry.entry.keys()[0]) +
-- ': ' + var_entry.entry.values()[0])
-+ convert_to_printable(list(var_entry.entry.keys())[0]) +
-+ ': ' + list(var_entry.entry.values())[0])
-
- dump.add_newline()
-
-@@ -3930,5 +3930,5 @@ class PE:
- if __name__ == "__main__":
- import sys
- pe = PE(sys.argv[1])
-- print pe
-+ print(pe)
-
-diff --git a/launcher/game/project.rpy b/launcher/game/project.rpy
-index 8ff9ade..524e838 100644
---- a/launcher/game/project.rpy
-+++ b/launcher/game/project.rpy
-@@ -273,7 +273,7 @@ init python in project:
-
- for f in files:
-
-- data = file(self.unelide_filename(f))
-+ data = open(self.unelide_filename(f))
-
- for l, line in enumerate(data):
- l += 1
-diff --git a/launcher/game/tkaskdir.py b/launcher/game/tkaskdir.py
-index 5b64008..a88d089 100644
---- a/launcher/game/tkaskdir.py
-+++ b/launcher/game/tkaskdir.py
-@@ -31,8 +31,8 @@ try:
- from tkinter import Tk
- from tkinter.filedialog import askdirectory
- except ImportError:
-- from Tkinter import Tk
-- from tkFileDialog import askdirectory
-+ from tkinter import Tk
-+ from tkinter.filedialog import askdirectory
-
- # Binary mode stdout for python3.
- try:
-diff --git a/module/gen/renpy.text.textsupport.c b/module/gen/renpy.text.textsupport.c
-index f09ec46..bbe9b3a 100644
---- a/module/gen/renpy.text.textsupport.c
-+++ b/module/gen/renpy.text.textsupport.c
-@@ -800,7 +800,7 @@ int __pyx_module_is_main_renpy__text__textsupport = 0;
- static PyObject *__pyx_builtin_range;
- static PyObject *__pyx_builtin_Exception;
- static PyObject *__pyx_builtin_ord;
--static PyObject *__pyx_builtin_unichr;
-+static PyObject *__pyx_builtin_chr;
- static int __pyx_pf_5renpy_4text_11textsupport_5Glyph___init__(struct __pyx_obj_5renpy_4text_11textsupport_Glyph *__pyx_v_self); /* proto */
- static PyObject *__pyx_pf_5renpy_4text_11textsupport_5Glyph_2__repr__(struct __pyx_obj_5renpy_4text_11textsupport_Glyph *__pyx_v_self); /* proto */
- static PyObject *__pyx_pf_5renpy_4text_11textsupport_5Glyph_1x___get__(struct __pyx_obj_5renpy_4text_11textsupport_Glyph *__pyx_v_self); /* proto */
-@@ -964,7 +964,7 @@ static char __pyx_k_offset[] = "offset";
- static char __pyx_k_source[] = "source";
- static char __pyx_k_spaces[] = "spaces";
- static char __pyx_k_splitx[] = "splitx";
--static char __pyx_k_unichr[] = "unichr";
-+static char __pyx_k_chr[] = "chr";
- static char __pyx_k_CLASSES[] = "CLASSES";
- static char __pyx_k_advance[] = "advance";
- static char __pyx_k_justify[] = "justify";
-@@ -1190,7 +1190,7 @@ static PyObject *__pyx_n_s_text_align;
- static PyObject *__pyx_n_s_tokenize;
- static PyObject *__pyx_n_s_tpg;
- static PyObject *__pyx_n_s_tweak_glyph_spacing;
--static PyObject *__pyx_n_s_unichr;
-+static PyObject *__pyx_n_s_chr;
- static PyObject *__pyx_n_s_w;
- static PyObject *__pyx_n_s_width;
- static PyObject *__pyx_n_s_x;
-@@ -5652,7 +5652,7 @@ static PyObject *__pyx_pf_5renpy_4text_11textsupport_12linebreak_debug(CYTHON_UN
- * if g.split == SPLIT_INSTEAD:
- * rv += "|"
- * elif g.split == SPLIT_BEFORE: # <<<<<<<<<<<<<<
-- * rv += "[" + unichr(g.character)
-+ * rv += "[" + chr(g.character)
- * else:
- */
- switch (__pyx_v_g->split) {
-@@ -5671,7 +5671,7 @@ static PyObject *__pyx_pf_5renpy_4text_11textsupport_12linebreak_debug(CYTHON_UN
- * if g.split == SPLIT_INSTEAD:
- * rv += "|" # <<<<<<<<<<<<<<
- * elif g.split == SPLIT_BEFORE:
-- * rv += "[" + unichr(g.character)
-+ * rv += "[" + chr(g.character)
- */
- __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_rv, __pyx_kp_s__2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
-@@ -5683,7 +5683,7 @@ static PyObject *__pyx_pf_5renpy_4text_11textsupport_12linebreak_debug(CYTHON_UN
- * if g.split == SPLIT_INSTEAD:
- * rv += "|"
- * elif g.split == SPLIT_BEFORE: # <<<<<<<<<<<<<<
-- * rv += "[" + unichr(g.character)
-+ * rv += "[" + chr(g.character)
- * else:
- */
- case __pyx_e_5renpy_4text_11textsupport_SPLIT_BEFORE:
-@@ -5691,9 +5691,9 @@ static PyObject *__pyx_pf_5renpy_4text_11textsupport_12linebreak_debug(CYTHON_UN
- /* "renpy/text/textsupport.pyx":395
- * rv += "|"
- * elif g.split == SPLIT_BEFORE:
-- * rv += "[" + unichr(g.character) # <<<<<<<<<<<<<<
-+ * rv += "[" + chr(g.character) # <<<<<<<<<<<<<<
- * else:
-- * rv += unichr(g.character)
-+ * rv += chr(g.character)
- */
- __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_g->character); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
-@@ -5702,7 +5702,7 @@ static PyObject *__pyx_pf_5renpy_4text_11textsupport_12linebreak_debug(CYTHON_UN
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
- __Pyx_GIVEREF(__pyx_t_3);
- __pyx_t_3 = 0;
-- __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_unichr, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_chr, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
- __pyx_t_4 = PyNumber_Add(__pyx_kp_s__3, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-@@ -5717,9 +5717,9 @@ static PyObject *__pyx_pf_5renpy_4text_11textsupport_12linebreak_debug(CYTHON_UN
- default:
-
- /* "renpy/text/textsupport.pyx":397
-- * rv += "[" + unichr(g.character)
-+ * rv += "[" + chr(g.character)
- * else:
-- * rv += unichr(g.character) # <<<<<<<<<<<<<<
-+ * rv += chr(g.character) # <<<<<<<<<<<<<<
- *
- * return rv
- */
-@@ -5730,7 +5730,7 @@ static PyObject *__pyx_pf_5renpy_4text_11textsupport_12linebreak_debug(CYTHON_UN
- PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
- __Pyx_GIVEREF(__pyx_t_3);
- __pyx_t_3 = 0;
-- __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_unichr, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_chr, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __Pyx_GOTREF(__pyx_t_3);
- __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
- __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_rv, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-@@ -5752,7 +5752,7 @@ static PyObject *__pyx_pf_5renpy_4text_11textsupport_12linebreak_debug(CYTHON_UN
- __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
- /* "renpy/text/textsupport.pyx":399
-- * rv += unichr(g.character)
-+ * rv += chr(g.character)
- *
- * return rv # <<<<<<<<<<<<<<
- *
-@@ -10826,7 +10826,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
- {&__pyx_n_s_tokenize, __pyx_k_tokenize, sizeof(__pyx_k_tokenize), 0, 0, 1, 1},
- {&__pyx_n_s_tpg, __pyx_k_tpg, sizeof(__pyx_k_tpg), 0, 0, 1, 1},
- {&__pyx_n_s_tweak_glyph_spacing, __pyx_k_tweak_glyph_spacing, sizeof(__pyx_k_tweak_glyph_spacing), 0, 0, 1, 1},
-- {&__pyx_n_s_unichr, __pyx_k_unichr, sizeof(__pyx_k_unichr), 0, 0, 1, 1},
-+ {&__pyx_n_s_chr, __pyx_k_chr, sizeof(__pyx_k_chr), 0, 0, 1, 1},
- {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1},
- {&__pyx_n_s_width, __pyx_k_width, sizeof(__pyx_k_width), 0, 0, 1, 1},
- {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1},
-@@ -10838,7 +10838,7 @@ static int __Pyx_InitCachedBuiltins(void) {
- __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_builtin_Exception = __Pyx_GetBuiltinName(__pyx_n_s_Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- __pyx_builtin_ord = __Pyx_GetBuiltinName(__pyx_n_s_ord); if (!__pyx_builtin_ord) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-- __pyx_builtin_unichr = __Pyx_GetBuiltinName(__pyx_n_s_unichr); if (!__pyx_builtin_unichr) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-+ __pyx_builtin_chr = __Pyx_GetBuiltinName(__pyx_n_s_chr); if (!__pyx_builtin_chr) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
- return 0;
- __pyx_L1_error:;
- return -1;
-diff --git a/module/generate_linebreak.py b/module/generate_linebreak.py
-index 670adb7..8914199 100644
---- a/module/generate_linebreak.py
-+++ b/module/generate_linebreak.py
-@@ -41,24 +41,24 @@ other_classes = " PITCH AI BK CB CJ CR LF NL SA SG SP XX"
-
- lines = breaking.split("\n")
-
--print "# This is generated code. Do not edit."
--print
-+print("# This is generated code. Do not edit.")
-+print()
-
- # A map from character class to the number that represents it.
- cl = { }
-
-
- for i, j in enumerate((lines[0] + other_classes).split()):
-- print "cdef char BC_{} = {}".format(j, i)
-+ print("cdef char BC_{} = {}".format(j, i))
- cl[j] = i
-
--print "CLASSES = {"
-+print("CLASSES = {")
-
- for i, j in enumerate((lines[0] + other_classes).split()):
-- print " \"{}\" : {},".format(j, i)
-+ print(" \"{}\" : {},".format(j, i))
- cl[j] = i
-
--print "}"
-+print("}")
-
- rules = [ ]
-
-@@ -66,12 +66,12 @@ for l in lines[1:]:
- for c in l.split()[1:]:
- rules.append(c)
-
--print
--print "cdef char *break_rules = \"" + "".join(rules) + "\""
-+print()
-+print("cdef char *break_rules = \"" + "".join(rules) + "\"")
-
- cc = [ 'XX' ] * 65536
-
--for l in file("LineBreak.txt"):
-+for l in open("LineBreak.txt"):
- m = re.match("(\w+)\.\.(\w+);(\w\w)", l)
- if m:
- start = int(m.group(1), 16)
-@@ -108,7 +108,7 @@ def generate(name, func):
- assert "CJ" not in ncc
- assert "AI" not in ncc
-
-- print "cdef char *break_" + name + " = \"" + "".join("\\x%02x" % cl[i] for i in ncc) + "\""
-+ print("cdef char *break_" + name + " = \"" + "".join("\\x%02x" % cl[i] for i in ncc) + "\"")
-
- def western(i, cl):
- if cl == "CJ":
-diff --git a/module/generate_styles.py b/module/generate_styles.py
-index e8f6957..f2942ca 100644
---- a/module/generate_styles.py
-+++ b/module/generate_styles.py
-@@ -19,17 +19,13 @@
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
--from __future__ import print_function, unicode_literals, division, absolute_import
--
--str = unicode # @ReservedAssignment
--
- import collections
- import os
-
- try:
- from io import StringIO
- except:
-- from StringIO import StringIO
-+ from io import StringIO
-
- # Paths
- BASE = os.path.dirname(os.path.abspath(__file__))
-@@ -335,7 +331,7 @@ synthetic_properties = sorted_dict(
-
- all_properties = collections.OrderedDict()
-
--for k, v in style_properties.items():
-+for k, v in list(style_properties.items()):
- all_properties[k] = [ (k, None) ]
-
- all_properties.update(synthetic_properties)
-@@ -372,7 +368,7 @@ class CodeGen(object):
- return
-
- with open(self.filename, "wb") as f:
-- f.write(text)
-+ f.write(bytes(text, "utf-8"))
-
- def write(self, s, *args, **kwargs):
- out = " " * self.depth
-@@ -403,7 +399,7 @@ def generate_constants():
- g.write("DEF PREFIX_COUNT = {}", PREFIX_COUNT)
- g.write("DEF STYLE_PROPERTY_COUNT = {}", style_property_count)
-
-- for p in prefixes.values():
-+ for p in list(prefixes.values()):
- if p.index < 0:
- continue
-
-@@ -460,13 +456,13 @@ def generate_property_functions():
- This generates code that defines the property functions.
- """
-
-- for prefix in sorted(prefixes.values(), key=lambda p : p.index):
-+ for prefix in sorted(list(prefixes.values()), key=lambda p : p.index):
- g = CodeGen("module/gen/style_{}functions.pyx".format(prefix.name))
-
- g.write('include "style_common.pxi"')
- g.write('')
-
-- for propname, proplist in all_properties.items():
-+ for propname, proplist in list(all_properties.items()):
- generate_property_function(g, prefix, propname, proplist)
-
- g.close()
-@@ -522,13 +518,13 @@ def generate_sets():
-
- ap = collections.OrderedDict()
-
-- for k, v in all_properties.items():
-+ for k, v in list(all_properties.items()):
- ap[k] = [ i[0] for i in v ]
-
- prefix_priority = collections.OrderedDict()
- prefix_alts = collections.OrderedDict()
-
-- for p in prefixes.values():
-+ for p in list(prefixes.values()):
- prefix_priority[p.name] = p.priority
- prefix_alts[p.name] = p.alt_names
-
-diff --git a/module/maketegl.py b/module/maketegl.py
-index b5e1bda..4b9edc6 100644
---- a/module/maketegl.py
-+++ b/module/maketegl.py
-@@ -26,8 +26,6 @@
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- # SUCH DAMAGE.
-
--from __future__ import print_function
--
- # Modified in 2010,2014 by PyTom to generate Cython code that uses glew.
-
- VERSION = "0.1"
-diff --git a/module/pysdlsound/__init__.py b/module/pysdlsound/__init__.py
-index 8f2c8e9..a349a0d 100644
---- a/module/pysdlsound/__init__.py
-+++ b/module/pysdlsound/__init__.py
-@@ -9,7 +9,7 @@ except:
- pass
-
- try:
-- import linmixer #@UnresolvedImport
-+ from . import linmixer #@UnresolvedImport
- sys.modules['linmixer'] = sys.modules['pysdlsound.linmixer']
- except:
- pass
-diff --git a/module/setup.py b/module/setup.py
-index 38854d0..ea390e2 100644
---- a/module/setup.py
-+++ b/module/setup.py
-@@ -103,7 +103,7 @@ if has_fribidi and (not android) and (not ios):
- try:
- # Some versions of fribidi require glib, and it doesn't hurt to include it in
- # our path.
-- glib_flags = subprocess.check_output(["pkg-config", "--cflags", "glib-2.0"])
-+ glib_flags = subprocess.check_output(["pkg-config", "--cflags", "glib-2.0"]).decode("utf-8")
- setuplib.extra_compile_args.extend(glib_flags.split())
- except:
- pass
-@@ -232,4 +232,4 @@ import renpy
- setuplib.setup("Ren'Py", renpy.version[7:])
-
- if not has_fribidi:
-- print "Warning: Did not include fribidi."
-+ print("Warning: Did not include fribidi.")
-diff --git a/module/setuplib.py b/module/setuplib.py
-index 3b27819..c2b6eee 100644
---- a/module/setuplib.py
-+++ b/module/setuplib.py
-@@ -96,9 +96,9 @@ def include(header, directory=None, optional=True):
- return False
-
- if directory is None:
-- print "Could not find required header {0}.".format(header)
-+ print("Could not find required header {0}.".format(header))
- else:
-- print "Could not find required header {0}/{1}.".format(directory, header)
-+ print("Could not find required header {0}/{1}.".format(directory, header))
-
- sys.exit(-1)
-
-@@ -133,7 +133,7 @@ def library(name, optional=False):
- if optional:
- return False
-
-- print "Could not find required library {0}.".format(name)
-+ print("Could not find required library {0}.".format(name))
- sys.exit(-1)
-
- # A list of extension objects that we use.
-@@ -182,7 +182,7 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[], pyx=None
- elif os.path.exists(fn):
- pass
- else:
-- print "Could not find {0}.".format(fn)
-+ print("Could not find {0}.".format(fn))
- sys.exit(-1)
-
- module_dir = os.path.dirname(fn)
-@@ -190,7 +190,7 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[], pyx=None
- # Figure out what it depends on.
- deps = [ fn ]
-
-- f = file(fn)
-+ f = open(fn)
- for l in f:
-
- m = re.search(r'from\s*([\w.]+)\s*cimport', l)
-@@ -243,19 +243,19 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[], pyx=None
- elif os.path.exists(dep_fn):
- pass
- else:
-- print "{0} depends on {1}, which can't be found.".format(fn, dep_fn)
-+ print("{0} depends on {1}, which can't be found.".format(fn, dep_fn))
- sys.exit(-1)
-
- if os.path.getmtime(dep_fn) > c_mtime:
- out_of_date = True
-
- if out_of_date and not cython_command:
-- print "WARNING:", name, "is out of date, but RENPY_CYTHON isn't set."
-+ print("WARNING:", name, "is out of date, but RENPY_CYTHON isn't set.")
- out_of_date = False
-
- # If the file is out of date, regenerate it.
- if out_of_date:
-- print name, "is out of date."
-+ print(name, "is out of date.")
-
- try:
- import subprocess
-@@ -280,10 +280,10 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[], pyx=None
- "-o",
- c_fn])
-
-- except subprocess.CalledProcessError, e:
-- print
-- print str(e)
-- print
-+ except subprocess.CalledProcessError as e:
-+ print()
-+ print(str(e))
-+ print()
- sys.exit(-1)
-
- # Build the module normally once we have the c file.
-@@ -299,7 +299,7 @@ def find_unnecessary_gen():
- if i in necessary_gen:
- continue
-
-- print "Unnecessary file", os.path.join("gen", i)
-+ print("Unnecessary file", os.path.join("gen", i))
-
-
- py_modules = [ ]
-@@ -326,14 +326,14 @@ def copyfile(source, dest, replace=None, replace_with=None):
- if os.path.getmtime(sfn) <= os.path.getmtime(dfn):
- return
-
-- sf = file(sfn, "rb")
-+ sf = open(sfn, "rb")
- data = sf.read()
- sf.close()
-
- if replace:
- data = data.replace(replace, replace_with)
-
-- df = file(dfn, "wb")
-+ df = open(dfn, "wb")
- df.write("# This file was automatically generated from " + source + "\n")
- df.write("# Modifications will be automatically overwritten.\n\n")
- df.write(data)
-diff --git a/renpy/__init__.py b/renpy/__init__.py
-index e6f5310..91a6f24 100644
---- a/renpy/__init__.py
-+++ b/renpy/__init__.py
-@@ -27,7 +27,7 @@ import os
- import copy
- import types
- import threading
--import cPickle
-+import pickle
-
- ################################################################################
- # Version information
-@@ -200,14 +200,14 @@ class Backup():
- if mobile:
- return
-
-- for m in sys.modules.values():
-+ for m in list(sys.modules.values()):
- if m is None:
- continue
-
- self.backup_module(m)
-
- # A pickled version of self.objects.
-- self.objects_pickle = cPickle.dumps(self.objects, cPickle.HIGHEST_PROTOCOL)
-+ self.objects_pickle = pickle.dumps(self.objects, pickle.HIGHEST_PROTOCOL)
-
- self.objects = None
-
-@@ -229,7 +229,7 @@ class Backup():
-
- self.names[mod] = set(vars(mod).keys())
-
-- for k, v in vars(mod).iteritems():
-+ for k, v in vars(mod).items():
-
- if k.startswith("__") and k.endswith("__"):
- continue
-@@ -248,10 +248,10 @@ class Backup():
- # If we have a problem pickling things, uncomment the next block.
-
- try:
-- cPickle.dumps(v, cPickle.HIGHEST_PROTOCOL)
-+ pickle.dumps(v, pickle.HIGHEST_PROTOCOL)
- except:
-- print "Cannot pickle", name + "." + k, "=", repr(v)
-- print "Reduce Ex is:", repr(v.__reduce_ex__(cPickle.HIGHEST_PROTOCOL))
-+ print("Cannot pickle", name + "." + k, "=", repr(v))
-+ print("Reduce Ex is:", repr(v.__reduce_ex__(pickle.HIGHEST_PROTOCOL)))
-
- def restore(self):
- """
-@@ -263,15 +263,15 @@ class Backup():
- return
-
- # Remove new variables from the module.
-- for mod, names in self.names.iteritems():
-+ for mod, names in self.names.items():
- modvars = vars(mod)
- for name in set(modvars.keys()) - names:
- del modvars[name]
-
-
-- objects = cPickle.loads(self.objects_pickle)
-+ objects = pickle.loads(self.objects_pickle)
-
-- for k, v in self.variables.iteritems():
-+ for k, v in self.variables.items():
- mod, field = k
- setattr(mod, field, objects[v])
-
-@@ -473,12 +473,12 @@ def post_import():
- import subprocess
- sys.modules['renpy.subprocess'] = subprocess
-
-- for k, v in renpy.defaultstore.__dict__.iteritems():
-+ for k, v in renpy.defaultstore.__dict__.items():
- renpy.store.__dict__.setdefault(k, v)
-
- # Import everything into renpy.exports, provided it isn't
- # already there.
-- for k, v in globals().iteritems():
-+ for k, v in globals().items():
- vars(renpy.exports).setdefault(k, v)
-
-
-@@ -519,7 +519,7 @@ def reload_all():
- renpy.display.interface = None
-
- # Delete the store modules.
-- for i in sys.modules.keys():
-+ for i in list(sys.modules.keys()):
- if i.startswith("store") or i == "renpy.store":
- m = sys.modules[i]
-
-diff --git a/renpy/add_from.py b/renpy/add_from.py
-index 9935b29..5b2e3b5 100644
---- a/renpy/add_from.py
-+++ b/renpy/add_from.py
-@@ -82,7 +82,7 @@ def process_file(fn):
- consumed = 0
-
- # The output.
-- output = u""
-+ output = ""
-
- for position, target in edits:
- output += data[consumed:position]
-diff --git a/renpy/ast.py b/renpy/ast.py
-index ec2cbf5..286c54a 100644
---- a/renpy/ast.py
-+++ b/renpy/ast.py
-@@ -30,7 +30,8 @@ import renpy.display
-
- import re
- import time
--import md5
-+import hashlib
-+import collections
-
- def statement_name(name):
- """
-@@ -102,7 +103,7 @@ class ParameterInfo(object):
-
- extrapos = tuple(args[len(self.positional):])
-
-- for name, value in kwargs.iteritems():
-+ for name, value in kwargs.items():
- if name in values:
- if not ignore_errors:
- raise Exception("Parameter %s has two values." % name)
-@@ -133,7 +134,7 @@ class ParameterInfo(object):
- if self.extrakw:
- rv[self.extrakw] = values
- elif values and not ignore_errors:
-- raise Exception("Unknown keyword arguments: %s" % ( ", ".join(values.keys())))
-+ raise Exception("Unknown keyword arguments: %s" % ( ", ".join(list(values.keys()))))
-
- return rv
-
-@@ -192,7 +193,7 @@ def __newobj__(cls, *args):
- return cls.__new__(cls, *args)
-
- # This represents a string containing python code.
--class PyExpr(unicode):
-+class PyExpr(str):
-
- __slots__ = [
- 'filename',
-@@ -200,14 +201,14 @@ class PyExpr(unicode):
- ]
-
- def __new__(cls, s, filename, linenumber):
-- self = unicode.__new__(cls, s)
-+ self = str.__new__(cls, s)
- self.filename = filename
- self.linenumber = linenumber
-
- return self
-
- def __getnewargs__(self):
-- return (unicode(self), self.filename, self.linenumber) # E1101
-+ return (str(self), self.filename, self.linenumber) # E1101
-
- class PyCode(object):
-
-@@ -261,7 +262,7 @@ class PyCode(object):
- if isinstance(code, renpy.python.ast.AST): #@UndefinedVariable
- code = renpy.python.ast.dump(code) #@UndefinedVariable
-
-- self.hash = chr(renpy.bytecode_version) + md5.md5(repr(self.location) + code.encode("utf-8")).digest()
-+ self.hash = chr(renpy.bytecode_version) + hashlib.md5(repr(self.location) + code.encode("utf-8")).digest()
- return self.hash
-
-
-@@ -291,7 +292,7 @@ class Scry(object):
- def __getattr__(self, name):
- return None
-
-- def next(self): #@ReservedAssignment
-+ def __next__(self): #@ReservedAssignment
- if self._next is None:
- return None
- else:
-@@ -382,7 +383,7 @@ class Node(object):
- node.
- """
-
-- if self.next is old:
-+ if self.__next__ is old:
- self.next = new
-
- def execute(self):
-@@ -409,8 +410,8 @@ class Node(object):
- renpy.display.predict.screen to be called as necessary.
- """
-
-- if self.next:
-- return [ self.next ]
-+ if self.__next__:
-+ return [ self.__next__ ]
- else:
- return [ ]
-
-@@ -421,7 +422,7 @@ class Node(object):
- """
-
- rv = Scry()
-- rv._next = self.next # W0201
-+ rv._next = self.__next__ # W0201
- return rv
-
- def restructure(self, callback):
-@@ -573,7 +574,7 @@ class Say(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("say")
-
- try:
-@@ -584,8 +585,8 @@ class Say(Node):
-
- if not (
- (who is None) or
-- callable(who) or
-- isinstance(who, basestring) ):
-+ isinstance(who, collections.Callable) or
-+ isinstance(who, str) ):
-
- raise Exception("Sayer %s is not a function or string." % self.who.encode("utf-8"))
-
-@@ -630,7 +631,7 @@ class Say(Node):
- finally:
- renpy.game.context().say_attributes = old_attributes
-
-- return [ self.next ]
-+ return [ self.__next__ ]
-
- def scry(self):
- rv = Node.scry(self)
-@@ -685,7 +686,7 @@ class Init(Node):
- chain_block(self.block, None)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("init")
-
- def restructure(self, callback):
-@@ -743,14 +744,14 @@ class Label(Node):
- self.next = next
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("label")
-
- renpy.game.context().mark_seen()
-
- values = apply_arguments(self.parameters, renpy.store._args, renpy.store._kwargs)
-
-- for k, v in values.iteritems():
-+ for k, v in values.items():
- renpy.exports.dynamic(k)
- setattr(renpy.store, k, v)
-
-@@ -798,7 +799,7 @@ class Python(Node):
- renpy.python.create_store(self.store)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("python")
-
- try:
-@@ -845,7 +846,7 @@ class EarlyPython(Node):
- return (EarlyPython, self.code.source)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("python early")
-
- def early_execute(self):
-@@ -889,7 +890,7 @@ class Image(Node):
- # Note: We should always check that self.code is None before
- # accessing self.atl, as self.atl may not always exist.
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("image")
-
- if self.code is not None:
-@@ -933,7 +934,7 @@ class Transform(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("transform")
-
- parameters = getattr(self, "parameters", None)
-@@ -1058,14 +1059,14 @@ class Show(Node):
- return (Show, tuple(self.imspec[0]))
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("show")
-
- show_imspec(self.imspec, atl=getattr(self, "atl", None))
-
- def predict(self):
- predict_imspec(self.imspec, atl=getattr(self, "atl", None))
-- return [ self.next ]
-+ return [ self.__next__ ]
-
- def analyze(self):
- if getattr(self, 'atl', None) is not None:
-@@ -1091,7 +1092,7 @@ class ShowLayer(Node):
- return (ShowLayer, self.layer)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("show layer")
-
- at_list = [ renpy.python.py_eval(i) for i in self.at_list ]
-@@ -1103,7 +1104,7 @@ class ShowLayer(Node):
- renpy.exports.layer_at_list(at_list, layer=self.layer)
-
- def predict(self):
-- return [ self.next ]
-+ return [ self.__next__ ]
-
- def analyze(self):
- if self.atl is not None:
-@@ -1142,7 +1143,7 @@ class Scene(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("scene")
-
- renpy.config.scene(self.layer)
-@@ -1155,7 +1156,7 @@ class Scene(Node):
- if self.imspec:
- predict_imspec(self.imspec, atl=getattr(self, "atl", None), scene=True)
-
-- return [ self.next ]
-+ return [ self.__next__ ]
-
- def analyze(self):
- if getattr(self, 'atl', None) is not None:
-@@ -1204,11 +1205,11 @@ class Hide(Node):
-
- renpy.game.context().images.predict_hide(tag, layer)
-
-- return [ self.next ]
-+ return [ self.__next__ ]
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("hide")
-
- if len(self.imspec) == 3:
-@@ -1252,7 +1253,7 @@ class With(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("with")
-
- trans = renpy.python.py_eval(self.expr)
-@@ -1276,7 +1277,7 @@ class With(Node):
- pass
-
-
-- return [ self.next ]
-+ return [ self.__next__ ]
-
-
- class Call(Node):
-@@ -1423,7 +1424,7 @@ class Menu(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("menu")
-
- choices = [ ]
-@@ -1452,7 +1453,7 @@ class Menu(Node):
- if choice is not None:
- next_node(self.items[choice][2][0])
- else:
-- next_node(self.next)
-+ next_node(self.__next__)
-
-
- def predict(self):
-@@ -1547,7 +1548,7 @@ class Pass(Node):
- return (Pass,)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("pass")
-
-
-@@ -1585,14 +1586,14 @@ class While(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("while")
-
- if renpy.python.py_eval(self.condition):
- next_node(self.block[0])
-
- def predict(self):
-- return [ self.block[0], self.next ]
-+ return [ self.block[0], self.__next__ ]
-
- def scry(self):
- rv = Node.scry(self)
-@@ -1640,7 +1641,7 @@ class If(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("if")
-
- for condition, block in self.entries:
-@@ -1651,7 +1652,7 @@ class If(Node):
- def predict(self):
-
- return [ block[0] for _condition, block in self.entries ] + \
-- [ self.next ]
-+ [ self.__next__ ]
-
- def scry(self):
- rv = Node.scry(self)
-@@ -1726,7 +1727,7 @@ class UserStatement(Node):
- if rv is not None:
- return renpy.game.script.lookup(rv)
- else:
-- return self.next
-+ return self.__next__
-
- def scry(self):
- rv = Node.scry(self)
-@@ -1787,7 +1788,7 @@ class Define(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("define")
-
- value = renpy.python.py_eval_bytecode(self.code.bytecode)
-@@ -1834,7 +1835,7 @@ class Default(Node):
-
- def execute(self):
-
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("default")
-
- default_statements.append(self)
-@@ -1889,7 +1890,7 @@ class Screen(Node):
- return (Screen, self.screen.name)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("screen")
-
- self.screen.define((self.filename, self.linenumber))
-@@ -1956,7 +1957,7 @@ class Translate(Node):
- statement_name("translate")
-
- if self.language is not None:
-- next_node(self.next)
-+ next_node(self.__next__)
- raise Exception("Translation nodes cannot be run directly.")
-
- if self.identifier not in renpy.game.persistent._seen_translates: # @UndefinedVariable
-@@ -2000,7 +2001,7 @@ class EndTranslate(Node):
- return (EndTranslate,)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("end translate")
-
- renpy.game.context().translate_identifier = None
-@@ -2030,7 +2031,7 @@ class TranslateString(Node):
- return (TranslateString,)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("translate string")
-
- renpy.translation.add_string_translation(self.language, self.old, self.new)
-@@ -2066,7 +2067,7 @@ class TranslatePython(Node):
- return (TranslatePython, self.code.source)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("translate_python")
-
- # def early_execute(self):
-@@ -2106,7 +2107,7 @@ class TranslateBlock(Node):
- chain_block(self.block, None)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("translate_block")
-
- def restructure(self, callback):
-@@ -2156,7 +2157,7 @@ class Style(Node):
- return (Style, self.style_name)
-
- def execute(self):
-- next_node(self.next)
-+ next_node(self.__next__)
- statement_name("style")
-
- if self.variant is not None:
-@@ -2180,7 +2181,7 @@ class Style(Node):
-
- if self.properties:
- properties = { }
-- for name, expr in self.properties.items():
-+ for name, expr in list(self.properties.items()):
- properties[name] = renpy.python.py_eval(expr)
-
- s.add_properties(properties)
-diff --git a/renpy/atl.py b/renpy/atl.py
-index d0f9d31..582f531 100644
---- a/renpy/atl.py
-+++ b/renpy/atl.py
-@@ -39,7 +39,7 @@ def executing(loc):
- warpers = { }
-
- def atl_warper(f):
-- name = f.func_name
-+ name = f.__name__
- warpers[name] = f
- return f
-
-@@ -135,7 +135,7 @@ def interpolate(t, a, b, type): #@ReservedAssignment
- return tuple(interpolate(t, i, j, ty) for i, j, ty in zip(a, b, type))
-
- # Deal with booleans, nones, etc.
-- elif b is None or isinstance(b, (bool, basestring)):
-+ elif b is None or isinstance(b, (bool, str)):
- if t >= 1.0:
- return b
- else:
-@@ -375,7 +375,7 @@ class ATLTransformBase(renpy.object.Object):
- raise Exception("Too many arguments passed to ATL transform.")
-
- # Handle keyword arguments.
-- for k, v in kwargs.iteritems():
-+ for k, v in kwargs.items():
-
- if k in positional:
- positional.remove(k)
-@@ -1113,7 +1113,7 @@ class Interpolation(Statement):
- linear, revolution, splines = state
-
- # Linearly interpolate between the things in linear.
-- for k, (old, new) in linear.iteritems():
-+ for k, (old, new) in linear.items():
- value = interpolate(complete, old, new, PROPERTIES[k])
-
- setattr(trans.state, k, value)
-@@ -1356,19 +1356,19 @@ class RawOn(RawStatement):
-
- handlers = { }
-
-- for k, v in self.handlers.iteritems():
-+ for k, v in self.handlers.items():
- handlers[k] = v.compile(ctx)
-
- return On(self.loc, handlers)
-
- def predict(self, ctx):
-- for i in self.handlers.itervalues():
-+ for i in self.handlers.values():
- i.predict(ctx)
-
- def mark_constant(self):
- constant = GLOBAL_CONST
-
-- for block in self.handlers.itervalues():
-+ for block in self.handlers.values():
- block.mark_constant()
- constant = min(constant, block.constant)
-
-@@ -1450,7 +1450,7 @@ class On(Statement):
- return "event", (name, arg), None
-
- def visit(self):
-- return [ j for i in self.handlers.itervalues() for j in i.visit() ]
-+ return [ j for i in self.handlers.values() for j in i.visit() ]
-
-
- # Event statement.
-diff --git a/renpy/audio/androidhw.py b/renpy/audio/androidhw.py
-index 1c3b6ed..e487b56 100644
---- a/renpy/audio/androidhw.py
-+++ b/renpy/audio/androidhw.py
-@@ -79,7 +79,7 @@ class AndroidVideoChannel(object):
-
- filename = self.queue.pop(0)
-
-- print "Playing", filename
-+ print("Playing", filename)
-
- f = renpy.loader.load(filename)
-
-diff --git a/renpy/audio/audio.py b/renpy/audio/audio.py
-index d265a3a..f322aab 100644
---- a/renpy/audio/audio.py
-+++ b/renpy/audio/audio.py
-@@ -803,7 +803,7 @@ def pause_all():
- Pause all playback channels.
- """
-
-- for c in channels.values():
-+ for c in list(channels.values()):
- c.pause()
-
- def unpause_all():
-@@ -811,5 +811,5 @@ def unpause_all():
- Unpause all playback channels.
- """
-
-- for c in channels.values():
-+ for c in list(channels.values()):
- c.unpause()
-diff --git a/renpy/audio/music.py b/renpy/audio/music.py
-index bf959b5..9ccce1c 100644
---- a/renpy/audio/music.py
-+++ b/renpy/audio/music.py
-@@ -76,7 +76,7 @@ def play(filenames, channel="music", loop=None, fadeout=None, synchro_start=Fals
- if filenames is None:
- return
-
-- if isinstance(filenames, basestring):
-+ if isinstance(filenames, str):
- filenames = [ filenames ]
-
- try:
-@@ -151,7 +151,7 @@ def queue(filenames, channel="music", loop=None, clear_queue=True, fadein=0, tig
- filenames = [ ]
- loop = False
-
-- if isinstance(filenames, basestring):
-+ if isinstance(filenames, str):
- filenames = [ filenames ]
-
- try:
-diff --git a/renpy/bootstrap.py b/renpy/bootstrap.py
-index 9dbe2e0..9261c2b 100644
---- a/renpy/bootstrap.py
-+++ b/renpy/bootstrap.py
-@@ -64,8 +64,8 @@ def extra_imports():
- import compiler; compiler
- import textwrap; textwrap
- import copy; copy
-- import urllib; urllib
-- import urllib2; urllib2
-+ import urllib.request, urllib.parse, urllib.error; urllib
-+ import urllib.request, urllib.error, urllib.parse; urllib2
- import codecs; codecs
- import rsa; rsa
- import decimal; decimal
-@@ -102,14 +102,14 @@ trace_local = None
-
- def trace_function(frame, event, arg):
- fn = os.path.basename(frame.f_code.co_filename)
-- print >>trace_file, fn, frame.f_lineno, frame.f_code.co_name, event
-+ print(fn, frame.f_lineno, frame.f_code.co_name, event, file=trace_file)
- return trace_local
-
- def enable_trace(level):
- global trace_file
- global trace_local
-
-- trace_file = file("trace.txt", "w", 1)
-+ trace_file = open("trace.txt", "w", 1)
-
- if level > 1:
- trace_local = trace_function
-@@ -137,13 +137,13 @@ def bootstrap(renpy_base):
- if os.environ.get("SDL_VIDEODRIVER", "") == "windib":
- del os.environ["SDL_VIDEODRIVER"]
-
-- renpy_base = unicode(renpy_base, FSENCODING, "replace")
-+ renpy_base = str(renpy_base.encode(errors="replace"), FSENCODING, "replace")
-
- # If environment.txt exists, load it into the os.environ dictionary.
- if os.path.exists(renpy_base + "/environment.txt"):
- evars = { }
-- execfile(renpy_base + "/environment.txt", evars)
-- for k, v in evars.iteritems():
-+ exec(compile(open(renpy_base + "/environment.txt").read(), renpy_base + "/environment.txt", 'exec'), evars)
-+ for k, v in evars.items():
- if k not in os.environ:
- os.environ[k] = str(v)
-
-@@ -155,8 +155,8 @@ def bootstrap(renpy_base):
-
- if os.path.exists(alt_path + "/environment.txt"):
- evars = { }
-- execfile(alt_path + "/environment.txt", evars)
-- for k, v in evars.iteritems():
-+ exec(compile(open(alt_path + "/environment.txt").read(), alt_path + "/environment.txt", 'exec'), evars)
-+ for k, v in evars.items():
- if k not in os.environ:
- os.environ[k] = str(v)
-
-@@ -226,14 +226,14 @@ def bootstrap(renpy_base):
- import pygame_sdl2
- pygame_sdl2.import_as_pygame()
- except:
-- print >>sys.stderr, """\
-+ print("""\
- Could not import pygame_sdl2. Please ensure that this program has been built
- and unpacked properly. Also, make sure that the directories containing
- this program do not contain : or ; in their names.
-
- You may be using a system install of python. Please run {0}.sh,
- {0}.exe, or {0}.app instead.
--""".format(name)
-+""".format(name), file=sys.stderr)
-
- raise
-
-@@ -241,13 +241,13 @@ You may be using a system install of python. Please run {0}.sh,
- try:
- import _renpy; _renpy
- except:
-- print >>sys.stderr, """\
-+ print("""\
- Could not import _renpy. Please ensure that this program has been built
- and unpacked properly.
-
- You may be using a system install of python. Please run {0}.sh,
- {0}.exe, or {0}.app instead.
--""".format(name)
-+""".format(name), file=sys.stderr)
- raise
-
- # Load up all of Ren'Py, in the right order.
-@@ -276,7 +276,7 @@ You may be using a system install of python. Please run {0}.sh,
- renpy.config.logdir = basedir
-
- if not os.path.exists(renpy.config.logdir):
-- os.makedirs(renpy.config.logdir, 0777)
-+ os.makedirs(renpy.config.logdir, 0o777)
-
- renpy.main.main()
-
-@@ -304,7 +304,7 @@ You may be using a system install of python. Please run {0}.sh,
- except renpy.game.ParseErrorException:
- pass
-
-- except Exception, e:
-+ except Exception as e:
- renpy.error.report_exception(e)
- pass
-
-diff --git a/renpy/character.py b/renpy/character.py
-index 2d36bbc..1fc049d 100644
---- a/renpy/character.py
-+++ b/renpy/character.py
-@@ -56,12 +56,12 @@ class DialogueTextTags(object):
- while True:
-
- try:
-- self.text += i.next()
-+ self.text += next(i)
-
-- quoted = i.next()
-- full_tag = i.next()
-- tag = i.next()
-- value = i.next()
-+ quoted = next(i)
-+ full_tag = next(i)
-+ tag = next(i)
-+ value = next(i)
-
- if value is not None:
- value = float(value)
-@@ -152,7 +152,7 @@ def compute_widget_properties(who_args, what_args, window_args, variant=None):
-
- style = d["style"]
-
-- if isinstance(style, basestring):
-+ if isinstance(style, str):
- style = getattr(renpy.store.style, style)
-
- if variant is not None:
-@@ -230,7 +230,7 @@ def show_display_say(who, what, who_args={}, what_args={}, window_args={},
-
- def merge_style(style, properties):
-
-- if isinstance(style, basestring):
-+ if isinstance(style, str):
- style = getattr(renpy.store.style, style)
-
- if variant is not None:
-@@ -764,7 +764,7 @@ class ADVCharacter(object):
- if not (self.condition is None or renpy.python.py_eval(self.condition)):
- return True
-
-- if not isinstance(what, basestring):
-+ if not isinstance(what, str):
- raise Exception("Character expects its what argument to be a string, got %r." % (what,))
-
- self.resolve_say_attributes(False)
-@@ -831,7 +831,7 @@ class ADVCharacter(object):
- self.do_done(who, what)
-
- # Finally, log this line of dialogue.
-- if who and isinstance(who, (str, unicode)):
-+ if who and isinstance(who, str):
- renpy.exports.log(who)
- renpy.exports.log(what)
- renpy.exports.log("")
-diff --git a/renpy/color.py b/renpy/color.py
-index 4bde2af..8df0c64 100644
---- a/renpy/color.py
-+++ b/renpy/color.py
-@@ -123,7 +123,7 @@ class Color(tuple):
- if len(c) == 3:
- return tuple.__new__(cls, c + (int(255 * alpha),))
-
-- if isinstance(c, basestring):
-+ if isinstance(c, str):
- if c[0] == '#':
- c = c[1:]
-
-@@ -308,7 +308,7 @@ class Color(tuple):
- `other` may be a string, Color or an HSV tuple.
- """
-
-- if isinstance(other, basestring):
-+ if isinstance(other, str):
- other = Color(other, alpha=self.alpha)
- elif not isinstance(other, Color):
- other = Color(hsv=other, alpha=self.alpha)
-@@ -330,7 +330,7 @@ class Color(tuple):
- `other` may be a string, Color or an HLS tuple.
- """
-
-- if isinstance(other, basestring):
-+ if isinstance(other, str):
- other = Color(other, alpha=self.alpha)
- elif not isinstance(other, Color):
- other = Color(hls=other, alpha=self.alpha)
-diff --git a/renpy/common/00updater.rpy b/renpy/common/00updater.rpy
-index b18dce0..6a35d66 100644
---- a/renpy/common/00updater.rpy
-+++ b/renpy/common/00updater.rpy
-@@ -93,7 +93,7 @@ init -1500 python in updater:
- time.sleep(3)
-
- try:
-- log = file(DEFERRED_UPDATE_LOG, "ab")
-+ log = open(DEFERRED_UPDATE_LOG, "ab")
- except:
- log = StringIO.StringIO()
-
-@@ -919,7 +919,7 @@ init -1500 python in updater:
- break
-
- try:
-- f = file(new_fn + ".part", "rb")
-+ f = open(new_fn + ".part", "rb")
- except:
- self.log.write("partfile does not exist\n")
- continue
-@@ -1046,7 +1046,7 @@ init -1500 python in updater:
- # Extract regular files.
- tff = tf.extractfile(info)
- new_path = path + ".new"
-- f = file(new_path, "wb")
-+ f = open(new_path, "wb")
-
- while True:
- data = tff.read(1024 * 1024)
-diff --git a/renpy/common/_developer/developer.rpym b/renpy/common/_developer/developer.rpym
-index 27922d0..d3377c4 100644
---- a/renpy/common/_developer/developer.rpym
-+++ b/renpy/common/_developer/developer.rpym
-@@ -496,7 +496,7 @@ label _filename_list:
-
- python hide:
- import os
-- f = file("files.txt", "w")
-+ f = open("files.txt", "w")
-
- for dirname, dirs, files in os.walk(config.gamedir):
-
-diff --git a/renpy/curry.py b/renpy/curry.py
-index f7266bf..4b47eaa 100644
---- a/renpy/curry.py
-+++ b/renpy/curry.py
-@@ -35,7 +35,7 @@ class Curry(object):
-
- def __call__(self, *args, **kwargs):
- return self.callable(*(self.args + args),
-- **dict(self.kwargs.items() + kwargs.items()))
-+ **dict(list(self.kwargs.items()) + list(kwargs.items())))
- def __repr__(self):
- return "<curry %s %r %r>" % (self.callable, self.args, self.kwargs)
-
-diff --git a/renpy/display/anim.py b/renpy/display/anim.py
-index 70c8fe4..fc31002 100644
---- a/renpy/display/anim.py
-+++ b/renpy/display/anim.py
-@@ -120,7 +120,7 @@ class Edge(object):
- self.prob = prob
-
- def add(self, sma):
-- for _i in xrange(0, self.prob):
-+ for _i in range(0, self.prob):
- sma.edges.setdefault(self.old, []).append(self)
-
-
-@@ -201,7 +201,7 @@ class SMAnimation(renpy.display.core.Displayable):
- self.state = None
-
- def visit(self):
-- return [ i.image for i in self.states.itervalues() ]
-+ return [ i.image for i in self.states.values() ]
-
- def pick_edge(self, state):
- """
-@@ -304,10 +304,10 @@ class SMAnimation(renpy.display.core.Displayable):
-
- args = [ ]
-
-- for state in self.states.itervalues():
-+ for state in self.states.values():
- args.append(state.motion_copy(child))
-
-- for edges in self.edges.itervalues():
-+ for edges in self.edges.values():
- args.extend(edges)
-
- return SMAnimation(self.initial, delay=self.delay, *args, **self.properties)
-diff --git a/renpy/display/behavior.py b/renpy/display/behavior.py
-index e325abb..7c8849b 100644
---- a/renpy/display/behavior.py
-+++ b/renpy/display/behavior.py
-@@ -30,6 +30,7 @@ from renpy.display.render import render, Render
- import pygame_sdl2 as pygame
-
- import math
-+import collections
-
- def compile_event(key, keydown):
- """
-@@ -395,7 +396,7 @@ class Keymap(renpy.display.layout.Null):
-
- def event(self, ev, x, y, st):
-
-- for name, action in self.keymap.iteritems():
-+ for name, action in self.keymap.items():
- if map_event(ev, name):
-
- if self.style.activate_sound:
-@@ -409,7 +410,7 @@ class Keymap(renpy.display.layout.Null):
- raise renpy.display.core.IgnoreEvent()
-
- def predict_one_action(self):
-- for i in self.keymap.itervalues():
-+ for i in self.keymap.values():
- predict_action(i)
-
-
-@@ -634,7 +635,7 @@ class Button(renpy.display.layout.Window):
- predict_action(self.alternate)
-
- if self.keymap:
-- for v in self.keymap.itervalues():
-+ for v in self.keymap.values():
- predict_action(v)
-
- def render(self, width, height, st, at):
-@@ -663,7 +664,7 @@ class Button(renpy.display.layout.Window):
- try:
- mask = renpy.display.render.render(mask, rv.width, rv.height, st, at)
- except:
-- if callable(mask):
-+ if isinstance(mask, collections.Callable):
- mask = mask
- else:
- raise Exception("Focus_mask must be None, True, a displayable, or a callable.")
-@@ -776,7 +777,7 @@ class Button(renpy.display.layout.Window):
- return None
-
- # Check the keymap.
-- for name, action in self.keymap.iteritems():
-+ for name, action in self.keymap.items():
- if map_event(ev, name):
- return run(action)
-
-@@ -881,7 +882,7 @@ class ImageButton(Button):
- **properties)
-
- def visit(self):
-- return self.state_children.values()
-+ return list(self.state_children.values())
-
- def get_child(self):
- return self.style.child or self.state_children[self.style.prefix]
-@@ -910,8 +911,8 @@ class Input(renpy.text.text.Text): #@UndefinedVariable
- caret_pos = 0
- old_caret_pos = 0
- pixel_width = None
-- default = u""
-- edit_text = u""
-+ default = ""
-+ edit_text = ""
-
- def __init__(self,
- default="",
-@@ -930,7 +931,7 @@ class Input(renpy.text.text.Text): #@UndefinedVariable
-
- super(Input, self).__init__("", style=style, replaces=replaces, substitute=False, **properties)
-
-- self.default = unicode(default)
-+ self.default = str(default)
- self.content = self.default
-
- self.length = length
-@@ -1017,7 +1018,7 @@ class Input(renpy.text.text.Text): #@UndefinedVariable
- def set_content(content):
-
- if content == "":
-- content = u"\u200b"
-+ content = "\u200b"
-
- if editable:
- l = len(content)
-@@ -1131,8 +1132,8 @@ class Input(renpy.text.text.Text): #@UndefinedVariable
- raw_text = ev.text
-
- elif ev.type == pygame.KEYDOWN:
-- if ev.unicode and ord(ev.unicode[0]) >= 32:
-- raw_text = ev.unicode
-+ if ev.str and ord(ev.str[0]) >= 32:
-+ raw_text = ev.str
- elif renpy.display.interface.text_event_in_queue():
- raw_text = ''
-
-diff --git a/renpy/display/core.py b/renpy/display/core.py
-index 5462336..3b708b8 100644
---- a/renpy/display/core.py
-+++ b/renpy/display/core.py
-@@ -31,7 +31,7 @@ import pygame_sdl2 as pygame
- import sys
- import os
- import time
--import cStringIO
-+import io
- import threading
-
- import_time = time.time()
-@@ -276,7 +276,7 @@ class Displayable(renpy.object.Object):
- return self.__class__.__name__
-
- def __repr__(self):
-- return "<{} at {:x}>".format(unicode(self).encode("utf-8"), id(self))
-+ return "<{} at {:x}>".format(str(self).encode("utf-8"), id(self))
-
- def find_focusable(self, callback, focus_name):
-
-@@ -963,7 +963,7 @@ class SceneLists(renpy.object.Object):
- """
-
- rv = [ ]
-- for l in self.layers.itervalues():
-+ for l in self.layers.values():
- for sle in l:
- rv.append(sle.displayable)
-
-@@ -976,7 +976,7 @@ class SceneLists(renpy.object.Object):
- be displayed, or everything will be removed.
- """
-
-- for i in reversed(xrange(len(self.layers[layer]))):
-+ for i in reversed(range(len(self.layers[layer]))):
-
- sle = self.layers[layer][i]
-
-@@ -1031,7 +1031,7 @@ class SceneLists(renpy.object.Object):
-
- # Have to iterate in reverse order, since otherwise
- # the indexes might change.
-- for i in reversed(xrange(len(self.layers[layer]))):
-+ for i in reversed(range(len(self.layers[layer]))):
- self.hide_or_replace(layer, i, hide)
-
- self.at_list[layer].clear()
-@@ -1047,10 +1047,10 @@ class SceneLists(renpy.object.Object):
- time with the given time.
- """
-
-- for l, (t, list) in self.layer_at_list.items(): #@ReservedAssignment
-+ for l, (t, list) in list(self.layer_at_list.items()): #@ReservedAssignment
- self.layer_at_list[l] = (t or time, list)
-
-- for l, ll in self.layers.iteritems():
-+ for l, ll in self.layers.items():
- self.layers[l] = [ i.update_time(time) for i in ll ]
-
- def showing(self, layer, name):
-@@ -1590,7 +1590,7 @@ class Interface(object):
- renpy.display.log.write(s)
-
- if renpy.android and not renpy.config.log_to_stdout:
-- print s
-+ print(s)
-
- def post_init(self):
- """
-@@ -1893,7 +1893,7 @@ class Interface(object):
-
- self.screenshot_surface = surf
-
-- sio = cStringIO.StringIO()
-+ sio = io.StringIO()
- renpy.display.module.save_png(surf, sio, 0)
- self.screenshot = sio.getvalue()
- sio.close()
-@@ -2006,7 +2006,7 @@ class Interface(object):
- scene_lists = renpy.game.context().scene_lists
-
- # Compute the scene.
-- for layer, d in self.compute_scene(scene_lists).iteritems():
-+ for layer, d in self.compute_scene(scene_lists).items():
- if layer not in self.transition:
- self.old_scene[layer] = d
-
-@@ -2243,7 +2243,7 @@ class Interface(object):
-
- renpy.exports.free_memory()
-
-- print "Entered background."
-+ print("Entered background.")
-
- while True:
- ev = pygame.event.wait()
-@@ -2254,7 +2254,7 @@ class Interface(object):
- if ev.type == pygame.APP_TERMINATING:
- sys.exit(0)
-
-- print "Entering foreground."
-+ print("Entering foreground.")
-
- # Since we came back to life, we can get rid of the
- # auto-reload.
-@@ -2583,7 +2583,7 @@ class Interface(object):
- renpy.display.tts.set_root(scene[None])
-
- # If necessary, load all images here.
-- for w in scene.itervalues():
-+ for w in scene.values():
- try:
- renpy.display.predict.displayable(w)
- except:
-@@ -2766,7 +2766,7 @@ class Interface(object):
-
- if first_pass:
- scene_lists.set_times(self.interact_time)
-- for k, v in self.transition_time.iteritems():
-+ for k, v in self.transition_time.items():
- if v is None:
- self.transition_time[k] = self.interact_time
-
-@@ -2777,8 +2777,8 @@ class Interface(object):
- new_time = get_time()
-
- if self.profile_once or (new_time - self.profile_time > .015):
-- print "Profile: Redraw took %.3f ms." % (1000 * (new_time - self.frame_time))
-- print "Profile: %.3f ms to complete event." % (1000 * (new_time - self.profile_time))
-+ print("Profile: Redraw took %.3f ms." % (1000 * (new_time - self.frame_time)))
-+ print("Profile: %.3f ms to complete event." % (1000 * (new_time - self.profile_time)))
-
- self.profile_once = False
-
-diff --git a/renpy/display/dragdrop.py b/renpy/display/dragdrop.py
-index 8816ee0..34aed98 100644
---- a/renpy/display/dragdrop.py
-+++ b/renpy/display/dragdrop.py
-@@ -28,6 +28,7 @@ from renpy.display.core import absolute
- from renpy.display.behavior import map_event, run, run_unhovered
-
- import pygame_sdl2 as pygame
-+import collections
-
- def default_drag_group():
- """
-@@ -449,7 +450,7 @@ class Drag(renpy.display.core.Displayable, renpy.python.RevertableObject):
- try:
- mask = renpy.display.render.render(mask, fw, fh, st, at)
- except:
-- if callable(mask):
-+ if isinstance(mask, collections.Callable):
- mask = mask
- else:
- raise Exception("Focus_mask must be None, True, a displayable, or a callable.")
-diff --git a/renpy/display/im.py b/renpy/display/im.py
-index de4a043..52f22d5 100644
---- a/renpy/display/im.py
-+++ b/renpy/display/im.py
-@@ -27,7 +27,7 @@ import renpy.display
-
- import math
- import zipfile
--import cStringIO
-+import io
- import threading
- import time
-
-@@ -266,7 +266,7 @@ class Cache(object):
- # If we're outside the cache limit, we need to go and start
- # killing off some of the entries until we're back inside it.
-
-- for ce in sorted(self.cache.itervalues(), key=lambda a : a.time):
-+ for ce in sorted(iter(self.cache.values()), key=lambda a : a.time):
-
- if ce.time == self.time:
- # If we're bigger than the limit, and there's nothing
-@@ -375,7 +375,7 @@ class Cache(object):
-
- # Remove things that are not in the workset from the pin cache,
- # and remove things that are in the workset from pin cache.
-- for i in self.pin_cache.keys():
-+ for i in list(self.pin_cache.keys()):
-
- if i in workset:
- workset.remove(i)
-@@ -509,9 +509,9 @@ class Image(ImageBase):
-
- def __unicode__(self):
- if len(self.filename) < 20:
-- return u"Image %r" % self.filename
-+ return "Image %r" % self.filename
- else:
-- return u"Image \u2026%s" % self.filename[-20:]
-+ return "Image \u2026%s" % self.filename[-20:]
-
-
- def get_hash(self):
-@@ -530,7 +530,7 @@ class Image(ImageBase):
-
- return surf
-
-- except Exception, e:
-+ except Exception as e:
-
- if renpy.config.missing_image_callback:
- im = renpy.config.missing_image_callback(self.filename)
-@@ -565,7 +565,7 @@ class ZipFileImage(ImageBase):
- try:
- zf = zipfile.ZipFile(self.zipfilename, 'r')
- data = zf.read(self.filename)
-- sio = cStringIO.StringIO(data)
-+ sio = io.StringIO(data)
- rv = renpy.display.pgrender.load_image(sio, self.filename)
- zf.close()
- return rv
-@@ -1562,7 +1562,7 @@ def image(arg, loose=False, **properties):
- if isinstance(arg, ImageBase):
- return arg
-
-- elif isinstance(arg, basestring):
-+ elif isinstance(arg, str):
- return Image(arg, **properties)
-
- elif isinstance(arg, renpy.display.image.ImageReference):
-@@ -1608,7 +1608,7 @@ def load_surface(im):
-
-
- def reset_module():
-- print "Resetting cache."
-+ print("Resetting cache.")
-
- global cache
- cache = Cache()
-diff --git a/renpy/display/image.py b/renpy/display/image.py
-index e5ae353..64574c3 100644
---- a/renpy/display/image.py
-+++ b/renpy/display/image.py
-@@ -45,7 +45,7 @@ def get_available_image_tags():
- Returns a list of image tags that have been defined.
- """
-
-- return [ k for k, v in image_attributes.items() if v ]
-+ return [ k for k, v in list(image_attributes.items()) if v ]
-
- def get_available_image_attributes(tag, attributes=()):
- """
-@@ -149,7 +149,7 @@ class ImageReference(renpy.display.core.Displayable):
- self.name = name
-
- def __unicode__(self):
-- return u"<ImageReference {!r}>".format(self.name)
-+ return "<ImageReference {!r}>".format(self.name)
-
- def __hash__(self):
- return hash(self.name)
-@@ -215,7 +215,7 @@ class ImageReference(renpy.display.core.Displayable):
-
- self.param_target = self.target
-
-- except Exception, e:
-+ except Exception as e:
- if renpy.config.debug:
- raise
-
-@@ -323,7 +323,7 @@ class DynamicImage(renpy.display.core.Displayable):
- return self.find_target(scope, update)
-
- def __unicode__(self):
-- return u"DynamicImage {!r}".format(self.name)
-+ return "DynamicImage {!r}".format(self.name)
-
- def __hash__(self):
- return hash(self.name)
-@@ -514,7 +514,7 @@ class ShownImageInfo(renpy.object.Object):
- if layer is None:
- layer = 'master'
-
-- for l, t in self.attributes.keys():
-+ for l, t in list(self.attributes.keys()):
- if l == layer:
- del self.attributes[l, t]
-
-diff --git a/renpy/display/imagelike.py b/renpy/display/imagelike.py
-index d8b9201..3f9a6b3 100644
---- a/renpy/display/imagelike.py
-+++ b/renpy/display/imagelike.py
-@@ -275,8 +275,8 @@ class Frame(renpy.display.core.Displayable):
- newcr = Render(cdw, cdh)
- newcr.clipping = True
-
-- for x in xrange(0, cdw, csw):
-- for y in xrange(0, cdh, csh):
-+ for x in range(0, cdw, csw):
-+ for y in range(0, cdh, csh):
- newcr.blit(cr, (x, y))
-
- cr = newcr
-diff --git a/renpy/display/layout.py b/renpy/display/layout.py
-index 7ded388..3b2fd9f 100644
---- a/renpy/display/layout.py
-+++ b/renpy/display/layout.py
-@@ -180,7 +180,7 @@ class Container(renpy.display.core.Displayable):
- if len(offsets) != len(children):
- return None
-
-- for i in xrange(len(offsets) - 1, -1, -1):
-+ for i in range(len(offsets) - 1, -1, -1):
-
- d = children[i]
- xo, yo = offsets[i]
-@@ -641,9 +641,9 @@ class MultiBox(Container):
- rv = None
-
- if self.style.order_reverse:
-- iterator = zip(reversed(self.children), reversed(csts), reversed(cats))
-+ iterator = list(zip(reversed(self.children), reversed(csts), reversed(cats)))
- else:
-- iterator = zip(self.children, csts, cats)
-+ iterator = list(zip(self.children, csts, cats))
-
- for child, cst, cat in iterator:
-
-@@ -889,7 +889,7 @@ class MultiBox(Container):
-
- def event(self, ev, x, y, st):
-
-- children_offsets = zip(self.children, self.offsets, self.start_times)
-+ children_offsets = list(zip(self.children, self.offsets, self.start_times))
-
- if not self.style.order_reverse:
- children_offsets.reverse()
-@@ -1126,7 +1126,7 @@ class DynamicDisplayable(renpy.display.core.Displayable):
- super(DynamicDisplayable, self).__init__()
- self.child = None
-
-- if isinstance(function, basestring):
-+ if isinstance(function, str):
- args = ( function, )
- kwargs = { }
- function = dynamic_displayable_compat
-@@ -1669,7 +1669,7 @@ class Side(Container):
-
- super(Side, self).__init__(style=style, **properties)
-
-- if isinstance(positions, basestring):
-+ if isinstance(positions, str):
- positions = positions.split()
-
- seen = set()
-diff --git a/renpy/display/module.py b/renpy/display/module.py
-index 24c0f7d..de7ad91 100644
---- a/renpy/display/module.py
-+++ b/renpy/display/module.py
-@@ -172,11 +172,11 @@ def twomap(src, dst, white, black):
- wb + 1,
- wa + 1)
- else:
-- map(src, dst,
-+ list(map(src, dst,
- ramp(br, wr),
- ramp(bg, wg),
- ramp(bb, wb),
-- ramp(0, wa))
-+ ramp(0, wa)))
-
-
- def alpha_munge(src, dst, amap):
-diff --git a/renpy/display/motion.py b/renpy/display/motion.py
-index c80ae9e..d24b2d8 100644
---- a/renpy/display/motion.py
-+++ b/renpy/display/motion.py
-@@ -542,7 +542,7 @@ class Transform(Container):
- self.arguments = { }
-
- # Fill self.arguments with a
-- for k, v in kwargs.iteritems():
-+ for k, v in kwargs.items():
-
- prefix = ""
- prop = k
-@@ -568,7 +568,7 @@ class Transform(Container):
- prefix = new_prefix
-
- if "" in self.arguments:
-- for k, v in self.arguments[""].iteritems():
-+ for k, v in self.arguments[""].items():
- setattr(self.state, k, v)
-
- else:
-@@ -627,7 +627,7 @@ class Transform(Container):
- if d is None:
- continue
-
-- for k, v in d.iteritems():
-+ for k, v in d.items():
- setattr(state, k, v)
-
- return None
-@@ -803,7 +803,7 @@ class Transform(Container):
- if not offsets:
- return None
-
-- for i in xrange(len(self.children)-1, -1, -1):
-+ for i in range(len(self.children)-1, -1, -1):
-
- d = children[i]
- xo, yo = offsets[i]
-@@ -1221,10 +1221,11 @@ class Revolver(object):
- self.pos = pos
- self.child = child
-
-- def __call__(self, t, (w, h, cw, ch)):
-+ def __call__(self, t, xxx_todo_changeme):
-
- # Converts a float to an integer in the given range, passes
- # integers through unchanged.
-+ (w, h, cw, ch) = xxx_todo_changeme
- def fti(x, r):
- if x is None:
- x = 0
-diff --git a/renpy/display/particle.py b/renpy/display/particle.py
-index f821dc8..959fce1 100644
---- a/renpy/display/particle.py
-+++ b/renpy/display/particle.py
-@@ -295,7 +295,7 @@ class SpriteManager(renpy.display.core.Displayable):
- return rv
-
- def event(self, ev, x, y, st):
-- for i in xrange(len(self.children) -1, -1, -1):
-+ for i in range(len(self.children) -1, -1, -1):
- s = self.children[i]
-
- if s.events:
-@@ -432,7 +432,7 @@ class SnowBlossomFactory(renpy.python.NoRollback):
- self.init()
-
- def init(self):
-- self.starts = [ random.uniform(0, self.start) for _i in xrange(0, self.count) ] # W0201
-+ self.starts = [ random.uniform(0, self.start) for _i in range(0, self.count) ] # W0201
- self.starts.append(self.start)
- self.starts.sort()
-
-@@ -447,7 +447,7 @@ class SnowBlossomFactory(renpy.python.NoRollback):
- if (st == 0) and not particles and self.fast:
- rv = [ ]
-
-- for _i in xrange(0, self.count):
-+ for _i in range(0, self.count):
- rv.append(SnowBlossomParticle(self.image,
- ranged(self.xspeed),
- ranged(self.yspeed),
-diff --git a/renpy/display/pgrender.py b/renpy/display/pgrender.py
-index 9418095..c86000e 100644
---- a/renpy/display/pgrender.py
-+++ b/renpy/display/pgrender.py
-@@ -87,14 +87,14 @@ class Surface(pygame.Surface):
- rv = pygame.Surface.subsurface(self, rect)
- return rv
-
--def surface((width, height), alpha):
-+def surface(xxx_todo_changeme, alpha):
- """
- Constructs a new surface. The allocated surface is actually a subsurface
- of a surface that has a 2 pixel border in all directions.
-
- `alpha` - True if the new surface should have an alpha channel.
- """
--
-+ (width, height) = xxx_todo_changeme
- if isinstance(alpha, pygame.Surface):
- alpha = alpha.get_masks()[3]
-
-diff --git a/renpy/display/predict.py b/renpy/display/predict.py
-index 2b37a9f..305e0b5 100644
---- a/renpy/display/predict.py
-+++ b/renpy/display/predict.py
-@@ -120,7 +120,7 @@ def prediction_coroutine(root_widget):
- if len(renpy.game.contexts) >= 2:
- sls = renpy.game.contexts[-2].scene_lists
-
-- for l in sls.layers.itervalues():
-+ for l in sls.layers.values():
- for sle in l:
- try:
- displayable(sle.displayable)
-@@ -138,7 +138,7 @@ def prediction_coroutine(root_widget):
-
-
- # Predict screens given with renpy.start_predict_screen.
-- for name, value in renpy.store._predict_screen.items():
-+ for name, value in list(renpy.store._predict_screen.items()):
- args, kwargs = value
-
- renpy.display.screen.predict_screen(name, *args, **kwargs)
-diff --git a/renpy/display/screen.py b/renpy/display/screen.py
-index 585c6bf..622ba60 100644
---- a/renpy/display/screen.py
-+++ b/renpy/display/screen.py
-@@ -103,7 +103,7 @@ class ScreenProfile(renpy.object.Object):
- self.const = const
-
- if name is not None:
-- if isinstance(name, basestring):
-+ if isinstance(name, str):
- name = tuple(name.split())
- profile[name] = self
-
-@@ -116,7 +116,7 @@ def get_profile(name):
- A string or tuple.
- """
-
-- if isinstance(name, basestring):
-+ if isinstance(name, str):
- name = tuple(name.split())
-
- if name in profile:
-@@ -202,7 +202,7 @@ class Screen(renpy.object.Object):
- location=None):
-
- # The name of this screen.
-- if isinstance(name, basestring):
-+ if isinstance(name, str):
- name = tuple(name.split())
-
- self.name = name
-@@ -700,7 +700,7 @@ def get_all_screen_variants(name):
-
- rv = [ ]
-
-- for k, v in screens.iteritems():
-+ for k, v in screens.items():
- if k[0] == name:
- rv.append((k[1], v))
-
-@@ -733,7 +733,7 @@ def sort_screens():
- # For each screen, the set of screens that use it.
- reverse = collections.defaultdict(set)
-
-- for k, v in screens.items():
-+ for k, v in list(screens.items()):
-
- name = k[0]
-
-@@ -751,7 +751,7 @@ def sort_screens():
-
- rv = [ ]
-
-- workset = { k for k, v in depends.items() if not len(v) }
-+ workset = { k for k, v in list(depends.items()) if not len(v) }
-
- while workset:
- name = workset.pop()
-@@ -782,7 +782,7 @@ def sorted_variants():
- rv = [ ]
-
- for name in sort_screens():
-- rv.extend(screens_by_name[name].values())
-+ rv.extend(list(screens_by_name[name].values()))
-
- return rv
-
-@@ -892,7 +892,7 @@ def get_screen(name, layer="screens"):
-
- """
-
-- if isinstance(name, basestring):
-+ if isinstance(name, str):
- name = (name, )
-
- sl = renpy.exports.scene_lists()
-@@ -1057,7 +1057,7 @@ def predict_screen(_screen_name, *_args, **kwargs):
- if renpy.config.debug_image_cache:
- import traceback
-
-- print "While predicting screen", _screen_name
-+ print("While predicting screen", _screen_name)
- traceback.print_exc()
-
- renpy.ui.reset()
-@@ -1175,7 +1175,7 @@ def before_restart():
- longer defined.
- """
-
-- for k, layer in renpy.display.interface.old_scene.iteritems():
-+ for k, layer in renpy.display.interface.old_scene.items():
- if k is None:
- continue
-
-diff --git a/renpy/display/swdraw.py b/renpy/display/swdraw.py
-index 1f620f1..a90e524 100644
---- a/renpy/display/swdraw.py
-+++ b/renpy/display/swdraw.py
-@@ -303,7 +303,7 @@ def draw_special(what, dest, x, y):
-
- ramp = "\x00" * 256
-
-- for i in xrange(0, ramplen):
-+ for i in range(0, ramplen):
- ramp += chr(255 * i / ramplen)
-
- ramp += "\xff" * 256
-diff --git a/renpy/dump.py b/renpy/dump.py
-index f047146..c01a960 100644
---- a/renpy/dump.py
-+++ b/renpy/dump.py
-@@ -113,14 +113,14 @@ def dump(error):
- # Labels.
- label = location["label"] = { }
-
-- for name, n in renpy.game.script.namemap.iteritems():
-+ for name, n in renpy.game.script.namemap.items():
- filename = n.filename
- line = n.linenumber
-
-- if not isinstance(name, basestring):
-+ if not isinstance(name, str):
- continue
-
-- if not filter(name, filename):
-+ if not list(filter(name, filename)):
- continue
-
- label[name] = [ filename, line ]
-@@ -130,7 +130,7 @@ def dump(error):
- define = location["define"] = { }
-
- for name, filename, line in definitions:
-- if not filter(name, filename):
-+ if not list(filter(name, filename)):
- continue
-
- define[name] = [ filename, line ]
-@@ -139,7 +139,7 @@ def dump(error):
- screen = location["screen"] = { }
-
- for name, filename, line in screens:
-- if not filter(name, filename):
-+ if not list(filter(name, filename)):
- continue
-
- screen[name] = [ filename, line ]
-@@ -148,7 +148,7 @@ def dump(error):
- transform = location["transform"] = { }
-
- for name, filename, line in transforms:
-- if not filter(name, filename):
-+ if not list(filter(name, filename)):
- continue
-
- transform[name] = [ filename, line ]
-@@ -166,16 +166,16 @@ def dump(error):
- """
-
- if inspect.isfunction(o):
-- return inspect.getfile(o), o.func_code.co_firstlineno
-+ return inspect.getfile(o), o.__code__.co_firstlineno
-
- if inspect.ismethod(o):
-- return get_line(o.im_func)
-+ return get_line(o.__func__)
-
- return None, None
-
- code = location["callable"] = { }
-
-- for modname, mod in sys.modules.items():
-+ for modname, mod in list(sys.modules.items()):
-
- if mod is None:
- continue
-@@ -187,7 +187,7 @@ def dump(error):
- else:
- continue
-
-- for name, o in mod.__dict__.items():
-+ for name, o in list(mod.__dict__.items()):
-
- if inspect.isfunction(o):
- try:
-@@ -199,7 +199,7 @@ def dump(error):
- if filename is None:
- continue
-
-- if not filter(name, filename):
-+ if not list(filter(name, filename)):
- continue
-
- code[prefix + name] = [ filename, line ]
-@@ -208,7 +208,7 @@ def dump(error):
-
- if inspect.isclass(o):
-
-- for methname, method in o.__dict__.iteritems():
-+ for methname, method in o.__dict__.items():
-
- try:
- if inspect.getmodule(method) != mod:
-@@ -219,10 +219,10 @@ def dump(error):
- if filename is None:
- continue
-
-- if not filter(name, filename):
-+ if not list(filter(name, filename)):
- continue
-
-- if not filter(methname, filename):
-+ if not list(filter(methname, filename)):
- continue
-
- code[prefix + name + "." + methname] = [ filename, line ]
-@@ -236,7 +236,7 @@ def dump(error):
- pass
-
- if args.json_dump != "-":
-- with file(args.json_dump, "w") as f:
-+ with open(args.json_dump, "w") as f:
- json.dump(result, f)
- else:
- json.dump(result, sys.stdout, indent=2)
-diff --git a/renpy/easy.py b/renpy/easy.py
-index 6aacea1..85f3d17 100644
---- a/renpy/easy.py
-+++ b/renpy/easy.py
-@@ -36,7 +36,7 @@ def displayable_or_none(d, scope=None):
- if d is None:
- return d
-
-- if isinstance(d, basestring):
-+ if isinstance(d, str):
- if not d:
- raise Exception("An empty string cannot be used as a displayable.")
- elif ("[" in d) and renpy.config.dynamic_images:
-@@ -70,7 +70,7 @@ def displayable(d, scope=None):
- if isinstance(d, renpy.display.core.Displayable):
- return d
-
-- if isinstance(d, basestring):
-+ if isinstance(d, str):
- if not d:
- raise Exception("An empty string cannot be used as a displayable.")
- elif ("[" in d) and renpy.config.dynamic_images:
-@@ -97,7 +97,7 @@ def dynamic_image(d, scope=None):
- Substitutes a scope into `d`, then returns a displayable.
- """
-
-- if isinstance(d, basestring):
-+ if isinstance(d, str):
- d = renpy.substitutions.substitute(d, scope=scope, force=True, translate=False)[0]
-
- return displayable_or_none(d)
-@@ -114,7 +114,7 @@ def predict(d):
- def timed(name):
- start = time.time()
- yield
-- print "{0}: {1:.2f} ms".format(name, (time.time() - start) * 1000.0)
-+ print("{0}: {1:.2f} ms".format(name, (time.time() - start) * 1000.0))
-
-
- def split_properties(properties, *prefixes):
-@@ -145,7 +145,7 @@ def split_properties(properties, *prefixes):
-
- prefix_d = list(zip(prefixes, rv))
-
-- for k, v in properties.iteritems():
-+ for k, v in properties.items():
- for prefix, d in prefix_d:
- if k.startswith(prefix):
- d[k[len(prefix):]] = v
-diff --git a/renpy/editor.py b/renpy/editor.py
-index 7be4c32..bac80f7 100644
---- a/renpy/editor.py
-+++ b/renpy/editor.py
-@@ -114,7 +114,7 @@ def init():
- return
-
- scope = { "__file__" : path }
-- execfile(path, scope, scope)
-+ exec(compile(open(path).read(), path, 'exec'), scope, scope)
-
- if "Editor" in scope:
- editor = scope["Editor"]()
-diff --git a/renpy/error.py b/renpy/error.py
-index d70fe2a..513cd73 100644
---- a/renpy/error.py
-+++ b/renpy/error.py
-@@ -23,7 +23,7 @@
-
- import traceback
- import sys
--import cStringIO
-+import io
- import platform
- import linecache
-
-@@ -43,8 +43,8 @@ def write_utf8_traceback_list(out, l):
- for filename, line, what, text in l:
-
- # Filename is either unicode or an fsecoded string.
-- if not isinstance(filename, unicode):
-- filename = unicode(filename, FSENCODING, "replace")
-+ if not isinstance(filename, str):
-+ filename = str(filename, FSENCODING, "replace")
-
- # Line is a number.
-
-@@ -52,12 +52,12 @@ def write_utf8_traceback_list(out, l):
- # or comes from inside Ren'Py.
-
- if isinstance(text, str):
-- text = text.decode("utf-8", "replace")
-+ text = text.encode(errors="replace").decode("utf-8", "replace")
-
- ul.append((filename, line, what, text))
-
- for t in traceback.format_list(ul):
-- out.write(t.encode("utf-8", "replace"))
-+ out.write(str(t.encode("utf-8", "replace"), errors="replace"))
-
-
- def traceback_list(tb):
-@@ -127,13 +127,13 @@ def open_error_file(fn, mode):
-
- try:
- new_fn = os.path.join(renpy.config.logdir, fn)
-- f = file(new_fn, mode)
-+ f = open(new_fn, mode)
- return f, new_fn
- except:
- pass
-
- try:
-- f = file(fn, mode)
-+ f = open(fn, mode)
- return f, fn
- except:
- pass
-@@ -141,7 +141,7 @@ def open_error_file(fn, mode):
- import tempfile
-
- new_fn = os.path.join(tempfile.gettempdir(), "renpy-" + fn)
-- return file(new_fn, mode), new_fn
-+ return open(new_fn, mode), new_fn
-
- def report_exception(e, editor=True):
- """
-@@ -157,11 +157,11 @@ def report_exception(e, editor=True):
-
- type, _value, tb = sys.exc_info() #@ReservedAssignment
-
-- print(repr(e))
-+ print((repr(e)))
-
- def safe_utf8(e):
- try:
-- m = unicode(e)
-+ m = str(e)
- except:
- try:
- if len(e.args) == 0:
-@@ -176,27 +176,27 @@ def report_exception(e, editor=True):
- except:
- m = "<Could not encode exception.>"
-
-- if isinstance(m, unicode):
-+ if isinstance(m, str):
- return m.encode("utf-8", "replace")
- else:
- return m
-
- # Return values - which can be displayed to the user.
-- simple = cStringIO.StringIO()
-- full = cStringIO.StringIO()
-+ simple = io.StringIO()
-+ full = io.StringIO()
-
- full_tl = traceback_list(tb)
- simple_tl = filter_traceback_list(full_tl)
-
-- print >>simple, renpy.game.exception_info
-+ print(renpy.game.exception_info, file=simple)
- write_utf8_traceback_list(simple, simple_tl)
-- print >>simple, type.__name__ + ":",
-- print >>simple, safe_utf8(e)
-+ print(type.__name__ + ":", end=' ', file=simple)
-+ print(safe_utf8(e), file=simple)
-
-- print >>full, "Full traceback:"
-+ print("Full traceback:", file=full)
- write_utf8_traceback_list(full, full_tl)
-- print >>full, type.__name__ + ":",
-- print >>full, safe_utf8(e)
-+ print(type.__name__ + ":", end=' ', file=full)
-+ print(safe_utf8(e), file=full)
-
- # Write to stdout/stderr.
- sys.stdout.write("\n")
-@@ -204,11 +204,11 @@ def report_exception(e, editor=True):
- sys.stdout.write("\n")
- sys.stdout.write(simple.getvalue())
-
-- print >>full
-+ print(file=full)
- try:
-- print >>full, platform.platform()
-- print >>full, renpy.version
-- print >>full, renpy.config.name + " " + renpy.config.version
-+ print(platform.platform(), file=full)
-+ print(renpy.version, file=full)
-+ print(renpy.config.name + " " + renpy.config.version, file=full)
- except:
- pass
-
-@@ -223,14 +223,14 @@ def report_exception(e, editor=True):
-
- f.write(codecs.BOM_UTF8)
-
-- print >>f, "I'm sorry, but an uncaught exception occurred."
-- print >>f
-+ print("I'm sorry, but an uncaught exception occurred.", file=f)
-+ print(file=f)
-
- f.write(simple)
-
-- print >>f
-- print >>f, "-- Full Traceback ------------------------------------------------------------"
-- print >>f
-+ print(file=f)
-+ print("-- Full Traceback ------------------------------------------------------------", file=f)
-+ print(file=f)
-
- f.write(full)
- f.close()
-@@ -249,6 +249,6 @@ def report_exception(e, editor=True):
- except:
- pass
-
-- return simple.decode("utf-8", "replace"), full.decode("utf-8", "replace"), traceback_fn
-+ return simple.encode(errors="replace").decode("utf-8", "replace"), full.encode(errors="replace").decode("utf-8", "replace"), traceback_fn
-
-
-diff --git a/renpy/execution.py b/renpy/execution.py
-index 224c631..a41b59a 100644
---- a/renpy/execution.py
-+++ b/renpy/execution.py
-@@ -210,7 +210,7 @@ class Context(renpy.object.Object):
-
- vars(self.info).update(vars(context.info))
-
-- for k, v in context.music.iteritems():
-+ for k, v in context.music.items():
- self.music[k] = v.copy()
-
- self.images = renpy.display.image.ShownImageInfo(context.images)
-@@ -279,7 +279,7 @@ class Context(renpy.object.Object):
-
- dynamic = self.dynamic_stack.pop()
-
-- for k, v in dynamic.iteritems():
-+ for k, v in dynamic.items():
- if isinstance(v, Delete):
- del store[k]
- else:
-@@ -390,14 +390,14 @@ class Context(renpy.object.Object):
- if developer and self.next_node:
- self.check_stacks()
-
-- except renpy.game.CONTROL_EXCEPTIONS, e:
-+ except renpy.game.CONTROL_EXCEPTIONS as e:
-
- # An exception ends the current translation.
- self.translate_interaction = None
-
- raise
-
-- except Exception, e:
-+ except Exception as e:
- self.translate_interaction = None
-
- exc_info = sys.exc_info()
-@@ -408,18 +408,18 @@ class Context(renpy.object.Object):
- self.exception_handler(short, full, traceback_fn)
- elif renpy.display.error.report_exception(short, full, traceback_fn):
- raise
-- except renpy.game.CONTROL_EXCEPTIONS, ce:
-+ except renpy.game.CONTROL_EXCEPTIONS as ce:
- raise ce
-- except Exception, ce:
-- raise exc_info[0], exc_info[1], exc_info[2]
-+ except Exception as ce:
-+ raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
-
- node = self.next_node
-
-- except renpy.game.JumpException, e:
-+ except renpy.game.JumpException as e:
- node = renpy.game.script.lookup(e.args[0])
- self.abnormal = True
-
-- except renpy.game.CallException, e:
-+ except renpy.game.CallException as e:
-
- if self.next_node is None:
- raise Exception("renpy.call can't be used when the next node is undefined.")
-@@ -495,7 +495,7 @@ class Context(renpy.object.Object):
- if renpy.game.script.has_label(self.return_stack[-1]):
- node = renpy.game.script.lookup(self.return_stack[-1])
- elif renpy.game.script.has_label(self.call_location_stack[-1]):
-- node = renpy.game.script.lookup(self.call_location_stack[-1]).next
-+ node = renpy.game.script.lookup(self.call_location_stack[-1]).__next__
-
- if node is None:
-
-@@ -629,9 +629,9 @@ class Context(renpy.object.Object):
- if renpy.config.debug_image_cache:
- import traceback
-
-- print
-+ print()
- traceback.print_exc()
-- print "While predicting images."
-+ print("While predicting images.")
-
- self.images = old_images
- self.predict_return_stack = None
-diff --git a/renpy/exports.py b/renpy/exports.py
-index faccd36..82bc282 100644
---- a/renpy/exports.py
-+++ b/renpy/exports.py
-@@ -25,7 +25,7 @@
- # alone as part of the api.
-
- # Remember the real file.
--_file = file
-+_file = open
-
- import renpy.display
- import renpy.audio
-@@ -39,7 +39,7 @@ def renpy_pure(fn):
-
- name = fn
-
-- if not isinstance(name, basestring):
-+ if not isinstance(name, str):
- name = fn.__name__
-
- pure("renpy." + name)
-@@ -371,7 +371,7 @@ def copy_images(old, new):
-
- lenold = len(old)
-
-- for k, v in renpy.display.image.images.items():
-+ for k, v in list(renpy.display.image.images.items()):
- if len(k) < lenold:
- continue
-
-@@ -495,7 +495,7 @@ def predict_show(name, layer=None, what=None, tag=None, at_list=[ ]):
-
- if what is None:
- what = name
-- elif isinstance(what, basestring):
-+ elif isinstance(what, str):
- what = tuple(what.split())
-
- if isinstance(what, renpy.display.core.Displayable):
-@@ -593,7 +593,7 @@ def show(name, at_list=[ ], layer=None, what=None, zorder=None, tag=None, behind
-
- if what is None:
- what = name
-- elif isinstance(what, basestring):
-+ elif isinstance(what, str):
- what = tuple(what.split())
-
- if isinstance(what, renpy.display.core.Displayable):
-@@ -740,7 +740,7 @@ def input(prompt, default='', allow=None, exclude='{}', length=None, with_none=N
- renpy.exports.mode('input')
-
- roll_forward = renpy.exports.roll_forward_info()
-- if not isinstance(roll_forward, basestring):
-+ if not isinstance(roll_forward, str):
- roll_forward = None
-
- # use previous data in rollback
-@@ -1038,7 +1038,7 @@ class TagQuotingDict(object):
- if key in store:
- rv = store[key]
-
-- if isinstance(rv, (str, unicode)):
-+ if isinstance(rv, str):
- rv = rv.replace("{", "{{")
-
- return rv
-@@ -1060,7 +1060,7 @@ def predict_say(who, what):
- if who is None:
- who = renpy.store.narrator # E1101 @UndefinedVariable
-
-- if isinstance(who, (str, unicode)):
-+ if isinstance(who, str):
- return renpy.store.predict_say(who, what)
-
- predict = getattr(who, 'predict', None)
-@@ -1115,7 +1115,7 @@ def say(who, what, interact=True):
- if who is None:
- who = renpy.store.narrator # E1101 @UndefinedVariable
-
-- if isinstance(who, (str, unicode)):
-+ if isinstance(who, str):
- renpy.store.say(who, what, interact=interact)
- else:
- who(what, interact=interact)
-@@ -1444,8 +1444,8 @@ def get_all_labels():
- """
- rv = [ ]
-
-- for i in renpy.game.script.namemap.iterkeys():
-- if isinstance(i, basestring):
-+ for i in renpy.game.script.namemap.keys():
-+ if isinstance(i, str):
- rv.append(i)
-
- return renpy.python.RevertableSet(rv)
-@@ -1792,7 +1792,7 @@ def log(msg):
-
- import textwrap
-
-- print >>logfile, textwrap.fill(msg, renpy.config.log_width).encode("utf-8")
-+ print(textwrap.fill(msg, renpy.config.log_width).encode("utf-8"), file=logfile)
- logfile.flush()
-
- except:
-@@ -1908,7 +1908,7 @@ def seen_image(name):
- return name in renpy.game.persistent._seen_images # @UndefinedVariable
-
-
--def file(fn): #@ReservedAssignment
-+def open(fn): #@ReservedAssignment
- """
- :doc: file
-
-@@ -1958,7 +1958,7 @@ def get_at_list(name, layer=None):
- If `layer` is None, uses the default layer for the given tag.
- """
-
-- if isinstance(name, basestring):
-+ if isinstance(name, str):
- name = tuple(name.split())
-
- tag = name[0]
-@@ -2173,7 +2173,7 @@ def load_string(s, filename="<string>"):
- old_locked = renpy.config.locked
- renpy.config.locked = False
-
-- stmts, initcode = renpy.game.script.load_string(filename, unicode(s))
-+ stmts, initcode = renpy.game.script.load_string(filename, str(s))
-
- if stmts is None:
- return None
-@@ -2459,7 +2459,7 @@ def call_screen(_screen_name, *args, **kwargs):
-
- try:
- rv = renpy.ui.interact(mouse="screen", type="screen", roll_forward=roll_forward)
-- except (renpy.game.JumpException, renpy.game.CallException), e:
-+ except (renpy.game.JumpException, renpy.game.CallException) as e:
- rv = e
-
- renpy.exports.checkpoint(rv)
-@@ -2616,7 +2616,7 @@ def variant(name):
- returns True if any of the variants is selected.
- """
-
-- if isinstance(name, basestring):
-+ if isinstance(name, str):
- return name in renpy.config.variants
- else:
- for n in name:
-@@ -2745,7 +2745,7 @@ def fsencode(s):
- Converts s from unicode to the filesystem encoding.
- """
-
-- if not isinstance(s, unicode):
-+ if not isinstance(s, str):
- return s
-
- fsencoding = sys.getfilesystemencoding() or "utf-8"
-diff --git a/renpy/game.py b/renpy/game.py
-index d66800c..1ba0fe5 100644
---- a/renpy/game.py
-+++ b/renpy/game.py
-@@ -264,7 +264,7 @@ def invoke_in_new_context(callable, *args, **kwargs): #@ReservedAssignment
-
- return callable(*args, **kwargs)
-
-- except renpy.game.JumpOutException, e:
-+ except renpy.game.JumpOutException as e:
-
- raise renpy.game.JumpException(e.args[0])
-
-@@ -312,7 +312,7 @@ def call_in_new_context(label, *args, **kwargs):
- context.goto_label(label)
- return renpy.execution.run_context(False)
-
-- except renpy.game.JumpOutException, e:
-+ except renpy.game.JumpOutException as e:
-
- raise renpy.game.JumpException(e.args[0])
-
-@@ -350,7 +350,7 @@ def call_replay(label, scope={}):
-
- renpy.exports.execute_default_statement(True)
-
-- for k, v in scope.iteritems():
-+ for k, v in scope.items():
- setattr(renpy.store, k, v)
-
- renpy.store._in_replay = label
-diff --git a/renpy/lint.py b/renpy/lint.py
-index 088b89c..b6f131c 100644
---- a/renpy/lint.py
-+++ b/renpy/lint.py
-@@ -28,9 +28,9 @@ import sys
- import collections
- import textwrap
-
--import __builtin__
-+import builtins
-
--python_builtins = set(dir(__builtin__))
-+python_builtins = set(dir(builtins))
- renpy_builtins = set()
-
- image_prefixes = None
-@@ -53,13 +53,13 @@ report_node = None
- # Reports a message to the user.
- def report(msg, *args):
- if report_node:
-- out = u"%s:%d " % (renpy.parser.unicode_filename(report_node.filename), report_node.linenumber)
-+ out = "%s:%d " % (renpy.parser.unicode_filename(report_node.filename), report_node.linenumber)
- else:
- out = ""
-
- out += msg % args
-- print
-- print out.encode('utf-8')
-+ print()
-+ print(out.encode('utf-8'))
-
- added = { }
-
-@@ -68,7 +68,7 @@ added = { }
- def add(msg):
- if not msg in added:
- added[msg] = True
-- print unicode(msg).encode('utf-8')
-+ print(str(msg).encode('utf-8'))
-
-
- # Trys to evaluate an expression, announcing an error if it fails.
-@@ -473,7 +473,7 @@ def check_define(node, kind):
- def check_style(name, s):
-
- for p in s.properties:
-- for k, v in p.iteritems():
-+ for k, v in p.items():
-
- kname = name + ", property " + k
-
-@@ -504,7 +504,7 @@ def check_label(node):
-
-
- def check_styles():
-- for full_name, s in renpy.style.styles.iteritems(): # @UndefinedVariable
-+ for full_name, s in renpy.style.styles.items(): # @UndefinedVariable
- name = "style." + full_name[0]
- for i in full_name[1:]:
- name += "[{!r}]".format(i)
-@@ -588,8 +588,8 @@ def lint():
-
- renpy.game.lint = True
-
-- print codecs.BOM_UTF8
-- print unicode(renpy.version + " lint report, generated at: " + time.ctime()).encode("utf-8")
-+ print(codecs.BOM_UTF8)
-+ print(str(renpy.version + " lint report, generated at: " + time.ctime()).encode("utf-8"))
-
- # This supports check_hide.
- global image_prefixes
-@@ -723,10 +723,10 @@ characters per block. """.format(
- lines.append(s)
-
-
-- print
-- print
-- print "Statistics:"
-- print
-+ print()
-+ print()
-+ print("Statistics:")
-+ print()
-
- languages = list(counts)
- languages.sort()
-@@ -738,17 +738,17 @@ characters per block. """.format(
-
- for l in lines:
- for ll in textwrap.wrap(l, 78):
-- print ll.encode("utf-8")
-+ print(ll.encode("utf-8"))
-
-- print
-+ print()
-
-- print
-+ print()
- if renpy.config.developer:
-- print "Remember to set config.developer to False before releasing."
-- print
-+ print("Remember to set config.developer to False before releasing.")
-+ print()
-
-- print "Lint is not a substitute for thorough testing. Remember to update Ren'Py"
-- print "before releasing. New releases fix bugs and improve compatibility."
-+ print("Lint is not a substitute for thorough testing. Remember to update Ren'Py")
-+ print("before releasing. New releases fix bugs and improve compatibility.")
-
- return False
-
-diff --git a/renpy/loader.py b/renpy/loader.py
-index 0760219..f3a7a7b 100644
---- a/renpy/loader.py
-+++ b/renpy/loader.py
-@@ -22,7 +22,7 @@
- import renpy
- import os.path
- from pickle import loads
--from cStringIO import StringIO
-+from io import StringIO
- import sys
- import types
- import threading
-@@ -30,7 +30,7 @@ import zlib
-
- # Ensure the utf-8 codec is loaded, to prevent recursion when we use it
- # to look up filenames.
--u"".encode("utf-8")
-+"".encode("utf-8")
-
-
- ################################################################# Physical Paths
-@@ -61,7 +61,7 @@ try:
-
- expansion = os.environ.get("ANDROID_EXPANSION", None)
- if expansion is not None:
-- print "Using expansion file", expansion
-+ print("Using expansion file", expansion)
-
- apks = [
- android.apk.APK(apk=expansion, prefix='assets/x-game/'),
-@@ -71,7 +71,7 @@ try:
- game_apks = [ apks[0] ]
-
- else:
-- print "Not using expansion file."
-+ print("Not using expansion file.")
-
- apks = [
- android.apk.APK(prefix='assets/x-game/'),
-@@ -121,7 +121,7 @@ def index_archives():
-
- try:
- fn = transfn(prefix + ".rpa")
-- f = file(fn, "rb")
-+ f = open(fn, "rb")
- l = f.readline()
-
- # 3.0 Branch.
-@@ -133,7 +133,7 @@ def index_archives():
-
- # Deobfuscate the index.
-
-- for k in index.keys():
-+ for k in list(index.keys()):
-
- if len(index[k][0]) == 2:
- index[k] = [ (offset ^ key, dlen ^ key) for offset, dlen in index[k] ]
-@@ -158,7 +158,7 @@ def index_archives():
- f.close()
-
- fn = transfn(prefix + ".rpi")
-- index = loads(file(fn, "rb").read().decode("zlib"))
-+ index = loads(open(fn, "rb").read().decode("zlib"))
- archives.append((prefix, index))
- except:
- raise
-@@ -253,7 +253,7 @@ def scandirfiles():
- files = game_files
-
- for _prefix, index in archives:
-- for j in index.iterkeys():
-+ for j in index.keys():
- add(None, j)
-
-
-@@ -380,7 +380,7 @@ class SubFile(object):
- def __iter__(self):
- return self
-
-- def next(self): #@ReservedAssignment
-+ def __next__(self): #@ReservedAssignment
- rv = self.readline()
-
- if not rv:
-@@ -489,7 +489,7 @@ def load_core(name):
-
- # Compatibility path.
- else:
-- f = file(afn, "rb")
-+ f = open(afn, "rb")
-
- for offset, dlen in index[name]:
- f.seek(offset)
-@@ -684,13 +684,13 @@ class RenpyImporter(object):
- mod.__path__ = [ filename[:-len("__init__.py")] ]
-
- source = load(filename).read().decode("utf8")
-- if source and source[0] == u'\ufeff':
-+ if source and source[0] == '\ufeff':
- source = source[1:]
- source = source.encode("raw_unicode_escape")
-
- source = source.replace("\r", "")
- code = compile(source, filename, 'exec')
-- exec code in mod.__dict__
-+ exec(code, mod.__dict__)
- return mod
-
- def get_data(self, filename):
-@@ -773,7 +773,7 @@ def auto_thread_function():
- if auto_quit_flag:
- return
-
-- items = auto_mtimes.items()
-+ items = list(auto_mtimes.items())
-
- for fn, mtime in items:
-
-diff --git a/renpy/loadsave.py b/renpy/loadsave.py
-index 862105d..07fd357 100644
---- a/renpy/loadsave.py
-+++ b/renpy/loadsave.py
-@@ -22,9 +22,9 @@
- # This file contains functions that load and save the game state.
-
- import pickle
--import cPickle
-+import pickle
-
--from cStringIO import StringIO
-+from io import StringIO
-
- import zipfile
- import re
-@@ -40,13 +40,13 @@ from json import dumps as json_dumps
- # Dump that chooses which pickle to use:
- def dump(o, f):
- if renpy.config.use_cpickle:
-- cPickle.dump(o, f, cPickle.HIGHEST_PROTOCOL)
-+ pickle.dump(o, f, pickle.HIGHEST_PROTOCOL)
- else:
- pickle.dump(o, f, pickle.HIGHEST_PROTOCOL)
-
- def loads(s):
- if renpy.config.use_cpickle:
-- return cPickle.loads(s)
-+ return pickle.loads(s)
- else:
- return pickle.loads(s)
-
-@@ -71,10 +71,10 @@ def save_dump(roots, log):
- f.write("{0: 7d} {1} = alias {2}\n".format(0, path, o_repr_cache[ido]))
- return 0
-
-- if isinstance(o, (int, float, types.NoneType, types.ModuleType, types.ClassType)):
-+ if isinstance(o, (int, float, type(None), types.ModuleType, type)):
- o_repr = repr(o)
-
-- elif isinstance(o, (str, unicode)):
-+ elif isinstance(o, str):
- if len(o) <= 80:
- o_repr = repr(o).encode("utf-8")
- else:
-@@ -87,7 +87,7 @@ def save_dump(roots, log):
- o_repr = "<" + o.__class__.__name__ + ">"
-
- elif isinstance(o, types.MethodType):
-- o_repr = "<method {0}.{1}>".format(o.im_class.__name__, o.im_func.__name__)
-+ o_repr = "<method {0}.{1}>".format(o.__self__.__class__.__name__, o.__func__.__name__)
-
- elif isinstance(o, object):
- o_repr = "<{0}>".format(type(o).__name__)
-@@ -98,10 +98,10 @@ def save_dump(roots, log):
-
- o_repr_cache[ido] = o_repr
-
-- if isinstance(o, (int, float, types.NoneType, types.ModuleType, types.ClassType)):
-+ if isinstance(o, (int, float, type(None), types.ModuleType, type)):
- size = 1
-
-- elif isinstance(o, (str, unicode)):
-+ elif isinstance(o, str):
- size = len(o) / 40 + 1
-
- elif isinstance(o, (tuple, list)):
-@@ -112,12 +112,12 @@ def save_dump(roots, log):
-
- elif isinstance(o, dict):
- size = 2
-- for k, v in o.iteritems():
-+ for k, v in o.items():
- size += 2
- size += visit(v, "{0}[{1!r}]".format(path, k))
-
- elif isinstance(o, types.MethodType):
-- size = 1 + visit(o.im_self, path + ".im_self")
-+ size = 1 + visit(o.__self__, path + ".im_self")
-
- else:
-
-@@ -141,7 +141,7 @@ def save_dump(roots, log):
-
- state = get(2, { })
- if isinstance(state, dict):
-- for k, v in state.iteritems():
-+ for k, v in state.items():
- size += 2
- size += visit(v, path + "." + k)
- else:
-@@ -166,7 +166,7 @@ def save_dump(roots, log):
-
- return size
-
-- f = file("save_dump.txt", "w")
-+ f = open("save_dump.txt", "w")
-
- visit(roots, "roots")
- visit(log, "log")
-@@ -712,7 +712,7 @@ def clear_cache():
- Clears the entire cache.
- """
-
-- for c in cache.values():
-+ for c in list(cache.values()):
- c.clear()
-
- newest_slot_cache.clear()
-diff --git a/renpy/log.py b/renpy/log.py
-index 87f349e..8f34999 100644
---- a/renpy/log.py
-+++ b/renpy/log.py
-@@ -86,7 +86,7 @@ class LogFile(object):
- altfn = os.path.join(tempfile.gettempdir(), "renpy-" + self.name + ".txt")
-
- if renpy.android:
-- print "Logging to", fn
-+ print("Logging to", fn)
-
- if self.append:
- mode = "a"
-@@ -132,7 +132,7 @@ class LogFile(object):
- s = s % args
- s += "\n"
-
-- if not isinstance(s, unicode):
-+ if not isinstance(s, str):
- s = s.decode("latin-1")
-
- s = s.replace("\n", "\r\n")
-diff --git a/renpy/main.py b/renpy/main.py
-index f8bee19..721eecc 100644
---- a/renpy/main.py
-+++ b/renpy/main.py
-@@ -39,7 +39,7 @@ def log_clock(s):
-
- renpy.display.log.write(s)
- if renpy.android and not renpy.config.log_to_stdout:
-- print s
-+ print(s)
-
- last_clock = now
-
-@@ -146,7 +146,7 @@ def load_rpe(fn):
- zfn.close()
-
- sys.path.insert(0, fn)
-- exec autorun in dict()
-+ exec(autorun, dict())
-
- def choose_variants():
-
-@@ -174,10 +174,10 @@ def choose_variants():
- manufacturer = Build.MANUFACTURER
- model = Build.MODEL
-
-- print "Manufacturer", manufacturer, "model", model
-+ print("Manufacturer", manufacturer, "model", model)
-
- if manufacturer == "Amazon" and model.startswith("AFT"):
-- print "Running on a Fire TV."
-+ print("Running on a Fire TV.")
- renpy.config.variants.insert(0, "firetv")
- except:
- pass
-@@ -186,7 +186,7 @@ def choose_variants():
- package_manager = android.activity.getPackageManager()
-
- if package_manager.hasSystemFeature("android.hardware.type.television"):
-- print "Running on a television."
-+ print("Running on a television.")
- renpy.config.variants.insert(0, "tv")
- renpy.config.variants.insert(0, "small")
- return
-@@ -198,7 +198,7 @@ def choose_variants():
-
- info = renpy.display.get_info()
- diag = math.hypot(info.current_w, info.current_h) / android.get_dpi()
-- print "Screen diagonal is", diag, "inches."
-+ print("Screen diagonal is", diag, "inches.")
-
- if diag >= 6:
- renpy.config.variants.insert(0, 'tablet')
-@@ -216,7 +216,7 @@ def choose_variants():
-
- idiom = UIDevice.currentDevice().userInterfaceIdiom
-
-- print "iOS device idiom", idiom
-+ print("iOS device idiom", idiom)
-
- # idiom 0 is iPhone, 1 is iPad. We assume any bigger idiom will
- # be tablet-like.
-@@ -359,7 +359,7 @@ def main():
- renpy.game.script = renpy.script.Script()
- renpy.game.script.load_script()
-
-- print time.time() - start
-+ print(time.time() - start)
- sys.exit(0)
-
- renpy.game.exception_info = 'After loading the script.'
-@@ -470,7 +470,7 @@ def main():
- restart = (renpy.config.end_game_transition, "_invoke_main_menu", "_main_menu")
- renpy.persistent.update(True)
-
-- except game.FullRestartException, e:
-+ except game.FullRestartException as e:
- restart = e.reason
-
- finally:
-diff --git a/renpy/memory.py b/renpy/memory.py
-index 7751db1..c127e3f 100644
---- a/renpy/memory.py
-+++ b/renpy/memory.py
-@@ -83,7 +83,7 @@ def walk_memory(roots, seen=None):
- get_referents = gc.get_referents
- worklist_append = worklist.append
-
-- ignore_types = (types.ModuleType, types.ClassType, types.FunctionType)
-+ ignore_types = (types.ModuleType, type, types.FunctionType)
-
- while worklist:
- name, o = worklist.pop(0)
-@@ -133,7 +133,7 @@ def profile_memory_common(packages=[ "renpy", "store" ]):
- if mod_name.startswith("renpy.store"):
- continue
-
-- for name, o in mod.__dict__.items():
-+ for name, o in list(mod.__dict__.items()):
- roots.append((mod_name + "." + name, o))
-
- return walk_memory(roots)
-@@ -169,7 +169,7 @@ def profile_memory(fraction=1.0, minimum=0):
- write("Memory profile at " + time.ctime() + ":")
- write("")
-
-- usage = [ (v, k) for (k, v) in profile_memory_common()[0].items() ]
-+ usage = [ (v, k) for (k, v) in list(profile_memory_common()[0].items()) ]
- usage.sort()
-
- # The total number of bytes allocated.
-@@ -223,7 +223,7 @@ def diff_memory(update=True):
-
- diff = [ ]
-
-- for k, v in usage.iteritems():
-+ for k, v in usage.items():
- diff.append((
- v - old_usage.get(k, 0),
- k))
-@@ -275,8 +275,8 @@ def profile_rollback():
- # Walk the log, finding new roots and rollback information.
- for rb in log:
-
-- for store_name, store in rb.stores.iteritems():
-- for var_name, o in store.iteritems():
-+ for store_name, store in rb.stores.items():
-+ for var_name, o in store.items():
- name = store_name + "." + var_name
- id_o = id(o)
-
-@@ -300,7 +300,7 @@ def profile_rollback():
-
- sizes = walk_memory(roots, seen)[0]
-
-- usage = [ (v, k) for (k, v) in sizes.iteritems() ]
-+ usage = [ (v, k) for (k, v) in sizes.items() ]
- usage.sort()
-
- write("Total Bytes".rjust(13) + " " + "Per Rollback".rjust(13))
-@@ -344,15 +344,15 @@ def find_parents(cls):
-
- objects.append(o)
-
-- print prefix + str(id(o)), type(o),
-+ print(prefix + str(id(o)), type(o), end=' ')
-
- try:
- if isinstance(o, dict) and "__name__" in o:
-- print "with name", o["__name__"]
-+ print("with name", o["__name__"])
- else:
-- print repr(o)#[:1000]
-+ print(repr(o))#[:1000]
- except:
-- print "Bad repr."
-+ print("Bad repr.")
-
- found = False
-
-@@ -364,7 +364,7 @@ def find_parents(cls):
- continue
-
- if isinstance(o, weakref.WeakKeyDictionary):
-- for k, v in o.data.items():
-+ for k, v in list(o.data.items()):
- if v is objects[-4]:
- k = k()
- seen.add(id(k))
-@@ -390,7 +390,7 @@ def find_parents(cls):
- break
-
- if not found:
-- print "<no parent, popping>"
-+ print("<no parent, popping>")
-
- o, prefix = queue.pop()
-
-@@ -399,8 +399,8 @@ def find_parents(cls):
- import random
- if random.random() < .1:
-
-- print
-- print "==================================================="
-- print
-+ print()
-+ print("===================================================")
-+ print()
-
- print_path(o)
-diff --git a/renpy/parser.py b/renpy/parser.py
-index 0b48859..1001749 100644
---- a/renpy/parser.py
-+++ b/renpy/parser.py
-@@ -37,7 +37,7 @@ parse_errors = [ ]
- class ParseError(Exception):
-
- def __init__(self, filename, number, msg, line=None, pos=None, first=False):
-- message = u"File \"%s\", line %d: %s" % (unicode_filename(filename), number, msg)
-+ message = "File \"%s\", line %d: %s" % (unicode_filename(filename), number, msg)
-
- if line:
- lines = line.split('\n')
-@@ -97,7 +97,7 @@ def unicode_filename(fn):
- Converts the supplied filename to unicode.
- """
-
-- if isinstance(fn, unicode):
-+ if isinstance(fn, str):
- return fn
-
- # Windows.
-@@ -200,7 +200,7 @@ def list_logical_lines(filename, filedata=None, linenumber=1):
- pos = 0
-
- # Skip the BOM, if any.
-- if len(data) and data[0] == u'\ufeff':
-+ if len(data) and data[0] == '\ufeff':
- pos += 1
-
- if renpy.game.context().init_phase:
-@@ -480,7 +480,7 @@ ESCAPED_OPERATORS = [
-
- operator_regexp = "|".join([ re.escape(i) for i in OPERATORS ] + ESCAPED_OPERATORS)
-
--word_regexp = ur'[a-zA-Z_\u00a0-\ufffd][0-9a-zA-Z_\u00a0-\ufffd]*'
-+word_regexp = r'[a-zA-Z_\u00a0-\ufffd][0-9a-zA-Z_\u00a0-\ufffd]*'
-
- class Lexer(object):
- """
-@@ -564,7 +564,7 @@ class Lexer(object):
-
- # print self.text[self.pos].encode('unicode_escape')
-
-- self.match_regexp(ur"(\s+|\\\n)+")
-+ self.match_regexp(r"(\s+|\\\n)+")
-
- def match(self, regexp):
- """
-@@ -689,7 +689,7 @@ class Lexer(object):
- s = s.replace("\\[", "[[")
- s = s.replace("\\%", "%%")
- s = re.sub(r'\\u([0-9a-fA-F]{1,4})',
-- lambda m : unichr(int(m.group(1), 16)), s)
-+ lambda m : chr(int(m.group(1), 16)), s)
- s = re.sub(r'\\(.)', r'\1', s)
-
- return s
-@@ -1005,7 +1005,7 @@ class Lexer(object):
- name = name or thing
- rv = self.match(thing)
- else:
-- name = name or thing.im_func.func_name
-+ name = name or thing.__func__.__name__
- rv = thing()
-
- if rv is None:
-@@ -2315,7 +2315,7 @@ def parse_block(l):
- else:
- rv.append(stmt)
-
-- except ParseError, e:
-+ except ParseError as e:
- parse_errors.append(e.message)
- l.advance()
-
-@@ -2339,7 +2339,7 @@ def parse(fn, filedata=None, linenumber=1):
- try:
- lines = list_logical_lines(fn, filedata, linenumber)
- nested = group_logical_lines(lines)
-- except ParseError, e:
-+ except ParseError as e:
- parse_errors.append(e.message)
- return None
-
-@@ -2369,11 +2369,11 @@ def report_parse_errors():
- full_text = ""
-
- f, error_fn = renpy.error.open_error_file("errors.txt", "w")
-- f.write(codecs.BOM_UTF8)
-+ f.write(str(codecs.BOM_UTF8))
-
-- print >>f, "I'm sorry, but errors were detected in your script. Please correct the"
-- print >>f, "errors listed below, and try again."
-- print >>f
-+ print("I'm sorry, but errors were detected in your script. Please correct the", file=f)
-+ print("errors listed below, and try again.", file=f)
-+ print(file=f)
-
- for i in parse_errors:
-
-@@ -2385,14 +2385,14 @@ def report_parse_errors():
- except:
- pass
-
-- print
-- print >>f
-- print i
-- print >>f, i
-+ print()
-+ print(file=f)
-+ print(i)
-+ print(i, file=f)
-
-
-- print >>f
-- print >>f, "Ren'Py Version:", renpy.version
-+ print(file=f)
-+ print("Ren'Py Version:", renpy.version, file=f)
-
- f.close()
-
-diff --git a/renpy/persistent.py b/renpy/persistent.py
-index 2201010..8e81dd2 100644
---- a/renpy/persistent.py
-+++ b/renpy/persistent.py
-@@ -26,7 +26,7 @@ import time
- import renpy
-
- from renpy.loadsave import dump, loads
--from cPickle import dumps
-+from pickle import dumps
-
- # The class that's used to hold the persistent data.
- class Persistent(object):
-@@ -178,7 +178,7 @@ def load(filename):
-
- # Unserialize the persistent data.
- try:
-- f = file(filename, "rb")
-+ f = open(filename, "rb")
- s = f.read().decode("zlib")
- f.close()
- persistent = loads(s)
-@@ -207,7 +207,7 @@ def init():
- # Create the backup of the persistent data.
- v = vars(persistent)
-
-- for k, v in vars(persistent).iteritems():
-+ for k, v in vars(persistent).items():
- backup[k] = safe_deepcopy(v)
-
- return persistent
-@@ -401,7 +401,7 @@ class _MultiPersistent(object):
- def save(self):
-
- fn = self._filename
-- f = file(fn + ".new", "wb")
-+ f = open(fn + ".new", "wb")
- dump(self, f)
- f.close()
-
-@@ -451,7 +451,7 @@ def MultiPersistent(name):
- break
-
- try:
-- rv = loads(file(fn).read())
-+ rv = loads(open(fn).read())
- except:
- rv = _MultiPersistent()
-
-diff --git a/renpy/pyanalysis.py b/renpy/pyanalysis.py
-index f5267bb..041ea8d 100644
---- a/renpy/pyanalysis.py
-+++ b/renpy/pyanalysis.py
-@@ -19,11 +19,6 @@
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
--from __future__ import print_function
--from __future__ import unicode_literals
--from __future__ import division
--from __future__ import absolute_import
--
- import renpy # @UnusedImport
- from renpy.python import py_compile
-
-@@ -31,7 +26,7 @@ from renpy.python import py_compile
- import ast
-
- import zlib
--from cPickle import loads, dumps
-+from pickle import loads, dumps
-
- # The set of names that should be treated as constants.
- always_constants = { 'True', 'False', 'None' }
-@@ -45,7 +40,7 @@ pure_functions = {
- "getattr", "globals", "hasattr", "hash", "hex", "int", "isinstance",
- "len", "list", "long", "map", "max", "min", "oct", "ord", "pow",
- "range", "reduce", "repr", "round", "set", "sorted",
-- "str", "sum", "tuple", "unichr", "unicode", "vars", "zip",
-+ "str", "sum", "tuple", "vars", "zip",
-
- # enumerator and reversed return iterators at the moment.
-
-@@ -137,7 +132,7 @@ def pure(fn):
-
- name = fn
-
-- if not isinstance(name, basestring):
-+ if not isinstance(name, str):
- name = fn.__name__
-
- if name not in not_constants:
-@@ -297,7 +292,7 @@ class Analysis(object):
- not changed since the last time we called this function.
- """
-
-- for i in self.children.values():
-+ for i in list(self.children.values()):
- if not i.at_fixed_point():
- return False
-
-diff --git a/renpy/python.py b/renpy/python.py
-index 22e7405..22f5ecb 100644
---- a/renpy/python.py
-+++ b/renpy/python.py
-@@ -30,7 +30,6 @@ import marshal
- import random
- import weakref
- import re
--import sets
- import sys
-
- import renpy.audio
-@@ -121,7 +120,7 @@ class StoreDict(dict):
- if k not in self.old:
- rv[k] = deleted
-
-- for k, v in self.old.iteritems():
-+ for k, v in self.old.items():
-
- new_v = self.get(k, deleted)
-
-@@ -168,7 +167,7 @@ def create_store(name):
- # Set up the default contents of the store.
- eval("1", d)
-
-- for k, v in renpy.minstore.__dict__.iteritems():
-+ for k, v in renpy.minstore.__dict__.items():
- if k not in d:
- d[k] = v
-
-@@ -200,14 +199,14 @@ class StoreBackup():
- self.ever_been_changed = { }
-
-
-- for k, v in store_dicts.iteritems():
-+ for k, v in store_dicts.items():
- self.store[k] = dict(v)
- self.old[k] = dict(v.old)
- self.ever_been_changed[k] = set(v.ever_been_changed)
-
- def restore(self):
-
-- for k, sd in store_dicts.iteritems():
-+ for k, sd in store_dicts.items():
-
- sd.clear()
- sd.update(self.store[k])
-@@ -229,7 +228,7 @@ def make_clean_stores():
-
- global clean_store_backup
-
-- for _k, v in store_dicts.iteritems():
-+ for _k, v in store_dicts.items():
-
- v.old.clear()
- v.ever_been_changed.clear()
-@@ -294,14 +293,14 @@ def reached(obj, reachable, wait):
-
- try:
- # Treat as fields, indexed by strings.
-- for v in vars(obj).itervalues():
-+ for v in vars(obj).values():
- reached(v, reachable, wait)
- except:
- pass
-
- try:
- # Treat as iterable
-- if not isinstance(obj, basestring):
-+ if not isinstance(obj, str):
- for v in obj.__iter__():
- reached(v, reachable, wait)
- except:
-@@ -309,7 +308,7 @@ def reached(obj, reachable, wait):
-
- try:
- # Treat as dict.
-- for v in obj.itervalues():
-+ for v in obj.values():
- reached(v, reachable, wait)
- except:
- pass
-@@ -326,14 +325,14 @@ def reached_vars(store, reachable, wait):
- the path by which the object was reached.
- """
-
-- for v in store.itervalues():
-+ for v in store.values():
- reached(v, reachable, wait)
-
- for c in renpy.game.contexts:
- reached(c.info, reachable, wait)
- reached(c.music, reachable, wait)
- for d in c.dynamic_stack:
-- for v in d.itervalues():
-+ for v in d.values():
- reached(v, reachable, wait)
-
-
-@@ -417,7 +416,7 @@ def set_filename(filename, offset, tree):
- worklist.extend(node.getChildNodes())
-
-
--unicode_re = re.compile(ur'[\u0080-\uffff]')
-+unicode_re = re.compile(r'[\u0080-\uffff]')
-
- def unicode_sub(m):
- """
-@@ -483,7 +482,7 @@ def py_compile(source, mode, filename='<none>', lineno=1, ast_node=False):
- filename = source.filename
- lineno = source.linenumber
-
-- source = unicode(source)
-+ source = str(source)
- source = source.replace("\r", "")
- source = escape_unicode(source)
-
-@@ -504,7 +503,7 @@ def py_compile(source, mode, filename='<none>', lineno=1, ast_node=False):
-
- return compile(tree, filename, mode)
-
-- except SyntaxError, e:
-+ except SyntaxError as e:
-
- if e.lineno is not None:
- e.lineno += line_offset
-@@ -558,7 +557,6 @@ class RevertableList(list):
- list.__init__(self, *args)
-
- __delitem__ = mutator(list.__delitem__)
-- __delslice__ = mutator(list.__delslice__)
- __setitem__ = mutator(list.__setitem__)
- __iadd__ = mutator(list.__iadd__)
- __imul__ = mutator(list.__imul__)
-@@ -577,7 +575,6 @@ class RevertableList(list):
- return newmethod
-
- __add__ = wrapper(list.__add__)
-- __getslice__ = wrapper(list.__getslice__)
- __mul__ = wrapper(list.__mul__)
- __rmul__ = wrapper(list.__rmul__)
-
-@@ -590,7 +587,7 @@ class RevertableList(list):
- self[:] = old
-
- def revertable_range(*args):
-- return RevertableList(range(*args))
-+ return RevertableList(list(range(*args)))
-
- def revertable_sorted(*args, **kwargs):
- return RevertableList(sorted(*args, **kwargs))
-@@ -630,7 +627,7 @@ class RevertableDict(dict):
- return rv
-
- def get_rollback(self):
-- return self.items()
-+ return list(self.items())
-
- def rollback(self, old):
- self.clear()
-@@ -638,7 +635,7 @@ class RevertableDict(dict):
- for k, v in old:
- self[k] = v
-
--class RevertableSet(sets.Set):
-+class RevertableSet(set):
-
- def __init__(self, *args):
- log = renpy.game.log
-@@ -646,44 +643,43 @@ class RevertableSet(sets.Set):
- if log is not None:
- log.mutated[id(self)] = None
-
-- sets.Set.__init__(self, *args)
--
-- __iand__ = mutator(sets.Set.__iand__)
-- __ior__ = mutator(sets.Set.__ior__)
-- __isub__ = mutator(sets.Set.__isub__)
-- __ixor__ = mutator(sets.Set.__ixor__)
-- add = mutator(sets.Set.add)
-- clear = mutator(sets.Set.clear)
-- difference_update = mutator(sets.Set.difference_update)
-- discard = mutator(sets.Set.discard)
-- intersection_update = mutator(sets.Set.intersection_update)
-- pop = mutator(sets.Set.pop)
-- remove = mutator(sets.Set.remove)
-- symmetric_difference_update = mutator(sets.Set.symmetric_difference_update)
-- union_update = mutator(sets.Set.union_update)
-- update = mutator(sets.Set.update)
-+ set.__init__(self, *args)
-+
-+ __iand__ = mutator(set.__iand__)
-+ __ior__ = mutator(set.__ior__)
-+ __isub__ = mutator(set.__isub__)
-+ __ixor__ = mutator(set.__ixor__)
-+ add = mutator(set.add)
-+ clear = mutator(set.clear)
-+ difference_update = mutator(set.difference_update)
-+ discard = mutator(set.discard)
-+ intersection_update = mutator(set.intersection_update)
-+ pop = mutator(set.pop)
-+ remove = mutator(set.remove)
-+ symmetric_difference_update = mutator(set.symmetric_difference_update)
-+ union = mutator(set.union)
-+ update = mutator(set.update)
-
- def wrapper(method): # E0213 @NoSelf
- def newmethod(*args, **kwargs):
- rv = method(*args, **kwargs) # E1102
-- if isinstance(rv, sets.Set):
-+ if isinstance(rv, set):
- return RevertableSet(rv)
- else:
- return rv
-
- return newmethod
-
-- __and__ = wrapper(sets.Set.__and__)
-- __copy__ = wrapper(sets.Set.__copy__)
-- __deepcopy__ = wrapper(sets.Set.__deepcopy__)
-- __sub__ = wrapper(sets.Set.__sub__)
-- __xor__ = wrapper(sets.Set.__xor__)
-- __or__ = wrapper(sets.Set.__or__)
-- copy = wrapper(sets.Set.copy)
-- difference = wrapper(sets.Set.difference)
-- intersection = wrapper(sets.Set.intersection)
-- symmetric_difference = wrapper(sets.Set.symmetric_difference)
-- union = wrapper(sets.Set.union)
-+ __and__ = wrapper(set.__and__)
-+ copy = wrapper(set.copy)
-+ __sub__ = wrapper(set.__sub__)
-+ __xor__ = wrapper(set.__xor__)
-+ __or__ = wrapper(set.__or__)
-+ copy = wrapper(set.copy)
-+ difference = wrapper(set.difference)
-+ intersection = wrapper(set.intersection)
-+ symmetric_difference = wrapper(set.symmetric_difference)
-+ union = wrapper(set.union)
-
- del wrapper
-
-@@ -691,8 +687,8 @@ class RevertableSet(sets.Set):
- return list(self)
-
- def rollback(self, old):
-- sets.Set.clear(self)
-- sets.Set.update(self, old)
-+ set.clear(self)
-+ set.update(self, old)
-
-
- class RevertableObject(object):
-@@ -869,15 +865,15 @@ class Rollback(renpy.object.Object):
-
- # Add objects reachable from the stores. (Objects that might be
- # unreachable at the moment.)
-- for changes in self.stores.itervalues():
-- for _k, v in changes.iteritems():
-+ for changes in self.stores.values():
-+ for _k, v in changes.items():
- if v is not deleted:
- reached(v, reachable, wait)
-
- # Add in objects reachable through the context.
- reached(self.context.info, reachable, wait)
- for d in self.context.dynamic_stack:
-- for v in d.itervalues():
-+ for v in d.values():
- reached(v, reachable, wait)
-
- # Add in objects reachable through displayables.
-@@ -892,7 +888,7 @@ class Rollback(renpy.object.Object):
- reached(rb, reachable, wait)
- else:
- if renpy.config.debug:
-- print "Removing unreachable:", o
-+ print("Removing unreachable:", o)
-
- pass
-
-@@ -911,12 +907,12 @@ class Rollback(renpy.object.Object):
- if roll is not None:
- obj.rollback(roll)
-
-- for name, changes in self.stores.iteritems():
-+ for name, changes in self.stores.items():
- store = store_dicts.get(name, None)
- if store is None:
- return
-
-- for name, value in changes.iteritems():
-+ for name, value in changes.items():
- if value is deleted:
- if name in store:
- del store[name]
-@@ -1045,7 +1041,7 @@ class RollbackLog(renpy.object.Object):
- self.rolled_forward = False
-
- # Reset the point that changes are relative to.
-- for sd in store_dicts.itervalues():
-+ for sd in store_dicts.values():
- sd.begin()
-
- def complete(self):
-@@ -1059,18 +1055,18 @@ class RollbackLog(renpy.object.Object):
-
- # Update self.current.stores with the changes from each store.
- # Also updates .ever_been_changed.
-- for name, sd in store_dicts.iteritems():
-+ for name, sd in store_dicts.items():
- self.current.stores[name] = sd.get_changes()
-
- # Update the list of mutated objects and what we need to do to
- # restore them.
-
-- for _i in xrange(4):
-+ for _i in range(4):
-
- self.current.objects = [ ]
-
- try:
-- for _k, v in self.mutated.iteritems():
-+ for _k, v in self.mutated.items():
-
- if v is None:
- continue
-@@ -1102,7 +1098,7 @@ class RollbackLog(renpy.object.Object):
-
- rv = { }
-
-- for store_name, sd in store_dicts.iteritems():
-+ for store_name, sd in store_dicts.items():
- for name in sd.ever_been_changed:
- if name in sd:
- rv[store_name + "." + name] = sd[name]
-@@ -1300,7 +1296,7 @@ class RollbackLog(renpy.object.Object):
-
- # Otherwise, just give up.
-
-- print "Can't find a place to rollback to. Not rolling back."
-+ print("Can't find a place to rollback to. Not rolling back.")
-
- revlog.reverse()
- self.log = self.log + revlog
-@@ -1422,7 +1418,7 @@ class RollbackLog(renpy.object.Object):
- clean_stores()
- renpy.translation.init_translation()
-
-- for name, value in roots.iteritems():
-+ for name, value in roots.items():
-
- if "." in name:
- store_name, name = name.rsplit(".", 1)
-@@ -1458,7 +1454,7 @@ def py_exec_bytecode(bytecode, hide=False, globals=None, locals=None, store="sto
- if locals is None:
- locals = globals #@ReservedAssignment
-
-- exec bytecode in globals, locals
-+ exec(bytecode, globals, locals)
-
-
- def py_exec(source, hide=False, store=None):
-@@ -1471,7 +1467,7 @@ def py_exec(source, hide=False, store=None):
- else:
- locals = store #@ReservedAssignment
-
-- exec py_compile(source, 'exec') in store, locals
-+ exec(py_compile(source, 'exec'), store, locals)
-
-
- def py_eval_bytecode(bytecode, globals=None, locals=None): #@ReservedAssignment
-@@ -1485,7 +1481,7 @@ def py_eval_bytecode(bytecode, globals=None, locals=None): #@ReservedAssignment
- return eval(bytecode, globals, locals)
-
- def py_eval(code, globals=None, locals=None): #@ReservedAssignment
-- if isinstance(code, basestring):
-+ if isinstance(code, str):
- code = py_compile(code, 'eval')
- return py_eval_bytecode(code, globals, locals)
-
-@@ -1505,7 +1501,7 @@ def raise_at_location(e, loc):
- code = compile(node, filename, 'exec')
-
- # PY3 - need to change to exec().
-- exec code in { "e" : e }
-+ exec(code, { "e" : e })
-
-
- # This was used to proxy accesses to the store. Now it's kept around to deal
-@@ -1524,18 +1520,18 @@ class StoreProxy(object):
-
- # Code for pickling bound methods.
- def method_pickle(method):
-- name = method.im_func.__name__
-+ name = method.__func__.__name__
-
-- obj = method.im_self
-+ obj = method.__self__
-
- if obj is None:
-- obj = method.im_class
-+ obj = method.__self__.__class__
-
- return method_unpickle, (obj, name)
-
- def method_unpickle(obj, name):
- return getattr(obj, name)
-
--import copy_reg
-+import copyreg
- import types
--copy_reg.pickle(types.MethodType, method_pickle, method_unpickle)
-+copyreg.pickle(types.MethodType, method_pickle, method_unpickle)
-diff --git a/renpy/savelocation.py b/renpy/savelocation.py
-index 9fc813a..567ccc5 100644
---- a/renpy/savelocation.py
-+++ b/renpy/savelocation.py
-@@ -113,7 +113,7 @@ class FileLocation(object):
-
- self.mtimes = new_mtimes
-
-- for slotname, mtime in new_mtimes.iteritems():
-+ for slotname, mtime in new_mtimes.items():
- if old_mtimes.get(slotname, None) != mtime:
- clear_slot(slotname)
-
-diff --git a/renpy/screenlang.py b/renpy/screenlang.py
-index 4a537eb..b393a53 100644
---- a/renpy/screenlang.py
-+++ b/renpy/screenlang.py
-@@ -231,12 +231,12 @@ class Parser(object):
- and expr instances, and adjusts the line number.
- """
-
-- if isinstance(expr, unicode):
-+ if isinstance(expr, str):
- expr = renpy.python.escape_unicode(expr)
-
- try:
- rv = ast.parse(expr, 'eval').body[0].value
-- except SyntaxError, e:
-+ except SyntaxError as e:
- raise renpy.parser.ParseError(
- filename,
- lineno + e[1][1] - 1,
-@@ -254,12 +254,12 @@ class Parser(object):
- adjusts the line number. Returns a list of statements.
- """
-
-- if isinstance(code, unicode):
-+ if isinstance(code, str):
- code = renpy.python.escape_unicode(code)
-
- try:
- rv = ast.parse(code, 'exec')
-- except SyntaxError, e:
-+ except SyntaxError as e:
-
- raise renpy.parser.ParseError(
- filename,
-diff --git a/renpy/script.py b/renpy/script.py
-index 61d6b5f..5f31183 100644
---- a/renpy/script.py
-+++ b/renpy/script.py
-@@ -27,13 +27,13 @@ import renpy
- import os
- import imp
- import difflib
--import md5
-+import hashlib
- import time
- import marshal
- import struct
- import zlib
-
--from cPickle import loads, dumps
-+from pickle import loads, dumps
- import shutil
-
- # The version of the dumped script.
-@@ -103,7 +103,7 @@ class Script(object):
- renpy.game.script = self
-
- if os.path.exists(renpy.config.renpy_base + "/lock.txt"):
-- self.key = file(renpy.config.renpy_base + "/lock.txt", "rb").read()
-+ self.key = open(renpy.config.renpy_base + "/lock.txt", "rb").read()
- else:
- self.key = None
-
-@@ -130,7 +130,8 @@ class Script(object):
-
- self.serial = 0
-
-- self.digest = md5.md5(renpy.version_only)
-+ self.digest = hashlib.md5(renpy.version_only.encode())
-+ self.md5 = hashlib.md5
-
- self.loaded_rpy = False
- self.backup_list = [ ]
-@@ -195,7 +196,7 @@ class Script(object):
- continue
-
- try:
-- os.makedirs(os.path.dirname(target_fn), 0700)
-+ os.makedirs(os.path.dirname(target_fn), 0o700)
- except:
- pass
-
-@@ -402,7 +403,7 @@ class Script(object):
- name = node.name
-
- if name in self.namemap:
-- if not isinstance(bad_name, basestring):
-+ if not isinstance(bad_name, str):
- bad_name = name
- bad_node = node
- old_node = self.namemap[name]
-@@ -566,7 +567,7 @@ class Script(object):
- self.assign_names(stmts, fullfn)
-
- try:
-- f = file(rpycfn, "wb")
-+ f = open(rpycfn, "wb")
-
- self.write_rpyc_header(f)
- self.write_rpyc_data(f, 1, dumps((data, stmts), 2))
-@@ -579,7 +580,7 @@ class Script(object):
- self.write_rpyc_data(f, 2, dumps((data, stmts), 2))
-
- with open(fullfn, "rU") as fullf:
-- rpydigest = md5.md5(fullf.read()).digest()
-+ rpydigest = hashlib.md5(fullf.read().encode()).digest()
-
- self.write_rpyc_md5(f, rpydigest)
-
-@@ -615,7 +616,7 @@ class Script(object):
- return None, None
-
- if data is None:
-- print "Failed to load", fn
-+ print("Failed to load", fn)
- return None, None
-
- if not isinstance(data, dict):
-@@ -652,8 +653,8 @@ class Script(object):
- raise Exception("Could not load from archive %s." % (lastfn,))
-
- f = renpy.loader.load(fn + compiled)
-- f.seek(-md5.digest_size, 2)
-- digest = f.read(md5.digest_size)
-+ f.seek(-self.md5.digest_size, 2)
-+ digest = f.read(self.md5.digest_size)
- f.close()
-
- else:
-@@ -667,15 +668,15 @@ class Script(object):
-
- if os.path.exists(rpyfn):
- with open(rpyfn, "rU") as f:
-- rpydigest = md5.md5(f.read()).digest()
-+ rpydigest = hashlib.md5(f.read().encode()).digest()
- else:
- rpydigest = None
-
- try:
- if os.path.exists(rpycfn):
- with open(rpycfn, "rb") as f:
-- f.seek(-md5.digest_size, 2)
-- rpycdigest = f.read(md5.digest_size)
-+ f.seek(-self.md5.digest_size, 2)
-+ rpycdigest = f.read(self.md5.digest_size)
- else:
- rpycdigest = None
- except:
-@@ -698,11 +699,11 @@ class Script(object):
- data, stmts = self.load_file(dir, fn + compiled)
-
- if data is None:
-- print "Could not load " + rpycfn
-+ print("Could not load " + rpycfn)
-
- except:
- if "RENPY_RPYC_EXCEPTIONS" in os.environ:
-- print "While loading", rpycfn
-+ print("While loading", rpycfn)
- raise
-
- pass
-@@ -763,7 +764,7 @@ class Script(object):
- # bytecode.
- for i in self.all_pycode:
-
-- key = i.get_hash() + MAGIC
-+ key = i.get_hash() + str(MAGIC)
-
- code = self.bytecode_oldcache.get(key, None)
-
-@@ -781,7 +782,7 @@ class Script(object):
- elif i.mode == 'eval':
- code = renpy.python.py_compile_eval_bytecode(i.source, filename=i.location[0], lineno=i.location[1])
-
-- except SyntaxError, e:
-+ except SyntaxError as e:
-
- text = e.text
-
-@@ -789,9 +790,9 @@ class Script(object):
- text = ''
-
- try:
-- text = text.decode("utf-8")
-+ text = text.encode().decode("utf-8")
- except:
-- text = text.decode("latin-1")
-+ text = text.encode().decode("latin-1")
-
- pem = renpy.parser.ParseError(
- filename = e.filename,
-diff --git a/renpy/scriptedit.py b/renpy/scriptedit.py
-index 92994d0..6818c59 100644
---- a/renpy/scriptedit.py
-+++ b/renpy/scriptedit.py
-@@ -90,7 +90,7 @@ def adjust_line_locations(filename, linenumber, char_offset, line_offset):
-
- new_lines = { }
-
-- for key, line in lines.iteritems():
-+ for key, line in lines.items():
-
- (fn, ln) = key
-
-@@ -204,13 +204,13 @@ def first_and_last_nodes(nodes):
-
- for i in nodes:
- for j in nodes:
-- if j.next is i:
-+ if j.__next__ is i:
- break
- else:
- firsts.append(i)
-
- for j in nodes:
-- if i.next is j:
-+ if i.__next__ is j:
- break
-
- else:
-@@ -288,7 +288,7 @@ def remove_from_ast(filename, linenumber):
- if i in nodes:
- continue
-
-- i.replace_next(first, last.next)
-+ i.replace_next(first, last.__next__)
-
- new_stmts.append(i)
-
-diff --git a/renpy/sl2/slast.py b/renpy/sl2/slast.py
-index defd86f..78c2f01 100644
---- a/renpy/sl2/slast.py
-+++ b/renpy/sl2/slast.py
-@@ -30,7 +30,7 @@
- import ast
- import collections
- import linecache
--from cPickle import loads, dumps
-+from pickle import loads, dumps
- import zlib
-
- import renpy.display
-@@ -43,7 +43,8 @@ from renpy.display.predict import displayable as predict_displayable
-
- from renpy.python import py_eval_bytecode
- from renpy.pyanalysis import Analysis, NOT_CONST, GLOBAL_CONST, ccache
--import md5
-+import hashlib
-+md5 = hashlib.md5
-
- # This file contains the abstract syntax tree for a screen language
- # screen.
-@@ -1398,7 +1399,7 @@ class SLFor(SLBlock):
- if c is None:
- return
-
-- for child_cache in c.values():
-+ for child_cache in list(c.values()):
- for i in self.children:
- i.copy_on_change(child_cache)
-
-@@ -1422,7 +1423,7 @@ class SLPython(SLNode):
- analysis.python(self.code.source)
-
- def execute(self, context):
-- exec self.code.bytecode in context.globals, context.scope
-+ exec(self.code.bytecode, context.globals, context.scope)
-
- def prepare(self, analysis):
- self.constant = NOT_CONST
-diff --git a/renpy/styledata/styleutil.py b/renpy/styledata/styleutil.py
-index fcd65c1..054f7c8 100644
---- a/renpy/styledata/styleutil.py
-+++ b/renpy/styledata/styleutil.py
-@@ -22,6 +22,7 @@
- # Utility functions used by the various property functions:
-
- import renpy
-+import collections
-
- def none_is_null(o):
- if o is None:
-@@ -36,7 +37,7 @@ def expand_focus_mask(v):
- return v
- elif v is True:
- return v
-- elif callable(v):
-+ elif isinstance(v, collections.Callable):
- return v
- else:
- return renpy.easy.displayable(v)
-diff --git a/renpy/text/extras.py b/renpy/text/extras.py
-index 2fa4d49..75e2f3f 100644
---- a/renpy/text/extras.py
-+++ b/renpy/text/extras.py
-@@ -73,7 +73,7 @@ def check_text_tags(s):
- else:
- all_tags = text_tags
-
-- tokens = textsupport.tokenize(unicode(s))
-+ tokens = textsupport.tokenize(str(s))
-
- tag_stack = [ ]
-
-diff --git a/renpy/text/font.py b/renpy/text/font.py
-index 07ac3ab..12e4d0f 100644
---- a/renpy/text/font.py
-+++ b/renpy/text/font.py
-@@ -92,7 +92,7 @@ class ImageFont(object):
- return
-
- for g in glyphs:
-- c = unichr(g.character)
-+ c = chr(g.character)
-
- cxo, cyo = self.offsets[c]
- x = g.x + xo + cxo
-@@ -143,20 +143,20 @@ class SFont(ImageFont):
- self.baseline = height # W0201
-
- # Create space characters.
-- self.chars[u' '] = renpy.display.pgrender.surface((self.spacewidth, height), True)
-- self.width[u' '] = self.spacewidth
-- self.advance[u' '] = self.spacewidth
-- self.offsets[u' '] = (0, 0)
-+ self.chars[' '] = renpy.display.pgrender.surface((self.spacewidth, height), True)
-+ self.width[' '] = self.spacewidth
-+ self.advance[' '] = self.spacewidth
-+ self.offsets[' '] = (0, 0)
-
-- self.chars[u'\u200b'] = renpy.display.pgrender.surface((0, height), True)
-- self.width[u'\u200b'] = 0
-- self.advance[u'\u200b'] = 0
-- self.offsets[u'\u200b'] = (0, 0)
-+ self.chars['\u200b'] = renpy.display.pgrender.surface((0, height), True)
-+ self.width['\u200b'] = 0
-+ self.advance['\u200b'] = 0
-+ self.offsets['\u200b'] = (0, 0)
-
-- self.chars[u'\u00a0'] = self.chars[u' ']
-- self.width[u'\u00a0'] = self.width[u' ']
-- self.advance[u'\u00a0'] = self.advance[u' ']
-- self.offsets[u'\u00a0'] = self.offsets[u' ']
-+ self.chars['\u00a0'] = self.chars[' ']
-+ self.width['\u00a0'] = self.width[' ']
-+ self.advance['\u00a0'] = self.advance[' ']
-+ self.offsets['\u00a0'] = self.offsets[' ']
-
- # The color key used to separate characters.
- i = 0
-@@ -234,7 +234,7 @@ class MudgeFont(ImageFont):
- if char < 0:
- continue
-
-- c = unichr(char)
-+ c = chr(char)
- x = int(e.attrib["x"])
- y = int(e.attrib["y"])
- w = int(e.attrib["width"])
-@@ -254,22 +254,22 @@ class MudgeFont(ImageFont):
- self.baseline = height # W0201
-
- # Create space characters.
-- if u' ' not in self.chars:
-- self.chars[u' '] = renpy.display.pgrender.surface((self.spacewidth, height), True)
-- self.width[u' '] = self.spacewidth
-- self.advance[u' '] = self.spacewidth
-- self.offsets[u' '] = (0, 0)
-+ if ' ' not in self.chars:
-+ self.chars[' '] = renpy.display.pgrender.surface((self.spacewidth, height), True)
-+ self.width[' '] = self.spacewidth
-+ self.advance[' '] = self.spacewidth
-+ self.offsets[' '] = (0, 0)
-
-- if u'\u00a0' not in self.chars:
-- self.chars[u'\u00a0'] = self.chars[u' ']
-- self.width[u'\u00a0'] = self.width[u' ']
-- self.advance[u'\u00a0'] = self.advance[u' ']
-- self.offsets[u'\u00a0'] = self.offsets[u' ']
-+ if '\u00a0' not in self.chars:
-+ self.chars['\u00a0'] = self.chars[' ']
-+ self.width['\u00a0'] = self.width[' ']
-+ self.advance['\u00a0'] = self.advance[' ']
-+ self.offsets['\u00a0'] = self.offsets[' ']
-
-- self.chars[u'\u200b'] = renpy.display.pgrender.surface((0, height), True)
-- self.width[u'\u200b'] = 0
-- self.advance[u'\u200b'] = 0
-- self.offsets[u'\u200b'] = (0, 0)
-+ self.chars['\u200b'] = renpy.display.pgrender.surface((0, height), True)
-+ self.width['\u200b'] = 0
-+ self.advance['\u200b'] = 0
-+ self.offsets['\u200b'] = (0, 0)
-
-
-
-@@ -330,7 +330,7 @@ class BMFont(ImageFont):
- elif kind == "page":
- pages[int(args["id"])] = renpy.display.im.Image(args["file"]).load(unscaled=True)
- elif kind == "char":
-- c = unichr(int(args["id"]))
-+ c = chr(int(args["id"]))
- x = int(args["x"])
- y = int(args["y"])
- w = int(args["width"])
-@@ -350,17 +350,17 @@ class BMFont(ImageFont):
-
- f.close()
-
-- if u'\u00a0' not in self.chars:
-- self.chars[u'\u00a0'] = self.chars[u' ']
-- self.width[u'\u00a0'] = self.width[u' ']
-- self.advance[u'\u00a0'] = self.advance[u' ']
-- self.offsets[u'\u00a0'] = self.offsets[u' ']
-+ if '\u00a0' not in self.chars:
-+ self.chars['\u00a0'] = self.chars[' ']
-+ self.width['\u00a0'] = self.width[' ']
-+ self.advance['\u00a0'] = self.advance[' ']
-+ self.offsets['\u00a0'] = self.offsets[' ']
-
-
-- self.chars[u'\u200b'] = renpy.display.pgrender.surface((0, self.height), True)
-- self.width[u'\u200b'] = 0
-- self.advance[u'\u200b'] = 0
-- self.offsets[u'\u200b'] = (0, 0)
-+ self.chars['\u200b'] = renpy.display.pgrender.surface((0, self.height), True)
-+ self.width['\u200b'] = 0
-+ self.advance['\u200b'] = 0
-+ self.offsets['\u200b'] = (0, 0)
-
- class ScaledImageFont(ImageFont):
- """
-@@ -376,14 +376,14 @@ class ScaledImageFont(ImageFont):
- self.baseline = scale(parent.baseline)
- self.default_kern = scale(parent.default_kern)
-
-- self.width = { k : scale(v) for k, v in parent.width.iteritems() }
-- self.advance = { k : scale(v) for k, v in parent.advance.iteritems() }
-- self.offsets = { k : (scale(v[0]), scale(v[1])) for k, v in parent.offsets.iteritems() }
-- self.kerns = { k : scale(v) for k, v in parent.kerns.iteritems() }
-+ self.width = { k : scale(v) for k, v in parent.width.items() }
-+ self.advance = { k : scale(v) for k, v in parent.advance.items() }
-+ self.offsets = { k : (scale(v[0]), scale(v[1])) for k, v in parent.offsets.items() }
-+ self.kerns = { k : scale(v) for k, v in parent.kerns.items() }
-
- self.chars = { }
-
-- for k, v in parent.chars.iteritems():
-+ for k, v in parent.chars.items():
- w, h = v.get_size()
- nw = scale(w)
- nh = scale(h)
-@@ -392,7 +392,7 @@ class ScaledImageFont(ImageFont):
-
- def register_sfont(name=None, size=None, bold=False, italics=False, underline=False,
- filename=None, spacewidth=10, default_kern=0, kerns={},
-- charset=u"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"):
-+ charset="!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"):
-
- """
- :doc: image_fonts
-@@ -570,12 +570,12 @@ def load_face(fn):
-
- pygame.sysfont.initsysfonts()
-
-- for v in pygame.sysfont.Sysfonts.itervalues():
-+ for v in pygame.sysfont.Sysfonts.values():
- if v is not None:
-- for _flags, ffn in v.iteritems():
-+ for _flags, ffn in v.items():
- for i in fonts:
- if ffn.lower().endswith(i):
-- font_file = file(ffn, "rb")
-+ font_file = open(ffn, "rb")
- break
-
- if font_file:
-@@ -661,7 +661,7 @@ def free_memory():
-
-
- def load_image_fonts():
-- for i in image_fonts.itervalues():
-+ for i in image_fonts.values():
- i.load()
-
-
-diff --git a/renpy/text/text.py b/renpy/text/text.py
-index 0d78ddf..748dbbd 100644
---- a/renpy/text/text.py
-+++ b/renpy/text/text.py
-@@ -844,7 +844,7 @@ class Layout(object):
- if isinstance(i[0], (TextSegment, SpaceSegment, DisplayableSegment)):
- return
-
-- line.extend(tss[-1].subsegment(u" "))
-+ line.extend(tss[-1].subsegment(" "))
-
- for type, text in tokens: #@ReservedAssignment
-
-@@ -864,7 +864,7 @@ class Layout(object):
- continue
-
- elif type == DISPLAYABLE:
-- line.append((DisplayableSegment(tss[-1], text, renders), u""))
-+ line.append((DisplayableSegment(tss[-1], text, renders), ""))
- continue
-
- # Otherwise, we have a text tag.
-@@ -896,7 +896,7 @@ class Layout(object):
-
- elif tag == "space":
- width = self.scale_int(int(value))
-- line.append((SpaceSegment(tss[-1], width=width), u""))
-+ line.append((SpaceSegment(tss[-1], width=width), ""))
-
- elif tag == "vspace":
- # Duplicates from the newline tag.
-@@ -906,7 +906,7 @@ class Layout(object):
- if line:
- paragraphs.append(line)
-
-- line = [ (SpaceSegment(tss[-1], height=height), u"") ]
-+ line = [ (SpaceSegment(tss[-1], height=height), "") ]
- paragraphs.append(line)
-
- line = [ ]
-@@ -1295,7 +1295,7 @@ class Text(renpy.display.core.Displayable):
-
- # Check that the text is all text-able things.
- for i in text:
-- if not isinstance(i, (basestring, renpy.display.core.Displayable)):
-+ if not isinstance(i, (str, renpy.display.core.Displayable)):
- if renpy.config.developer:
- raise Exception("Cannot display {0!r} as text.".format(i))
- else:
-@@ -1345,15 +1345,15 @@ class Text(renpy.display.core.Displayable):
- s = ""
-
- for i in self.text:
-- if isinstance(i, basestring):
-+ if isinstance(i, str):
- s += i
-
- if len(s) > 25:
-- s = s[:24] + u"\u2026"
-+ s = s[:24] + "\u2026"
- break
-
- s = s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n")
-- return u"Text \"{}\"".format(s)
-+ return "Text \"{}\"".format(s)
-
- def _scope(self, scope, update=True):
- """
-@@ -1377,12 +1377,12 @@ class Text(renpy.display.core.Displayable):
-
- # Perform substitution as necessary.
- for i in text:
-- if isinstance(i, basestring):
-+ if isinstance(i, str):
- if substitute is not False:
- i, did_sub = renpy.substitutions.substitute(i, scope, substitute)
- uses_scope = uses_scope or did_sub
-
-- i = unicode(i)
-+ i = str(i)
-
- new_text.append(i)
-
-@@ -1482,7 +1482,7 @@ class Text(renpy.display.core.Displayable):
-
- for i in self.text:
-
-- if not isinstance(i, basestring):
-+ if not isinstance(i, str):
- continue
-
- rv.append(i)
-@@ -1826,11 +1826,11 @@ class Text(renpy.display.core.Displayable):
-
- for i in text:
-
-- if isinstance(i, unicode):
-+ if isinstance(i, str):
- tokens.extend(textsupport.tokenize(i))
-
- elif isinstance(i, str):
-- tokens.extend(textsupport.tokenize(unicode(i)))
-+ tokens.extend(textsupport.tokenize(str(i)))
-
- elif isinstance(i, renpy.display.core.Displayable):
- tokens.append((DISPLAYABLE, i))
-@@ -1854,7 +1854,7 @@ class Text(renpy.display.core.Displayable):
- kind, text = t
-
- if kind == TEXT and renpy.config.replace_text:
-- rv.append((TEXT, unicode(renpy.config.replace_text(text))))
-+ rv.append((TEXT, str(renpy.config.replace_text(text))))
-
- elif kind != TAG:
- rv.append(t)
-@@ -1906,7 +1906,7 @@ class Text(renpy.display.core.Displayable):
-
- for kind2, text2 in new_contents:
- if isinstance(text2, str):
-- text2 = unicode(text2)
-+ text2 = str(text2)
-
- new_tokens.append((kind2, text2))
-
-diff --git a/renpy/text/textsupport.pyx b/renpy/text/textsupport.pyx
-index feabbc3..5b31613 100644
---- a/renpy/text/textsupport.pyx
-+++ b/renpy/text/textsupport.pyx
-@@ -392,9 +392,9 @@ def linebreak_debug(list glyphs):
- if g.split == SPLIT_INSTEAD:
- rv += "|"
- elif g.split == SPLIT_BEFORE:
-- rv += "[" + unichr(g.character)
-+ rv += "[" + chr(g.character)
- else:
-- rv += unichr(g.character)
-+ rv += chr(g.character)
-
- return rv
-
-diff --git a/renpy/translation.py b/renpy/translation.py
-index 3b62fee..0cd1150 100644
---- a/renpy/translation.py
-+++ b/renpy/translation.py
-@@ -101,7 +101,7 @@ class ScriptTranslator(object):
- continue
-
- if n.name.__class__ is not tuple:
-- if isinstance(n.name, basestring):
-+ if isinstance(n.name, str):
- label = n.name
-
- type_n = n.__class__
-@@ -360,16 +360,16 @@ class StringTranslator(object):
-
- f = open_tl_file(fn)
-
-- f.write(u"translate {} strings:\n".format(language))
-- f.write(u"\n")
-+ f.write("translate {} strings:\n".format(language))
-+ f.write("\n")
-
- for i in self.unknown:
-
- i = quote_unicode(i)
-
-- f.write(u" old \"{}\"\n".format(i))
-- f.write(u" new \"{}\"\n".format(i))
-- f.write(u"\n")
-+ f.write(" old \"{}\"\n".format(i))
-+ f.write(" new \"{}\"\n".format(i))
-+ f.write("\n")
-
- f.close()
-
-@@ -597,13 +597,13 @@ def open_tl_file(fn):
- pass
-
- f = io.open(fn, "a", encoding="utf-8")
-- f.write(u"\ufeff")
-+ f.write("\ufeff")
-
- else:
- f = io.open(fn, "a", encoding="utf-8")
-
-- f.write(u"# TODO: Translation updated at {}\n".format(time.strftime("%Y-%m-%d %H:%M")))
-- f.write(u"\n")
-+ f.write("# TODO: Translation updated at {}\n".format(time.strftime("%Y-%m-%d %H:%M")))
-+ f.write("\n")
-
- return f
-
-@@ -682,17 +682,17 @@ class TranslateFile(object):
- if label is None:
- label = ""
-
-- self.f.write(u"# {}:{}\n".format(t.filename, t.linenumber))
-- self.f.write(u"translate {} {}:\n".format(self.language, t.identifier))
-- self.f.write(u"\n")
-+ self.f.write("# {}:{}\n".format(t.filename, t.linenumber))
-+ self.f.write("translate {} {}:\n".format(self.language, t.identifier))
-+ self.f.write("\n")
-
- for n in t.block:
-- self.f.write(u" # " + n.get_code() + "\n")
-+ self.f.write(" # " + n.get_code() + "\n")
-
- for n in t.block:
-- self.f.write(u" " + n.get_code(self.filter) + "\n")
-+ self.f.write(" " + n.get_code(self.filter) + "\n")
-
-- self.f.write(u"\n")
-+ self.f.write("\n")
-
- def write_strings(self):
- """
-@@ -715,15 +715,15 @@ class TranslateFile(object):
- started = True
-
- self.open()
-- self.f.write(u"translate {} strings:\n".format(self.language))
-- self.f.write(u"\n")
-+ self.f.write("translate {} strings:\n".format(self.language))
-+ self.f.write("\n")
-
- fs = self.filter(s)
-
-- self.f.write(u" # {}:{}\n".format(filename, line))
-- self.f.write(u" old \"{}\"\n".format(quote_unicode(s)))
-- self.f.write(u" new \"{}\"\n".format(quote_unicode(fs)))
-- self.f.write(u"\n")
-+ self.f.write(" # {}:{}\n".format(filename, line))
-+ self.f.write(" old \"{}\"\n".format(quote_unicode(s)))
-+ self.f.write(" new \"{}\"\n".format(quote_unicode(fs)))
-+ self.f.write("\n")
-
- def null_filter(s):
- return s
-diff --git a/renpy/ui.py b/renpy/ui.py
-index 464440b..26ee95d 100644
---- a/renpy/ui.py
-+++ b/renpy/ui.py
-@@ -477,7 +477,7 @@ class Wrapper(renpy.object.Object):
-
- try:
- w = self.function(*args, **keyword)
-- except TypeError, e:
-+ except TypeError as e:
- etype, e, tb = sys.exc_info(); etype
-
- if tb.tb_next is None:
-@@ -799,9 +799,9 @@ def menu(menuitems,
- text = choice_chosen_style
- button = choice_chosen_button_style
-
-- if isinstance(button, basestring):
-+ if isinstance(button, str):
- button = getattr(renpy.game.style, button)
-- if isinstance(text, basestring):
-+ if isinstance(text, str):
- text = getattr(renpy.game.style, text)
-
- button = button[label]
-@@ -826,7 +826,7 @@ def imagemap_compat(ground,
- button_style='hotspot',
- **properties):
-
-- if isinstance(button_style, basestring):
-+ if isinstance(button_style, str):
- button_style = getattr(renpy.game.style, button_style)
-
- fixed(style=style, **properties)
-@@ -995,7 +995,7 @@ def _bar(*args, **properties):
- else:
- style = value.get_style()[0]
-
-- if isinstance(style, basestring):
-+ if isinstance(style, str):
- style = style_group_style(style, NoStyleGroupGiven)
-
- properties["style"] = style
-@@ -1038,7 +1038,7 @@ def viewport(scrollbars=None, **properties):
- viewport_properties = { }
- side_properties = { }
-
-- for k, v in properties.iteritems():
-+ for k, v in properties.items():
- if k.startswith("side_"):
- side_properties[k[5:]] = v
- else:
-@@ -1293,7 +1293,7 @@ returns = renpy.curry.curry(_returns)
-
- def _jumps(label, transition=None):
-
-- if isinstance(transition, basestring):
-+ if isinstance(transition, str):
- transition = getattr(renpy.config, transition)
-
- if transition is not None:
-@@ -1343,6 +1343,6 @@ def screen_id(id_, d):
-
- # Update the wrappers to have names.
- k, v = None, None
--for k, v in globals().iteritems():
-+for k, v in globals().items():
- if isinstance(v, Wrapper):
- v.name = k
-diff --git a/renpy/warp.py b/renpy/warp.py
-index 41bd1be..8675c4e 100644
---- a/renpy/warp.py
-+++ b/renpy/warp.py
-@@ -24,7 +24,6 @@
- # location.
-
- import renpy
--import sets
-
- warp_spec = None
-
-@@ -56,7 +55,7 @@ def warp():
-
- prev = { }
-
-- workset = sets.Set([ n for n in renpy.game.script.namemap.itervalues() if isinstance(n, renpy.ast.Scene) ])
-+ workset = sets.Set([ n for n in renpy.game.script.namemap.values() if isinstance(n, renpy.ast.Scene) ])
- seenset = sets.Set(workset)
-
- # This is called to indicate that next can be executed following node.
-@@ -100,7 +99,7 @@ def warp():
- add(n, n.get_next())
-
- elif getattr(n, 'next', None) is not None:
-- add(n, n.next)
-+ add(n, n.__next__)
-
- # Now, attempt to find a statement preceding the line that the
- # user wants to warp to.
-diff --git a/renpy.py b/renpy.py
-index 7548cf6..847b8d0 100644
---- a/renpy.py
-+++ b/renpy.py
-@@ -68,7 +68,7 @@ def path_to_saves(gamedir, save_directory=None):
- if os.path.isdir(rv) and test_writable(rv):
- break
-
-- print "Saving to", rv
-+ print("Saving to", rv)
-
- # We return the last path as the default.
-
-@@ -94,7 +94,7 @@ def path_to_saves(gamedir, save_directory=None):
- except:
- rv = url.path.UTF8String().decode("utf-8")
-
-- print "Saving to", rv
-+ print("Saving to", rv)
- return rv
-
- # No save directory given.
-@@ -151,7 +151,7 @@ try:
- import ast; ast
- except:
- raise
-- print "Ren'Py requires at least python 2.6."
-+ print("Ren'Py requires at least python 2.6.")
- sys.exit(0)
-
- android = ("ANDROID_PRIVATE" in os.environ)
-@@ -186,8 +186,8 @@ def main():
- try:
- import renpy.bootstrap
- except ImportError:
-- print >>sys.stderr, "Could not import renpy.bootstrap. Please ensure you decompressed Ren'Py"
-- print >>sys.stderr, "correctly, preserving the directory structure."
-+ print("Could not import renpy.bootstrap. Please ensure you decompressed Ren'Py", file=sys.stderr)
-+ print("correctly, preserving the directory structure.", file=sys.stderr)
- raise
-
- renpy.bootstrap.bootstrap(renpy_base)
-diff --git a/tutorial/game/examples.rpy b/tutorial/game/examples.rpy
-index 6612f99..216ffd2 100644
---- a/tutorial/game/examples.rpy
-+++ b/tutorial/game/examples.rpy
-@@ -128,7 +128,7 @@ init python hide:
-
- for fn in files:
-
-- f = file(fn, "r")
-+ f = open(fn, "r")
-
- open_examples = set()
-
diff --git a/pcr/renpy-python3/renpy b/pcr/renpy-python3/renpy
deleted file mode 100644
index dfa11b101..000000000
--- a/pcr/renpy-python3/renpy
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/sh
-
-exec python /usr/share/renpy/renpy.py "$@"
diff --git a/pcr/renpy-python3/renpy-ffmpeg30.patch b/pcr/renpy-python3/renpy-ffmpeg30.patch
deleted file mode 100644
index 026719750..000000000
--- a/pcr/renpy-python3/renpy-ffmpeg30.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 4aac7ca5a59960ec776e3c4cd74a30f269342502 Mon Sep 17 00:00:00 2001
-From: Markus Koschany <apo@debian.org>
-Date: Wed, 27 Jan 2016 00:43:37 +0100
-Subject: [PATCH] ffmpeg
-
----
- module/ffdecode.c | 26 +++++++++++++-------------
- 1 file changed, 13 insertions(+), 13 deletions(-)
-
-diff --git a/module/ffdecode.c b/module/ffdecode.c
-index 71704cf..085000d 100644
---- a/module/ffdecode.c
-+++ b/module/ffdecode.c
-@@ -103,8 +103,8 @@ typedef struct VideoState {
- compensation */
-
- #ifndef HAS_RESAMPLE
-- uint8_t audio_buf1[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2] __attribute__ ((aligned (16))) ;
-- uint8_t audio_buf2[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2] __attribute__ ((aligned (16))) ;
-+ uint8_t audio_buf1[(192000 * 3) / 2] __attribute__ ((aligned (16))) ;
-+ uint8_t audio_buf2[(192000 * 3) / 2] __attribute__ ((aligned (16))) ;
- #else
- uint8_t *audio_buf1;
- #endif
-@@ -583,7 +583,7 @@ static int video_refresh(void *opaque)
-
- is->first_frame = 0;
-
-- av_free(vp->frame);
-+ av_frame_free(&vp->frame);
- vp->frame = NULL;
-
- /* update queue size and signal for next picture */
-@@ -635,13 +635,13 @@ static void alloc_picture(void *opaque, PyObject *pysurf)
-
- pixel = SDL_MapRGBA(surf->format, 1, 2, 3, 4);
- if (bytes[0] == 4 && bytes[1] == 1) {
-- vp->fmt = PIX_FMT_ARGB;
-+ vp->fmt = AV_PIX_FMT_ARGB;
- } else if (bytes[0] == 4 && bytes[1] == 3) {
-- vp->fmt = PIX_FMT_ABGR;
-+ vp->fmt = AV_PIX_FMT_ABGR;
- } else if (bytes[0] == 1) {
-- vp->fmt = PIX_FMT_RGBA;
-+ vp->fmt = AV_PIX_FMT_RGBA;
- } else {
-- vp->fmt = PIX_FMT_BGRA;
-+ vp->fmt = AV_PIX_FMT_BGRA;
- }
-
- pixel = SDL_MapRGBA(surf->format, 0, 0, 0, 255);
-@@ -764,7 +764,7 @@ static int video_thread(void *arg)
- double pts;
-
- for(;;) {
-- frame = avcodec_alloc_frame();
-+ frame = av_frame_alloc();
-
- while (is->paused && !is->videoq.abort_request) {
- SDL_Delay(2);
-@@ -824,10 +824,10 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
- int resample_changed, audio_resample;
-
- if (!is->frame) {
-- if (!(is->frame = avcodec_alloc_frame()))
-+ if (!(is->frame = av_frame_alloc()))
- return AVERROR(ENOMEM);
- } else
-- avcodec_get_frame_defaults(is->frame);
-+ av_frame_unref(is->frame);
-
- if (flush_complete)
- break;
-@@ -1244,9 +1244,9 @@ static int stream_component_open(VideoState *is, int stream_index)
- /* prepare audio output */
- if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (enc->channels > 0) {
-- enc->request_channels = FFMIN(2, enc->channels);
-+ enc->request_channel_layout = av_get_default_channel_layout(FFMIN(2, enc->channels));
- } else {
-- enc->request_channels = 2;
-+ enc->request_channel_layout = av_get_default_channel_layout(2);
- }
- }
-
-@@ -1653,7 +1653,7 @@ void ffpy_stream_close(VideoState *is)
- for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
- vp = &is->pictq[i];
- if (vp->frame) {
-- av_free(vp->frame);
-+ av_frame_free(&vp->frame);
- }
- }
-
diff --git a/pcr/renpy-python3/renpy.desktop b/pcr/renpy-python3/renpy.desktop
deleted file mode 100644
index 4fa6bbd16..000000000
--- a/pcr/renpy-python3/renpy.desktop
+++ /dev/null
@@ -1,9 +0,0 @@
-[Desktop Entry]
-Version=1.0
-Type=Application
-Name=Ren'Py
-GenericName=renpy
-Comment=Ren'Py is a visual novel engine that helps you use words, images, and sounds to tell interactive stories that run on computers and mobile devices.
-Icon=renpy
-Exec=renpy
-Categories=Game;AdventureGame;
diff --git a/pcr/renpy-python3/renpy.png b/pcr/renpy-python3/renpy.png
deleted file mode 100644
index c7e1f9dfb..000000000
--- a/pcr/renpy-python3/renpy.png
+++ /dev/null
Binary files differ