Better unicode support.
authorSven Trenkel <collectd@semidefinite.de>
Sun, 6 Dec 2009 01:20:05 +0000 (02:20 +0100)
committerSven Trenkel <collectd@semidefinite.de>
Sun, 6 Dec 2009 01:20:05 +0000 (02:20 +0100)
src/collectd-python.pod
src/python.c

index c07ebf9..cd9678a 100644 (file)
@@ -27,6 +27,8 @@ for collectd in Python. This is a lot more efficient than executing a
 Python-script every time you want to read a value with the C<exec plugin> (see
 L<collectd-exec(5)>) and provides a lot more functionality, too.
 
+Currently only python2 is supported and at least version 2.3 is required.
+
 =head1 CONFIGURATION
 
 =over 4
@@ -40,7 +42,14 @@ see. If you don't do this or your platform does not support it, the embeded
 interpreter will start anywa but you won't be able to load certain python
 modules, e.g. "time".
 
-=item B<MudulePath> I<Name>
+=item B<Encoding> I<Name>
+
+The default encoding for unicode objects you pass to collectd. If you obmit
+this option it will default to B<ascii> on python2 and B<utf-8> on python3.
+This is hardcoded in python and will ignore everything else, including your
+locale.
+
+=item B<ModulePath> I<Name>
 
 Appends I<Name> to B<sys.path>. You won't be able to import any scripts you
 wrote unless they are located in one of the directuries in this list. Please
index cdc6d26..08abfd1 100644 (file)
@@ -634,7 +634,13 @@ static PyObject *cpy_unregister_generic_userdata(cpy_unregister_function_t *unre
        char buf[512];
        const char *name;
 
-       if (PyString_Check(arg)) {
+       if (PyUnicode_Check(arg)) {
+               arg = PyUnicode_AsEncodedString(arg, NULL, NULL);
+               if (arg == NULL)
+                       return NULL;
+               name = PyString_AsString(arg);
+               Py_DECREF(arg);
+       } else if (PyString_Check(arg)) {
                name = PyString_AsString(arg);
        } else {
                if (!PyCallable_Check(arg)) {
@@ -888,6 +894,12 @@ static int cpy_config(oconfig_item_t *ci) {
                        if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
                                continue;
                        do_interactive = item->values[0].value.boolean;
+               } else if (strcasecmp(item->key, "Encoding") == 0) {
+                       if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_STRING)
+                               continue;
+                       /* Why is this even necessary? And undocumented? */
+                       if (PyUnicode_SetDefaultEncoding(item->values[0].value.string))
+                               cpy_log_exception("setting default encoding");
                } else if (strcasecmp(item->key, "LogTraces") == 0) {
                        if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
                                continue;