From 16fa850f246ef7214f42903a7d249267d69ffdad Mon Sep 17 00:00:00 2001 From: Dave Andreoli Date: Sat, 5 Nov 2016 11:42:26 +0100 Subject: [PATCH] Fix for cython 0.25 New cython do not like our cdef @DEPRECATED decorator implementation, I'm not able to fix it, so I just rewrite it in pure python. The new one is a bit simpler, it do not print the source file anymore, but still augment the documentation. Tested with Cython 0.24.1 and 0.25.1 on both python 2.7 and 3.5, hope is enough. #IHateCython --- efl/ecore_x/efl.ecore_x.pyx | 2 +- efl/elementary/__init__.pyx | 2 +- efl/evas/efl.evas_rect.pxi | 2 +- efl/utils/deprecated.pyx | 85 +++++++++----------------------- include/efl.utils.deprecated.pxd | 10 ++-- 5 files changed, 31 insertions(+), 70 deletions(-) diff --git a/efl/ecore_x/efl.ecore_x.pyx b/efl/ecore_x/efl.ecore_x.pyx index 8cec6ae..2d70a35 100644 --- a/efl/ecore_x/efl.ecore_x.pyx +++ b/efl/ecore_x/efl.ecore_x.pyx @@ -17,7 +17,7 @@ #from cpython cimport PyObject, Py_INCREF, Py_DECREF from cpython cimport PyMem_Malloc, PyMem_Free, PyUnicode_AsUTF8String -from efl.utils.deprecated cimport DEPRECATED +from efl.utils.deprecated import DEPRECATED import atexit diff --git a/efl/elementary/__init__.pyx b/efl/elementary/__init__.pyx index 91081d2..2f5709e 100644 --- a/efl/elementary/__init__.pyx +++ b/efl/elementary/__init__.pyx @@ -1187,7 +1187,7 @@ def sys_notify_send( from cpython cimport PyObject_GetBuffer, PyBuffer_Release, PyBUF_SIMPLE, \ PyObject_CheckBuffer -from efl.utils.deprecated cimport DEPRECATED +from efl.utils.deprecated import DEPRECATED from efl.utils.conversions cimport * from efl.eo cimport Eo, object_from_instance from efl.evas cimport SmartObject, EventKeyDown, EventKeyUp, EventMouseWheel diff --git a/efl/evas/efl.evas_rect.pxi b/efl/evas/efl.evas_rect.pxi index 26be907..89ce5fc 100644 --- a/efl/evas/efl.evas_rect.pxi +++ b/efl/evas/efl.evas_rect.pxi @@ -15,7 +15,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this Python-EFL. If not, see . -from efl.utils.deprecated cimport DEPRECATED +from efl.utils.deprecated import DEPRECATED cimport cython diff --git a/efl/utils/deprecated.pyx b/efl/utils/deprecated.pyx index 8e36323..e0b2aba 100644 --- a/efl/utils/deprecated.pyx +++ b/efl/utils/deprecated.pyx @@ -15,34 +15,35 @@ # You should have received a copy of the GNU Lesser General Public License # along with this Python-EFL. If not, see . -import traceback -import types -from functools import update_wrapper -from cpython cimport PY_VERSION_HEX, PyUnicode_AsUTF8String +import functools -from efl.eina cimport EINA_LOG_DOM_WARN -from efl.utils.logger cimport PY_EFL_LOG_DOMAIN -cdef class DEPRECATED(object): +class DEPRECATED(object): - def __init__(self, version=None, message=None): + def __init__(self, version, message): self.version = version self.message = message - def __call__(self, f): - wrapper = WRAPPER(f, self.version, self.message) + def __call__(self, func_or_meth): + # This wrapper will be called instead of the original one + def wrapper(*args, **kwargs): + + print("WARNING: Deprecated function '{0}' called. {1}".format( + func_or_meth.__name__, self.message)) + + return func_or_meth(*args, **kwargs) + + # copy metadata from original func assignments = ["__name__", "__doc__"] - if hasattr(f, "__module__"): + if hasattr(func_or_meth, "__module__"): assignments.append("__module__") - update_wrapper(wrapper, f, assigned=assignments) - - # Version is required for the deprecated directive + functools.update_wrapper(wrapper, func_or_meth, assigned=assignments) + # Augment the function doc with the sphinx deprecated tag doc = wrapper.__doc__ - - if doc is not None and self.version is not None: + if doc is not None: lines = doc.expandtabs().splitlines() indent = 0 @@ -53,53 +54,11 @@ cdef class DEPRECATED(object): indent = len(line) - len(stripped) break - wrapper.__doc__ += "\n\n" - - wrapper.__doc__ += indent * " " + ".. deprecated:: %s\n" % (self.version,) - - wrapper.__doc__ += (indent + 4) * " " + "%s\n" % (self.message,) + wrapper.__doc__ += \ + "\n\n" \ + "{indent}.. deprecated:: {version}\n" \ + "{indent} {message}\n".format( + indent=indent * " ", version=self.version, message=self.message) return wrapper - -class WRAPPER(object): - def __init__(self, f, version, message): - self.f = f - self.version = version - self.message = message - - def __get__(self, obj, objtype): - if PY_VERSION_HEX < 0x03000000: - return types.MethodType(self, obj, objtype) - else: - return types.MethodType(self, obj) - - def __call__(self, *args, **kwargs): - cdef: - list stack - tuple caller - str msg - - stack = list(traceback.extract_stack()) - caller = tuple(stack[-1]) - caller_module, caller_line, caller_name, caller_code = caller - if caller_code is not None: - if hasattr(self.f, "__objclass__"): - msg = "Deprecated method %s of class %s called in %s:%s %s." % \ - (self.f.__name__, self.f.__objclass__.__name__, caller_module, caller_line, caller_code) - else: - msg = "Deprecated function %s called in %s:%s %s." % \ - (self.f.__name__, caller_module, caller_line, caller_code) - else: - msg = "Deprecated function %s called in %s:%s." % \ - (self.f.__name__, caller_module, caller_line) - - if self.message is not None: - msg += " " + self.message - - msg2 = msg - if isinstance(msg2, unicode): msg2 = PyUnicode_AsUTF8String(msg2) - - EINA_LOG_DOM_WARN(PY_EFL_LOG_DOMAIN, msg2, NULL) - - return self.f(*args, **kwargs) diff --git a/include/efl.utils.deprecated.pxd b/include/efl.utils.deprecated.pxd index ae153a6..5c8e44d 100644 --- a/include/efl.utils.deprecated.pxd +++ b/include/efl.utils.deprecated.pxd @@ -15,7 +15,9 @@ # You should have received a copy of the GNU Lesser General Public License # along with this Python-EFL. If not, see . -cdef: - class DEPRECATED(object): - cdef: - str version, message +# 1.19: Converted to pure python implementation + +# cdef: +# class DEPRECATED(object): +# cdef: +# str version, message