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