bpo-37178: Allow a one argument form of math.perm() (GH-13905)


diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h
index cdf4305..966b99b 100644
--- a/Modules/clinic/mathmodule.c.h
+++ b/Modules/clinic/mathmodule.c.h
@@ -639,7 +639,7 @@
 }
 
 PyDoc_STRVAR(math_perm__doc__,
-"perm($module, n, k, /)\n"
+"perm($module, n, k=None, /)\n"
 "--\n"
 "\n"
 "Number of ways to choose k items from n items without repetition and with order.\n"
@@ -647,6 +647,9 @@
 "Evaluates to n! / (n - k)! when k <= n and evaluates\n"
 "to zero when k > n.\n"
 "\n"
+"If k is not specified or is None, then k defaults to n\n"
+"and the function returns n!.\n"
+"\n"
 "Raises TypeError if either of the arguments are not integers.\n"
 "Raises ValueError if either of the arguments are negative.");
 
@@ -661,13 +664,17 @@
 {
     PyObject *return_value = NULL;
     PyObject *n;
-    PyObject *k;
+    PyObject *k = Py_None;
 
-    if (!_PyArg_CheckPositional("perm", nargs, 2, 2)) {
+    if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) {
         goto exit;
     }
     n = args[0];
+    if (nargs < 2) {
+        goto skip_optional;
+    }
     k = args[1];
+skip_optional:
     return_value = math_perm_impl(module, n, k);
 
 exit:
@@ -713,4 +720,4 @@
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=5004266613284dcc input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0eb1e76a769cdd30 input=a9049054013a1b77]*/
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 9a9a815..ed11476 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -3002,7 +3002,7 @@
 math.perm
 
     n: object
-    k: object
+    k: object = None
     /
 
 Number of ways to choose k items from n items without repetition and with order.
@@ -3010,18 +3010,24 @@
 Evaluates to n! / (n - k)! when k <= n and evaluates
 to zero when k > n.
 
+If k is not specified or is None, then k defaults to n
+and the function returns n!.
+
 Raises TypeError if either of the arguments are not integers.
 Raises ValueError if either of the arguments are negative.
 [clinic start generated code]*/
 
 static PyObject *
 math_perm_impl(PyObject *module, PyObject *n, PyObject *k)
-/*[clinic end generated code: output=e021a25469653e23 input=b2e7729d9a1949cf]*/
+/*[clinic end generated code: output=e021a25469653e23 input=5311c5a00f359b53]*/
 {
     PyObject *result = NULL, *factor = NULL;
     int overflow, cmp;
     long long i, factors;
 
+    if (k == Py_None) {
+        return math_factorial(module, n);
+    }
     n = PyNumber_Index(n);
     if (n == NULL) {
         return NULL;