From 88db824a77db54a4dc75a13d0aa23c0a6da59d4c Mon Sep 17 00:00:00 2001 From: Kai Huuhko Date: Fri, 20 Sep 2013 12:01:50 +0300 Subject: [PATCH] Change the _METHOD_DEPRECATED function into a decorator. - move the decorator into a new package/module: utils/deprecated - simplify setup.py logic slightly, it still needs work --- efl/elementary/genlist.pyx | 4 ++-- efl/elementary/label.pyx | 26 +++++++-------------- efl/elementary/naviframe.pyx | 18 +++++++++++++-- efl/elementary/need.pyx | 9 ++++---- efl/elementary/object.pyx | 19 ++++++++++++--- efl/elementary/scroller.pyx | 14 ++++------- efl/eo/efl.eo.pyx | 23 ------------------ efl/utils/__init__.py | 0 efl/utils/deprecated.pyx | 45 ++++++++++++++++++++++++++++++++++++ include/efl.eo.pxd | 1 - setup.py | 41 +++++++++++++++----------------- 11 files changed, 115 insertions(+), 85 deletions(-) create mode 100644 efl/utils/__init__.py create mode 100644 efl/utils/deprecated.pyx diff --git a/efl/elementary/genlist.pyx b/efl/elementary/genlist.pyx index 9cdeb89..cecad29 100644 --- a/efl/elementary/genlist.pyx +++ b/efl/elementary/genlist.pyx @@ -504,7 +504,7 @@ include "tooltips.pxi" from cpython cimport PyUnicode_AsUTF8String -from efl.eo cimport _METHOD_DEPRECATED +from efl.utils.deprecated import DEPRECATED from object_item cimport ObjectItem, _object_item_to_python, \ elm_object_item_widget_get, _object_item_from_python, \ @@ -689,8 +689,8 @@ class GenlistItemsCount(int): def __init__(self, Object obj, int count): self.obj = obj + @DEPRECATED def __call__(self): - _METHOD_DEPRECATED(self.obj, "Use items_count instead.") return self.obj._items_count() include "genlist_item_class.pxi" diff --git a/efl/elementary/label.pyx b/efl/elementary/label.pyx index 15b0f32..beaa52e 100644 --- a/efl/elementary/label.pyx +++ b/efl/elementary/label.pyx @@ -97,7 +97,7 @@ Slide modes include "widget_header.pxi" from layout_class cimport LayoutClass -from efl.eo cimport _METHOD_DEPRECATED +from efl.utils.deprecated import DEPRECATED cimport enums @@ -182,34 +182,24 @@ cdef class Label(LayoutClass): return elm_label_ellipsis_get(self.obj) property slide: - """The sliding effect of the label widget. + """ - If set to True, the text of the label will slide/scroll through the - length of label. - - .. warning:: This only works with the themes "slide_short", - "slide_long" and "slide_bounce". - - .. warning:: Deprecated. use slide_mode instead - - :type: bool + .. deprecated:: 1.8 + Use :py:attr:`slide_mode` instead. """ def __get__(self): - _METHOD_DEPRECATED(self, "Use slide_mode instead.") - return bool(elm_label_slide_mode_get(self.obj)) + return self.slide_get() def __set__(self, slide): - _METHOD_DEPRECATED(self, "Use slide_mode instead.") - elm_label_slide_mode_set(self.obj, - ELM_LABEL_SLIDE_MODE_ALWAYS if slide else ELM_LABEL_SLIDE_MODE_NONE) + self.slide_set(ELM_LABEL_SLIDE_MODE_ALWAYS if slide else ELM_LABEL_SLIDE_MODE_NONE) + @DEPRECATED def slide_set(self, bint slide): - _METHOD_DEPRECATED(self, "Use slide_mode instead.") elm_label_slide_mode_set(self.obj, ELM_LABEL_SLIDE_MODE_ALWAYS if slide else ELM_LABEL_SLIDE_MODE_NONE) + @DEPRECATED def slide_get(self): - _METHOD_DEPRECATED(self, "Use slide_mode instead.") return bool(elm_label_slide_mode_get(self.obj)) property slide_duration: diff --git a/efl/elementary/naviframe.pyx b/efl/elementary/naviframe.pyx index d908450..5211d77 100644 --- a/efl/elementary/naviframe.pyx +++ b/efl/elementary/naviframe.pyx @@ -101,6 +101,8 @@ from layout_class cimport LayoutClass from object_item cimport _object_item_to_python, \ _object_item_list_to_python +from efl.utils.deprecated import DEPRECATED + cdef class NaviframeItem(ObjectItem): """An item for the Naviframe widget.""" @@ -257,8 +259,14 @@ cdef class NaviframeItem(ObjectItem): else: return None + @DEPRECATED def item_pop_to(self): - #_METHOD_DEPRECATED(self, "pop_to") + """item_pop_to() + + .. deprecated:: 1.8 + Use :py:func:`pop_to` instead. + + """ elm_naviframe_item_pop_to(self.item) def pop_to(self): @@ -269,8 +277,14 @@ cdef class NaviframeItem(ObjectItem): """ elm_naviframe_item_pop_to(self.item) + @DEPRECATED def item_promote(self): - #_METHOD_DEPRECATED(self, "promote") + """item_promote() + + .. deprecated:: 1.8 + Use :py:func:`promote` instead. + + """ elm_naviframe_item_promote(self.item) def promote(self): diff --git a/efl/elementary/need.pyx b/efl/elementary/need.pyx index 5a2669d..8f69e09 100644 --- a/efl/elementary/need.pyx +++ b/efl/elementary/need.pyx @@ -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.eo cimport _METHOD_DEPRECATED +from efl.utils.deprecated import DEPRECATED def need_efreet(): """need_efreet() -> bool @@ -62,23 +62,24 @@ def need_sys_notify(): """ return bool(elm_need_sys_notify()) +@DEPRECATED def need_e_dbus(): """need_e_dbus() -> bool Request that your elementary application needs e_dbus - This initializes the E_dbus library when called and if support exists + This initializes the e_dbus library when called and if support exists it returns True, otherwise returns False. This must be called before any e_dbus calls. :return: True if support exists and initialization succeeded. :rtype: bool - :deprecated: Use :py:func:`need_edbus` for EDBus (v2) support. Old API is + .. deprecated:: 1.8 + Use :py:func:`need_eldbus` for eldbus (v2) support. Old API is deprecated. """ - print("need_e_dbus() is deprecated. Use need_edbus instead.") return bool(elm_need_eldbus()) def need_eldbus(): diff --git a/efl/elementary/object.pyx b/efl/elementary/object.pyx index f173991..05c4ac1 100644 --- a/efl/elementary/object.pyx +++ b/efl/elementary/object.pyx @@ -189,7 +189,8 @@ from cpython cimport PyObject, Py_INCREF, Py_DECREF, PyObject_GetAttr, \ include "widget_header.pxi" include "tooltips.pxi" -from efl.eo cimport _object_list_to_python, _METHOD_DEPRECATED +from efl.eo cimport _object_list_to_python +from efl.utils.deprecated import DEPRECATED from efl.evas cimport EventKeyDown, EventKeyUp, EventMouseWheel from efl.evas cimport evas_object_smart_callback_add @@ -1369,8 +1370,14 @@ cdef class Object(evasObject): return bool(elm_object_tooltip_window_mode_get(self.obj)) #Translatable text + @DEPRECATED def domain_translatable_text_part_set(self, part, domain, text): - _METHOD_DEPRECATED(self, "Use domain_translatable_part_text_set() instead.") + """domain_translatable_text_part_set(part, domain, text) + + .. deprecated:: 1.8 + Use :py:func:`domain_translatable_part_text_set` instead. + + """ if isinstance(part, unicode): part = PyUnicode_AsUTF8String(part) if isinstance(domain, unicode): domain = PyUnicode_AsUTF8String(domain) if isinstance(text, unicode): text = PyUnicode_AsUTF8String(text) @@ -1424,8 +1431,14 @@ cdef class Object(evasObject): domain if domain is not None else NULL, text if text is not None else NULL) + @DEPRECATED def translatable_text_part_get(self, part): - _METHOD_DEPRECATED(self, "Use translatable_part_text_get() instead.") + """translatable_text_part_get(part) -> unicode + + .. deprecated:: 1.8 + Use :py:func:`translatable_part_text_get` instead. + + """ if isinstance(part, unicode): part = PyUnicode_AsUTF8String(part) return _ctouni(elm_object_translatable_part_text_get(self.obj, part if part is not None else NULL)) diff --git a/efl/elementary/scroller.pyx b/efl/elementary/scroller.pyx index 4efa482..dbc14a7 100644 --- a/efl/elementary/scroller.pyx +++ b/efl/elementary/scroller.pyx @@ -118,7 +118,7 @@ include "widget_header.pxi" from object cimport Object from layout_class cimport LayoutClass -from efl.eo cimport _METHOD_DEPRECATED +from efl.utils.deprecated import DEPRECATED cimport enums @@ -143,18 +143,14 @@ cdef class ScrollableInterface(Object): # TODO: Use the scrollable interface functions? Need to base on # evas.SmartObject? + @DEPRECATED def custom_widget_base_theme_set(self, widget, base): - """custom_widget_base_theme_set(unicode widget, unicode base) + """custom_widget_base_theme_set(widget, base) - Set custom theme elements for the scroller - - :param widget: The widget name to use (default is "scroller") - :type widget: string - :param base: The base name to use (default is "base") - :type base: string + .. deprecated:: 1.8 + Use :py:attr:`theme` instead. """ - _METHOD_DEPRECATED(self, "Use the property 'theme' instead.") if isinstance(widget, unicode): widget = PyUnicode_AsUTF8String(widget) if isinstance(base, unicode): base = PyUnicode_AsUTF8String(base) elm_scroller_custom_widget_base_theme_set(self.obj, diff --git a/efl/eo/efl.eo.pyx b/efl/eo/efl.eo.pyx index 8efd914..a2c7332 100644 --- a/efl/eo/efl.eo.pyx +++ b/efl/eo/efl.eo.pyx @@ -27,8 +27,6 @@ from efl.c_eo cimport Eo as cEo, eo_init, eo_shutdown, eo_del, eo_do, \ Eo_Event_Description, const_Eo_Event_Description, \ eo_parent_get, EO_EV_DEL -import traceback - ###################################################################### # # TODO: Automate these @@ -157,27 +155,6 @@ cdef Eina_List *convert_python_list_objects_to_eina_list(list objects): return lst -cdef void _METHOD_DEPRECATED(object self, char *message): - cdef: - object stack - tuple caller - str msg - - stack = traceback.extract_stack() - caller = stack[-1] - caller_module, caller_line, caller_name, caller_code = caller - if caller_code is not None: - msg = "%s:%s %s (class %s) is deprecated. %s" % \ - (caller_module, caller_line, caller_code, - type(self).__name__, message) - else: - msg = "%s:%s %s.%s() is deprecated. %s" % \ - (caller_module, caller_line, - type(self).__name__, caller_name, message) -# log.warn(msg) - print(msg) - - ###################################################################### diff --git a/efl/utils/__init__.py b/efl/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/efl/utils/deprecated.pyx b/efl/utils/deprecated.pyx new file mode 100644 index 0000000..908a682 --- /dev/null +++ b/efl/utils/deprecated.pyx @@ -0,0 +1,45 @@ +import traceback +import types +from functools import update_wrapper + + +class DEPRECATED(object): + + def __init__(self, object f): + self.f = f + + assignments = ["__name__", "__doc__"] + if hasattr(f, "__module__"): + assignments.append("__module__") + update_wrapper(self, f, assigned=assignments) + + #if hasattr(f, "__objclass__"): + #print("WARNING: method %s.%s is deprecated" % (f.__objclass__.__name__, f.__name__)) + #else: + #print("WARNING: function %s is deprecated" % (f.__name__)) + + def __get__(self, obj, objtype): + return types.MethodType(self, obj, objtype) + + def __call__(self, *args, **kwargs): + cdef: + object stack + tuple caller + str msg + + stack = traceback.extract_stack() + caller = stack[-1] + caller_module, caller_line, caller_name, caller_code = caller + if caller_code is not None: + if hasattr(self.f, "__objclass__"): + msg = "WARNING: 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 = "WARNING: Deprecated function %s called in %s:%s %s." % \ + (self.f.__name__, caller_module, caller_line, caller_code) + else: + msg = "WARNING: Deprecated function %s.%s called in %s:%s." % \ + (self.f.__name__, caller_name, caller_module, caller_line) + print(msg) + + return self.f(*args, **kwargs) diff --git a/include/efl.eo.pxd b/include/efl.eo.pxd index 0e3aef4..542023f 100644 --- a/include/efl.eo.pxd +++ b/include/efl.eo.pxd @@ -45,4 +45,3 @@ cdef list convert_eina_list_strings_to_python_list(const_Eina_List *lst) cdef Eina_List * convert_python_list_strings_to_eina_list(list strings) cdef list _object_list_to_python(const_Eina_List *lst) cdef Eina_List *convert_python_list_objects_to_eina_list(list objects) -cdef void _METHOD_DEPRECATED(object self, char *message) diff --git a/setup.py b/setup.py index 11eb871..5a33d46 100755 --- a/setup.py +++ b/setup.py @@ -8,8 +8,8 @@ from distutils.version import StrictVersion # Cython +min_ver = "0.17.0" try: - min_ver = "0.17.0" from Cython.Distutils import build_ext from Cython.Build import cythonize import Cython.Compiler.Options @@ -56,26 +56,17 @@ def pkg_config(name, require, min_vers=None): modules = [] -if len(sys.argv) is 2 and "build_doc" in sys.argv: - # - # The idea here is that we *don't need* the version checks or extensions - # when *only* building the documentation: - # ./setup.py build_doc - # - # If we *both* build the extensions *and* docs, they *are* needed: - # ./setup.py build build_doc - # - pass -else: - ## This is usefull while working on the source, to force the rebuild of modules. - # subprocess.call("rm -rfv efl/eo/*.c", shell=True) - # subprocess.call("rm -rfv efl/evas/*.c", shell=True) - # subprocess.call("rm -rfv efl/ecore/*.c", shell=True) - # subprocess.call("rm -rfv efl/edje/*.c", shell=True) - # subprocess.call("rm -rfv efl/edje/edit/*.c", shell=True) - # subprocess.call("rm -rfv efl/emotion/*.c", shell=True) - # subprocess.call("rm -rfv efl/elementary/*.c", shell=True) - # subprocess.call("rm -rfv efl/dbus_mainloop/dbus_mainloop.c", shell=True) +class CleanGenerated(Command): + description = "Clean C and html files generated by Cython" + user_options = [] + def initialize_options(self): pass + def finalize_options(self): pass + def run(self): + for lib in "eo", "evas", "ecore", "edje", "edje/edit", "emotion", "elementary": + subprocess.call("rm -rfv efl/{0}/*.c efl/{0}/*.html".format(lib), shell=True) + subprocess.call("rm -rfv efl/dbus_mainloop/dbus_mainloop.c efl/dbus_mainloop/dbus_mainloop.html", shell=True) + +if set(("build", "build_ext", "install")) & set(sys.argv): # Eo eo_cflags, eo_libs = pkg_config('Eo', 'eo', "1.7.99") @@ -87,6 +78,10 @@ else: extra_link_args = eo_libs + eina_libs) modules.append(eo_ext) + # Utilities + utils_ext = Extension("efl.utils.deprecated", ["efl/utils/deprecated.pyx"]) + modules.append(utils_ext) + # Evas evas_cflags, evas_libs = pkg_config('Evas', 'evas', "1.7.99") evas_ext = Extension("efl.evas", ["efl/evas/efl.evas.pyx"], @@ -240,8 +235,8 @@ if __name__ == "__main__": url = "http://www.enlightenment.org", description = "Python bindings for the EFL stack", license = "GNU Lesser General Public License (LGPL)", - packages = ["efl", "efl.elementary"], - cmdclass = {'build_ext': build_ext, 'build_doc': BuildDoc}, + packages = ["efl", "efl.elementary", "efl.utils"], + cmdclass = {'build_ext': build_ext, 'build_doc': BuildDoc, 'clean_generated_files': CleanGenerated}, # command_options = { # "build_doc": { # "builder": (None, "html"),