[pygobject] Fix symbol names to be locale independent
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Fix symbol names to be locale independent
- Date: Thu, 5 May 2011 04:54:22 +0000 (UTC)
commit 63c7f17c224821cb7136d06e8ef87eab7291848d
Author: Martin Pitt <martin pitt ubuntu com>
Date: Mon May 2 15:49:52 2011 +0200
Fix symbol names to be locale independent
We currently use upper() to present enum values, which are usually defined in
lower case in the typelib, in upper cases. However, upper() is locale
dependent, so that e. g. in tr_TR.UTF-8, "invalid" becomes "iNVALiD"
because Turkish has some extra variants of "i".
Use a local ASCII-only translate() call instead to avoid this. Thanks to Nils
Philippsen for the idea!
This also adds a test locale "te_ST nouppera" which defines toupper('a') == 'a'.
Run the Enum tests under this locale to reproduce the bug and verify the fix.
https://bugzilla.gnome.org/show_bug.cgi?id=649165
gi/module.py | 9 ++++++++-
tests/te_ST nouppera | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/test_gi.py | 30 ++++++++++++++++++++++++++++++
3 files changed, 88 insertions(+), 1 deletions(-)
---
diff --git a/gi/module.py b/gi/module.py
index 3e2b59e..463d975 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -24,6 +24,7 @@ from __future__ import absolute_import
import os
import gobject
+import string
import gi
from .overrides import registry
@@ -120,8 +121,14 @@ class IntrospectionModule(object):
wrapper.__info__ = info
wrapper.__module__ = 'gi.repository.' + info.get_namespace()
+ # Don't use upper() here to avoid locale specific
+ # identifier conversion (e. g. in Turkish 'i'.upper() == 'i')
+ # see https://bugzilla.gnome.org/show_bug.cgi?id=649165
+ ascii_upper_trans = string.maketrans(
+ 'abcdefgjhijklmnopqrstuvwxyz',
+ 'ABCDEFGJHIJKLMNOPQRSTUVWXYZ')
for value_info in info.get_values():
- value_name = value_info.get_name().upper()
+ value_name = value_info.get_name().translate(ascii_upper_trans)
setattr(wrapper, value_name, wrapper(value_info.get_value()))
if g_type != gobject.TYPE_NONE:
diff --git a/tests/te_ST nouppera b/tests/te_ST nouppera
new file mode 100644
index 0000000..a511e90
--- /dev/null
+++ b/tests/te_ST nouppera
@@ -0,0 +1,50 @@
+LC_IDENTIFICATION
+title "pygobject test locale"
+END LC_IDENTIFICATION
+
+LC_COLLATE
+copy "POSIX"
+END LC_COLLATE
+
+LC_CTYPE
+# a â?? a, other characters normally
+toupper (<U0061>,<U0061>); (<U0062>,<U0042>); (<U0063>,<U0043>); \
+ (<U0076>,<U0056>); (<U006C>,<U004C>); (<U0075>,<U0055>); \
+ (<U0065>,<U0045>);
+END LC_CTYPE
+
+LC_MESSAGES
+copy "en_US"
+END LC_MESSAGES
+
+LC_MONETARY
+copy "en_US"
+END LC_MONETARY
+
+LC_NUMERIC
+copy "POSIX"
+END LC_NUMERIC
+
+LC_TIME
+copy "POSIX"
+END LC_TIME
+
+LC_PAPER
+copy "en_US"
+END LC_PAPER
+
+LC_TELEPHONE
+copy "en_US"
+END LC_TELEPHONE
+
+LC_MEASUREMENT
+copy "en_US"
+END LC_MEASUREMENT
+
+LC_NAME
+copy "en_US"
+END LC_NAME
+
+LC_ADDRESS
+copy "en_US"
+END LC_ADDRESS
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 4aa5532..6990225 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -5,6 +5,11 @@
import sys
import unittest
+import tempfile
+import shutil
+import os
+import locale
+import subprocess
from gi.repository import GObject
import gobject
@@ -960,6 +965,31 @@ class TestPointer(unittest.TestCase):
class TestEnum(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ '''Run tests under a test locale.
+
+ Upper case conversion of member names should not be locale specific;
+ e. g. in Turkish, "i".upper() == "i", which gives results like "iNVALiD"
+
+ Run test under a locale which defines toupper('a') == 'a'
+ '''
+ cls.locale_dir = tempfile.mkdtemp()
+ subprocess.check_call(['localedef', '-i',
+ os.path.join(os.path.dirname(os.path.realpath(__file__)), 'te_ST nouppera'),
+ '-c', '-f', 'UTF-8', os.path.join(cls.locale_dir, 'te_ST UTF-8 nouppera')])
+ os.environ['LOCPATH'] = cls.locale_dir
+ locale.setlocale(locale.LC_ALL, 'te_ST UTF-8 nouppera')
+
+ @classmethod
+ def tearDownClass(cls):
+ locale.setlocale(locale.LC_ALL, 'C')
+ shutil.rmtree(cls.locale_dir)
+ try:
+ del os.environ['LOCPATH']
+ except KeyError:
+ pass
+
def test_enum(self):
self.assertTrue(issubclass(GIMarshallingTests.Enum, int))
self.assertTrue(isinstance(GIMarshallingTests.Enum.VALUE1, GIMarshallingTests.Enum))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]