From 5bfd93842cb3126a31a223bb671089ab60ac493c Mon Sep 17 00:00:00 2001 From: Dmitry Mikheev Date: Sat, 15 Jul 2017 18:39:01 +0500 Subject: [PATCH 1/2] Let users extend their bottom buttons functions Like this: ``` aqt.deckbrowser.DeckBrowser.drawLinks.extend([ ["", "rebuildAll", _("Rebuild All")], ["", "emptyAll", _("Empty All")], ]) ``` --- aqt/deckbrowser.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/aqt/deckbrowser.py b/aqt/deckbrowser.py index 9f2dc2c5e..7eeb7517c 100644 --- a/aqt/deckbrowser.py +++ b/aqt/deckbrowser.py @@ -333,14 +333,15 @@ where id > ?""", (self.mw.col.sched.dayCutoff-86400)*1000) # Top buttons ###################################################################### - def _drawButtons(self): - links = [ + drawLinks = [ ["", "shared", _("Get Shared")], ["", "create", _("Create Deck")], - ["Ctrl+I", "import", _("Import File")], - ] + ["Ctrl+I", "import", _("Import File")], # Ctrl+I works from menu + ] + + def _drawButtons(self): buf = "" - for b in links: + for b in drawLinks: if b[0]: b[0] = _("Shortcut key: %s") % shortcut(b[0]) buf += """ From 37ba8832f839e1e186faa97eb6880b833bf8a82c Mon Sep 17 00:00:00 2001 From: dequis Date: Sun, 16 Jul 2017 23:25:34 -0300 Subject: [PATCH 2/2] Make hooks.wrap preserve signatures, fixes hooking some pyqt5 callbacks It looks like pyqt5 is playing dirty and checking the number of args of functions before calling them. When using hooks.wrap, pyqt5 thinks it can pass any amount of arguments (because *args) and you get exceptions like this inside the wrap function, when calling the 'old' function: >TypeError: onFindDupes() takes 1 positional argument but 2 were given This commit fixes it by preserving the signature of the wrapped method, by adding an optional dependency on the "decorator" module. Making it an optional dependency is probably not the wisest idea but since this is a small edge case it might be smoother to start like this. I also added functools.wraps() as a fallback, which won't help much but is slightly more correct. See this article for details: https://hynek.me/articles/decorators/ --- anki/hooks.py | 17 ++++++++++++++++- requirements.txt | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/anki/hooks.py b/anki/hooks.py index 7c5270bce..f29e75003 100644 --- a/anki/hooks.py +++ b/anki/hooks.py @@ -13,6 +13,14 @@ If you call wrap() with pos='around', the original function will not be called automatically but can be called with _old(). """ +import functools + +try: + # optional: like functools.wraps, but signature-preserving + import decorator +except ImportError: + decorator = None + # Hooks ############################################################################## @@ -59,4 +67,11 @@ def wrap(old, new, pos="after"): return old(*args, **kwargs) else: return new(_old=old, *args, **kwargs) - return repl + + if decorator is None: + return functools.wraps(repl) + + def decorator_wrapper(f, *args, **kwargs): + return repl(*args, **kwargs) + + return decorator.decorator(decorator_wrapper)(old) diff --git a/requirements.txt b/requirements.txt index cd37c7b9e..ba519212a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ send2trash httplib2 pyaudio requests +decorator