[weboob] [PATCH 1/1] use abstractmethod decorator

Pierre-Louis Bonicoli pierre-louis.bonicoli at gmx.fr
Mon Jul 20 16:01:24 CEST 2015


Classes ignored:
- IFormatter: all subclasses doesn't implement format_dict
- capabilities

Signed-off-by: Pierre-Louis Bonicoli <pierre-louis.bonicoli at gmx.fr>
---
 weboob/browser/browsers.py                        |  8 ++++++++
 weboob/browser/filters/json.py                    |  8 +++++++-
 weboob/browser/filters/standard.py                |  7 ++++---
 weboob/browser/pages.py                           |  6 +++++-
 weboob/browser/profiles.py                        |  6 ++++++
 weboob/core/repositories.py                       |  8 +++++++-
 weboob/core/scheduler.py                          | 10 +++++++++-
 weboob/tools/application/base.py                  |  6 +++++-
 weboob/tools/application/formatters/iformatter.py |  4 ++++
 weboob/tools/application/results.py               |  6 ++++++
 weboob/tools/config/iconfig.py                    | 12 +++++++++++-
 weboob/tools/storage.py                           | 10 +++++++++-
 12 files changed, 81 insertions(+), 10 deletions(-)

diff --git a/weboob/browser/browsers.py b/weboob/browser/browsers.py
index 52d4949..9371928 100644
--- a/weboob/browser/browsers.py
+++ b/weboob/browser/browsers.py
@@ -19,6 +19,7 @@
 
 from __future__ import absolute_import, print_function
 
+from abc import ABCMeta, abstractmethod
 import re
 import pickle
 import base64
@@ -751,16 +752,23 @@ def need_login(func):
     return inner
 
 
+class LoginBrowserMeta(ABCMeta, _PagesBrowserMeta):
+    pass
+
+
 class LoginBrowser(PagesBrowser):
     """
     A browser which supports login.
     """
 
+    __metaclass__ = LoginBrowserMeta
+
     def __init__(self, username, password, *args, **kwargs):
         super(LoginBrowser, self).__init__(*args, **kwargs)
         self.username = username
         self.password = password
 
+    @abstractmethod
     def do_login(self):
         """
         Abstract method to implement to login on website.
diff --git a/weboob/browser/filters/json.py b/weboob/browser/filters/json.py
index 52fd155..f217cc2 100644
--- a/weboob/browser/filters/json.py
+++ b/weboob/browser/filters/json.py
@@ -18,6 +18,8 @@
 # along with weboob. If not, see <http://www.gnu.org/licenses/>.
 
 
+from abc import ABCMeta
+
 from .standard import _Filter, _NO_DEFAULT, Filter, ParseError
 
 __all__ = ['Dict']
@@ -35,8 +37,12 @@ class _DictMeta(type):
         return cls(name)
 
 
+class DictMeta(_DictMeta, ABCMeta):
+    pass
+
+
 class Dict(Filter):
-    __metaclass__ = _DictMeta
+    __metaclass__ = DictMeta
 
     def __init__(self, selector=None, default=_NO_DEFAULT):
         super(Dict, self).__init__(self, default=default)
diff --git a/weboob/browser/filters/standard.py b/weboob/browser/filters/standard.py
index d86bff4..75cb216 100644
--- a/weboob/browser/filters/standard.py
+++ b/weboob/browser/filters/standard.py
@@ -19,6 +19,7 @@
 
 from __future__ import absolute_import
 
+from abc import ABCMeta, abstractmethod
 import datetime
 import re
 import unicodedata
@@ -154,6 +155,8 @@ class Filter(_Filter):
     Decimal('229.90')
     """
 
+    __metaclass__ = ABCMeta
+
     def __init__(self, selector=None, default=_NO_DEFAULT):
         super(Filter, self).__init__(default=default)
         self.selector = selector
@@ -175,6 +178,7 @@ class Filter(_Filter):
         return self.filter(self.select(self.selector, item, key=self._key, obj=self._obj))
 
     @debug()
+    @abstractmethod
     def filter(self, value):
         """
         This method have to be overrided by children classes.
@@ -652,9 +656,6 @@ class MultiFilter(Filter):
         values = [self.select(selector, item, obj=self._obj, key=self._key) for selector in self.selector]
         return self.filter(tuple(values))
 
-    def filter(self, values):
-        raise NotImplementedError()
-
 
 class CombineDate(MultiFilter):
     def __init__(self, date, time):
diff --git a/weboob/browser/pages.py b/weboob/browser/pages.py
index 33f7713..9ce304a 100644
--- a/weboob/browser/pages.py
+++ b/weboob/browser/pages.py
@@ -19,6 +19,7 @@
 
 from __future__ import absolute_import
 
+from abc import ABCMeta, abstractmethod
 import warnings
 from io import BytesIO
 import codecs
@@ -89,7 +90,7 @@ class NextPage(Exception):
         self.request = request
 
 
-class Page(object):
+class Page:
     """
     Represents a page.
 
@@ -111,6 +112,8 @@ class Page(object):
 
     """
 
+    __metaclass__ = ABCMeta
+
     ENCODING = None
     """
     Force a page encoding.
@@ -187,6 +190,7 @@ class Page(object):
         Event called when browser leaves this page.
         """
 
+    @abstractmethod
     def build_doc(self, content):
         """
         Abstract method to be implemented by subclasses to build structured
diff --git a/weboob/browser/profiles.py b/weboob/browser/profiles.py
index c900f43..b2b1397 100644
--- a/weboob/browser/profiles.py
+++ b/weboob/browser/profiles.py
@@ -18,12 +18,18 @@
 # along with weboob. If not, see <http://www.gnu.org/licenses/>.
 
 
+from abc import ABCMeta, abstractmethod
+
+
 class Profile(object):
     """
     A profile represents the way Browser should act.
     Usually it is to mimic a real browser.
     """
 
+    __metaclass__ = ABCMeta
+
+    @abstractmethod
     def setup_session(self, session):
         """
         Change default headers, set up hooks, etc.
diff --git a/weboob/core/repositories.py b/weboob/core/repositories.py
index 5afde3e..517b46b 100644
--- a/weboob/core/repositories.py
+++ b/weboob/core/repositories.py
@@ -19,6 +19,7 @@
 
 
 from __future__ import print_function
+from abc import ABCMeta, abstractmethod
 import imp
 import posixpath
 import shutil
@@ -374,13 +375,18 @@ class Versions(object):
             config.write(fp)
 
 
-class IProgress(object):
+class IProgress:
+    __metaclass__ = ABCMeta
+
+    @abstractmethod
     def progress(self, percent, message):
         raise NotImplementedError()
 
+    @abstractmethod
     def error(self, message):
         raise NotImplementedError()
 
+    @abstractmethod
     def prompt(self, message):
         raise NotImplementedError()
 
diff --git a/weboob/core/scheduler.py b/weboob/core/scheduler.py
index 2b3a037..df92c9a 100644
--- a/weboob/core/scheduler.py
+++ b/weboob/core/scheduler.py
@@ -20,6 +20,7 @@
 
 from __future__ import print_function
 
+from abc import ABCMeta, abstractmethod
 from threading import Event, RLock
 try:
     from threading import _Timer as Timer
@@ -33,19 +34,26 @@ from weboob.tools.misc import get_backtrace
 __all__ = ['Scheduler']
 
 
-class IScheduler(object):
+class IScheduler:
+    __metaclass__ = ABCMeta
+
+    @abstractmethod
     def schedule(self, interval, function, *args):
         raise NotImplementedError()
 
+    @abstractmethod
     def repeat(self, interval, function, *args):
         raise NotImplementedError()
 
+    @abstractmethod
     def cancel(self, ev):
         raise NotImplementedError()
 
+    @abstractmethod
     def run(self):
         raise NotImplementedError()
 
+    @abstractmethod
     def want_stop(self):
         raise NotImplementedError()
 
diff --git a/weboob/tools/application/base.py b/weboob/tools/application/base.py
index 3cd66bd..eb04977 100644
--- a/weboob/tools/application/base.py
+++ b/weboob/tools/application/base.py
@@ -20,6 +20,7 @@
 
 from __future__ import print_function
 
+from abc import ABCMeta, abstractmethod
 import logging
 import optparse
 from optparse import OptionGroup, OptionParser
@@ -72,7 +73,7 @@ class ApplicationStorage(object):
             return self.storage.save('applications', self.name)
 
 
-class Application(object):
+class Application:
     """
     Base application.
 
@@ -80,6 +81,8 @@ class Application(object):
     applications.
     """
 
+    __metaclass__ = ABCMeta
+
     # ------ Class attributes --------------------------------------
 
     # Application name
@@ -232,6 +235,7 @@ class Application(object):
         self.config = klass(path)
         self.config.load(self.CONFIG)
 
+    @abstractmethod
     def main(self, argv):
         """
         Main method
diff --git a/weboob/tools/application/formatters/iformatter.py b/weboob/tools/application/formatters/iformatter.py
index bbfa8ec..ce500b3 100644
--- a/weboob/tools/application/formatters/iformatter.py
+++ b/weboob/tools/application/formatters/iformatter.py
@@ -20,6 +20,7 @@
 
 from __future__ import print_function
 
+from abc import ABCMeta, abstractmethod
 import os
 import sys
 import subprocess
@@ -244,6 +245,8 @@ class IFormatter(object):
 
 
 class PrettyFormatter(IFormatter):
+    __metaclass__ = ABCMeta
+
     def format_obj(self, obj, alias):
         title = self.get_title(obj)
         desc = self.get_description(obj)
@@ -263,6 +266,7 @@ class PrettyFormatter(IFormatter):
 
         return result
 
+    @abstractmethod
     def get_title(self, obj):
         raise NotImplementedError()
 
diff --git a/weboob/tools/application/results.py b/weboob/tools/application/results.py
index e079087..82962be 100644
--- a/weboob/tools/application/results.py
+++ b/weboob/tools/application/results.py
@@ -17,6 +17,9 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with weboob. If not, see <http://www.gnu.org/licenses/>.
 
+
+from abc import ABCMeta, abstractmethod
+
 from weboob.capabilities import UserError
 
 
@@ -24,6 +27,9 @@ __all__ = ['ResultsCondition', 'ResultsConditionError']
 
 
 class IResultsCondition(object):
+    __metaclass__ = ABCMeta
+
+    @abstractmethod
     def is_valid(self, obj):
         raise NotImplementedError()
 
diff --git a/weboob/tools/config/iconfig.py b/weboob/tools/config/iconfig.py
index 46efd88..c7d46a7 100644
--- a/weboob/tools/config/iconfig.py
+++ b/weboob/tools/config/iconfig.py
@@ -18,22 +18,32 @@
 # along with weboob. If not, see <http://www.gnu.org/licenses/>.
 
 
+from abc import ABCMeta, abstractmethod
+
+
 class ConfigError(Exception):
     pass
 
 
-class IConfig(object):
+class IConfig:
+    __metaclass__ = ABCMeta
+
+    @abstractmethod
     def load(self, default={}):
         raise NotImplementedError()
 
+    @abstractmethod
     def save(self):
         raise NotImplementedError()
 
+    @abstractmethod
     def set(self, *args):
         raise NotImplementedError()
 
+    @abstractmethod
     def delete(self, *args):
         raise NotImplementedError()
 
+    @abstractmethod
     def get(self, *args, **kwargs):
         raise NotImplementedError()
diff --git a/weboob/tools/storage.py b/weboob/tools/storage.py
index be70238..e54b111 100644
--- a/weboob/tools/storage.py
+++ b/weboob/tools/storage.py
@@ -18,36 +18,44 @@
 # along with weboob. If not, see <http://www.gnu.org/licenses/>.
 
 
+from abc import ABCMeta, abstractmethod
 from copy import deepcopy
 
 from .config.yamlconfig import YamlConfig
 
 
-class IStorage(object):
+class IStorage:
+    __metaclass__ = ABCMeta
+
+    @abstractmethod
     def load(self, what, name, default={}):
         """
         Load data from storage.
         """
         raise NotImplementedError()
 
+    @abstractmethod
     def save(self, what, name):
         """
         Write changes in storage on the disk.
         """
         raise NotImplementedError()
 
+    @abstractmethod
     def set(self, what, name, *args):
         """
         Set data in a path.
         """
         raise NotImplementedError()
 
+    @abstractmethod
     def delete(self, what, name, *args):
         """
         Delete a value or a path.
         """
         raise NotImplementedError()
 
+    @abstractmethod
     def get(self, what, name, *args, **kwargs):
         """
         Get a value or a path.
-- 
2.1.4




More information about the weboob mailing list