summaryrefslogtreecommitdiffstats
path: root/Modules/mathmodule.c
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2019-07-27 21:04:29 (GMT)
committerGitHub <noreply@github.com>2019-07-27 21:04:29 (GMT)
commit6b5f1b496f0b20144592b640b9c975df43a29eb0 (patch)
tree02675047df60efacb1a5f449c1c373a7485e7330 /Modules/mathmodule.c
parent3221a63c69268a9362802371a616f49d522a5c4f (diff)
downloadcpython-6b5f1b496f0b20144592b640b9c975df43a29eb0.zip
cpython-6b5f1b496f0b20144592b640b9c975df43a29eb0.tar.gz
cpython-6b5f1b496f0b20144592b640b9c975df43a29eb0.tar.bz2
bpo-37691: Let math.dist() accept sequences and iterables for coordinates (GH-14975)
Diffstat (limited to 'Modules/mathmodule.c')
-rw-r--r--Modules/mathmodule.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 4c1dbbe..e1b46ec 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -2427,14 +2427,14 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan)
/*[clinic input]
math.dist
- p: object(subclass_of='&PyTuple_Type')
- q: object(subclass_of='&PyTuple_Type')
+ p: object
+ q: object
/
Return the Euclidean distance between two points p and q.
-The points should be specified as tuples of coordinates.
-Both tuples must be the same size.
+The points should be specified as sequences (or iterables) of
+coordinates. Both inputs must have the same dimension.
Roughly equivalent to:
sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
@@ -2442,16 +2442,34 @@ Roughly equivalent to:
static PyObject *
math_dist_impl(PyObject *module, PyObject *p, PyObject *q)
-/*[clinic end generated code: output=56bd9538d06bbcfe input=937122eaa5f19272]*/
+/*[clinic end generated code: output=56bd9538d06bbcfe input=74e85e1b6092e68e]*/
{
PyObject *item;
double max = 0.0;
double x, px, qx, result;
Py_ssize_t i, m, n;
- int found_nan = 0;
+ int found_nan = 0, p_allocated = 0, q_allocated = 0;
double diffs_on_stack[NUM_STACK_ELEMS];
double *diffs = diffs_on_stack;
+ if (!PyTuple_Check(p)) {
+ p = PySequence_Tuple(p);
+ if (p == NULL) {
+ return NULL;
+ }
+ p_allocated = 1;
+ }
+ if (!PyTuple_Check(q)) {
+ q = PySequence_Tuple(q);
+ if (q == NULL) {
+ if (p_allocated) {
+ Py_DECREF(p);
+ }
+ return NULL;
+ }
+ q_allocated = 1;
+ }
+
m = PyTuple_GET_SIZE(p);
n = PyTuple_GET_SIZE(q);
if (m != n) {
@@ -2482,12 +2500,24 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q)
if (diffs != diffs_on_stack) {
PyObject_Free(diffs);
}
+ if (p_allocated) {
+ Py_DECREF(p);
+ }
+ if (q_allocated) {
+ Py_DECREF(q);
+ }
return PyFloat_FromDouble(result);
error_exit:
if (diffs != diffs_on_stack) {
PyObject_Free(diffs);
}
+ if (p_allocated) {
+ Py_DECREF(p);
+ }
+ if (q_allocated) {
+ Py_DECREF(q);
+ }
return NULL;
}