diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 7b8ad5a113..3662484f6b 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -46,7 +46,7 @@ Distributed under the following license(s): ## [wrapt](https://pypi.org/project/wrapt) -Copyright (c) 2013-2017, Graham Dumpleton +Copyright (c) 2013-2019, Graham Dumpleton All rights reserved. Distributed under the following license(s): diff --git a/newrelic/packages/wrapt/LICENSE b/newrelic/packages/wrapt/LICENSE index f4f2dcf818..d49cae8439 100644 --- a/newrelic/packages/wrapt/LICENSE +++ b/newrelic/packages/wrapt/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2017, Graham Dumpleton +Copyright (c) 2013-2019, Graham Dumpleton All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/newrelic/packages/wrapt/__init__.py b/newrelic/packages/wrapt/__init__.py index 182a1e1100..7be739bf65 100644 --- a/newrelic/packages/wrapt/__init__.py +++ b/newrelic/packages/wrapt/__init__.py @@ -1,10 +1,10 @@ -__version_info__ = ('1', '10', '11') +__version_info__ = ('1', '12', '1') __version__ = '.'.join(__version_info__) from .wrappers import (ObjectProxy, CallableObjectProxy, FunctionWrapper, - BoundFunctionWrapper, WeakFunctionProxy, resolve_path, apply_patch, - wrap_object, wrap_object_attribute, function_wrapper, - wrap_function_wrapper, patch_function_wrapper, + BoundFunctionWrapper, WeakFunctionProxy, PartialCallableObjectProxy, + resolve_path, apply_patch, wrap_object, wrap_object_attribute, + function_wrapper, wrap_function_wrapper, patch_function_wrapper, transient_function_wrapper) from .decorators import (adapter_factory, AdapterFactory, decorator, @@ -13,7 +13,4 @@ from .importer import (register_post_import_hook, when_imported, notify_module_loaded, discover_post_import_hooks) -try: - from inspect import getcallargs -except ImportError: - from .arguments import getcallargs +from inspect import getcallargs diff --git a/newrelic/packages/wrapt/_wrappers.c b/newrelic/packages/wrapt/_wrappers.c index d9995c0a50..660ad6b3bc 100644 --- a/newrelic/packages/wrapt/_wrappers.c +++ b/newrelic/packages/wrapt/_wrappers.c @@ -21,6 +21,15 @@ typedef struct { PyTypeObject WraptObjectProxy_Type; PyTypeObject WraptCallableObjectProxy_Type; +typedef struct { + WraptObjectProxyObject object_proxy; + + PyObject *args; + PyObject *kwargs; +} WraptPartialCallableObjectProxyObject; + +PyTypeObject WraptPartialCallableObjectProxy_Type; + typedef struct { WraptObjectProxyObject object_proxy; @@ -185,7 +194,11 @@ static PyObject *WraptObjectProxy_repr(WraptObjectProxyObject *self) /* ------------------------------------------------------------------------- */ -static long WraptObjectProxy_hash(WraptObjectProxyObject *self) +#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 3) +typedef long Py_hash_t; +#endif + +static Py_hash_t WraptObjectProxy_hash(WraptObjectProxyObject *self) { if (!self->wrapped) { PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); @@ -211,21 +224,23 @@ static PyObject *WraptObjectProxy_str(WraptObjectProxyObject *self) static PyObject *WraptObjectProxy_add(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Add(o1, o2); } @@ -234,21 +249,23 @@ static PyObject *WraptObjectProxy_add(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_subtract(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Subtract(o1, o2); @@ -258,21 +275,23 @@ static PyObject *WraptObjectProxy_subtract(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_multiply(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Multiply(o1, o2); } @@ -282,21 +301,23 @@ static PyObject *WraptObjectProxy_multiply(PyObject *o1, PyObject *o2) #if PY_MAJOR_VERSION < 3 static PyObject *WraptObjectProxy_divide(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Divide(o1, o2); } @@ -306,21 +327,23 @@ static PyObject *WraptObjectProxy_divide(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_remainder(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Remainder(o1, o2); } @@ -329,21 +352,23 @@ static PyObject *WraptObjectProxy_remainder(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_divmod(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Divmod(o1, o2); } @@ -353,21 +378,23 @@ static PyObject *WraptObjectProxy_divmod(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_power(PyObject *o1, PyObject *o2, PyObject *modulo) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Power(o1, o2, modulo); } @@ -436,21 +463,23 @@ static PyObject *WraptObjectProxy_invert(WraptObjectProxyObject *self) static PyObject *WraptObjectProxy_lshift(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Lshift(o1, o2); } @@ -459,21 +488,23 @@ static PyObject *WraptObjectProxy_lshift(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_rshift(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Rshift(o1, o2); } @@ -482,21 +513,23 @@ static PyObject *WraptObjectProxy_rshift(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_and(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_And(o1, o2); } @@ -505,21 +538,23 @@ static PyObject *WraptObjectProxy_and(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_xor(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Xor(o1, o2); } @@ -528,21 +563,23 @@ static PyObject *WraptObjectProxy_xor(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_or(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_Or(o1, o2); } @@ -920,6 +957,9 @@ static PyObject *WraptObjectProxy_inplace_or(WraptObjectProxyObject *self, object = PyNumber_InPlaceOr(self->wrapped, other); + if (!object) + return NULL; + Py_DECREF(self->wrapped); self->wrapped = object; @@ -931,21 +971,23 @@ static PyObject *WraptObjectProxy_inplace_or(WraptObjectProxyObject *self, static PyObject *WraptObjectProxy_floor_divide(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_FloorDivide(o1, o2); } @@ -954,21 +996,23 @@ static PyObject *WraptObjectProxy_floor_divide(PyObject *o1, PyObject *o2) static PyObject *WraptObjectProxy_true_divide(PyObject *o1, PyObject *o2) { - if (!((WraptObjectProxyObject *)o1)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o1)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (!((WraptObjectProxyObject *)o2)->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); - return NULL; + o1 = ((WraptObjectProxyObject *)o1)->wrapped; } - if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) - o1 = ((WraptObjectProxyObject *)o1)->wrapped; + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) { + if (!((WraptObjectProxyObject *)o2)->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } - if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) o2 = ((WraptObjectProxyObject *)o2)->wrapped; + } return PyNumber_TrueDivide(o1, o2); } @@ -1158,6 +1202,50 @@ static PyObject *WraptObjectProxy_exit( /* ------------------------------------------------------------------------- */ +static PyObject *WraptObjectProxy_copy( + WraptObjectProxyObject *self, PyObject *args, PyObject *kwds) +{ + PyErr_SetString(PyExc_NotImplementedError, + "object proxy must define __copy__()"); + + return NULL; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *WraptObjectProxy_deepcopy( + WraptObjectProxyObject *self, PyObject *args, PyObject *kwds) +{ + PyErr_SetString(PyExc_NotImplementedError, + "object proxy must define __deepcopy__()"); + + return NULL; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *WraptObjectProxy_reduce( + WraptObjectProxyObject *self, PyObject *args, PyObject *kwds) +{ + PyErr_SetString(PyExc_NotImplementedError, + "object proxy must define __reduce_ex__()"); + + return NULL; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *WraptObjectProxy_reduce_ex( + WraptObjectProxyObject *self, PyObject *args, PyObject *kwds) +{ + PyErr_SetString(PyExc_NotImplementedError, + "object proxy must define __reduce_ex__()"); + + return NULL; +} + +/* ------------------------------------------------------------------------- */ + static PyObject *WraptObjectProxy_bytes( WraptObjectProxyObject *self, PyObject *args) { @@ -1226,6 +1314,33 @@ static PyObject *WraptObjectProxy_round( /* ------------------------------------------------------------------------- */ +static PyObject *WraptObjectProxy_complex( + WraptObjectProxyObject *self, PyObject *args) +{ + if (!self->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } + + return PyObject_CallFunctionObjArgs((PyObject *)&PyComplex_Type, + self->wrapped, NULL); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *WraptObjectProxy_mro_entries( + WraptObjectProxyObject *self, PyObject *args, PyObject *kwds) +{ + if (!self->wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } + + return Py_BuildValue("(O)", self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + static PyObject *WraptObjectProxy_get_name( WraptObjectProxyObject *self) { @@ -1628,12 +1743,25 @@ static PyMethodDef WraptObjectProxy_methods[] = { METH_VARARGS | METH_KEYWORDS, 0 }, { "__exit__", (PyCFunction)WraptObjectProxy_exit, METH_VARARGS | METH_KEYWORDS, 0 }, + { "__copy__", (PyCFunction)WraptObjectProxy_copy, + METH_NOARGS, 0 }, + { "__deepcopy__", (PyCFunction)WraptObjectProxy_deepcopy, + METH_VARARGS | METH_KEYWORDS, 0 }, + { "__reduce__", (PyCFunction)WraptObjectProxy_reduce, + METH_NOARGS, 0 }, + { "__reduce_ex__", (PyCFunction)WraptObjectProxy_reduce_ex, + METH_VARARGS | METH_KEYWORDS, 0 }, { "__getattr__", (PyCFunction)WraptObjectProxy_getattr, METH_VARARGS , 0 }, { "__bytes__", (PyCFunction)WraptObjectProxy_bytes, METH_NOARGS, 0 }, { "__reversed__", (PyCFunction)WraptObjectProxy_reversed, METH_NOARGS, 0 }, #if PY_MAJOR_VERSION >= 3 { "__round__", (PyCFunction)WraptObjectProxy_round, METH_NOARGS, 0 }, +#endif + { "__complex__", (PyCFunction)WraptObjectProxy_complex, METH_NOARGS, 0 }, +#if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 7) + { "__mro_entries__", (PyCFunction)WraptObjectProxy_mro_entries, + METH_VARARGS | METH_KEYWORDS, 0 }, #endif { NULL, NULL }, }; @@ -1779,6 +1907,252 @@ PyTypeObject WraptCallableObjectProxy_Type = { /* ------------------------------------------------------------------------- */ +static PyObject *WraptPartialCallableObjectProxy_new(PyTypeObject *type, + PyObject *args, PyObject *kwds) +{ + WraptPartialCallableObjectProxyObject *self; + + self = (WraptPartialCallableObjectProxyObject *)WraptObjectProxy_new(type, + args, kwds); + + if (!self) + return NULL; + + self->args = NULL; + self->kwargs = NULL; + + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static int WraptPartialCallableObjectProxy_raw_init( + WraptPartialCallableObjectProxyObject *self, + PyObject *wrapped, PyObject *args, PyObject *kwargs) +{ + int result = 0; + + result = WraptObjectProxy_raw_init((WraptObjectProxyObject *)self, + wrapped); + + if (result == 0) { + Py_INCREF(args); + Py_XDECREF(self->args); + self->args = args; + + Py_XINCREF(kwargs); + Py_XDECREF(self->kwargs); + self->kwargs = kwargs; + } + + return result; +} + +/* ------------------------------------------------------------------------- */ + +static int WraptPartialCallableObjectProxy_init( + WraptPartialCallableObjectProxyObject *self, PyObject *args, + PyObject *kwds) +{ + PyObject *wrapped = NULL; + PyObject *fnargs = NULL; + + int result = 0; + + if (!PyObject_Length(args)) { + PyErr_SetString(PyExc_TypeError, + "__init__ of partial needs an argument"); + return -1; + } + + if (PyObject_Length(args) < 1) { + PyErr_SetString(PyExc_TypeError, + "partial type takes at least one argument"); + return -1; + } + + wrapped = PyTuple_GetItem(args, 0); + + if (!PyCallable_Check(wrapped)) { + PyErr_SetString(PyExc_TypeError, + "the first argument must be callable"); + return -1; + } + + fnargs = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + + if (!fnargs) + return -1; + + result = WraptPartialCallableObjectProxy_raw_init(self, wrapped, + fnargs, kwds); + + Py_DECREF(fnargs); + + return result; +} + +/* ------------------------------------------------------------------------- */ + +static int WraptPartialCallableObjectProxy_traverse( + WraptPartialCallableObjectProxyObject *self, + visitproc visit, void *arg) +{ + WraptObjectProxy_traverse((WraptObjectProxyObject *)self, visit, arg); + + Py_VISIT(self->args); + Py_VISIT(self->kwargs); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static int WraptPartialCallableObjectProxy_clear( + WraptPartialCallableObjectProxyObject *self) +{ + WraptObjectProxy_clear((WraptObjectProxyObject *)self); + + Py_CLEAR(self->args); + Py_CLEAR(self->kwargs); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static void WraptPartialCallableObjectProxy_dealloc( + WraptPartialCallableObjectProxyObject *self) +{ + PyObject_GC_UnTrack(self); + + WraptPartialCallableObjectProxy_clear(self); + + WraptObjectProxy_dealloc((WraptObjectProxyObject *)self); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *WraptPartialCallableObjectProxy_call( + WraptPartialCallableObjectProxyObject *self, PyObject *args, + PyObject *kwds) +{ + PyObject *fnargs = NULL; + PyObject *fnkwargs = NULL; + + PyObject *result = NULL; + + long i; + long offset; + + if (!self->object_proxy.wrapped) { + PyErr_SetString(PyExc_ValueError, "wrapper has not been initialized"); + return NULL; + } + + fnargs = PyTuple_New(PyTuple_Size(self->args)+PyTuple_Size(args)); + + for (i=0; iargs); i++) { + PyObject *item; + item = PyTuple_GetItem(self->args, i); + Py_INCREF(item); + PyTuple_SetItem(fnargs, i, item); + } + + offset = PyTuple_Size(self->args); + + for (i=0; ikwargs && PyDict_Update(fnkwargs, self->kwargs) == -1) { + Py_DECREF(fnargs); + Py_DECREF(fnkwargs); + return NULL; + } + + if (kwds && PyDict_Update(fnkwargs, kwds) == -1) { + Py_DECREF(fnargs); + Py_DECREF(fnkwargs); + return NULL; + } + + result = PyObject_Call(self->object_proxy.wrapped, + fnargs, fnkwargs); + + Py_DECREF(fnargs); + Py_DECREF(fnkwargs); + + return result; +} + +/* ------------------------------------------------------------------------- */; + +static PyGetSetDef WraptPartialCallableObjectProxy_getset[] = { + { "__module__", (getter)WraptObjectProxy_get_module, + (setter)WraptObjectProxy_set_module, 0 }, + { "__doc__", (getter)WraptObjectProxy_get_doc, + (setter)WraptObjectProxy_set_doc, 0 }, + { NULL }, +}; + +PyTypeObject WraptPartialCallableObjectProxy_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "PartialCallableObjectProxy", /*tp_name*/ + sizeof(WraptPartialCallableObjectProxyObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)WraptPartialCallableObjectProxy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + (ternaryfunc)WraptPartialCallableObjectProxy_call, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ +#if PY_MAJOR_VERSION < 3 + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ +#else + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC, /*tp_flags*/ +#endif + 0, /*tp_doc*/ + (traverseproc)WraptPartialCallableObjectProxy_traverse, /*tp_traverse*/ + (inquiry)WraptPartialCallableObjectProxy_clear, /*tp_clear*/ + 0, /*tp_richcompare*/ + offsetof(WraptObjectProxyObject, weakreflist), /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + WraptPartialCallableObjectProxy_getset, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + (initproc)WraptPartialCallableObjectProxy_init, /*tp_init*/ + 0, /*tp_alloc*/ + WraptPartialCallableObjectProxy_new, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +/* ------------------------------------------------------------------------- */ + static PyObject *WraptFunctionWrapperBase_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1908,6 +2282,8 @@ static int WraptFunctionWrapperBase_clear(WraptFunctionWrapperObject *self) static void WraptFunctionWrapperBase_dealloc(WraptFunctionWrapperObject *self) { + PyObject_GC_UnTrack(self); + WraptFunctionWrapperBase_clear(self); WraptObjectProxy_dealloc((WraptObjectProxyObject *)self); @@ -2334,44 +2710,21 @@ static PyObject *WraptBoundFunctionWrapper_call( * so the wrapper doesn't see anything as being different. */ - PyObject *module = NULL; - PyObject *dict = NULL; - PyObject *partial = NULL; - if (PyTuple_Size(args) == 0) { PyErr_SetString(PyExc_TypeError, "missing 1 required positional argument"); return NULL; } - module = PyImport_ImportModule("functools"); - - if (!module) - return NULL; - - dict = PyModule_GetDict(module); - partial = PyDict_GetItemString(dict, "partial"); - - if (!partial) { - Py_DECREF(module); - return NULL; - } - - Py_INCREF(partial); - Py_DECREF(module); - instance = PyTuple_GetItem(args, 0); - if (!instance) { - Py_DECREF(partial); + if (!instance) return NULL; - } - wrapped = PyObject_CallFunctionObjArgs(partial, + wrapped = PyObject_CallFunctionObjArgs( + (PyObject *)&WraptPartialCallableObjectProxy_Type, self->object_proxy.wrapped, instance, NULL); - Py_DECREF(partial); - if (!wrapped) return NULL; @@ -2681,12 +3034,15 @@ moduleinit(void) /* Ensure that inheritance relationships specified. */ WraptCallableObjectProxy_Type.tp_base = &WraptObjectProxy_Type; + WraptPartialCallableObjectProxy_Type.tp_base = &WraptObjectProxy_Type; WraptFunctionWrapperBase_Type.tp_base = &WraptObjectProxy_Type; WraptBoundFunctionWrapper_Type.tp_base = &WraptFunctionWrapperBase_Type; WraptFunctionWrapper_Type.tp_base = &WraptFunctionWrapperBase_Type; if (PyType_Ready(&WraptCallableObjectProxy_Type) < 0) return NULL; + if (PyType_Ready(&WraptPartialCallableObjectProxy_Type) < 0) + return NULL; if (PyType_Ready(&WraptFunctionWrapperBase_Type) < 0) return NULL; if (PyType_Ready(&WraptBoundFunctionWrapper_Type) < 0) @@ -2700,6 +3056,8 @@ moduleinit(void) Py_INCREF(&WraptCallableObjectProxy_Type); PyModule_AddObject(module, "CallableObjectProxy", (PyObject *)&WraptCallableObjectProxy_Type); + PyModule_AddObject(module, "PartialCallableObjectProxy", + (PyObject *)&WraptPartialCallableObjectProxy_Type); Py_INCREF(&WraptFunctionWrapper_Type); PyModule_AddObject(module, "FunctionWrapper", (PyObject *)&WraptFunctionWrapper_Type); diff --git a/newrelic/packages/wrapt/arguments.py b/newrelic/packages/wrapt/arguments.py deleted file mode 100644 index 428ffaed04..0000000000 --- a/newrelic/packages/wrapt/arguments.py +++ /dev/null @@ -1,96 +0,0 @@ -# This is a copy of the inspect.getcallargs() function from Python 2.7 -# so we can provide it for use under Python 2.6. As the code in this -# file derives from the Python distribution, it falls under the version -# of the PSF license used for Python 2.7. - -from inspect import getargspec, ismethod -import sys - -def getcallargs(func, *positional, **named): - """Get the mapping of arguments to values. - - A dict is returned, with keys the function argument names (including the - names of the * and ** arguments, if any), and values the respective bound - values from 'positional' and 'named'.""" - args, varargs, varkw, defaults = getargspec(func) - f_name = func.__name__ - arg2value = {} - - # The following closures are basically because of tuple parameter unpacking. - assigned_tuple_params = [] - def assign(arg, value): - if isinstance(arg, str): - arg2value[arg] = value - else: - assigned_tuple_params.append(arg) - value = iter(value) - for i, subarg in enumerate(arg): - try: - subvalue = next(value) - except StopIteration: - raise ValueError('need more than %d %s to unpack' % - (i, 'values' if i > 1 else 'value')) - assign(subarg, subvalue) - try: - next(value) - except StopIteration: - pass - else: - raise ValueError('too many values to unpack') - def is_assigned(arg): - if isinstance(arg, str): - return arg in arg2value - return arg in assigned_tuple_params - if ismethod(func) and func.im_self is not None: - # implicit 'self' (or 'cls' for classmethods) argument - positional = (func.im_self,) + positional - num_pos = len(positional) - num_total = num_pos + len(named) - num_args = len(args) - num_defaults = len(defaults) if defaults else 0 - for arg, value in zip(args, positional): - assign(arg, value) - if varargs: - if num_pos > num_args: - assign(varargs, positional[-(num_pos-num_args):]) - else: - assign(varargs, ()) - elif 0 < num_args < num_pos: - raise TypeError('%s() takes %s %d %s (%d given)' % ( - f_name, 'at most' if defaults else 'exactly', num_args, - 'arguments' if num_args > 1 else 'argument', num_total)) - elif num_args == 0 and num_total: - if varkw: - if num_pos: - # XXX: We should use num_pos, but Python also uses num_total: - raise TypeError('%s() takes exactly 0 arguments ' - '(%d given)' % (f_name, num_total)) - else: - raise TypeError('%s() takes no arguments (%d given)' % - (f_name, num_total)) - for arg in args: - if isinstance(arg, str) and arg in named: - if is_assigned(arg): - raise TypeError("%s() got multiple values for keyword " - "argument '%s'" % (f_name, arg)) - else: - assign(arg, named.pop(arg)) - if defaults: # fill in any missing values with the defaults - for arg, value in zip(args[-num_defaults:], defaults): - if not is_assigned(arg): - assign(arg, value) - if varkw: - assign(varkw, named) - elif named: - unexpected = next(iter(named)) - if isinstance(unexpected, unicode): - unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace') - raise TypeError("%s() got an unexpected keyword argument '%s'" % - (f_name, unexpected)) - unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) - if unassigned: - num_required = num_args - num_defaults - raise TypeError('%s() takes %s %d %s (%d given)' % ( - f_name, 'at least' if defaults else 'exactly', num_required, - 'arguments' if num_required > 1 else 'argument', num_total)) - return arg2value diff --git a/newrelic/packages/wrapt/decorators.py b/newrelic/packages/wrapt/decorators.py index 2ad3494617..506303d7a3 100644 --- a/newrelic/packages/wrapt/decorators.py +++ b/newrelic/packages/wrapt/decorators.py @@ -6,16 +6,8 @@ import sys PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -if PY3: - string_types = str, - - import builtins - exec_ = getattr(builtins, "exec") - del builtins - -else: +if PY2: string_types = basestring, def exec_(_code_, _globs_=None, _locs_=None): @@ -30,6 +22,14 @@ def exec_(_code_, _globs_=None, _locs_=None): _locs_ = _globs_ exec("""exec _code_ in _globs_, _locs_""") +else: + string_types = str, + + import builtins + + exec_ = getattr(builtins, "exec") + del builtins + from functools import partial from inspect import ismethod, isclass, formatargspec from collections import namedtuple @@ -99,11 +99,6 @@ def __signature__(self): if 'signature' not in globals(): return self._self_adapter.__signature__ else: - # Can't allow this to fail on Python 3 else it falls - # through to using __wrapped__, but that will be the - # wrong function we want to derive the signature - # from. Thus generate the signature ourselves. - return signature(self._self_adapter) if PY2: @@ -117,6 +112,13 @@ def __func__(self): return _AdapterFunctionSurrogate(self.__wrapped__.__func__, self._self_parent._self_adapter) + @property + def __signature__(self): + if 'signature' not in globals(): + return self.__wrapped__.__signature__ + else: + return signature(self._self_parent._self_adapter) + if PY2: im_func = __func__ @@ -206,7 +208,7 @@ def _build(wrapped, wrapper, enabled=None, adapter=None): ns = {} if not isinstance(adapter, string_types): adapter = formatargspec(*adapter) - exec_('def adapter{0}: pass'.format(adapter), ns, ns) + exec_('def adapter{}: pass'.format(adapter), ns, ns) adapter = ns['adapter'] return AdapterWrapper(wrapped=wrapped, wrapper=wrapper, @@ -393,9 +395,12 @@ def _capture(target_wrapped): # We first return our magic function wrapper here so we can # determine in what context the decorator factory was used. In - # other words, it is itself a universal decorator. + # other words, it is itself a universal decorator. The decorator + # function is used as the adapter so that linters see a signature + # corresponding to the decorator and not the wrapper it is being + # applied to. - return _build(wrapper, _wrapper) + return _build(wrapper, _wrapper, adapter=decorator) else: # The wrapper still has not been provided, so we are just @@ -474,10 +479,7 @@ def _synchronized_lock(context): # creation and assignment of the lock attribute against # the context. - meta_lock = vars(synchronized).setdefault( - '_synchronized_meta_lock', Lock()) - - with meta_lock: + with synchronized._synchronized_meta_lock: # We need to check again for whether the lock we want # exists in case two threads were trying to create it # at the same time and were competing to create the @@ -496,7 +498,7 @@ def _synchronized_wrapper(wrapped, instance, args, kwargs): # desired context is held. If instance is None then the # wrapped function is used as the context. - with _synchronized_lock(instance or wrapped): + with _synchronized_lock(instance if instance is not None else wrapped): return wrapped(*args, **kwargs) class _FinalDecorator(FunctionWrapper): @@ -510,3 +512,5 @@ def __exit__(self, *args): self._self_lock.release() return _FinalDecorator(wrapped=wrapped, wrapper=_synchronized_wrapper) + +synchronized._synchronized_meta_lock = Lock() diff --git a/newrelic/packages/wrapt/importer.py b/newrelic/packages/wrapt/importer.py index 7fd2d8dfa6..4665f38650 100644 --- a/newrelic/packages/wrapt/importer.py +++ b/newrelic/packages/wrapt/importer.py @@ -7,13 +7,12 @@ import threading PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -if PY3: +if PY2: + string_types = basestring, +else: import importlib string_types = str, -else: - string_types = basestring, from .decorators import synchronized @@ -188,21 +187,7 @@ def find_module(self, fullname, path=None): # Now call back into the import system again. try: - if PY3: - # For Python 3 we need to use find_loader() from - # the importlib module. It doesn't actually - # import the target module and only finds the - # loader. If a loader is found, we need to return - # our own loader which will then in turn call the - # real loader to import the module and invoke the - # post import hooks. - - loader = importlib.find_loader(fullname, path) - - if loader: - return _ImportHookChainedLoader(loader) - - else: + if PY2: # For Python 2 we don't have much choice but to # call back in to __import__(). This will # actually cause the module to be imported. If no @@ -215,6 +200,23 @@ def find_module(self, fullname, path=None): return _ImportHookLoader() + else: + # For Python 3 we need to use find_spec().loader + # from the importlib.util module. It doesn't actually + # import the target module and only finds the + # loader. If a loader is found, we need to return + # our own loader which will then in turn call the + # real loader to import the module and invoke the + # post import hooks. + try: + import importlib.util + loader = importlib.util.find_spec(fullname).loader + except (ImportError, AttributeError): + loader = importlib.find_loader(fullname, path) + if loader: + return _ImportHookChainedLoader(loader) + + finally: del self.in_progress[fullname] diff --git a/newrelic/packages/wrapt/wrappers.py b/newrelic/packages/wrapt/wrappers.py index 3b1e207fc9..18cf5e053e 100644 --- a/newrelic/packages/wrapt/wrappers.py +++ b/newrelic/packages/wrapt/wrappers.py @@ -1,3 +1,4 @@ +import os import sys import functools import operator @@ -5,12 +6,11 @@ import inspect PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -if PY3: - string_types = str, -else: +if PY2: string_types = basestring, +else: + string_types = str, def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" @@ -104,7 +104,7 @@ def __class__(self, value): @property def __annotations__(self): - return self.__wrapped__.__anotations__ + return self.__wrapped__.__annotations__ @__annotations__.setter def __annotations__(self, value): @@ -116,12 +116,12 @@ def __dir__(self): def __str__(self): return str(self.__wrapped__) - if PY3: + if not PY2: def __bytes__(self): return bytes(self.__wrapped__) def __repr__(self): - return '<%s at 0x%x for %s at 0x%x>' % ( + return '<{} at 0x{:x} for {} at 0x{:x}>'.format( type(self).__name__, id(self), type(self.__wrapped__).__name__, id(self.__wrapped__)) @@ -129,10 +129,14 @@ def __repr__(self): def __reversed__(self): return reversed(self.__wrapped__) - if PY3: + if not PY2: def __round__(self): return round(self.__wrapped__) + if sys.hexversion >= 0x03070000: + def __mro_entries__(self, bases): + return (self.__wrapped__,) + def __lt__(self, other): return self.__wrapped__ < other @@ -368,6 +372,9 @@ def __long__(self): def __float__(self): return float(self.__wrapped__) + def __complex__(self): + return complex(self.__wrapped__) + def __oct__(self): return oct(self.__wrapped__) @@ -410,11 +417,49 @@ def __exit__(self, *args, **kwargs): def __iter__(self): return iter(self.__wrapped__) + def __copy__(self): + raise NotImplementedError('object proxy must define __copy__()') + + def __deepcopy__(self, memo): + raise NotImplementedError('object proxy must define __deepcopy__()') + + def __reduce__(self): + raise NotImplementedError( + 'object proxy must define __reduce_ex__()') + + def __reduce_ex__(self, protocol): + raise NotImplementedError( + 'object proxy must define __reduce_ex__()') + class CallableObjectProxy(ObjectProxy): def __call__(self, *args, **kwargs): return self.__wrapped__(*args, **kwargs) +class PartialCallableObjectProxy(ObjectProxy): + + def __init__(self, *args, **kwargs): + if len(args) < 1: + raise TypeError('partial type takes at least one argument') + + wrapped, args = args[0], args[1:] + + if not callable(wrapped): + raise TypeError('the first argument must be callable') + + super(PartialCallableObjectProxy, self).__init__(wrapped) + + self._self_args = args + self._self_kwargs = kwargs + + def __call__(self, *args, **kwargs): + _args = self._self_args + args + + _kwargs = dict(self._self_kwargs) + _kwargs.update(kwargs) + + return self.__wrapped__(*_args, **_kwargs) + class _FunctionWrapperBase(ObjectProxy): __slots__ = ('_self_instance', '_self_wrapper', '_self_enabled', @@ -554,7 +599,7 @@ def __call__(self, *args, **kwargs): raise TypeError('missing 1 required positional argument') instance, args = args[0], args[1:] - wrapped = functools.partial(self.__wrapped__, instance) + wrapped = PartialCallableObjectProxy(self.__wrapped__, instance) return self._self_wrapper(wrapped, instance, args, kwargs) return self._self_wrapper(self.__wrapped__, self._self_instance, @@ -675,8 +720,10 @@ def __init__(self, wrapped, wrapper, enabled=None): enabled, binding) try: - from ._wrappers import (ObjectProxy, CallableObjectProxy, FunctionWrapper, - BoundFunctionWrapper, _FunctionWrapperBase) + if not os.environ.get('WRAPT_DISABLE_EXTENSIONS'): + from ._wrappers import (ObjectProxy, CallableObjectProxy, + PartialCallableObjectProxy, FunctionWrapper, + BoundFunctionWrapper, _FunctionWrapperBase) except ImportError: pass @@ -692,33 +739,34 @@ def resolve_path(module, name): path = name.split('.') attribute = path[0] - original = getattr(parent, attribute) - for attribute in path[1:]: - parent = original - - # We can't just always use getattr() because in doing - # that on a class it will cause binding to occur which - # will complicate things later and cause some things not - # to work. For the case of a class we therefore access - # the __dict__ directly. To cope though with the wrong - # class being given to us, or a method being moved into - # a base class, we need to walk the class hierarchy to - # work out exactly which __dict__ the method was defined - # in, as accessing it from __dict__ will fail if it was - # not actually on the class given. Fallback to using - # getattr() if we can't find it. If it truly doesn't - # exist, then that will fail. - - if inspect.isclass(original): - for cls in inspect.getmro(original): + # We can't just always use getattr() because in doing + # that on a class it will cause binding to occur which + # will complicate things later and cause some things not + # to work. For the case of a class we therefore access + # the __dict__ directly. To cope though with the wrong + # class being given to us, or a method being moved into + # a base class, we need to walk the class hierarchy to + # work out exactly which __dict__ the method was defined + # in, as accessing it from __dict__ will fail if it was + # not actually on the class given. Fallback to using + # getattr() if we can't find it. If it truly doesn't + # exist, then that will fail. + + def lookup_attribute(parent, attribute): + if inspect.isclass(parent): + for cls in inspect.getmro(parent): if attribute in vars(cls): - original = vars(cls)[attribute] - break + return vars(cls)[attribute] else: - original = getattr(original, attribute) - + return getattr(parent, attribute) else: - original = getattr(original, attribute) + return getattr(parent, attribute) + + original = lookup_attribute(parent, attribute) + + for attribute in path[1:]: + parent = original + original = lookup_attribute(parent, attribute) return (parent, attribute, original)