python: Share generated methods between objects.
[gpgme.git] / lang / python / pyme / util.py
1 # $Id$
2 # Copyright (C) 2004,2008 Igor Belyi <belyi@users.sourceforge.net>
3 # Copyright (C) 2002 John Goerzen <jgoerzen@complete.org>
4 #
5 #    This library is free software; you can redistribute it and/or
6 #    modify it under the terms of the GNU Lesser General Public
7 #    License as published by the Free Software Foundation; either
8 #    version 2.1 of the License, or (at your option) any later version.
9 #
10 #    This library is distributed in the hope that it will be useful,
11 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #    Lesser General Public License for more details.
14 #
15 #    You should have received a copy of the GNU Lesser General Public
16 #    License along with this library; if not, write to the Free Software
17 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
18
19 from . import pygpgme
20 from .errors import errorcheck
21
22 def process_constants(starttext, dict):
23     """Called by the constant libraries to load up the appropriate constants
24     from the C library."""
25     index = len(starttext)
26     for identifier in dir(pygpgme):
27         if not identifier.startswith(starttext):
28             continue
29         name = identifier[index:]
30         dict[name] = getattr(pygpgme, identifier)
31
32 class GpgmeWrapper(object):
33     """Base class all Pyme wrappers for GPGME functionality.  Not to be
34     instantiated directly."""
35     def __repr__(self):
36         return '<instance of %s.%s with GPG object at %s>' % \
37                (__name__, self.__class__.__name__,
38                 self.wrapped)
39
40     def __str__(self):
41         return repr(self)
42
43     def __hash__(self):
44         return hash(repr(self.wrapped))
45
46     def __eq__(self, other):
47         if other == None:
48             return False
49         else:
50             return repr(self.wrapped) == repr(other.wrapped)
51
52     def _getctype(self):
53         """Must be implemented by child classes.
54
55         Must return the name of the c type."""
56         raise NotImplementedError()
57
58     def _getnameprepend(self):
59         """Must be implemented by child classes.
60
61         Must return the prefix of all c functions mapped to methods of
62         this class."""
63         raise NotImplementedError()
64
65     def _errorcheck(self, name):
66         """Must be implemented by child classes.
67
68         This function must return a trueish value for all c functions
69         returning gpgme_error_t."""
70         raise NotImplementedError()
71
72     def __getattr__(self, key):
73         """On-the-fly function generation."""
74         if key[0] == '_' or self._getnameprepend() == None:
75             return None
76         name = self._getnameprepend() + key
77         func = getattr(pygpgme, name)
78
79         if self._errorcheck(name):
80             def _funcwrap(slf, *args, **kwargs):
81                 return errorcheck(func(slf.wrapped, *args, **kwargs),
82                                   "Invocation of " + name)
83         else:
84             def _funcwrap(slf, *args, **kwargs):
85                 return func(slf.wrapped, *args, **kwargs)
86
87         _funcwrap.__doc__ = getattr(func, "__doc__")
88
89         # Monkey-patch the class.
90         setattr(self.__class__, key, _funcwrap)
91
92         # Bind the method to 'self'.
93         def wrapper(*args, **kwargs):
94             return _funcwrap(self, *args, **kwargs)
95         _funcwrap.__doc__ = getattr(func, "__doc__")
96
97         return wrapper
98