[PyObjC-svn] r2605 - in trunk/pyobjc/pyobjc-core: . Lib/PyObjCTools Modules/objc PyObjCTest
[email protected] Tue, 28 Dec 2010 06:06:33 -0600
| Newsgroups | gmane.comp.python.pyobjc.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: ronaldoussoren
Date: Tue Dec 28 06:06:33 2010
New Revision: 2605
Log:
Add support for 3 Objective-C runtime functions that were introduced in
10.6: objc.setAssociatedObject (wraps objc_setAssociatedObject),
objc.getAssociatedObject and objc.removeAssociatedObjects.
Documentations will follow later, need to restructure the enture docset
anyway.
Added:
trunk/pyobjc/pyobjc-core/PyObjCTest/test_assocations.py (contents, props changed)
Modified:
trunk/pyobjc/pyobjc-core/Lib/PyObjCTools/TestSupport.py
trunk/pyobjc/pyobjc-core/Modules/objc/module.m
trunk/pyobjc/pyobjc-core/NEWS.txt
trunk/pyobjc/pyobjc-core/setup.py
Modified: trunk/pyobjc/pyobjc-core/Lib/PyObjCTools/TestSupport.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/Lib/PyObjCTools/TestSupport.py (original)
+++ trunk/pyobjc/pyobjc-core/Lib/PyObjCTools/TestSupport.py Tue Dec 28 06:06:33 2010
@@ -736,3 +736,13 @@
return test
+class filterWarnings (object):
+ def __init__(self, kind, category):
+ self._kind = kind
+ self._category = category
+
+ def __enter__(self):
+ warnings.filterwarnings(self._kind, category=self._category)
+
+ def __exit__(self, type, value, tp):
+ del warnings.filters[0]
Modified: trunk/pyobjc/pyobjc-core/Modules/objc/module.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/module.m (original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/module.m Tue Dec 28 06:06:33 2010
@@ -1671,6 +1671,133 @@
}
+#if PyObjC_BUILD_RELEASE >= 1006
+ /* Associated Object support. Functionality is available on OSX 10.6 or later. */
+
+PyDoc_STRVAR(PyObjC_setAssociatedObject_doc,
+ "setAssociatedObject(object, key, value, [policy=objc.OBJC_ASSOCIATION_RETAIN])\n"
+ "\n"
+ "Set the value for an object assiociation. Use 'None' as the\n"
+ "value to clear an association.");
+static PyObject*
+PyObjC_setAssociatedObject(PyObject* self __attribute__((__unused__)),
+ PyObject* args, PyObject* kwds)
+{
+static char* keywords[] = { "object", "key", "value", "policy", NULL };
+ id object;
+ PyObject* key;
+ id value;
+ long policy = OBJC_ASSOCIATION_RETAIN;
+
+ if (objc_setAssociatedObject == NULL) {
+ PyErr_SetString(PyObjCExc_Error, "setAssociatedObject not available on this platform");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&OO&|i",
+ keywords,
+ PyObjCObject_Convert, &object,
+ &key,
+ PyObjCObject_Convert, &value,
+ &policy
+ )) {
+
+ return NULL;
+ }
+
+ PyObjC_DURING
+ objc_setAssociatedObject(object, (void*)key, value, policy);
+ PyObjC_HANDLER
+ PyObjCErr_FromObjC(localException);
+ PyObjC_ENDHANDLER
+
+ if (PyErr_Occurred()) return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(PyObjC_getAssociatedObject_doc,
+ "getAssociatedObject(object, key) -> value\n"
+ "\n"
+ "Get the value for an object assiociation. Returns None \n"
+ "when they association doesn't exist.");
+static PyObject*
+PyObjC_getAssociatedObject(PyObject* self __attribute__((__unused__)),
+ PyObject* args, PyObject* kwds)
+{
+static char* keywords[] = { "object", "key", NULL};
+ id object;
+ PyObject* key;
+ id value;
+
+ if (objc_getAssociatedObject == NULL) {
+ PyErr_SetString(PyObjCExc_Error, "setAssociatedObject not available on this platform");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O",
+ keywords,
+ PyObjCObject_Convert, &object,
+ &key
+ )) {
+
+ return NULL;
+ }
+
+ PyObjC_DURING
+ value = objc_getAssociatedObject(object, (void*)key);
+ PyObjC_HANDLER
+ value = nil;
+ PyObjCErr_FromObjC(localException);
+ PyObjC_ENDHANDLER
+
+ if (PyErr_Occurred()) return NULL;
+
+ return PyObjC_IdToPython(value);
+}
+
+PyDoc_STRVAR(PyObjC_removeAssociatedObjects_doc,
+ "removeAssociatedObjects(object)\n"
+ "\n"
+ "Remove all assocations from an object. This should in general not be used because\n"
+ "it clear all references, including those made from unrelated code.\n");
+
+static PyObject*
+PyObjC_removeAssociatedObjects(PyObject* self __attribute__((__unused__)),
+ PyObject* args, PyObject* kwds)
+{
+static char* keywords[] = { "object", NULL};
+ id object;
+
+ if (objc_removeAssociatedObjects == NULL) {
+ PyErr_SetString(PyObjCExc_Error, "setAssociatedObject not available on this platform");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&",
+ keywords,
+ PyObjCObject_Convert, &object
+ )) {
+
+ return NULL;
+ }
+
+ PyObjC_DURING
+ objc_removeAssociatedObjects(object);
+ PyObjC_HANDLER
+ PyObjCErr_FromObjC(localException);
+ PyObjC_ENDHANDLER
+
+ if (PyErr_Occurred()) return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+
static PyMethodDef mod_methods[] = {
{
"_setClassSetUpHook",
@@ -1786,6 +1913,16 @@
{ "_clear_intern", (PyCFunction)_clear_intern, METH_NOARGS, NULL },
+#if PyObjC_BUILD_RELEASE >= 1006
+
+ { "setAssociatedObject", (PyCFunction)PyObjC_setAssociatedObject,
+ METH_VARARGS|METH_KEYWORDS, PyObjC_setAssociatedObject_doc },
+ { "getAssociatedObject", (PyCFunction)PyObjC_getAssociatedObject,
+ METH_VARARGS|METH_KEYWORDS, PyObjC_getAssociatedObject_doc },
+ { "removeAssociatedObjects", (PyCFunction)PyObjC_removeAssociatedObjects,
+ METH_VARARGS|METH_KEYWORDS, PyObjC_removeAssociatedObjects_doc },
+
+#endif /* PyObjC_BUILD_RELEASE >= 1006 */
{ 0, 0, 0, 0 } /* sentinel */
};
@@ -2068,6 +2205,42 @@
PyObjCPointerWrapper_Init();
PyObjC_InstallAllocHack();
+#if PyObjC_BUILD_RELEASE >= 1006
+ if (objc_setAssociatedObject != NULL) {
+ if (PyModule_AddIntConstant(m, "OBJC_ASSOCIATION_ASSIGN", OBJC_ASSOCIATION_ASSIGN) < 0) {
+ PyObjC_INITERROR();
+ }
+ if (PyModule_AddIntConstant(m, "OBJC_ASSOCIATION_RETAIN_NONATOMIC", OBJC_ASSOCIATION_RETAIN_NONATOMIC) < 0) {
+ PyObjC_INITERROR();
+ }
+ if (PyModule_AddIntConstant(m, "OBJC_ASSOCIATION_COPY_NONATOMIC", OBJC_ASSOCIATION_COPY_NONATOMIC) < 0) {
+ PyObjC_INITERROR();
+ }
+ if (PyModule_AddIntConstant(m, "OBJC_ASSOCIATION_RETAIN", OBJC_ASSOCIATION_RETAIN) < 0) {
+ PyObjC_INITERROR();
+ }
+ if (PyModule_AddIntConstant(m, "OBJC_ASSOCIATION_COPY", OBJC_ASSOCIATION_COPY) < 0) {
+ PyObjC_INITERROR();
+ }
+ } else {
+ /* Build on a system where object associations are available, running on a platform where they aren't.
+ * Disable the wrappers.
+ */
+ if (PyDict_DelItemString(d, "setAssociatedObject") < 0) {
+ PyErr_Clear();
+ }
+ if (PyDict_DelItemString(d, "getAssociatedObject") < 0) {
+ PyErr_Clear();
+ }
+ if (PyDict_DelItemString(d, "removeAssociatedObjects") < 0) {
+ PyErr_Clear();
+ }
+
+ }
+#endif /* PyObjC_BUILD_RELEASE >= 1006 */
+
+
+
#ifdef MAC_OS_X_VERSION_MAX_ALLOWED
/* An easy way to check for the MacOS X version we did build for */
if (PyModule_AddIntConstant(m, "MAC_OS_X_VERSION_MAX_ALLOWED", MAC_OS_X_VERSION_MAX_ALLOWED) < 0) {
Modified: trunk/pyobjc/pyobjc-core/NEWS.txt
==============================================================================
--- trunk/pyobjc/pyobjc-core/NEWS.txt (original)
+++ trunk/pyobjc/pyobjc-core/NEWS.txt Tue Dec 28 06:06:33 2010
@@ -13,6 +13,15 @@
- ``objc.FSRef.from_pathname`` actually works instead of always raising
a TypeError.
+- ``objc.getAssociatedObject``, ``objc.setAssociatedObject`` and
+ ``objc.removeAssociatedObjects`` are wrappers for the corresponding
+ functions in the Objective-C runtime API. These functions are only
+ available when PyObjC was build on a system running OSX 10.6 or later,
+ and the script is also running on such as system.
+
+ The ``policy`` argument for ``objc.setAssociatedObject`` is optional and
+ defaults to ``objc.OBJC_ASSOCIATION_RETAIN``.
+
Version 2.3
-----------
Modified: trunk/pyobjc/pyobjc-core/setup.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/setup.py (original)
+++ trunk/pyobjc/pyobjc-core/setup.py Tue Dec 28 06:06:33 2010
@@ -5,6 +5,7 @@
import shutil
import re
import os
+import plistlib
# We need at least Python 2.5
MIN_PYTHON = (2, 5)
@@ -41,9 +42,19 @@
use_2to3 = True,
)
+def get_os_level():
+ pl = plistlib.readPlist('/System/Library/CoreServices/SystemVersion.plist')
+ v = pl['ProductVersion']
+ return '.'.join(v.split('.')[:2])
+
+
+
+
+
from setuptools.command import build_py
from setuptools.command import test
from distutils import log
+
class oc_build_py (build_py.build_py):
def run_2to3(self, files, doctests=True):
files = [ fn for fn in files if not os.path.basename(fn).startswith('test3_') ]
@@ -295,6 +306,7 @@
"-Wno-long-long",
"-Wno-import",
+ "-DPyObjC_BUILD_RELEASE=%02d%02d"%(tuple(map(int, get_os_level().split('.')))),
])
## Arghh, a stupid compiler flag can cause problems. Don't
------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and,
should the need arise, upgrade to a full multi-node Oracle RAC database
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl