Commit eefcf53e authored by Boxiang Sun's avatar Boxiang Sun

apply 4.2.2 changes from Acquistion upstream.

The revision is 3f7211c67253983a051b4add25139c0520849de7
parent 09792502
File added
Changelog
=========
4.2.2 (2015-05-19)
------------------
- Make the pure-Python Acquirer objects cooperatively use the
superclass ``__getattribute__`` method, like the C implementation.
See https://github.com/zopefoundation/Acquisition/issues/7.
- The pure-Python implicit acquisition wrapper allows wrapped objects
to use ``object.__getattribute__(self, name)``. This differs from
the C implementation, but is important for compatibility with the
pure-Python versions of libraries like ``persistent``. See
https://github.com/zopefoundation/Acquisition/issues/9.
4.2.1 (2015-04-23)
------------------
- Correct several dangling pointer uses in the C extension,
potentially fixing a few interpreter crashes. See
https://github.com/zopefoundation/Acquisition/issues/5.
4.2 (2015-04-04)
----------------
- Add support for PyPy, PyPy3, and Python 3.2, 3.3, and 3.4.
4.1 (2014-12-18)
----------------
- Bump dependency on ``ExtensionClass`` to match current release.
4.0.3 (2014-11-02)
------------------
- Skip readme.rst tests when tests are run outside a source checkout.
4.0.2 (2014-11-02)
------------------
- Include ``*.rst`` files in the release.
4.0.1 (2014-10-30)
------------------
- Tolerate Unicode attribute names (ASCII only). LP #143358.
- Make module-level ``aq_acquire`` API respect the ``default`` parameter.
LP #1387363.
- Don't raise an attribute error for ``__iter__`` if the fallback to
``__getitem__`` succeeds. LP #1155760.
4.0 (2013-02-24)
----------------
- Added trove classifiers to project metadata.
4.0a1 (2011-12-13)
------------------
- Raise `RuntimeError: Recursion detected in acquisition wrapper` if an object
with a `__parent__` pointer points to a wrapper that in turn points to the
original object.
- Prevent wrappers to be created while accessing `__parent__` on types derived
from Explicit or Implicit base classes.
2.13.8 (2011-06-11)
-------------------
- Fixed a segfault on 64bit platforms when providing the `explicit` argument to
the aq_acquire method of an Acquisition wrapper. Thx to LP #675064 for the
hint to the solution. The code passed an int instead of a pointer into a
function.
2.13.7 (2011-03-02)
-------------------
- Fixed bug: When an object did not implement ``__unicode__``, calling
``unicode(wrapped)`` was calling ``__str__`` with an unwrapped ``self``.
2.13.6 (2011-02-19)
-------------------
- Add ``aq_explicit`` to ``IAcquisitionWrapper``.
- Fixed bug: ``unicode(wrapped)`` was not calling a ``__unicode__``
method on wrapped objects.
2.13.5 (2010-09-29)
-------------------
- Fixed unit tests that failed on 64bit Python on Windows machines.
2.13.4 (2010-08-31)
-------------------
- LP 623665: Fixed typo in Acquisition.h.
2.13.3 (2010-04-19)
-------------------
- Use the doctest module from the standard library and no longer depend on
zope.testing.
2.13.2 (2010-04-04)
-------------------
- Give both wrapper classes a ``__getnewargs__`` method, which causes the ZODB
optimization to fail and create persistent references using the ``_p_oid``
alone. This happens to be the persistent oid of the wrapped object. This lets
these objects to be persisted correctly, even though they are passed to the
ZODB in a wrapped state.
- Added failing tests for http://dev.plone.org/plone/ticket/10318. This shows
an edge-case where AQ wrappers can be pickled using the specific combination
of cPickle, pickle protocol one and a custom Pickler class with an
``inst_persistent_id`` hook. Unfortunately this is the exact combination used
by ZODB3.
2.13.1 (2010-02-23)
-------------------
- Update to include ExtensionClass 2.13.0.
- Fix the ``tp_name`` of the ImplicitAcquisitionWrapper and
ExplicitAcquisitionWrapper to match their Python visible names and thus have
a correct ``__name__``.
- Expand the ``tp_name`` of our extension types to hold the fully qualified
name. This ensures classes have their ``__module__`` set correctly.
2.13.0 (2010-02-14)
-------------------
- Added support for method cache in Acquisition. Patch contributed by
Yoshinori K. Okuji. See https://bugs.launchpad.net/zope2/+bug/486182.
2.12.4 (2009-10-29)
-------------------
- Fix iteration proxying to pass `self` acquisition-wrapped into both
`__iter__` as well as `__getitem__` (this fixes
https://bugs.launchpad.net/zope2/+bug/360761).
- Add tests for the __getslice__ proxying, including open-ended slicing.
2.12.3 (2009-08-08)
-------------------
- More 64-bit fixes in Py_BuildValue calls.
- More 64-bit issues fixed: Use correct integer size for slice operations.
2.12.2 (2009-08-02)
-------------------
- Fixed 64-bit compatibility issues for Python 2.5.x / 2.6.x. See
http://www.python.org/dev/peps/pep-0353/ for details.
2.12.1 (2009-04-15)
-------------------
- Update for iteration proxying: The proxy for `__iter__` must not rely on the
object to have an `__iter__` itself, but also support fall-back iteration via
`__getitem__` (this fixes https://bugs.launchpad.net/zope2/+bug/360761).
2.12 (2009-01-25)
-----------------
- Release as separate package.
include *.txt
include *.rst
recursive-include include *
recursive-include src *
global-exclude *.dll
global-exclude *.pyc
global-exclude *.pyo
global-exclude *.so
This diff is collapsed.
......@@ -208,10 +208,8 @@ static PyExtensionClass NAME ## Type = { PyObject_HEAD_INIT(NULL) 0, # NAME, \
PyExtensionClassCAPI->PyECMethod_New_((CALLABLE),(INST))
/* Return the instance that is bound by an extension class method. */
// Pyston change:
#define PyECMethod_Self(M) \
(PyMethod_Check((M)) ? PyMethod_GET_SELF(M) : NULL)
// (PyMethod_Check((M)) ? ((PyMethodObject*)(M))->im_self : NULL)
(PyMethod_Check((M)) ? ((PyMethodObject*)(M))->im_self : NULL)
/* Check whether an object has an __of__ method for returning itself
in the context of it's container. */
......
......@@ -14,31 +14,65 @@
"""Setup for the Acquisition distribution
"""
import os
import platform
import sys
from setuptools import setup, find_packages, Extension
setup(name='Acquisition',
version = '2.13.9',
url='http://pypi.python.org/pypi/Acquisition',
license='ZPL 2.1',
description="Acquisition is a mechanism that allows objects to obtain "
"attributes from the containment hierarchy they're in.",
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
long_description=open(
os.path.join('src', 'Acquisition', 'README.txt')).read() + '\n' +
open('CHANGES.txt').read(),
with open('README.rst') as f:
README = f.read()
packages=find_packages('src'),
package_dir={'': 'src'},
with open('CHANGES.rst') as f:
CHANGES = f.read()
ext_modules=[Extension("Acquisition._Acquisition",
[os.path.join('src', 'Acquisition',
'_Acquisition.c')],
include_dirs=['include', 'src']),
],
install_requires=[
'ExtensionClass<4.0.dev',
'zope.interface'],
include_package_data=True,
zip_safe=False,
)
# PyPy won't build the extension.
py_impl = getattr(platform, 'python_implementation', lambda: None)
is_pypy = py_impl() == 'PyPy'
is_pure = 'PURE_PYTHON' in os.environ
py3k = sys.version_info >= (3, )
if is_pypy or is_pure or py3k:
ext_modules = []
else:
ext_modules=[Extension("Acquisition._Acquisition",
[os.path.join('src', 'Acquisition',
'_Acquisition.c')],
include_dirs=['include', 'src']),
]
setup(
name='Acquisition',
version='4.2.2',
url='https://github.com/zopefoundation/Acquisition',
license='ZPL 2.1',
description="Acquisition is a mechanism that allows objects to obtain "
"attributes from the containment hierarchy they're in.",
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
long_description='\n\n'.join([README, CHANGES]),
packages=find_packages('src'),
package_dir={'': 'src'},
classifiers=[
"Development Status :: 6 - Mature",
"Environment :: Web Environment",
"Framework :: Zope2",
"License :: OSI Approved :: Zope Public License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
],
ext_modules=ext_modules,
install_requires=[
'ExtensionClass >= 4.1.1',
'zope.interface',
],
include_package_data=True,
zip_safe=False,
)
......@@ -452,6 +452,11 @@ Wrapper_acquire(Wrapper *self, PyObject *oname,
PyObject *filter, PyObject *extra, PyObject *orig,
int explicit, int containment);
static PyObject *
Wrapper_findattr_name(Wrapper *self, char* name, PyObject *oname,
PyObject *filter, PyObject *extra, PyObject *orig,
int sob, int sco, int explicit, int containment);
static PyObject *
Wrapper_findattr(Wrapper *self, PyObject *oname,
PyObject *filter, PyObject *extra, PyObject *orig,
......@@ -474,16 +479,48 @@ Wrapper_findattr(Wrapper *self, PyObject *oname,
attribute.
*/
{
PyObject *r, *v, *tb, *tmp;
PyObject *tmp=NULL;
PyObject *result;
char *name="";
if (PyString_Check(oname)) name=PyString_AS_STRING(oname);
if (PyUnicode_Check(oname)) {
else if (PyUnicode_Check(oname)) {
tmp=PyUnicode_AsASCIIString(oname);
if (tmp==NULL) return NULL;
name=PyString_AS_STRING(tmp);
Py_DECREF(tmp);
}
result = Wrapper_findattr_name(self, name, oname, filter, extra, orig,
sob, sco, explicit, containment);
Py_XDECREF(tmp);
return result;
}
static PyObject *
Wrapper_findattr_name(Wrapper *self, char* name, PyObject *oname,
PyObject *filter, PyObject *extra, PyObject *orig,
int sob, int sco, int explicit, int containment)
/*
Exactly the same as Wrapper_findattr, except that the incoming
Python name string/unicode object has already been decoded
into a C string. This helper function lets us more easily manage
the lifetime of any temporary allocations.
This function uses Wrapper_acquire, which only takes the original
oname value, not the decoded value. That function can call back into
this one (via Wrapper_findattr). Although that may lead to a few
temporary allocations as we walk through the containment hierarchy,
it is correct: This function may modify its internal view of the
`name` value, and if that were propagated up the hierarchy
the incorrect name may be looked up.
*/
{
PyObject *r, *v, *tb;
if ((*name=='a' && name[1]=='q' && name[2]=='_') ||
(strcmp(name, "__parent__")==0))
{
......@@ -551,7 +588,15 @@ Wrapper_findattr(Wrapper *self, PyObject *oname,
Py_XDECREF(r); Py_XDECREF(v); Py_XDECREF(tb);
r=NULL;
}
/* normal attribute lookup */
/* Deal with mixed __parent__ / aq_parent circles */
else if (self->container && isWrapper(self->container) &&
WRAPPER(self->container)->container &&
self == WRAPPER(WRAPPER(self->container)->container)) {
PyErr_SetString(PyExc_RuntimeError,
"Recursion detected in acquisition wrapper");
return NULL;
}
/* normal attribute lookup */
else if ((r=PyObject_GetAttr(self->obj,oname)))
{
if (r==Acquired)
......@@ -642,13 +687,15 @@ Wrapper_acquire(Wrapper *self, PyObject *oname,
acquisition wrapper in the first place (see above). */
else if ((r = PyObject_GetAttr(self->container, py__parent__)))
{
ASSIGN(self->container, newWrapper(self->container, r,
(PyTypeObject*)&Wrappertype));
/* Don't search the container when the parent of the parent
is the same object as 'self' */
if (WRAPPER(r)->obj == WRAPPER(self)->obj)
sco=0;
if (r == WRAPPER(self)->obj)
sco=0;
else if (WRAPPER(r)->obj == WRAPPER(self)->obj)
sco=0;
ASSIGN(self->container, newWrapper(self->container, r,
(PyTypeObject*)&Wrappertype));
Py_DECREF(r); /* don't need __parent__ anymore */
......@@ -722,62 +769,73 @@ Wrapper_getattro(Wrapper *self, PyObject *oname)
static PyObject *
Xaq_getattro(Wrapper *self, PyObject *oname)
{
PyObject *tmp;
PyObject *tmp=NULL;
PyObject *result;
char *name="";
/* Special case backward-compatible acquire method. */
if (PyString_Check(oname)) name=PyString_AS_STRING(oname);
if (PyUnicode_Check(oname)) {
else if (PyUnicode_Check(oname)) {
tmp=PyUnicode_AsASCIIString(oname);
if (tmp==NULL) return NULL;
name=PyString_AS_STRING(tmp);
Py_DECREF(tmp);
}
if (*name=='a' && name[1]=='c' && strcmp(name+2,"quire")==0)
return Py_FindAttr(OBJECT(self),oname);
result = Py_FindAttr(OBJECT(self),oname);
if (self->obj || self->container)
return Wrapper_findattr(self, oname, NULL, NULL, NULL, 1, 0, 0, 0);
else if (self->obj || self->container)
result = Wrapper_findattr(self, oname, NULL, NULL, NULL, 1, 0, 0, 0);
/* Maybe we are getting initialized? */
return Py_FindAttr(OBJECT(self),oname);
else result = Py_FindAttr(OBJECT(self),oname);
Py_XDECREF(tmp);
return result;
}
static int
Wrapper_setattro(Wrapper *self, PyObject *oname, PyObject *v)
{
PyObject *tmp;
PyObject *tmp=NULL;
char *name="";
int result;
/* Allow assignment to parent, to change context. */
if (PyString_Check(oname)) name=PyString_AS_STRING(oname);
if (PyUnicode_Check(oname)) {
else if (PyUnicode_Check(oname)) {
tmp=PyUnicode_AsASCIIString(oname);
if (tmp==NULL) return -1;
name=PyString_AS_STRING(tmp);
Py_DECREF(tmp);
}
if ((*name=='a' && name[1]=='q' && name[2]=='_'
&& strcmp(name+3,"parent")==0) || (strcmp(name, "__parent__")==0))
{
Py_XINCREF(v);
ASSIGN(self->container, v);
return 0;
result = 0;
}
if (self->obj)
else if (self->obj)
{
/* Unwrap passed in wrappers! */
while (v && isWrapper(v))
v=WRAPPER(v)->obj;
if (v) return PyObject_SetAttr(self->obj, oname, v);
else return PyObject_DelAttr(self->obj, oname);
if (v) result = PyObject_SetAttr(self->obj, oname, v);
else result = PyObject_DelAttr(self->obj, oname);
}
else
{
PyErr_SetString(PyExc_AttributeError,
"Attempt to set attribute on empty acquisition wrapper");
return -1;
result = -1;
}
Py_XDECREF(tmp);
return result;
}
static int
......@@ -1280,13 +1338,6 @@ Wrapper_acquire_method(Wrapper *self, PyObject *args, PyObject *kw)
if (filter==Py_None) filter=0;
/* DM 2005-08-25: argument "default" ignored -- fix it! */
# if 0
return Wrapper_findattr(self,name,filter,extra,OBJECT(self),1,
explicit ||
self->ob_type==(PyTypeObject*)&Wrappertype,
explicit, containment);
# else
result = Wrapper_findattr(self,name,filter,extra,OBJECT(self),1,
explicit ||
self->ob_type==(PyTypeObject*)&Wrappertype,
......@@ -1304,7 +1355,6 @@ Wrapper_acquire_method(Wrapper *self, PyObject *args, PyObject *kw)
}
}
return result;
# endif
}
/* forward declaration so that we can use it in Wrapper_inContextOf */
......
This diff is collapsed.
This diff is collapsed.
[tox]
envlist =
py26,py27,py27-pure,py32,py33,py34,pypy,pypy3,coverage
[testenv]
commands =
nosetests --with-doctest --doctest-tests --where={envsitepackagesdir}/Acquisition
deps =
nose
[testenv:py27-pure]
basepython =
python2.7
setenv =
PURE_PYTHON = 1
[testenv:coverage]
basepython =
python2.7
commands =
nosetests --with-xunit --with-xcoverage --with-doctest --doctest-tests --where={envsitepackagesdir}/Acquisition --cover-package=Acquisition
deps =
nose
coverage
nosexcover
setenv =
PURE_PYTHON = 1
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment