[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r9927 - in trunk/gnue-common/src: base lib
From: |
reinhard |
Subject: |
[gnue] r9927 - in trunk/gnue-common/src: base lib |
Date: |
Mon, 5 Oct 2009 14:47:26 -0500 (CDT) |
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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r9927 - in trunk/gnue-common/src: base lib,
reinhard <=