diff --git a/Bio/Align/_pairwisealigner.c b/Bio/Align/_pairwisealigner.c index 499bbdf59..f1805b095 100644 --- a/Bio/Align/_pairwisealigner.c +++ b/Bio/Align/_pairwisealigner.c @@ -1961,11 +1961,12 @@ Aligner_str(Aligner* self) { char text[1024]; char* p = text; + char* value; PyObject* substitution_matrix = self->substitution_matrix.obj; void* args[3]; int n = 0; PyObject* wildcard = NULL; - PyObject* s; + PyObject* s = NULL; p += sprintf(p, "Pairwise sequence aligner with parameters\n"); if (substitution_matrix) { @@ -1983,44 +1984,88 @@ Aligner_str(Aligner* self) p += sprintf(p, " wildcard: '%%U'\n"); args[n++] = wildcard; } - p += sprintf(p, " match_score: %f\n", self->match); - p += sprintf(p, " mismatch_score: %f\n", self->mismatch); + /* Use PyOS_double_to_string to ensure that the locale does + * not change the decimal point into a comma. + */ + value = PyOS_double_to_string(self->match, 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " match_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->mismatch, 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " mismatch_score: %s\n", value); + PyMem_Free(value); } if (self->insertion_score_function) { p += sprintf(p, " insertion_score_function: %%R\n"); args[n++] = self->insertion_score_function; } else { - p += sprintf(p, " open_internal_insertion_score: %f\n", - self->open_internal_insertion_score); - p += sprintf(p, " extend_internal_insertion_score: %f\n", - self->extend_internal_insertion_score); - p += sprintf(p, " open_left_insertion_score: %f\n", - self->open_left_insertion_score); - p += sprintf(p, " extend_left_insertion_score: %f\n", - self->extend_left_insertion_score); - p += sprintf(p, " open_right_insertion_score: %f\n", - self->open_right_insertion_score); - p += sprintf(p, " extend_right_insertion_score: %f\n", - self->extend_right_insertion_score); + value = PyOS_double_to_string(self->open_internal_insertion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " open_internal_insertion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->extend_internal_insertion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " extend_internal_insertion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->open_left_insertion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " open_left_insertion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->extend_left_insertion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " extend_left_insertion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->open_right_insertion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " open_right_insertion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->extend_right_insertion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " extend_right_insertion_score: %s\n", value); + PyMem_Free(value); } if (self->deletion_score_function) { p += sprintf(p, " deletion_score_function: %%R\n"); args[n++] = self->deletion_score_function; } else { - p += sprintf(p, " open_internal_deletion_score: %f\n", - self->open_internal_deletion_score); - p += sprintf(p, " extend_internal_deletion_score: %f\n", - self->extend_internal_deletion_score); - p += sprintf(p, " open_left_deletion_score: %f\n", - self->open_left_deletion_score); - p += sprintf(p, " extend_left_deletion_score: %f\n", - self->extend_left_deletion_score); - p += sprintf(p, " open_right_deletion_score: %f\n", - self->open_right_deletion_score); - p += sprintf(p, " extend_right_deletion_score: %f\n", - self->extend_right_deletion_score); + value = PyOS_double_to_string(self->open_internal_deletion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " open_internal_deletion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->extend_internal_deletion_score, + 'f', 6, 0, NULL); + p += sprintf(p, " extend_internal_deletion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->open_left_deletion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " open_left_deletion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->extend_left_deletion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " extend_left_deletion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->open_right_deletion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " open_right_deletion_score: %s\n", value); + PyMem_Free(value); + value = PyOS_double_to_string(self->extend_right_deletion_score, + 'f', 6, 0, NULL); + if (!value) goto exit; + p += sprintf(p, " extend_right_deletion_score: %s\n", value); + PyMem_Free(value); } switch (self->mode) { case Global: sprintf(p, " mode: global\n"); break; @@ -2031,6 +2076,8 @@ Aligner_str(Aligner* self) return NULL; } s = PyUnicode_FromFormat(text, args[0], args[1], args[2]); + +exit: Py_XDECREF(wildcard); return s; } diff --git a/Bio/Cluster/clustermodule.c b/Bio/Cluster/clustermodule.c index 87c2cbd14..a2005b319 100644 --- a/Bio/Cluster/clustermodule.c +++ b/Bio/Cluster/clustermodule.c @@ -682,8 +682,15 @@ PyNode_repr(PyNode* self) { char string[64]; - sprintf(string, "(%d, %d): %g", - self->node.left, self->node.right, self->node.distance); + /* Use PyOS_double_to_string to ensure that the locale does + * not change the decimal point into a comma. + */ + char* value = PyOS_double_to_string(self->node.distance, 'g', 6, 0, NULL); + if (!value) return NULL; + + sprintf(string, "(%d, %d): %s", self->node.left, self->node.right, value); + PyMem_Free(value); + return PyUnicode_FromString(string); } @@ -928,15 +935,27 @@ PyTree_str(PyTree* self) int i; const int n = self->n; char string[128]; + char* distance; Node node; PyObject* line; PyObject* output; PyObject* temp; output = PyUnicode_FromString(""); + if (!output) return NULL; + for (i = 0; i < n; i++) { node = self->nodes[i]; - sprintf(string, "(%d, %d): %g", node.left, node.right, node.distance); + distance = PyOS_double_to_string(node.distance, 'g', 6, 0, NULL); + if (!distance) { + Py_DECREF(output); + return NULL; + } + /* Use PyOS_double_to_string to ensure that the locale does + * not change the decimal point into a comma. + */ + sprintf(string, "(%d, %d): %s", node.left, node.right, distance); + PyMem_Free(distance); if (i < n-1) strcat(string, "\n"); line = PyUnicode_FromString(string); if (!line) { @@ -944,11 +963,9 @@ PyTree_str(PyTree* self) return NULL; } temp = PyUnicode_Concat(output, line); - if (!temp) { - Py_DECREF(output); - Py_DECREF(line); - return NULL; - } + Py_DECREF(line); + Py_DECREF(output); + if (!temp) return NULL; output = temp; } return output;