Initial Python 3 port
Many things work, some don't. Notably, genPOI doesn't work, and there's some signedness comparison stuff going on in the C extension. This also completely drops support for Python 2, as maintaining a C extension for both Python 2 and 3 is a pain and not worth it for the 9 months that Python 2 is still going to be supported upstream. The documentation needs to be adjusted as well. All of the few tests we have pass, and rendering a map works, both with a configuration file and without. We can also use optimizeimages. Concerns #1528.
This commit is contained in:
@@ -26,13 +26,13 @@ import stat
|
||||
import sys
|
||||
import time
|
||||
from collections import namedtuple
|
||||
from itertools import chain, izip, product
|
||||
from itertools import chain, product
|
||||
|
||||
from PIL import Image
|
||||
|
||||
import c_overviewer
|
||||
import rendermodes
|
||||
from c_overviewer import resize_half
|
||||
from . import c_overviewer
|
||||
from . import rendermodes
|
||||
from .c_overviewer import resize_half
|
||||
|
||||
from . import nbt, world
|
||||
from .files import FileReplacer, get_fs_caps
|
||||
@@ -95,7 +95,7 @@ do_work(workobj)
|
||||
# small but useful
|
||||
def iterate_base4(d):
|
||||
"""Iterates over a base 4 number with d digits"""
|
||||
return product(xrange(4), repeat=d)
|
||||
return product(range(4), repeat=d)
|
||||
|
||||
|
||||
# A named tuple class storing the row and column bounds for the to-be-rendered
|
||||
@@ -646,7 +646,7 @@ class TileSet(object):
|
||||
bounds = self._find_chunk_range()
|
||||
|
||||
# Calculate the depth of the tree
|
||||
for p in xrange(2, 33): # max 32
|
||||
for p in range(2, 33): # max 32
|
||||
# Will 2^p tiles wide and high suffice?
|
||||
|
||||
# X has twice as many chunks as tiles, then halved since this is a
|
||||
@@ -686,13 +686,13 @@ class TileSet(object):
|
||||
if self.treedepth > curdepth:
|
||||
logging.warning("Your map seems to have expanded beyond its previous bounds.")
|
||||
logging.warning("Doing some tile re-arrangements... just a sec...")
|
||||
for _ in xrange(self.treedepth - curdepth):
|
||||
for _ in range(self.treedepth - curdepth):
|
||||
self._increase_depth()
|
||||
elif self.treedepth < curdepth:
|
||||
logging.warning(
|
||||
"Your map seems to have shrunk. Did you delete some "
|
||||
"chunks? No problem. Re-arranging tiles, just a sec...")
|
||||
for _ in xrange(curdepth - self.treedepth):
|
||||
for _ in range(curdepth - self.treedepth):
|
||||
self._decrease_depth()
|
||||
logging.info(
|
||||
"There, done. I'm switching to --check-tiles mode for "
|
||||
@@ -798,12 +798,12 @@ class TileSet(object):
|
||||
os.rename(getpath("new3"), getpath("3"))
|
||||
|
||||
# Delete the files in the top directory to make sure they get re-created.
|
||||
files = [str(num) + "." + self.imgextension for num in xrange(4)] + \
|
||||
files = [str(num) + "." + self.imgextension for num in range(4)] + \
|
||||
["base." + self.imgextension]
|
||||
for f in files:
|
||||
try:
|
||||
os.unlink(getpath(f))
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
# Ignore file doesn't exist errors
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
@@ -964,7 +964,7 @@ class TileSet(object):
|
||||
if not quadPath_filtered:
|
||||
try:
|
||||
os.unlink(imgpath)
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
# Ignore errors if it's "file doesn't exist"
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
@@ -988,14 +988,14 @@ class TileSet(object):
|
||||
quad = Image.new("RGBA", (192, 192), self.options['bgcolor'])
|
||||
resize_half(quad, src)
|
||||
img.paste(quad, path[0])
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logging.warning("Couldn't open %s. It may be corrupt. Error was '%s'.", path[1], e)
|
||||
logging.warning(
|
||||
"I'm going to try and delete it. You will need to run "
|
||||
"the render again and with --check-tiles.")
|
||||
try:
|
||||
os.unlink(path[1])
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logging.error(
|
||||
"While attempting to delete corrupt image %s, an error was encountered. "
|
||||
"You will need to delete it yourself. Error was '%s'", path[1], e)
|
||||
@@ -1016,7 +1016,7 @@ class TileSet(object):
|
||||
|
||||
try:
|
||||
os.utime(tmppath, (max_mtime, max_mtime))
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
# Ignore errno ENOENT: file does not exist. Due to a race
|
||||
# condition, two processes could conceivably try and update
|
||||
# the same temp file at the same time
|
||||
@@ -1049,7 +1049,7 @@ class TileSet(object):
|
||||
"This may be a bug.", tile)
|
||||
try:
|
||||
os.unlink(imgpath)
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
# ignore only if the error was "file not found"
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
@@ -1062,7 +1062,7 @@ class TileSet(object):
|
||||
if not os.path.exists(dirdest):
|
||||
try:
|
||||
os.makedirs(dirdest)
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
# Ignore errno EEXIST: file exists. Due to a race condition,
|
||||
# two processes could conceivably try and create the same
|
||||
# directory at the same time
|
||||
@@ -1098,7 +1098,7 @@ class TileSet(object):
|
||||
# Some chunks are present on disk but not fully initialized.
|
||||
# This is okay.
|
||||
pass
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logging.error("Could not render chunk %s,%s for some reason. "
|
||||
"This is likely a render primitive option error.", chunkx, chunkz)
|
||||
logging.error("Full error was:", exc_info=1)
|
||||
@@ -1154,7 +1154,7 @@ class TileSet(object):
|
||||
imgpath = tileobj.get_filepath(self.outputdir, self.imgextension)
|
||||
try:
|
||||
tile_mtime = os.stat(imgpath)[stat.ST_MTIME]
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
tile_mtime = 0
|
||||
@@ -1198,7 +1198,7 @@ class TileSet(object):
|
||||
max_child_mtime = 0
|
||||
|
||||
# First, recurse to each of our children
|
||||
for childnum in xrange(4):
|
||||
for childnum in range(4):
|
||||
childpath = path + (childnum,)
|
||||
|
||||
# Check if this sub-tree should actually exist, so that we only
|
||||
@@ -1238,7 +1238,7 @@ class TileSet(object):
|
||||
logging.debug("Testing mtime for composite-tile %s", imgpath)
|
||||
try:
|
||||
tile_mtime = os.stat(imgpath)[stat.ST_MTIME]
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
tile_mtime = 0
|
||||
@@ -1296,7 +1296,7 @@ def unconvert_coords(col, row):
|
||||
|
||||
# col + row = chunkz + chunkz => (col + row)/2 = chunkz
|
||||
# col - row = chunkx + chunkx => (col - row)/2 = chunkx
|
||||
return ((col - row) / 2, (col + row) / 2)
|
||||
return ((col - row) // 2, (col + row) // 2)
|
||||
|
||||
|
||||
######################
|
||||
@@ -1325,9 +1325,9 @@ def get_tiles_by_chunk(chunkcol, chunkrow):
|
||||
# tile above it as well. Also touches the next 4 tiles down (16
|
||||
# rows)
|
||||
if chunkrow % 4 == 0:
|
||||
rowrange = xrange(tilerow - 4, tilerow + 32 + 1, 4)
|
||||
rowrange = range(tilerow - 4, tilerow + 32 + 1, 4)
|
||||
else:
|
||||
rowrange = xrange(tilerow, tilerow + 32 + 1, 4)
|
||||
rowrange = range(tilerow, tilerow + 32 + 1, 4)
|
||||
|
||||
return product(colrange, rowrange)
|
||||
|
||||
@@ -1358,13 +1358,13 @@ def get_chunks_by_tile(tile, regionset):
|
||||
# First do the odd. For each chunk in the tile's odd column the tile
|
||||
# "passes through" three chunk sections.
|
||||
oddcol_sections = []
|
||||
for i, y in enumerate(reversed(xrange(16))):
|
||||
for row in xrange(tile.row + 3 - i * 2, tile.row - 2 - i * 2, -2):
|
||||
for i, y in enumerate(reversed(range(16))):
|
||||
for row in range(tile.row + 3 - i * 2, tile.row - 2 - i * 2, -2):
|
||||
oddcol_sections.append((tile.col + 1, row, y))
|
||||
|
||||
evencol_sections = []
|
||||
for i, y in enumerate(reversed(xrange(16))):
|
||||
for row in xrange(tile.row + 4 - i * 2, tile.row - 3 - i * 2, -2):
|
||||
for i, y in enumerate(reversed(range(16))):
|
||||
for row in range(tile.row + 4 - i * 2, tile.row - 3 - i * 2, -2):
|
||||
evencol_sections.append((tile.col + 2, row, y))
|
||||
evencol_sections.append((tile.col, row, y))
|
||||
|
||||
@@ -1589,7 +1589,7 @@ class RendertileSet(object):
|
||||
# or more of the children down the tree are True.
|
||||
return True
|
||||
|
||||
def __nonzero__(self):
|
||||
def __bool__(self):
|
||||
"""Returns the boolean context of this particular node. If any
|
||||
descendent of this node is True return True. Otherwise, False.
|
||||
|
||||
@@ -1604,8 +1604,8 @@ class RendertileSet(object):
|
||||
# XXX There seems to be something wrong with the num_tiles calculation.
|
||||
# Calculate the number of tiles by iteration and emit a warning if it
|
||||
# does not match.
|
||||
from itertools import imap
|
||||
num = sum(imap(lambda _: 1, self.iterate()))
|
||||
|
||||
num = sum(map(lambda _: 1, self.iterate()))
|
||||
if num != self.num_tiles:
|
||||
logging.error("Please report this to the developers: RendertileSet num_tiles=%r, "
|
||||
"count=%r, children=%r", self.num_tiles, num, self.children)
|
||||
@@ -1619,22 +1619,23 @@ class RendertileSet(object):
|
||||
# XXX There seems to be something wrong with the num_tiles calculation.
|
||||
# Calculate the number of tiles by iteration and emit a warning if it
|
||||
# does not match.
|
||||
from itertools import imap
|
||||
num = sum(imap(lambda _: 1, self.posttraversal()))
|
||||
|
||||
num = sum(map(lambda _: 1, self.posttraversal()))
|
||||
if num != self.num_tiles_all:
|
||||
logging.error("Please report this to the developers: RendertileSet num_tiles_all=%r, "
|
||||
"count_all=%r, children=%r", self.num_tiles, num, self.children)
|
||||
return num
|
||||
|
||||
|
||||
def distance_sort(children, (off_x, off_y)):
|
||||
def distance_sort(children, xxx_todo_changeme):
|
||||
(off_x, off_y) = xxx_todo_changeme
|
||||
order = []
|
||||
for child, (dx, dy) in izip(children, [(-1, -1), (1, -1), (-1, 1), (1, 1)]):
|
||||
for child, (dx, dy) in zip(children, [(-1, -1), (1, -1), (-1, 1), (1, 1)]):
|
||||
x = off_x * 2 + dx
|
||||
y = off_y * 2 + dy
|
||||
order.append((child, (x, y)))
|
||||
|
||||
return sorted(order, key=lambda (_, (x, y)): x * x + y * y)
|
||||
return sorted(order, key=lambda __x_y: __x_y[1][0] * __x_y[1][0] + __x_y[1][1] * __x_y[1][1])
|
||||
|
||||
|
||||
class RenderTile(object):
|
||||
@@ -1733,7 +1734,7 @@ class RenderTile(object):
|
||||
|
||||
path = []
|
||||
|
||||
for level in xrange(depth):
|
||||
for level in range(depth):
|
||||
# Strategy: Find the midpoint of this level, and determine which
|
||||
# quadrant this row/col is in. Then set the bounds to that level
|
||||
# and repeat
|
||||
|
||||
Reference in New Issue
Block a user