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([
"src/mceditlib/nbt.pyx",
"src/mceditlib/relight/with_cython.pyx"
])
],
compile_time_env={'IS_PY2': True},
)
for m in mceditlib_ext_modules:
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
# 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 gzip
import zlib
from cStringIO import StringIO
from cpython cimport PyTypeObject, PyUnicode_DecodeUTF8, PyList_Append, PyString_FromStringAndSize
from cpython cimport PyTypeObject, PyUnicode_DecodeUTF8, PyList_Append
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
cdef extern from "cStringIO.h":
struct PycStringIO_CAPI:
int cwrite(object o, char * buf, Py_ssize_t len)
PyTypeObject * OutputType
cdef extern from "cobject.h":
void * PyCObject_Import(char * module_name, char * cobject_name)
IF IS_PY2:
cdef extern from "cStringIO.h":
struct PycStringIO_CAPI:
int cwrite(object o, char * buf, Py_ssize_t len)
PyTypeObject * OutputType
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 PyTypeObject * StringO = PycStringIO.OutputType
cdef PycStringIO_CAPI *PycStringIO = <PycStringIO_CAPI *> PyCObject_Import("cStringIO", "cStringIO_CAPI")
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
@ -131,7 +148,7 @@ cdef class TAG_Value:
def __set__(self, val):
IF UNICODE_NAMES:
if isinstance(val, str):
if isinstance(val, binary_type):
val = PyUnicode_DecodeUTF8(val, len(val), "strict")
ELSE:
if isinstance(val, unicode):
@ -327,7 +344,7 @@ cdef class TAG_String(TAG_Value):
return self._value
def __set__(self, value):
if isinstance(value, str):
if isinstance(value, binary_type):
value = PyUnicode_DecodeUTF8(value, len(value), "strict")
self._value = value
@ -509,7 +526,7 @@ cdef class _TAG_Compound(TAG_Value):
return data
if isinstance(filename_or_buf, basestring):
f = file(filename_or_buf, "wb")
f = open(filename_or_buf, "wb")
f.write(data)
else:
filename_or_buf.write(data)
@ -545,7 +562,7 @@ def load(filename="", buf=None):
:rtype: TAG_Compound
"""
if filename:
buf = file(filename, "rb")
buf = open(filename, "rb")
if hasattr(buf, "read"):
buf = buf.read()
@ -807,7 +824,10 @@ def hexdump(src, length=8):
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)
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):