tested django-newsletter

This commit is contained in:
Esther Kleinhenz
2018-10-26 15:21:17 +02:00
parent 7ed667d043
commit 811b7c5453
2352 changed files with 448169 additions and 1 deletions
@@ -0,0 +1,247 @@
/*****************************************************************************
Copyright (c) 1996-2002 Zope Foundation and Contributors.
All Rights Reserved.
This software is subject to the provisions of the Zope Public License,
Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
FOR A PARTICULAR PURPOSE
****************************************************************************/
/*
$Id$
Extension Class Definitions
Implementing base extension classes
A base extension class is implemented in much the same way that an
extension type is implemented, except:
- The include file, 'ExtensionClass.h', must be included.
- The type structure is declared to be of type
'PyExtensionClass', rather than of type 'PyTypeObject'.
- The type structure has an additional member that must be defined
after the documentation string. This extra member is a method chain
('PyMethodChain') containing a linked list of method definition
('PyMethodDef') lists. Method chains can be used to implement
method inheritance in C. Most extensions don't use method chains,
but simply define method lists, which are null-terminated arrays
of method definitions. A macro, 'METHOD_CHAIN' is defined in
'ExtensionClass.h' that converts a method list to a method chain.
(See the example below.)
- Module functions that create new instances must be replaced by an
'__init__' method that initializes, but does not create storage for
instances.
- The extension class must be initialized and exported to the module
with::
PyExtensionClass_Export(d,"name",type);
where 'name' is the module name and 'type' is the extension class
type object.
Attribute lookup
Attribute lookup is performed by calling the base extension class
'getattr' operation for the base extension class that includes C
data, or for the first base extension class, if none of the base
extension classes include C data. 'ExtensionClass.h' defines a
macro 'Py_FindAttrString' that can be used to find an object's
attributes that are stored in the object's instance dictionary or
in the object's class or base classes::
v = Py_FindAttrString(self,name);
In addition, a macro is provided that replaces 'Py_FindMethod'
calls with logic to perform the same sort of lookup that is
provided by 'Py_FindAttrString'.
Linking
The extension class mechanism was designed to be useful with
dynamically linked extension modules. Modules that implement
extension classes do not have to be linked against an extension
class library. The macro 'PyExtensionClass_Export' imports the
'ExtensionClass' module and uses objects imported from this module
to initialize an extension class with necessary behavior.
*/
#ifndef EXTENSIONCLASS_H
#define EXTENSIONCLASS_H
#include "Python.h"
#include "import.h"
/* Declarations for objects of type ExtensionClass */
#define EC PyTypeObject
#define PyExtensionClass PyTypeObject
#define EXTENSIONCLASS_BINDABLE_FLAG 1 << 2
#define EXTENSIONCLASS_NOINSTDICT_FLAG 1 << 5
typedef struct {
PyObject_HEAD
} _emptyobject;
static struct ExtensionClassCAPIstruct {
/*****************************************************************************
WARNING: THIS STRUCT IS PRIVATE TO THE EXTENSION CLASS INTERFACE
IMPLEMENTATION AND IS SUBJECT TO CHANGE !!!
*****************************************************************************/
PyObject *(*EC_findiattrs_)(PyObject *self, char *cname);
int (*PyExtensionClass_Export_)(PyObject *dict, char *name,
PyTypeObject *typ);
PyObject *(*PyECMethod_New_)(PyObject *callable, PyObject *inst);
PyExtensionClass *ECBaseType_;
PyExtensionClass *ECExtensionClassType_;
} *PyExtensionClassCAPI = NULL;
#define ECBaseType (PyExtensionClassCAPI->ECBaseType_)
#define ECExtensionClassType (PyExtensionClassCAPI->ECExtensionClassType_)
/* Following are macros that are needed or useful for defining extension
classes:
*/
/* This macro redefines Py_FindMethod to do attribute for an attribute
name given by a C string lookup using extension class meta-data.
This is used by older getattr implementations.
This macro is used in base class implementations of tp_getattr to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed.
Note that in Python 1.4, a getattr operation may be provided that
uses an object argument. Classes that support this new operation
should use Py_FindAttr.
*/
#define EC_findiattrs (PyExtensionClassCAPI->EC_findiattrs_)
#define Py_FindMethod(M,SELF,NAME) (EC_findiattrs((SELF),(NAME)))
/* Do method or attribute lookup for an attribute name given by a C
string using extension class meta-data.
This macro is used in base class implementations of tp_getattro to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed.
Note that in Python 1.4, a getattr operation may be provided that
uses an object argument. Classes that support this new operation
should use Py_FindAttr.
*/
#define Py_FindAttrString(SELF,NAME) (EC_findiattrs((SELF),(NAME)))
/* Do method or attribute lookup using extension class meta-data.
This macro is used in base class implementations of tp_getattr to
lookup methods or attributes that are not managed by the base type
directly. The macro is generally used to search for attributes
after other attribute searches have failed. */
#define Py_FindAttr (ECBaseType->tp_getattro)
/* Do attribute assignment for an attribute.
This macro is used in base class implementations of tp_setattro to
set attributes that are not managed by the base type directly. The
macro is generally used to assign attributes after other attribute
attempts to assign attributes have failed.
*/
#define PyEC_SetAttr(SELF,NAME,V) (ECBaseType->tp_setattro(SELF, NAME, V))
/* Convert a method list to a method chain. */
#define METHOD_CHAIN(DEF) (traverseproc)(DEF)
/* The following macro checks whether a type is an extension class: */
#define PyExtensionClass_Check(TYPE) \
PyObject_TypeCheck((PyObject*)(TYPE), ECExtensionClassType)
/* The following macro checks whether an instance is an extension instance: */
#define PyExtensionInstance_Check(INST) \
PyObject_TypeCheck(Py_TYPE(INST), ECExtensionClassType)
#define CHECK_FOR_ERRORS(MESS)
/* The following macro can be used to define an extension base class
that only provides method and that is used as a pure mix-in class. */
#define PURE_MIXIN_CLASS(NAME,DOC,METHODS) \
static PyExtensionClass NAME ## Type = { PyVarObject_HEAD_INIT(NULL, 0) # NAME, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0 , DOC, (traverseproc)METHODS, }
/* The following macros provide limited access to extension-class
method facilities. */
/* Test for an ExtensionClass method: */
#define PyECMethod_Check(O) PyMethod_Check((O))
/* Create a method object that wraps a callable object and an
instance. Note that if the callable object is an extension class
method, then the new method will wrap the callable object that is
wrapped by the extension class method. Also note that if the
callable object is an extension class method with a reference
count of 1, then the callable object will be rebound to the
instance and returned with an incremented reference count.
*/
#define PyECMethod_New(CALLABLE, INST) \
PyExtensionClassCAPI->PyECMethod_New_((CALLABLE),(INST))
/* Return the instance that is bound by an extension class method. */
#define PyECMethod_Self(M) (PyMethod_Check((M)) ? PyMethod_GET_SELF(M) : NULL)
/* Check whether an object has an __of__ method for returning itself
in the context of it's container. */
#define has__of__(O) (PyExtensionInstance_Check(O) && Py_TYPE(O)->tp_descr_get != NULL)
/* The following macros are used to check whether an instance
or a class' instanses have instance dictionaries: */
#define HasInstDict(O) (_PyObject_GetDictPtr(O) != NULL)
#define ClassHasInstDict(C) ((C)->tp_dictoffset > 0)
/* Get an object's instance dictionary. Use with caution */
#define INSTANCE_DICT(inst) (_PyObject_GetDictPtr(O))
/* Test whether an ExtensionClass, S, is a subclass of ExtensionClass C. */
#define ExtensionClassSubclass_Check(S,C) PyType_IsSubtype((S), (C))
/* Test whether an ExtensionClass instance , I, is a subclass of
ExtensionClass C. */
#define ExtensionClassSubclassInstance_Check(I,C) PyObject_TypeCheck((I), (C))
/* Export an Extension Base class in a given module dictionary with a
given name and ExtensionClass structure.
*/
#define PyExtensionClass_Export(D,N,T) \
if (! ExtensionClassImported || \
PyExtensionClassCAPI->PyExtensionClass_Export_((D),(N),&(T)) < 0) return NULL;
#define ExtensionClassImported \
((PyExtensionClassCAPI != NULL) || \
(PyExtensionClassCAPI = PyCapsule_Import("ExtensionClass.CAPI2", 0)))
#endif /* EXTENSIONCLASS_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,343 @@
##############################################################################
#
# Copyright (c) 2003 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ExtensionClass
Extension Class exists to support types derived from the old ExtensionType
meta-class that preceeded Python 2.2 and new-style classes.
As a meta-class, ExtensionClass provides the following features:
- Support for a class initialiser:
>>> from ExtensionClass import ExtensionClass, Base
>>> class C(Base):
... def __class_init__(self):
... print('class init called')
... print(self.__name__)
... def bar(self):
... return 'bar called'
class init called
C
>>> c = C()
>>> int(c.__class__ is C)
1
>>> int(c.__class__ is type(c))
1
- Making sure that every instance of the meta-class has Base as a base class:
>>> X = ExtensionClass('X', (), {})
>>> Base in X.__mro__
1
- Provide an inheritedAttribute method for looking up attributes in
base classes:
>>> class C2(C):
... def bar(*a):
... return C2.inheritedAttribute('bar')(*a), 42
class init called
C2
>>> o = C2()
>>> o.bar()
('bar called', 42)
This is for compatability with old code. New code should use super
instead.
The base class, Base, exists mainly to support the __of__ protocol.
The __of__ protocol is similar to __get__ except that __of__ is called
when an implementor is retrieved from an instance as well as from a
class:
>>> class O(Base):
... def __of__(*a):
... return a
>>> o1 = O()
>>> o2 = O()
>>> C.o1 = o1
>>> c.o2 = o2
>>> c.o1 == (o1, c)
1
>>> C.o1 == o1
1
>>> int(c.o2 == (o2, c))
1
We accomplish this by making a class that implements __of__ a
descriptor and treating all descriptor ExtensionClasses this way. That
is, if an extension class is a descriptor, it's __get__ method will be
called even when it is retrieved from an instance.
>>> class O(Base):
... def __get__(*a):
... return a
...
>>> o1 = O()
>>> o2 = O()
>>> C.o1 = o1
>>> c.o2 = o2
>>> int(c.o1 == (o1, c, type(c)))
1
>>> int(C.o1 == (o1, None, type(c)))
1
>>> int(c.o2 == (o2, c, type(c)))
1
"""
import inspect
import os
import platform
import sys
if sys.version_info > (3, ):
import copyreg as copy_reg
else: # pragma: no cover
import copy_reg
_IS_PYPY = platform.python_implementation() == 'PyPy'
_IS_PURE = 'PURE_PYTHON' in os.environ
C_EXTENSION = not (_IS_PYPY or _IS_PURE)
def of_get(self, inst, type_=None):
if not issubclass(type(type_), ExtensionClass):
return self
if inst is not None:
return self.__of__(inst)
return self
def pmc_init_of(cls):
# set up __get__ if __of__ is implemented
of = getattr(cls, '__of__', None)
if of is not None:
cls.__get__ = of_get
else:
get = getattr(cls, '__get__', None)
if (get is not None and
(get is of_get or getattr(get, '__func__', None) is of_get)):
del cls.__get__
_Base = type('dummy', (), {})
_NoInstanceDictionaryBase = type('dummy', (), {})
def _add_classic_mro(mro, cls):
if cls not in mro:
mro.append(cls)
for base in cls.__bases__:
if base not in mro:
mro.append(base)
_add_classic_mro(mro, base)
class ExtensionClass(type):
def __new__(cls, name, bases=(), attrs=None):
attrs = {} if attrs is None else attrs
# Make sure we have an ExtensionClass instance as a base
if (name != 'Base' and
not any(isinstance(b, ExtensionClass) for b in bases)):
bases += (_Base,)
if ('__slots__' not in attrs and
any(issubclass(b, _NoInstanceDictionaryBase) for b in bases)):
attrs['__slots__'] = []
cls = type.__new__(cls, name, bases, attrs)
# Inherit docstring
if not cls.__doc__:
cls.__doc__ = super(cls, cls).__doc__
# set up __get__ if __of__ is implemented
pmc_init_of(cls)
# call class init method
if hasattr(cls, '__class_init__'):
class_init = cls.__class_init__
if hasattr(class_init, '__func__'):
class_init = class_init.__func__
class_init(cls)
return cls
def __basicnew__(self):
"""Create a new empty object"""
return self.__new__(self)
def mro(self):
"""Compute an mro using the 'encapsulated base' scheme"""
mro = [self]
for base in self.__bases__:
if hasattr(base, '__mro__'):
for c in base.__mro__:
if c in (_Base, _NoInstanceDictionaryBase, object):
continue
if c in mro:
continue
mro.append(c)
else: # pragma: no cover (python 2 only)
_add_classic_mro(mro, base)
if _NoInstanceDictionaryBase in self.__bases__:
mro.append(_NoInstanceDictionaryBase)
elif self.__name__ != 'Base':
mro.append(_Base)
mro.append(object)
return mro
def inheritedAttribute(self, name):
"""Look up an inherited attribute"""
return getattr(super(self, self), name)
def __setattr__(self, name, value):
if name not in ('__get__', '__doc__', '__of__'):
if (name.startswith('__') and name.endswith('__') and
name.count('_') == 4):
raise TypeError(
"can't set attributes of built-in/extension type '%s.%s' "
"if the attribute name begins and ends with __ and "
"contains only 4 _ characters" %
(self.__module__, self.__name__))
return type.__setattr__(self, name, value)
# Base and object are always moved to the last two positions
# in a subclasses mro, no matter how they are declared in the
# hierarchy. This means the Base_* methods effectively don't have
# to care or worry about using super(): it's always object.
def Base_getattro(self, name):
descr = None
for base in type(self).__mro__:
if name in base.__dict__:
descr = base.__dict__[name]
break
if descr is not None and inspect.isdatadescriptor(descr):
return descr.__get__(self, type(self))
try:
# Don't do self.__dict__ otherwise you get recursion.
inst_dict = object.__getattribute__(self, '__dict__')
except AttributeError:
pass
else:
if name in inst_dict:
descr = inst_dict[name]
# If the tp_descr_get of res is of_get, then call it.
if name == '__parent__' or not isinstance(descr, Base):
return descr
if descr is not None:
descr_get = getattr(descr, '__get__', None)
if descr_get is None:
return descr
return descr_get(self, type(self))
raise AttributeError(
"'%.50s' object has not attribute '%s'",
type(self).__name__, name)
def _slotnames(self):
slotnames = copy_reg._slotnames(type(self))
return [x for x in slotnames
if not x.startswith('_p_') and
not x.startswith('_v_')]
def Base__getstate__(self):
idict = getattr(self, '__dict__', None)
slotnames = _slotnames(self)
if idict is not None:
d = dict([x for x in idict.items()
if not x[0].startswith('_p_') and
not x[0].startswith('_v_')])
else:
d = None
if slotnames:
s = {}
for slotname in slotnames:
value = getattr(self, slotname, self)
if value is not self:
s[slotname] = value
return d, s
return d
def Base__setstate__(self, state):
""" See IPersistent.
"""
try:
inst_dict, slots = state
except:
inst_dict, slots = state, ()
idict = getattr(self, '__dict__', None)
if inst_dict is not None:
if idict is None:
raise TypeError('No instance dict') # pragma no cover
idict.clear()
idict.update(inst_dict)
slotnames = _slotnames(self)
if slotnames:
for k, v in slots.items():
setattr(self, k, v)
def Base__reduce__(self):
gna = getattr(self, '__getnewargs__', lambda: ())
return (copy_reg.__newobj__,
(type(self),) + gna(), self.__getstate__())
def Base__new__(cls, *args, **kw):
return object.__new__(cls)
Base = ExtensionClass("Base", (object, ), {
'__slots__': (),
'__getattribute__': Base_getattro,
'__getstate__': Base__getstate__,
'__setstate__': Base__setstate__,
'__reduce__': Base__reduce__,
'__new__': Base__new__,
})
_Base = Base
class NoInstanceDictionaryBase(Base):
__slots__ = ()
_NoInstanceDictionaryBase = NoInstanceDictionaryBase
if C_EXTENSION: # pragma no cover
from ._ExtensionClass import * # NOQA
# We always want to get the CAPI2 value (if possible) so that
# MethodObject and anything else using the PyExtensionClass_Export
# macro from ExtensionClass.h doesn't break with an AttributeError
try:
from ._ExtensionClass import CAPI2
except ImportError: # pragma: no cover
pass
@@ -0,0 +1,53 @@
/*****************************************************************************
Copyright (c) 2012 Zope Foundation and Contributors.
All Rights Reserved.
This software is subject to the provisions of the Zope Public License,
Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
FOR A PARTICULAR PURPOSE
****************************************************************************/
#ifndef PERSISTENT__COMPAT_H
#define PERSISTENT__COMPAT_H
#include "Python.h"
#if PY_MAJOR_VERSION >= 3
#define PY3K
#endif
#ifdef PY3K
#define INTERN PyUnicode_InternFromString
#define INTERN_INPLACE PyUnicode_InternInPlace
#define NATIVE_CHECK PyUnicode_Check
#define NATIVE_CHECK_EXACT PyUnicode_CheckExact
#define NATIVE_FROM_STRING PyUnicode_FromString
#define NATIVE_FROM_STRING_AND_SIZE PyUnicode_FromStringAndSize
#define INT_FROM_LONG(x) PyLong_FromLong(x)
#define INT_CHECK(x) PyLong_Check(x)
#define INT_AS_LONG(x) PyLong_AS_LONG(x)
#define HAS_TP_DESCR_GET(ob) 1
#else
#define INTERN PyString_InternFromString
#define INTERN_INPLACE PyString_InternInPlace
#define NATIVE_CHECK PyString_Check
#define NATIVE_CHECK_EXACT PyString_CheckExact
#define NATIVE_FROM_STRING PyString_FromString
#define NATIVE_FROM_STRING_AND_SIZE PyString_FromStringAndSize
#define INT_FROM_LONG(x) PyInt_FromLong(x)
#define INT_CHECK(x) PyInt_Check(x)
#define INT_AS_LONG(x) PyInt_AS_LONG(x)
#define HAS_TP_DESCR_GET(ob) PyType_HasFeature(Py_TYPE(ob), Py_TPFLAGS_HAVE_CLASS)
#endif
#endif
@@ -0,0 +1,432 @@
/*****************************************************************************
Copyright (c) 2001, 2002 Zope Foundation and Contributors.
All Rights Reserved.
This software is subject to the provisions of the Zope Public License,
Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
FOR A PARTICULAR PURPOSE
****************************************************************************/
/* Strings initialized by init_strings() below. */
static PyObject *py___slotnames__, *copy_reg_slotnames, *__newobj__;
static PyObject *py___getnewargs__, *py___getstate__;
static int
pickle_setup(void)
{
PyObject* copy_reg;
#define INIT_STRING(S) if (!(py_ ## S = INTERN(#S))) return -1;
INIT_STRING(__slotnames__);
INIT_STRING(__getnewargs__);
INIT_STRING(__getstate__);
#undef INIT_STRING
#ifdef PY3K
copy_reg = PyImport_ImportModule("copyreg");
#else
copy_reg = PyImport_ImportModule("copy_reg");
#endif
if (!copy_reg) {
return -1;
}
copy_reg_slotnames = PyObject_GetAttrString(copy_reg, "_slotnames");
if (!copy_reg_slotnames)
{
Py_DECREF(copy_reg);
return -1;
}
__newobj__ = PyObject_GetAttrString(copy_reg, "__newobj__");
if (!__newobj__)
{
Py_DECREF(copy_reg);
return -1;
}
return 0;
}
static PyObject * pickle_slotnames(PyTypeObject *cls);
static PyObject * convert_name(PyObject *name);
/****************************************************************************/
static PyObject *
pickle_slotnames(PyTypeObject *cls)
{
PyObject *slotnames;
slotnames = PyDict_GetItem(cls->tp_dict, py___slotnames__);
if (slotnames)
{
int n = PyObject_Not(slotnames);
if (n < 0)
return NULL;
if (n)
slotnames = Py_None;
Py_INCREF(slotnames);
return slotnames;
}
slotnames = PyObject_CallFunctionObjArgs(copy_reg_slotnames,
(PyObject*)cls, NULL);
if (slotnames && !(slotnames == Py_None || PyList_Check(slotnames)))
{
PyErr_SetString(PyExc_TypeError,
"copy_reg._slotnames didn't return a list or None");
Py_DECREF(slotnames);
return NULL;
}
return slotnames;
}
static PyObject *
pickle_copy_dict(PyObject *state)
{
PyObject *copy, *key, *value;
char *ckey;
Py_ssize_t pos = 0;
copy = PyDict_New();
if (!copy)
return NULL;
if (!state)
return copy;
while (PyDict_Next(state, &pos, &key, &value))
{
int is_special;
#ifdef PY3K
if (key && PyUnicode_Check(key))
{
PyObject *converted = convert_name(key);
ckey = PyBytes_AS_STRING(converted);
#else
if (key && PyBytes_Check(key))
{
ckey = PyBytes_AS_STRING(key);
#endif
is_special = (*ckey == '_' &&
(ckey[1] == 'v' || ckey[1] == 'p') &&
ckey[2] == '_');
#ifdef PY3K
Py_DECREF(converted);
#endif
if (is_special) /* skip volatile and persistent */
continue;
}
if (PyObject_SetItem(copy, key, value) < 0)
goto err;
}
return copy;
err:
Py_DECREF(copy);
return NULL;
}
static char pickle___getstate__doc[] =
"Get the object serialization state\n"
"\n"
"If the object has no assigned slots and has no instance dictionary, then \n"
"None is returned.\n"
"\n"
"If the object has no assigned slots and has an instance dictionary, then \n"
"the a copy of the instance dictionary is returned. The copy has any items \n"
"with names starting with '_v_' or '_p_' ommitted.\n"
"\n"
"If the object has assigned slots, then a two-element tuple is returned. \n"
"The first element is either None or a copy of the instance dictionary, \n"
"as described above. The second element is a dictionary with items \n"
"for each of the assigned slots.\n"
;
static PyObject *
pickle___getstate__(PyObject *self)
{
PyObject *slotnames=NULL, *slots=NULL, *state=NULL;
PyObject **dictp;
int n=0;
slotnames = pickle_slotnames(Py_TYPE(self));
if (!slotnames)
return NULL;
dictp = _PyObject_GetDictPtr(self);
if (dictp)
state = pickle_copy_dict(*dictp);
else
{
state = Py_None;
Py_INCREF(state);
}
if (slotnames != Py_None)
{
int i;
slots = PyDict_New();
if (!slots)
goto end;
for (i = 0; i < PyList_GET_SIZE(slotnames); i++)
{
PyObject *name, *value;
char *cname;
int is_special;
name = PyList_GET_ITEM(slotnames, i);
#ifdef PY3K
if (PyUnicode_Check(name))
{
PyObject *converted = convert_name(name);
cname = PyBytes_AS_STRING(converted);
#else
if (PyBytes_Check(name))
{
cname = PyBytes_AS_STRING(name);
#endif
is_special = (*cname == '_' &&
(cname[1] == 'v' || cname[1] == 'p') &&
cname[2] == '_');
#ifdef PY3K
Py_DECREF(converted);
#endif
if (is_special) /* skip volatile and persistent */
{
continue;
}
}
/* Unclear: Will this go through our getattr hook? */
value = PyObject_GetAttr(self, name);
if (value == NULL)
PyErr_Clear();
else
{
int err = PyDict_SetItem(slots, name, value);
Py_DECREF(value);
if (err < 0)
goto end;
n++;
}
}
}
if (n)
state = Py_BuildValue("(NO)", state, slots);
end:
Py_XDECREF(slotnames);
Py_XDECREF(slots);
return state;
}
static int
pickle_setattrs_from_dict(PyObject *self, PyObject *dict)
{
PyObject *key, *value;
Py_ssize_t pos = 0;
if (!PyDict_Check(dict))
{
PyErr_SetString(PyExc_TypeError, "Expected dictionary");
return -1;
}
while (PyDict_Next(dict, &pos, &key, &value))
{
if (PyObject_SetAttr(self, key, value) < 0)
return -1;
}
return 0;
}
static char pickle___setstate__doc[] =
"Set the object serialization state\n\n"
"The state should be in one of 3 forms:\n\n"
"- None\n\n"
" Ignored\n\n"
"- A dictionary\n\n"
" In this case, the object's instance dictionary will be cleared and \n"
" updated with the new state.\n\n"
"- A two-tuple with a string as the first element. \n\n"
" In this case, the method named by the string in the first element will\n"
" be called with the second element.\n\n"
" This form supports migration of data formats.\n\n"
"- A two-tuple with None or a Dictionary as the first element and\n"
" with a dictionary as the second element.\n\n"
" If the first element is not None, then the object's instance dictionary \n"
" will be cleared and updated with the value.\n\n"
" The items in the second element will be assigned as attributes.\n"
;
static PyObject *
pickle___setstate__(PyObject *self, PyObject *state)
{
PyObject *slots=NULL;
if (PyTuple_Check(state))
{
if (!PyArg_ParseTuple(state, "OO:__setstate__", &state, &slots))
return NULL;
}
if (state != Py_None)
{
PyObject **dict;
PyObject *d_key, *d_value;
Py_ssize_t i;
dict = _PyObject_GetDictPtr(self);
if (!dict)
{
PyErr_SetString(PyExc_TypeError,
"this object has no instance dictionary");
return NULL;
}
if (!*dict)
{
*dict = PyDict_New();
if (!*dict)
return NULL;
}
PyDict_Clear(*dict);
i = 0;
while (PyDict_Next(state, &i, &d_key, &d_value)) {
/* normally the keys for instance attributes are
interned. we should try to do that here. */
if (NATIVE_CHECK_EXACT(d_key)) {
Py_INCREF(d_key);
INTERN_INPLACE(&d_key);
Py_DECREF(d_key);
}
if (PyObject_SetItem(*dict, d_key, d_value) < 0)
return NULL;
}
}
if (slots && pickle_setattrs_from_dict(self, slots) < 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
static char pickle___reduce__doc[] =
"Reduce an object to contituent parts for serialization\n"
;
static PyObject *
pickle___reduce__(PyObject *self)
{
PyObject *args=NULL, *bargs=NULL, *state=NULL, *getnewargs=NULL;
int l, i;
getnewargs = PyObject_GetAttr(self, py___getnewargs__);
if (getnewargs)
{
bargs = PyObject_CallFunctionObjArgs(getnewargs, NULL);
Py_DECREF(getnewargs);
if (!bargs)
return NULL;
l = PyTuple_Size(bargs);
if (l < 0)
goto end;
}
else
{
PyErr_Clear();
l = 0;
}
args = PyTuple_New(l+1);
if (args == NULL)
goto end;
Py_INCREF(Py_TYPE(self));
PyTuple_SET_ITEM(args, 0, (PyObject*)(Py_TYPE(self)));
for (i = 0; i < l; i++)
{
Py_INCREF(PyTuple_GET_ITEM(bargs, i));
PyTuple_SET_ITEM(args, i+1, PyTuple_GET_ITEM(bargs, i));
}
state = PyObject_CallMethodObjArgs(self, py___getstate__, NULL);
if (!state)
goto end;
state = Py_BuildValue("(OON)", __newobj__, args, state);
end:
Py_XDECREF(bargs);
Py_XDECREF(args);
return state;
}
/* convert_name() returns a new reference to a string name
or sets an exception and returns NULL.
*/
static PyObject *
convert_name(PyObject *name)
{
#ifdef Py_USING_UNICODE
/* The Unicode to string conversion is done here because the
existing tp_setattro slots expect a string object as name
and we wouldn't want to break those. */
if (PyUnicode_Check(name))
{
name = PyUnicode_AsEncodedString(name, NULL, NULL);
}
else
#endif
if (!PyBytes_Check(name))
{
PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
return NULL;
}
else
Py_INCREF(name);
return name;
}
#define PICKLE_GETSTATE_DEF \
{"__getstate__", (PyCFunction)pickle___getstate__, METH_NOARGS, \
pickle___getstate__doc},
#define PICKLE_SETSTATE_DEF \
{"__setstate__", (PyCFunction)pickle___setstate__, METH_O, \
pickle___setstate__doc},
#define PICKLE_GETNEWARGS_DEF
#define PICKLE_REDUCE_DEF \
{"__reduce__", (PyCFunction)pickle___reduce__, METH_NOARGS, \
pickle___reduce__doc},
#define PICKLE_METHODS PICKLE_GETSTATE_DEF PICKLE_SETSTATE_DEF \
PICKLE_GETNEWARGS_DEF PICKLE_REDUCE_DEF
File diff suppressed because it is too large Load Diff