Gentoo Archives: gentoo-portage-dev

From: "Michał Górny" <mgorny@g.o>
To: "Anthony G. Basile" <basile@××××××××××××××.edu>
Cc: gentoo-portage-dev@l.g.o, "Anthony G. Basile" <blueness@g.o>
Subject: Re: [gentoo-portage-dev] [PATCH 3/3] pym/portage/util/locale.py: add a C module to help check locale
Date: Sun, 29 May 2016 06:30:35
Message-Id: 20160529083023.7bec8b2b.mgorny@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH 3/3] pym/portage/util/locale.py: add a C module to help check locale by "Anthony G. Basile"
1 On Fri, 27 May 2016 10:26:44 -0400
2 "Anthony G. Basile" <basile@××××××××××××××.edu> wrote:
3
4 > From: "Anthony G. Basile" <blueness@g.o>
5 >
6 > The current method to check for a sane system locale is to use python's
7 > ctypes.util.find_library() to construct a full library path to the
8 > system libc.so and pass that path to ctypes.CDLL() so we can call
9 > toupper() and tolower() directly. However, this gets bogged down in
10 > implementation details and fails with musl.
11 >
12 > We work around this design flaw in ctypes with a small python module
13 > written in C which provides thin wrappers to toupper() and tolower(),
14 > and only fall back on the current ctypes-based check when this module
15 > is not available.
16 >
17 > This has been tested on glibc, uClibc and musl systems.
18 >
19 > X-Gentoo-bug: 571444
20 > X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=571444
21 >
22 > Signed-off-by: Anthony G. Basile <blueness@g.o>
23 > ---
24 > pym/portage/util/locale.py | 16 ++++++-----
25 > setup.py | 6 +++-
26 > src/portage_util_libc.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
27 > 3 files changed, 84 insertions(+), 8 deletions(-)
28 > create mode 100644 src/portage_util_libc.c
29 >
30 > diff --git a/pym/portage/util/locale.py b/pym/portage/util/locale.py
31 > index 093eb86..5b09945 100644
32 > --- a/pym/portage/util/locale.py
33 > +++ b/pym/portage/util/locale.py
34 > @@ -34,13 +34,15 @@ def _check_locale(silent):
35 > """
36 > The inner locale check function.
37 > """
38 > -
39 > - libc_fn = find_library("c")
40 > - if libc_fn is None:
41 > - return None
42 > - libc = LoadLibrary(libc_fn)
43 > - if libc is None:
44 > - return None
45 > + try:
46 > + from portage.util import libc
47 > + except ImportError:
48 > + libc_fn = find_library("c")
49 > + if libc_fn is None:
50 > + return None
51 > + libc = LoadLibrary(libc_fn)
52 > + if libc is None:
53 > + return None
54 >
55 > lc = list(range(ord('a'), ord('z')+1))
56 > uc = list(range(ord('A'), ord('Z')+1))
57 > diff --git a/setup.py b/setup.py
58 > index 25429bc..5ca8156 100755
59 > --- a/setup.py
60 > +++ b/setup.py
61 > @@ -47,7 +47,11 @@ x_scripts = {
62 > # Dictionary custom modules written in C/C++ here. The structure is
63 > # key = module name
64 > # value = list of C/C++ source code, path relative to top source directory
65 > -x_c_helpers = {}
66 > +x_c_helpers = {
67 > + 'portage.util.libc' : [
68 > + 'src/portage_util_libc.c',
69 > + ],
70 > +}
71 >
72 > class x_build(build):
73 > """ Build command with extra build_man call. """
74 > diff --git a/src/portage_util_libc.c b/src/portage_util_libc.c
75 > new file mode 100644
76 > index 0000000..00b09c2
77 > --- /dev/null
78 > +++ b/src/portage_util_libc.c
79 > @@ -0,0 +1,70 @@
80 > +/* Copyright 2005-2016 Gentoo Foundation
81 > + * Distributed under the terms of the GNU General Public License v2
82 > + */
83 > +
84 > +#include <Python.h>
85 > +#include <stdlib.h>
86 > +#include <ctype.h>
87 > +
88 > +static PyObject * _libc_tolower(PyObject *, PyObject *);
89 > +static PyObject * _libc_toupper(PyObject *, PyObject *);
90 > +
91 > +static PyMethodDef LibcMethods[] = {
92 > + {"tolower", _libc_tolower, METH_VARARGS, "Convert to lower case using system locale."},
93 > + {"toupper", _libc_toupper, METH_VARARGS, "Convert to upper case using system locale."},
94 > + {NULL, NULL, 0, NULL}
95 > +};
96 > +
97 > +#if PY_MAJOR_VERSION >= 3
98 > +static struct PyModuleDef moduledef = {
99 > + PyModuleDef_HEAD_INIT,
100 > + "libc", /* m_name */
101 > + "Module for converting case using the system locale", /* m_doc */
102 > + -1, /* m_size */
103 > + LibcMethods, /* m_methods */
104 > + NULL, /* m_reload */
105 > + NULL, /* m_traverse */
106 > + NULL, /* m_clear */
107 > + NULL, /* m_free */
108 > +};
109 > +#endif
110 > +
111 > +PyMODINIT_FUNC
112
113 Now you could call it nitpicking but since it decorates the function,
114 it would be better to have it inside the #ifdef. Otherwise, people
115 would think it's separate from that.
116
117 > +
118 > +#if PY_MAJOR_VERSION >= 3
119 > +PyInit_libc(void)
120 > +{
121 > + PyObject *m;
122 > + m = PyModule_Create(&moduledef);
123 > + return m;
124 > +}
125 > +#else
126 > +initlibc(void)
127 > +{
128 > + Py_InitModule("libc", LibcMethods);
129 > +}
130 > +#endif
131 > +
132 > +
133 > +static PyObject *
134 > +_libc_tolower(PyObject *self, PyObject *args)
135 > +{
136 > + int c;
137 > +
138 > + if (!PyArg_ParseTuple(args, "i", &c))
139 > + return NULL;
140 > +
141 > + return Py_BuildValue("i", tolower(c));
142 > +}
143 > +
144 > +
145 > +static PyObject *
146 > +_libc_toupper(PyObject *self, PyObject *args)
147 > +{
148 > + int c;
149 > +
150 > + if (!PyArg_ParseTuple(args, "i", &c))
151 > + return NULL;
152 > +
153 > + return Py_BuildValue("i", toupper(c));
154 > +}
155
156 Aside from that, it look nice and shiny now. Thanks a lot!
157
158 --
159 Best regards,
160 Michał Górny
161 <http://dev.gentoo.org/~mgorny/>

Replies

Subject Author
Re: [gentoo-portage-dev] [PATCH 3/3] pym/portage/util/locale.py: add a C module to help check locale "Anthony G. Basile" <basile@××××××××××××××.edu>