@unittest.skipUnless(hasattr(posix, 'confstr'),
'test needs posix.confstr()')
- @unittest.skipIf(support.is_apple_mobile, "gh-118201: Test is flaky on iOS")
def test_confstr(self):
- self.assertRaises(ValueError, posix.confstr, "CS_garbage")
- self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
+ with self.assertRaisesRegex(
+ ValueError, "unrecognized configuration name"
+ ):
+ posix.confstr("CS_garbage")
+
+ with self.assertRaisesRegex(
+ TypeError, "configuration names must be strings or integers"
+ ):
+ posix.confstr(1.23)
+
+ path = posix.confstr("CS_PATH")
+ self.assertGreater(len(path), 0)
+ self.assertEqual(posix.confstr(posix.confstr_names["CS_PATH"]), path)
+
+ @unittest.skipUnless(hasattr(posix, 'sysconf'),
+ 'test needs posix.sysconf()')
+ def test_sysconf(self):
+ with self.assertRaisesRegex(
+ ValueError, "unrecognized configuration name"
+ ):
+ posix.sysconf("SC_garbage")
+
+ with self.assertRaisesRegex(
+ TypeError, "configuration names must be strings or integers"
+ ):
+ posix.sysconf(1.23)
+
+ arg_max = posix.sysconf("SC_ARG_MAX")
+ self.assertGreater(arg_max, 0)
+ self.assertEqual(
+ posix.sysconf(posix.sysconf_names["SC_ARG_MAX"]), arg_max)
@unittest.skipUnless(hasattr(posix, 'dup2'),
'test needs posix.dup2()')
if (fd < 0) {
goto exit;
}
- if (!conv_path_confname(args[1], &name)) {
+ if (!conv_confname(module, args[1], &name, "pathconf_names")) {
goto exit;
}
_return_value = os_fpathconf_impl(module, fd, name);
if (!path_converter(args[0], &path)) {
goto exit;
}
- if (!conv_path_confname(args[1], &name)) {
+ if (!conv_confname(module, args[1], &name, "pathconf_names")) {
goto exit;
}
_return_value = os_pathconf_impl(module, &path, name);
PyObject *return_value = NULL;
int name;
- if (!conv_confstr_confname(arg, &name)) {
+ if (!conv_confname(module, arg, &name, "confstr_names")) {
goto exit;
}
return_value = os_confstr_impl(module, name);
int name;
long _return_value;
- if (!conv_sysconf_confname(arg, &name)) {
+ if (!conv_confname(module, arg, &name, "sysconf_names")) {
goto exit;
}
_return_value = os_sysconf_impl(module, name);
#ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF
#define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF
#endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */
-/*[clinic end generated code: output=a75be356cd4abca5 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=616483d525403f7c input=a9049054013a1b77]*/
type = 'Py_off_t'
conversion_fn = 'PyLong_FromPy_off_t'
-class path_confname_converter(CConverter):
+class confname_converter(CConverter):
type="int"
- converter="conv_path_confname"
+ converter="conv_confname"
-class confstr_confname_converter(path_confname_converter):
- converter='conv_confstr_confname'
+ def converter_init(self, *, table):
+ self.table = table
-class sysconf_confname_converter(path_confname_converter):
- converter="conv_sysconf_confname"
+ def parse_arg(self, argname, displayname, *, limited_capi):
+ return self.format_code("""
+ if (!{converter}(module, {argname}, &{paramname}, "{table}")) {{{{
+ goto exit;
+ }}}}
+ """, argname=argname, converter=self.converter, table=self.table)
[python start generated code]*/
-/*[python end generated code: output=da39a3ee5e6b4b0d input=577cb476e5d64960]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=a6199b1618d73f53]*/
/*[clinic input]
};
static int
-conv_confname(PyObject *arg, int *valuep, struct constdef *table,
- size_t tablesize)
+conv_confname(PyObject *module, PyObject *arg, int *valuep, const char *tablename)
{
- if (PyLong_Check(arg)) {
- int value = PyLong_AsInt(arg);
- if (value == -1 && PyErr_Occurred())
- return 0;
- *valuep = value;
- return 1;
- }
- else {
- /* look up the value in the table using a binary search */
- size_t lo = 0;
- size_t mid;
- size_t hi = tablesize;
- int cmp;
- const char *confname;
- if (!PyUnicode_Check(arg)) {
- PyErr_SetString(PyExc_TypeError,
- "configuration names must be strings or integers");
+ if (PyUnicode_Check(arg)) {
+ PyObject *table = PyObject_GetAttrString(module, tablename);
+ if (table == NULL) {
return 0;
}
- confname = PyUnicode_AsUTF8(arg);
- if (confname == NULL)
+
+ arg = PyObject_GetItem(table, arg);
+ Py_DECREF(table);
+ if (arg == NULL) {
+ PyErr_SetString(
+ PyExc_ValueError, "unrecognized configuration name");
return 0;
- while (lo < hi) {
- mid = (lo + hi) / 2;
- cmp = strcmp(confname, table[mid].name);
- if (cmp < 0)
- hi = mid;
- else if (cmp > 0)
- lo = mid + 1;
- else {
- *valuep = table[mid].value;
- return 1;
- }
}
- PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
- return 0;
+ } else {
+ Py_INCREF(arg); // Match the Py_DECREF below.
+ }
+
+ int success = 0;
+ if (!PyLong_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "configuration names must be strings or integers");
+ } else {
+ int value = PyLong_AsInt(arg);
+ if (!(value == -1 && PyErr_Occurred())) {
+ *valuep = value;
+ success = 1;
+ }
}
+ Py_DECREF(arg);
+ return success;
}
{"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
#endif
};
-
-static int
-conv_path_confname(PyObject *arg, int *valuep)
-{
- return conv_confname(arg, valuep, posix_constants_pathconf,
- sizeof(posix_constants_pathconf)
- / sizeof(struct constdef));
-}
#endif
os.fpathconf -> long
fd: fildes
- name: path_confname
+ name: confname(table="pathconf_names")
/
Return the configuration limit name for the file descriptor fd.
static long
os_fpathconf_impl(PyObject *module, int fd, int name)
-/*[clinic end generated code: output=d5b7042425fc3e21 input=5b8d2471cfaae186]*/
+/*[clinic end generated code: output=d5b7042425fc3e21 input=023d44589c9ed6aa]*/
{
long limit;
/*[clinic input]
os.pathconf -> long
path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
- name: path_confname
+ name: confname(table="pathconf_names")
Return the configuration limit name for the file or directory path.
static long
os_pathconf_impl(PyObject *module, path_t *path, int name)
-/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
+/*[clinic end generated code: output=5bedee35b293a089 input=6f6072f57b10c787]*/
{
long limit;
#endif
};
-static int
-conv_confstr_confname(PyObject *arg, int *valuep)
-{
- return conv_confname(arg, valuep, posix_constants_confstr,
- sizeof(posix_constants_confstr)
- / sizeof(struct constdef));
-}
-
/*[clinic input]
os.confstr
- name: confstr_confname
+ name: confname(table="confstr_names")
/
Return a string-valued system configuration variable.
static PyObject *
os_confstr_impl(PyObject *module, int name)
-/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
+/*[clinic end generated code: output=bfb0b1b1e49b9383 input=4c6ffca2837ec959]*/
{
PyObject *result = NULL;
char buffer[255];
#endif
};
-static int
-conv_sysconf_confname(PyObject *arg, int *valuep)
-{
- return conv_confname(arg, valuep, posix_constants_sysconf,
- sizeof(posix_constants_sysconf)
- / sizeof(struct constdef));
-}
-
/*[clinic input]
os.sysconf -> long
- name: sysconf_confname
+ name: confname(table="sysconf_names")
/
Return an integer-valued system configuration variable.
static long
os_sysconf_impl(PyObject *module, int name)
-/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
+/*[clinic end generated code: output=3662f945fc0cc756 input=930b8f23b5d15086]*/
{
long value;
#endif /* HAVE_SYSCONF */
-/* This code is used to ensure that the tables of configuration value names
- * are in sorted order as required by conv_confname(), and also to build
- * the exported dictionaries that are used to publish information about the
- * names available on the host platform.
- *
- * Sorting the table at runtime ensures that the table is properly ordered
- * when used, even for platforms we're not able to test on. It also makes
- * it easier to add additional entries to the tables.
- */
-
-static int
-cmp_constdefs(const void *v1, const void *v2)
-{
- const struct constdef *c1 =
- (const struct constdef *) v1;
- const struct constdef *c2 =
- (const struct constdef *) v2;
-
- return strcmp(c1->name, c2->name);
-}
-
static int
setup_confname_table(struct constdef *table, size_t tablesize,
const char *tablename, PyObject *module)
{
- PyObject *d = NULL;
- size_t i;
-
- qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
- d = PyDict_New();
+ PyObject *d = PyDict_New();
if (d == NULL)
return -1;
- for (i=0; i < tablesize; ++i) {
+ for (size_t i=0; i < tablesize; ++i) {
PyObject *o = PyLong_FromLong(table[i].value);
if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
Py_XDECREF(o);