Read-only python3 codepath in nbt.pyx

This commit is contained in:
Nikita Kitaev 2016-10-04 16:32:29 -07:00
parent 5250b2800f
commit bf8aed514f
2 changed files with 39 additions and 17 deletions

View File

@ -23,7 +23,9 @@ include_dirs = [numpy.get_include()]
mceditlib_ext_modules = cythonize([ mceditlib_ext_modules = cythonize([
"src/mceditlib/nbt.pyx", "src/mceditlib/nbt.pyx",
"src/mceditlib/relight/with_cython.pyx" "src/mceditlib/relight/with_cython.pyx"
]) ],
compile_time_env={'IS_PY2': True},
)
for m in mceditlib_ext_modules: for m in mceditlib_ext_modules:
m.include_dirs = include_dirs m.include_dirs = include_dirs

View File

@ -38,25 +38,42 @@ DEF UNICODE_NAMES = True
# For each NBT file loaded, cache all of the unicode strings used for tag names. Saves some hundred kilobytes per # For each NBT file loaded, cache all of the unicode strings used for tag names. Saves some hundred kilobytes per
# file since tag names often appear multiple times # file since tag names often appear multiple times
DEF UNICODE_CACHE = True # The value of the IS_PY2 macro is received from the build script
IF IS_PY2:
DEF UNICODE_CACHE = True
ELSE:
# This codepath is currently unsupported in the python3 version
DEF UNICODE_CACHE = False
import collections import collections
import gzip import gzip
import zlib import zlib
from cStringIO import StringIO from cpython cimport PyTypeObject, PyUnicode_DecodeUTF8, PyList_Append
from cpython cimport PyTypeObject, PyUnicode_DecodeUTF8, PyList_Append, PyString_FromStringAndSize IF IS_PY2:
from cStringIO import StringIO
from cpython cimport PyString_FromStringAndSize
binary_type = str
ELSE:
from io import BytesIO as StringIO
binary_type = bytes
import numpy import numpy
cdef extern from "cStringIO.h": IF IS_PY2:
struct PycStringIO_CAPI: cdef extern from "cStringIO.h":
int cwrite(object o, char * buf, Py_ssize_t len) struct PycStringIO_CAPI:
PyTypeObject * OutputType int cwrite(object o, char * buf, Py_ssize_t len)
cdef extern from "cobject.h": PyTypeObject * OutputType
void * PyCObject_Import(char * module_name, char * cobject_name) cdef extern from "cobject.h":
void * PyCObject_Import(char * module_name, char * cobject_name)
cdef PycStringIO_CAPI *PycStringIO = <PycStringIO_CAPI *> PyCObject_Import("cStringIO", "cStringIO_CAPI") cdef PycStringIO_CAPI *PycStringIO = <PycStringIO_CAPI *> PyCObject_Import("cStringIO", "cStringIO_CAPI")
cdef PyTypeObject * StringO = PycStringIO.OutputType cdef PyTypeObject * StringO = PycStringIO.OutputType
ELSE:
# The equivalent python3 code has not been written, so for now only reading
# is supported in python3
pass
# Tag IDs # Tag IDs
@ -131,7 +148,7 @@ cdef class TAG_Value:
def __set__(self, val): def __set__(self, val):
IF UNICODE_NAMES: IF UNICODE_NAMES:
if isinstance(val, str): if isinstance(val, binary_type):
val = PyUnicode_DecodeUTF8(val, len(val), "strict") val = PyUnicode_DecodeUTF8(val, len(val), "strict")
ELSE: ELSE:
if isinstance(val, unicode): if isinstance(val, unicode):
@ -327,7 +344,7 @@ cdef class TAG_String(TAG_Value):
return self._value return self._value
def __set__(self, value): def __set__(self, value):
if isinstance(value, str): if isinstance(value, binary_type):
value = PyUnicode_DecodeUTF8(value, len(value), "strict") value = PyUnicode_DecodeUTF8(value, len(value), "strict")
self._value = value self._value = value
@ -509,7 +526,7 @@ cdef class _TAG_Compound(TAG_Value):
return data return data
if isinstance(filename_or_buf, basestring): if isinstance(filename_or_buf, basestring):
f = file(filename_or_buf, "wb") f = open(filename_or_buf, "wb")
f.write(data) f.write(data)
else: else:
filename_or_buf.write(data) filename_or_buf.write(data)
@ -545,7 +562,7 @@ def load(filename="", buf=None):
:rtype: TAG_Compound :rtype: TAG_Compound
""" """
if filename: if filename:
buf = file(filename, "rb") buf = open(filename, "rb")
if hasattr(buf, "read"): if hasattr(buf, "read"):
buf = buf.read() buf = buf.read()
@ -807,7 +824,10 @@ def hexdump(src, length=8):
cdef void cwrite(obj, char *buf, size_t len): cdef void cwrite(obj, char *buf, size_t len):
#print "cwrite %s %s %d" % (map(ord, buf[:min(4, len)]), buf[:min(4, len)].decode('ascii', 'replace'), len) #print "cwrite %s %s %d" % (map(ord, buf[:min(4, len)]), buf[:min(4, len)].decode('ascii', 'replace'), len)
PycStringIO.cwrite(obj, buf, len) IF IS_PY2:
PycStringIO.cwrite(obj, buf, len)
ELSE:
raise Exception("[nbt.pyx python3 port] cwrite was not ported to python3")
cdef void save_tag_id(char tagID, object buf): cdef void save_tag_id(char tagID, object buf):