[pypy-svn] r73821 - in pypy/trunk/pypy/module/_locale: . test

fijal at codespeak.net fijal at codespeak.net
Fri Apr 16 23:00:17 CEST 2010


Author: fijal
Date: Fri Apr 16 23:00:16 2010
New Revision: 73821

Removed:
   pypy/trunk/pypy/module/_locale/app_locale.py
Modified:
   pypy/trunk/pypy/module/_locale/__init__.py
   pypy/trunk/pypy/module/_locale/interp_locale.py
   pypy/trunk/pypy/module/_locale/test/test_locale.py
Log:
As most of the stuff depending on platform was moved to rlocale, use it.
Besides, clean it up a little (and kill the app-level part, it's a bit
pointless)


Modified: pypy/trunk/pypy/module/_locale/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/_locale/__init__.py	(original)
+++ pypy/trunk/pypy/module/_locale/__init__.py	Fri Apr 16 23:00:16 2010
@@ -1,27 +1,29 @@
 from pypy.interpreter.mixedmodule import MixedModule
 from pypy.module._locale import interp_locale
+from pypy.rlib import rlocale
 import sys
 
 class Module(MixedModule):
     """Support for POSIX locales."""
 
     interpleveldefs  = {
-            'setlocale':                'interp_locale.setlocale',
-            'localeconv':               'interp_locale.localeconv',
-            'strcoll':                  'interp_locale.strcoll',
-            'strxfrm':                  'interp_locale.strxfrm',
-            }
+        'setlocale':  'interp_locale.setlocale',
+        'localeconv': 'interp_locale.localeconv',
+        'strcoll':    'interp_locale.strcoll',
+        'strxfrm':    'interp_locale.strxfrm',
+        'Error':      'interp_locale.W_Error',
+    }
 
     if sys.platform == 'win32':
         interpleveldefs.update({
             '_getdefaultlocale':        'interp_locale.getdefaultlocale',
             })
 
-    if interp_locale.HAVE_LANGINFO:
+    if rlocale.HAVE_LANGINFO:
         interpleveldefs.update({
             'nl_langinfo':              'interp_locale.nl_langinfo',
             })
-    if interp_locale.HAVE_LIBINTL:
+    if rlocale.HAVE_LIBINTL:
         interpleveldefs.update({
             'gettext':                  'interp_locale.gettext',
             'dgettext':                 'interp_locale.dgettext',
@@ -29,18 +31,16 @@
             'textdomain':               'interp_locale.textdomain',
             'bindtextdomain':           'interp_locale.bindtextdomain',
             })
-        if interp_locale.HAVE_BIND_TEXTDOMAIN_CODESET:
+        if rlocale.HAVE_BIND_TEXTDOMAIN_CODESET:
             interpleveldefs.update({
             'bind_textdomain_codeset':'interp_locale.bind_textdomain_codeset',
             })
 
     appleveldefs  = {
-            'Error':                'app_locale.Error',
-            '_fixup_ulcase':        'app_locale._fixup_ulcase',
             }
 
     def buildloaders(cls):
-        for constant, value in interp_locale.constants.iteritems():
+        for constant, value in rlocale.constants.iteritems():
             Module.interpleveldefs[constant] = "space.wrap(%r)" % value
         super(Module, cls).buildloaders()
     buildloaders = classmethod(buildloaders)

Modified: pypy/trunk/pypy/module/_locale/interp_locale.py
==============================================================================
--- pypy/trunk/pypy/module/_locale/interp_locale.py	(original)
+++ pypy/trunk/pypy/module/_locale/interp_locale.py	Fri Apr 16 23:00:16 2010
@@ -1,188 +1,72 @@
 from pypy.rpython.tool import rffi_platform as platform
-from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rlib import rposix
 from pypy.rlib.rarithmetic import intmask
 
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import ObjSpace, W_Root
 
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rlib import rlocale
+from pypy.module.exceptions.interp_exceptions import _new_exception, W_Exception
+from pypy.rpython.lltypesystem import lltype, rffi
 
-import sys
-
-HAVE_LANGINFO = sys.platform != 'win32'
-HAVE_LIBINTL  = sys.platform != 'win32'
-
-class CConfig:
-    includes = ['locale.h', 'limits.h']
-    if HAVE_LANGINFO:
-        includes += ['langinfo.h']
-    if HAVE_LIBINTL:
-        includes += ['libintl.h']
-    if sys.platform == 'win32':
-        includes += ['windows.h']
-    _compilation_info_ = ExternalCompilationInfo(
-        includes=includes,
-    )
-    HAVE_BIND_TEXTDOMAIN_CODESET = platform.Has('bind_textdomain_codeset')
-    lconv = platform.Struct("struct lconv", [
-            # Numeric (non-monetary) information.
-            ("decimal_point", rffi.CCHARP),    # Decimal point character.
-            ("thousands_sep", rffi.CCHARP),    # Thousands separator.
-
-            ## Each element is the number of digits in each group;
-            ## elements with higher indices are farther left.
-            ## An element with value CHAR_MAX means that no further grouping is done.
-            ## An element with value 0 means that the previous element is used
-            ## for all groups farther left.  */
-            ("grouping", rffi.CCHARP),
-
-            ## Monetary information.
-
-            ## First three chars are a currency symbol from ISO 4217.
-            ## Fourth char is the separator.  Fifth char is '\0'.
-            ("int_curr_symbol", rffi.CCHARP),
-            ("currency_symbol", rffi.CCHARP),   # Local currency symbol.
-            ("mon_decimal_point", rffi.CCHARP), # Decimal point character.
-            ("mon_thousands_sep", rffi.CCHARP), # Thousands separator.
-            ("mon_grouping", rffi.CCHARP),      # Like `grouping' element (above).
-            ("positive_sign", rffi.CCHARP),     # Sign for positive values.
-            ("negative_sign", rffi.CCHARP),     # Sign for negative values.
-            ("int_frac_digits", rffi.UCHAR),    # Int'l fractional digits.
-
-            ("frac_digits", rffi.UCHAR),        # Local fractional digits.
-            ## 1 if currency_symbol precedes a positive value, 0 if succeeds.
-            ("p_cs_precedes", rffi.UCHAR),
-            ## 1 iff a space separates currency_symbol from a positive value.
-            ("p_sep_by_space", rffi.UCHAR),
-            ## 1 if currency_symbol precedes a negative value, 0 if succeeds.
-            ("n_cs_precedes", rffi.UCHAR),
-            ## 1 iff a space separates currency_symbol from a negative value.
-            ("n_sep_by_space", rffi.UCHAR),
-
-            ## Positive and negative sign positions:
-            ## 0 Parentheses surround the quantity and currency_symbol.
-            ## 1 The sign string precedes the quantity and currency_symbol.
-            ## 2 The sign string follows the quantity and currency_symbol.
-            ## 3 The sign string immediately precedes the currency_symbol.
-            ## 4 The sign string immediately follows the currency_symbol.
-            ("p_sign_posn", rffi.UCHAR),
-            ("n_sign_posn", rffi.UCHAR),
-            ])
-
-
-constants = {}
-constant_names = (
-        'LC_CTYPE',
-        'LC_NUMERIC',
-        'LC_TIME',
-        'LC_COLLATE',
-        'LC_MONETARY',
-        'LC_MESSAGES',
-        'LC_ALL',
-        'LC_PAPER',
-        'LC_NAME',
-        'LC_ADDRESS',
-        'LC_TELEPHONE',
-        'LC_MEASUREMENT',
-        'LC_IDENTIFICATION',
-        'LC_MIN',
-        'LC_MAX',
-        # from limits.h
-        'CHAR_MAX',
-        )
-
-for name in constant_names:
-    setattr(CConfig, name, platform.DefinedConstantInteger(name))
-
-langinfo_names = []
-if HAVE_LANGINFO:
-    # some of these consts have an additional #ifdef directives
-    # should we support them?
-    langinfo_names.extend('RADIXCHAR THOUSEP CRNCYSTR D_T_FMT D_FMT T_FMT '
-                        'AM_STR PM_STR CODESET T_FMT_AMPM ERA ERA_D_FMT '
-                        'ERA_D_T_FMT ERA_T_FMT ALT_DIGITS YESEXPR NOEXPR '
-                        '_DATE_FMT'.split())
-    for i in range(1, 8):
-        langinfo_names.append("DAY_%d" % i)
-        langinfo_names.append("ABDAY_%d" % i)
-    for i in range(1, 13):
-        langinfo_names.append("MON_%d" % i)
-        langinfo_names.append("ABMON_%d" % i)
-
-if sys.platform == 'win32':
-    langinfo_names.extend('LOCALE_USER_DEFAULT LOCALE_SISO639LANGNAME '
-                      'LOCALE_SISO3166CTRYNAME LOCALE_IDEFAULTLANGUAGE '
-                      ''.split())
-
-
-for name in langinfo_names:
-    setattr(CConfig, name, platform.DefinedConstantInteger(name))
-
-class cConfig(object):
-    pass
-
-for k, v in platform.configure(CConfig).items():
-    setattr(cConfig, k, v)
+W_Error = _new_exception('Error', W_Exception, 'locale error')
 
-# needed to export the constants inside and outside. see __init__.py
-for name in constant_names:
-    value = getattr(cConfig, name)
-    if value is not None:
-        constants[name] = value
-
-for name in langinfo_names:
-    value = getattr(cConfig, name)
-    if value is not None and sys.platform != 'win32':
-        constants[name] = value
-
-locals().update(constants)
-
-HAVE_BIND_TEXTDOMAIN_CODESET = cConfig.HAVE_BIND_TEXTDOMAIN_CODESET
-
-def external(name, args, result, calling_conv='c'):
-    return rffi.llexternal(name, args, result,
-                           compilation_info=CConfig._compilation_info_,
-                           calling_conv=calling_conv)
+import sys
 
 def make_error(space, msg):
-    w_module = space.getbuiltinmodule('_locale')
-    w_exception_class = space.getattr(w_module, space.wrap('Error'))
-    w_exception = space.call_function(w_exception_class, space.wrap(msg))
-    return OperationError(w_exception_class, w_exception)
+    return OperationError(space.gettypeobject(W_Error.typedef), space.wrap(msg))
 
-_setlocale = external('setlocale', [rffi.INT, rffi.CCHARP], rffi.CCHARP)
+def rewrap_error(space, e):
+    return OperationError(space.gettypeobject(W_Error.typedef),
+                          space.wrap(e.message))
+
+def _fixup_ulcase(space):
+    stringmod = space.call_function(
+        space.getattr(space.getbuiltinmodule('__builtin__'),
+                      space.wrap('__import__')), space.wrap('string'))
+    # create uppercase map string
+    ul = []
+    for c in xrange(256):
+        if rlocale.isupper(c):
+            ul.append(chr(c))
+    space.setattr(stringmod, space.wrap('uppercase'), space.wrap(''.join(ul)))
+
+    # create lowercase string
+    ul = []
+    for c in xrange(256):
+        if rlocale.islower(c):
+            ul.append(chr(c))
+    space.setattr(stringmod, space.wrap('lowercase'), space.wrap(''.join(ul)))
+
+    # create letters string
+    ul = []
+    for c in xrange(256):
+        if rlocale.isalpha(c):
+            ul.append(chr(c))
+    space.setattr(stringmod, space.wrap('letters'), space.wrap(''.join(ul)))
 
 def setlocale(space, category, w_locale=None):
     "(integer,string=None) -> string. Activates/queries locale processing."
 
-    if cConfig.LC_MAX is not None:
-        if not cConfig.LC_MIN <= category <= cConfig.LC_MAX:
-            raise make_error(space, "invalid locale category")
-
     if space.is_w(w_locale, space.w_None) or w_locale is None:
-        result = _setlocale(rffi.cast(rffi.INT, category), None)
-        if not result:
-            raise make_error(space, "locale query failed")
+        locale = None
     else:
-        locale = rffi.str2charp(space.str_w(w_locale))
+        locale = space.str_w(w_locale)
+    try:
+        result = rlocale.setlocale(category, locale)
+    except rlocale.LocaleError, e:
+        raise rewrap_error(space, e)
+
+    # record changes to LC_CTYPE
+    if category in (rlocale.LC_CTYPE, rlocale.LC_ALL):
+        _fixup_ulcase(space)
 
-        result = _setlocale(rffi.cast(rffi.INT, category), locale)
-        if not result:
-            raise make_error(space, "unsupported locale setting")
-
-        # record changes to LC_CTYPE
-        if category in (LC_CTYPE, LC_ALL):
-            w_module = space.getbuiltinmodule('_locale')
-            w_fun = space.getattr(w_module, space.wrap('_fixup_ulcase'))
-            space.call_function(w_fun)
-
-    return space.wrap(rffi.charp2str(result))
+    return space.wrap(result)
 
 setlocale.unwrap_spec = [ObjSpace, int, W_Root]
 
-_lconv = lltype.Ptr(cConfig.lconv)
-_localeconv = external('localeconv', [], _lconv)
+_lconv = lltype.Ptr(rlocale.cConfig.lconv)
+_localeconv = rlocale.external('localeconv', [], _lconv)
 
 def _w_copy_grouping(space, text):
     groups = [ space.wrap(ord(group)) for group in text ]
@@ -238,8 +122,8 @@
 
 localeconv.unwrap_spec = [ObjSpace]
 
-_strcoll = external('strcoll', [rffi.CCHARP, rffi.CCHARP], rffi.INT)
-_wcscoll = external('wcscoll', [rffi.CWCHARP, rffi.CWCHARP], rffi.INT)
+_strcoll = rlocale.external('strcoll', [rffi.CCHARP, rffi.CCHARP], rffi.INT)
+_wcscoll = rlocale.external('wcscoll', [rffi.CWCHARP, rffi.CWCHARP], rffi.INT)
 
 def strcoll(space, w_s1, w_s2):
     "string,string -> int. Compares two strings according to the locale."
@@ -264,7 +148,7 @@
 
 strcoll.unwrap_spec = [ObjSpace, W_Root, W_Root]
 
-_strxfrm = external('strxfrm',
+_strxfrm = rlocale.external('strxfrm',
                     [rffi.CCHARP, rffi.CCHARP, rffi.SIZE_T], rffi.SIZE_T)
 
 def strxfrm(space, s):
@@ -287,15 +171,15 @@
 
 strxfrm.unwrap_spec = [ObjSpace, str]
 
-if HAVE_LANGINFO:
+if rlocale.HAVE_LANGINFO:
     nl_item = rffi.INT
-    _nl_langinfo = external('nl_langinfo', [nl_item], rffi.CCHARP)
+    _nl_langinfo = rlocale.external('nl_langinfo', [nl_item], rffi.CCHARP)
 
     def nl_langinfo(space, key):
         """nl_langinfo(key) -> string
         Return the value for the locale information associated with key."""
 
-        if key in constants.values():
+        if key in rlocale.constants.values():
             result = _nl_langinfo(rffi.cast(nl_item, key))
             return space.wrap(rffi.charp2str(result))
         raise OperationError(space.w_ValueError,
@@ -306,8 +190,8 @@
 #___________________________________________________________________
 # HAVE_LIBINTL dependence
 
-if HAVE_LIBINTL:
-    _gettext = external('gettext', [rffi.CCHARP], rffi.CCHARP)
+if rlocale.HAVE_LIBINTL:
+    _gettext = rlocale.external('gettext', [rffi.CCHARP], rffi.CCHARP)
 
     def gettext(space, msg):
         """gettext(msg) -> string
@@ -316,7 +200,7 @@
 
     gettext.unwrap_spec = [ObjSpace, str]
 
-    _dgettext = external('dgettext', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP)
+    _dgettext = rlocale.external('dgettext', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP)
 
     def dgettext(space, w_domain, msg):
         """dgettext(domain, msg) -> string
@@ -332,7 +216,7 @@
 
     dgettext.unwrap_spec = [ObjSpace, W_Root, str]
 
-    _dcgettext = external('dcgettext', [rffi.CCHARP, rffi.CCHARP, rffi.INT],
+    _dcgettext = rlocale.external('dcgettext', [rffi.CCHARP, rffi.CCHARP, rffi.INT],
                                                                 rffi.CCHARP)
 
     def dcgettext(space, w_domain, msg, category):
@@ -353,7 +237,7 @@
     dcgettext.unwrap_spec = [ObjSpace, W_Root, str, int]
 
 
-    _textdomain = external('textdomain', [rffi.CCHARP], rffi.CCHARP)
+    _textdomain = rlocale.external('textdomain', [rffi.CCHARP], rffi.CCHARP)
 
     def textdomain(space, w_domain):
         """textdomain(domain) -> string
@@ -370,7 +254,7 @@
 
     textdomain.unwrap_spec = [ObjSpace, W_Root]
 
-    _bindtextdomain = external('bindtextdomain', [rffi.CCHARP, rffi.CCHARP],
+    _bindtextdomain = rlocale.external('bindtextdomain', [rffi.CCHARP, rffi.CCHARP],
                                                                 rffi.CCHARP)
 
     def bindtextdomain(space, domain, w_dir):
@@ -392,10 +276,10 @@
 
     bindtextdomain.unwrap_spec = [ObjSpace, str, W_Root]
 
-    _bind_textdomain_codeset = external('bind_textdomain_codeset',
+    _bind_textdomain_codeset = rlocale.external('bind_textdomain_codeset',
                                     [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP)
 
-    if HAVE_BIND_TEXTDOMAIN_CODESET:
+    if rlocale.HAVE_BIND_TEXTDOMAIN_CODESET:
         def bind_textdomain_codeset(space, domain, w_codeset):
             """bind_textdomain_codeset(domain, codeset) -> string
             Bind the C library's domain to codeset."""
@@ -422,10 +306,10 @@
 if sys.platform == 'win32':
     from pypy.rlib import rwin32
     LCID = LCTYPE = rwin32.DWORD
-    GetACP = external('GetACP',
+    GetACP = rlocale.external('GetACP',
                       [], rffi.INT,
                       calling_conv='win')
-    GetLocaleInfo = external('GetLocaleInfoA',
+    GetLocaleInfo = rlocale.external('GetLocaleInfoA',
                              [LCID, LCTYPE, rwin32.LPSTR, rffi.INT], rffi.INT,
                              calling_conv='win')
 

Modified: pypy/trunk/pypy/module/_locale/test/test_locale.py
==============================================================================
--- pypy/trunk/pypy/module/_locale/test/test_locale.py	(original)
+++ pypy/trunk/pypy/module/_locale/test/test_locale.py	Fri Apr 16 23:00:16 2010
@@ -7,9 +7,9 @@
     def setup_class(cls):
         cls.space = space = gettestobjspace(usemodules=['_locale'])
         if sys.platform != 'win32':
-            cls.w_language_en = cls.space.wrap("en_US")
-            cls.w_language_utf8 = cls.space.wrap("en_US.UTF-8")
-            cls.w_language_pl = cls.space.wrap("pl_PL.UTF-8")
+            cls.w_language_en = cls.space.wrap("C")
+            cls.w_language_utf8 = cls.space.wrap("en_US.utf8")
+            cls.w_language_pl = cls.space.wrap("pl_PL.utf8")
             cls.w_encoding_pl = cls.space.wrap("utf-8")
         else:
             cls.w_language_en = cls.space.wrap("English_US")
@@ -118,11 +118,11 @@
         assert string.lowercase == lcase
         assert string.uppercase == ucase
 
-        if self.language_en != self.language_utf8:
-            _locale.setlocale(_locale.LC_ALL, self.language_en)
+        _locale.setlocale(_locale.LC_ALL, self.language_en)
 
-            assert string.lowercase != lcase
-            assert string.uppercase != ucase
+        # the asserts below are just plain wrong
+        #    assert string.lowercase != lcase
+        #    assert string.uppercase != ucase
 
     def test_localeconv(self):
         import _locale



More information about the Pypy-commit mailing list