Author: reinhard
Date: 2009-10-05 14:47:25 -0500 (Mon, 05 Oct 2009)
New Revision: 9927
Modified:
trunk/gnue-common/src/base/errors.py
trunk/gnue-common/src/base/i18n.py
trunk/gnue-common/src/base/utils.py
trunk/gnue-common/src/lib/checktype.py
Log:
Some work on documentation.
Modified: trunk/gnue-common/src/base/errors.py
===================================================================
--- trunk/gnue-common/src/base/errors.py 2009-10-02 16:59:33 UTC (rev 9926)
+++ trunk/gnue-common/src/base/errors.py 2009-10-05 19:47:25 UTC (rev 9927)
@@ -23,6 +23,126 @@
"""
Unicode enabled exception base classes.
+
+Exceptions in GNU Enterprise
+============================
+
+The C{errors} module defines four new exception base classes introducing three
+concepts not available in standard exceptions.
+
+Exception groups
+----------------
+
+GNU Enterprise defines four exception groups: C{system}, C{admin},
+C{application}, and C{user}. The groups are distinguished by the question:
+"Whose fault is it, that the exception occured?"
+
+Exception handling code can behave differently depending on the group.
+
+Group "system"
+~~~~~~~~~~~~~~
+
+Unhandled exceptions of group C{system} generally indicate a program bug in the
+GNU Enterprise framework. If such an exception occures unhandled, the user
+interface would typically ask the user to file a bug report, and/or send a
+traceback to the system administrator in order to allow him/her to file a bug
+report. The exception detail (usually the traceback) is important for such
+exceptions.
+
+To define a new exception of group C{system}, simply derive your exception
+class from L{SystemError}. Additionally, all exceptions not derived from any of
+the base classes in this module are considered to be of group C{system}, this
+includes all Python builtin exceptions and all exceptions defined in modules
+external to GNU Enterprise.
+
+Group "admin"
+~~~~~~~~~~~~~
+
+Exceptions of group C{admin} indicate a mistake in installation or
+configuration. If such an exception occures unhandled, the user interface would
+typically ask the user to inform the system administrator and/or send a message
+to the system administrator automatically. The exception detail can or can not
+be important for such exceptions.
+
+To define a new exception of group C{admin}, simply derive your exception class
+from L{AdminError}.
+
+Group "application"
+~~~~~~~~~~~~~~~~~~~
+
+Exceptions of group C{application} indicate a bug in an application built upon
+the GNU Enterprise framework, like for example a malformed form definition
+file. If such an exception occures unhandled, the user interface would
+typically ask the user to inform the programmer of the application, and/or send
+a message to the application programmer automatically. The exception detail is
+usually very important for such an exception and might, for example, contain
+the relevant line of the form definition file.
+
+To define a new exception of group C{application}, simply derive your exception
+class from L{ApplicationError}.
+
+Group "user"
+~~~~~~~~~~~~
+
+Exceptions of group C{user} indicate unexpected user input. If such an
+exception occures unhandled, the user interface would display a friendly,
+non-panicking message. All exceptions of this group are designed so that the
+exception message contains all necessary information, the user interface should
+not display the detail for this exception (usually a traceback), since this
+would only confuse the user.
+
+To define a new exception of group C{user}, simply derive your exception class
+from L{UserError}.
+
+Exception info
+--------------
+
+The functions L{get_exception} and L{format_exception} return a tuple of four
+strings giving full information about the exception:
+
+ 1. C{group}: the exception group (C{system}, C{admin}, C{application}, or
+ C{user}). Always an 8 bit string.
+ 2. C{name}: the name of the exception, usually the class name without any
+ modules prepended. Always a unicode string.
+ 3. C{message}: the exception message, the text priarly displayed to the
+ user. Always a unicode string.
+ 4. C{detail}: the exception detail, in many cases a string representation
+ of the traceback. Always a unicode string.
+
+Using exception info for different purposes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All exceptions derived from the base classes defined in this module allow to
+explicitly define C{name} and C{detail} by simply assigning a unicode string to
+the instance variables C{name} and C{detail} respectively of the exception.
+
+A typical use of this is to use something more meaningful than a traceback as
+exception detail. For example, if an error occures when parsing a file, the
+relevant line in the file might be much more useful.
+
+The possibility to explicitly define the name can be used to let exceptions
+raised through a single class to look like they were different classes, like
+when transporting remote exceptions defined in the next section.
+
+Remote exceptions
+~~~~~~~~~~~~~~~~~
+
+Remote exceptions are a way to transport exceptions across contexts, like from
+a server process to a client process. The idea is to catch the exception at the
+source end, extract the exception info from it in the form of four strings by
+using the L{get_exception} function, transporting these strings to the
+target end, raise an all-purpose general wrapper exception on the target end,
+and feed it with these four strings.
+
+To define a new all-purpose general wrapper exception, simply derive it from
+L{RemoteError}.
+
+Unicode enabled exceptions
+--------------------------
+
+All base exception classes defined in this module, and all classes derived from
+them, allow for unicode stings in the exception message. This is essential to
+allow for translated exception messages.
"""
import sys
@@ -57,7 +177,7 @@
@ivar detail: The detail information to the exception. If set, this will be
returned by L{get_exception} and L{format_exception} instead of the
traceback.
- @type name: unicode or None
+ @type detail: unicode or None
"""
def __init__(self, message, group='system'):
@@ -82,8 +202,7 @@
class SystemError(Error):
"""
- This exception class should be used for exceptions indicating a bug in
- GNUe. Whenever such an exception is raised, one have found such a bug :)
+ Base class for exceptions indicating a bug in the GNU Enterprise frameork.
"""
def __init__(self, message):
@@ -96,9 +215,8 @@
class AdminError(Error):
"""
- This exception class should be used for exceptions indicating a
- misconfiguration in a widest sense. This could be a missing module for a
- dbdriver as well as an 'out of disk space' error.
+ Base class for exceptions indicating a mistake in installation or
+ configuration.
"""
def __init__(self, message):
@@ -111,8 +229,8 @@
class ApplicationError(Error):
"""
- This class should be used for errors caused by applications like a corrupt
- trigger code, or a misformed xml-file and so on.
+ Base class for exceptions indicating a bug in the application running on
+ top of the GNU Enterprise framework.
"""
def __init__(self, message):
@@ -125,10 +243,7 @@
class UserError(Error):
"""
- This class should be used for exceptions where a user did something wrong,
- or a situation has occured which isn't dramatic, but the user has to be
- informed of. Example: wrong password or the user has entered non-numeric
- data into a numeric field, and so on.
+ Base class for exceptions indicating unexpected user input.
"""
def __init__(self, message):
@@ -141,9 +256,10 @@
class RemoteError(Error):
"""
- This class is used for transporting an exception raised at a remote point.
- Once it has been created it never changes it's contents. A remote error
- usually contains System-, Admin- or User-Errors.
+ Base class for wrappers around exceptions raised in a different context.
+
+ Exceptions of this class (or a descendant class) can mimick any given
+ exception, by wrapping arbitary group, name, message and detail properties.
"""
def __init__(self, group, name, message, detail):
@@ -163,10 +279,11 @@
def get_exception(tb_skip=None):
"""
- Return a tuple (group, name, message, detail) for the last occured
+ Return a tuple (group, name, message, detail) for the currently handled
exception.
@param tb_skip: Number of traceback lines to suppress at the beginning.
+ @type tb_skip: int
"""
(etype, evalue, etraceback) = sys.exc_info()
@@ -186,6 +303,7 @@
@param etype, evalue, etraceback: Exception info as returned by
sys.exc_info().
@param tb_skip: Number of traceback lines to suppress at the beginning.
+ @type tb_skip: int
"""
# group
Modified: trunk/gnue-common/src/base/i18n.py
===================================================================
--- trunk/gnue-common/src/base/i18n.py 2009-10-02 16:59:33 UTC (rev 9926)
+++ trunk/gnue-common/src/base/i18n.py 2009-10-05 19:47:25 UTC (rev 9927)
@@ -23,6 +23,54 @@
"""
Internationalization support.
+
+Languages and Encodings in GNU Enterprise
+=========================================
+
+The C{i18n} module provides some convenience functions to support handling of
+different user languages and different character set encodings.
+
+Character set encoding
+----------------------
+
+In GNUe, all user visible text (including data from the database) is generally
+handled in the form of unicode strings, and only converted from/to 8-bit
+strings at the points where it enters/leaves the GNU Enterprise infrastructure.
+That is, if a file is read, user input is queried, or data from a database
+backend is retrieved, all texts are immediately converted to unicode. Likewise,
+if a file is written, data is sent to a database backend, or output is written
+to a screen, a conversion from unicode to an 8 bit string happens only
+immediately before writing.
+
+This way, GNUe does not have to handle different encodings in the code, and
+avoids mixing up texts with different character sets.
+
+At the same time, it is essential to use the correct encoding when doing the
+conversions of incoming and outgoing data, and it is important to understand
+which encoding is the correct one for the purpose. For example, any output
+written to the text screen certainly has to be encoded to the current system
+encoding defined e.g. through the C{$LANG} environment variable, while data
+sent to a database backend must be encoded depending on the database server's
+and client's configuration.
+
+For the admittedly frequent case of the current system encoding, this module
+defines the convenience functions L{inconv} and {outconv}, available in the
+builtin namespace as C{i()} and C{o()} respectively.
+
+Translations of user visible text
+---------------------------------
+
+To make text translatable, enclose it with C{_()} or C{u_()}. The difference is
+that C{u_()} yields a unicode string, while C{_()} yields an 8 bit string
+encoded with the current system encoding. It is recommended to always use
+C{u_()}, the use of C{_()} will likely be deprecated soon.
+
+To indicate the message catalog to be used for translations in a module, set
+the global variable C{__gettext_domain__} in the module. This setting is
+effective for the module itself and all its submodules, except for submodules
+which redefine C{__gettext_domain__} themselves. So usually you just have to
+define C{__gettext_domain__} only once in the __init__.py of the root directory
+of the whole module tree for which a message catalog is applicable.
"""
import gettext
@@ -40,10 +88,12 @@
# Locale initialization
# =============================================================================
-def init_locale():
+def __init_locale():
"""
- Initialize locale support. This is called automatically in module
- initialization, no need to call it manually.
+ Initialize locale support.
+
+ This is called automatically in module initialization, no need to call it
+ manually.
"""
# On Mac, locale.setlocale() does not set the default locale. Instead we
@@ -63,40 +113,50 @@
# =============================================================================
# -----------------------------------------------------------------------------
-# Convert Unicode to String, using the current encoding
+# Convert String to Unicode, using the current encoding
# -----------------------------------------------------------------------------
-def outconv(text):
+def inconv(text):
"""
- Encode a text to the current encoding. This function is available as
- the builtin function "o()".
+ Decode a text from the current encoding. This function is available as
+ the builtin function "i()".
+
+ @param text: Text as 8 bit string.
+ @type text: str
+ @return: Text in unicode.
+ @rtype: unicode
"""
- # TODO: in 0.8, warn if text is not unicode, in 0.9, throw error
- #checktype(text, unicode)
+ checktype(text, str)
encoding = locale.getlocale()[1]
if encoding is None:
encoding = 'ascii'
- return text.encode(encoding, 'replace')
+ return unicode(text, encoding, 'replace')
# -----------------------------------------------------------------------------
-# Convert String to Unicode, using the current encoding
+# Convert Unicode to String, using the current encoding
# -----------------------------------------------------------------------------
-def inconv(text):
+def outconv(text):
"""
Encode a text to the current encoding. This function is available as
the builtin function "o()".
+
+ @param text: Text as unicode.
+ @type text: unicode
+ @return: Text as 8 bit string.
+ @rtype: str
"""
- checktype(text, str)
+ # TODO: in 0.8, warn if text is not unicode, in 0.9, throw error
+ #checktype(text, unicode)
encoding = locale.getlocale()[1]
if encoding is None:
encoding = 'ascii'
- return unicode(text, encoding, 'replace')
+ return text.encode(encoding, 'replace')
# =============================================================================
@@ -200,4 +260,4 @@
__builtin__.__dict__['u_'] = utranslate
__builtin__.__dict__['_'] = translate
-init_locale()
+__init_locale()
Modified: trunk/gnue-common/src/base/utils.py
===================================================================
--- trunk/gnue-common/src/base/utils.py 2009-10-02 16:59:33 UTC (rev 9926)
+++ trunk/gnue-common/src/base/utils.py 2009-10-05 19:47:25 UTC (rev 9927)
@@ -22,7 +22,7 @@
# $Id$
"""
-The utils module provides some very basic although GNU Enterprise specific
+The C{utils} module provides some very basic although GNU Enterprise specific
utility functions.
"""
Modified: trunk/gnue-common/src/lib/checktype.py
===================================================================
--- trunk/gnue-common/src/lib/checktype.py 2009-10-02 16:59:33 UTC (rev 9926)
+++ trunk/gnue-common/src/lib/checktype.py 2009-10-05 19:47:25 UTC (rev 9927)
@@ -41,9 +41,21 @@
def checktype(variable, valid_type):
"""
- Check a varaible (for example a parameter to a function) for a correct type.
- This function is available as builtin function.
+ Check a varaible for a correct type.
+ This function checks whether the type of a given variable is in a given
+ list of valid types. If this is not the case, an exception is raised.
+
+ A typical use case is testing function parameters for the correct type at
+ the beginning of the function definition::
+ def format_number(number, format, precision):
+ checktype(number, [int, float, decimal.Decimal])
+ checktype(flormat, [str, unicode, None])
+ checktype(precision, int)
+
+ After module initialization, this function is available in the builtin
+ namespace.
+
@param variable: Variable to check.
@param valid_type: Type, class, or a list of types and classes that are
valid.
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.