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.
 
 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
 =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".
 
 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
 
 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;
 
        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)) {
                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;
                        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;
                } else if (strcasecmp(item->key, "LogTraces") == 0) {
                        if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
                                continue;