mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
Fix broken pickling in Python 3 build
This commit is contained in:
parent
ed9bed425f
commit
15b0ba45f9
@ -21,10 +21,14 @@ context between all objects written by that Pickler.
|
||||
Unfortunately, cPickle cannot be supported, because it does not
|
||||
support extensions of this nature. """
|
||||
|
||||
from types import *
|
||||
from copy_reg import dispatch_table
|
||||
import sys
|
||||
from panda3d.core import BamWriter, BamReader
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
from copyreg import dispatch_table
|
||||
else:
|
||||
from copy_reg import dispatch_table
|
||||
|
||||
# A funny replacement for "import pickle" so we don't get confused
|
||||
# with the local pickle.py.
|
||||
pickle = __import__('pickle')
|
||||
@ -60,7 +64,7 @@ class Pickler(pickle.Pickler):
|
||||
|
||||
# Check for a class with a custom metaclass; treat as regular class
|
||||
try:
|
||||
issc = issubclass(t, TypeType)
|
||||
issc = issubclass(t, type)
|
||||
except TypeError: # t is not a class (old Boost; see SF #502085)
|
||||
issc = 0
|
||||
if issc:
|
||||
@ -91,12 +95,12 @@ class Pickler(pickle.Pickler):
|
||||
(t.__name__, obj))
|
||||
|
||||
# Check for string returned by reduce(), meaning "save as global"
|
||||
if type(rv) is StringType:
|
||||
if type(rv) is str:
|
||||
self.save_global(obj, rv)
|
||||
return
|
||||
|
||||
# Assert that reduce() returned a tuple
|
||||
if type(rv) is not TupleType:
|
||||
if type(rv) is not tuple:
|
||||
raise PicklingError("%s must return string or tuple" % reduce)
|
||||
|
||||
# Assert that it returned an appropriately sized tuple
|
||||
@ -131,21 +135,20 @@ class Unpickler(pickle.Unpickler):
|
||||
value = func(*args)
|
||||
|
||||
stack[-1] = value
|
||||
pickle.Unpickler.dispatch[pickle.REDUCE] = load_reduce
|
||||
|
||||
#FIXME: how to replace in Python 3?
|
||||
if sys.version_info < (3, 0):
|
||||
pickle.Unpickler.dispatch[pickle.REDUCE] = load_reduce
|
||||
|
||||
|
||||
# Shorthands
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
from io import BytesIO
|
||||
|
||||
def dump(obj, file, protocol=None):
|
||||
Pickler(file, protocol).dump(obj)
|
||||
|
||||
def dumps(obj, protocol=None):
|
||||
file = StringIO()
|
||||
file = BytesIO()
|
||||
Pickler(file, protocol).dump(obj)
|
||||
return file.getvalue()
|
||||
|
||||
@ -153,5 +156,5 @@ def load(file):
|
||||
return Unpickler(file).load()
|
||||
|
||||
def loads(str):
|
||||
file = StringIO(str)
|
||||
file = BytesIO(str)
|
||||
return Unpickler(file).load()
|
||||
|
@ -4703,9 +4703,18 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
|
||||
if (args_type == AT_single_arg) {
|
||||
out << "#if PY_MAJOR_VERSION >= 3\n";
|
||||
indent(out, indent_level)
|
||||
<< param_name << "_str = PyUnicode_AsUTF8AndSize(arg, &"
|
||||
<< param_name << "_len);\n";
|
||||
// As a special hack to fix pickling in Python 3, if the method name
|
||||
// starts with py_decode_, we take a bytes object instead of a str.
|
||||
if (remap->_cppfunc->get_local_name().substr(0, 10) == "py_decode_") {
|
||||
indent(out, indent_level) << "if (PyBytes_AsStringAndSize(arg, &"
|
||||
<< param_name << "_str, &" << param_name << "_len) == -1) {\n";
|
||||
indent(out, indent_level + 2) << param_name << "_str = NULL;\n";
|
||||
indent(out, indent_level) << "}\n";
|
||||
} else {
|
||||
indent(out, indent_level)
|
||||
<< param_name << "_str = PyUnicode_AsUTF8AndSize(arg, &"
|
||||
<< param_name << "_len);\n";
|
||||
}
|
||||
out << "#else\n"; // NB. PyString_AsStringAndSize also accepts a PyUnicode.
|
||||
indent(out, indent_level) << "if (PyString_AsStringAndSize(arg, &"
|
||||
<< param_name << "_str, &" << param_name << "_len) == -1) {\n";
|
||||
@ -4720,11 +4729,11 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
+ "_str, &" + param_name + "_len";
|
||||
}
|
||||
|
||||
// if (TypeManager::is_const_ptr_to_basic_string_char(orig_type)) {
|
||||
// pexpr_string = "&std::string(" + param_name + "_str, " + param_name +
|
||||
// "_len)"; } else {
|
||||
pexpr_string = param_name + "_str, " + param_name + "_len";
|
||||
// }
|
||||
//if (TypeManager::is_const_ptr_to_basic_string_char(orig_type)) {
|
||||
// pexpr_string = "&std::string(" + param_name + "_str, " + param_name + "_len)";
|
||||
//} else {
|
||||
pexpr_string = param_name + "_str, " + param_name + "_len";
|
||||
//}
|
||||
expected_params += "str";
|
||||
}
|
||||
// Remember to clear the TypeError that any of the above methods raise.
|
||||
|
@ -156,7 +156,11 @@ __reduce_persist__(PyObject *self, PyObject *pickler) const {
|
||||
}
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject *result = Py_BuildValue("(O(y#))", func, bam_stream.data(), (Py_ssize_t) bam_stream.size());
|
||||
#else
|
||||
PyObject *result = Py_BuildValue("(O(s#))", func, bam_stream.data(), (Py_ssize_t) bam_stream.size());
|
||||
#endif
|
||||
Py_DECREF(func);
|
||||
Py_DECREF(this_class);
|
||||
return result;
|
||||
|
@ -110,7 +110,11 @@ __reduce_persist__(PyObject *self, PyObject *pickler) const {
|
||||
}
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject *result = Py_BuildValue("(O(Oy#))", func, this_class, bam_stream.data(), (Py_ssize_t) bam_stream.size());
|
||||
#else
|
||||
PyObject *result = Py_BuildValue("(O(Os#))", func, this_class, bam_stream.data(), (Py_ssize_t) bam_stream.size());
|
||||
#endif
|
||||
Py_DECREF(func);
|
||||
Py_DECREF(this_class);
|
||||
return result;
|
||||
@ -212,10 +216,18 @@ py_decode_TypedWritable_from_bam_stream_persist(PyObject *pickler, PyObject *thi
|
||||
|
||||
PyObject *result;
|
||||
if (py_reader != NULL){
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
result = PyObject_CallFunction(func, (char *)"(y#O)", data.data(), (Py_ssize_t) data.size(), py_reader);
|
||||
#else
|
||||
result = PyObject_CallFunction(func, (char *)"(s#O)", data.data(), (Py_ssize_t) data.size(), py_reader);
|
||||
#endif
|
||||
Py_DECREF(py_reader);
|
||||
} else {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
result = PyObject_CallFunction(func, (char *)"(y#)", data.data(), (Py_ssize_t) data.size());
|
||||
#else
|
||||
result = PyObject_CallFunction(func, (char *)"(s#)", data.data(), (Py_ssize_t) data.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user