Eryk Sun <eryk...@gmail.com> added the comment:

> as long as the behavior is *consistent* with the env kwarg to 
> subprocess.run() 

subprocess isn't consistent with itself across platforms. The env parameter in 
Windows is strictly an str->str mapping, like os.environ. This is coded in 
getenvironment in Modules/_winapi.c:

    if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) {
        PyErr_SetString(PyExc_TypeError,
            "environment can only contain strings");
        goto error;
    }

At a lower level, should the env parameter of os.spawnve and os.execve  allow 
path-like objects? Should (Unix) os.putenv allow the name and value to be 
path-like?

Currently these cases use PyUnicode_FSConverter and PyUnicode_FSDecoder, which 
support __fspath__ via PyOS_FSPath. PyUnicode_FSDecoder also supports the 
buffer protocol, with a warning. 

Since we have cases like this where the filesystem encoding is used for string 
data that's not actually a file path, should alternate ParseTuple converters be 
added that are limited to just str and bytes? Maybe name them 
PyUnicode_FSStringEncoder and PyUnicode_FSStringDecoder, where "String" 
emphasizes that fspath and buffer objects are not allowed. For example:

    int
    PyUnicode_FSStringEncoder(PyObject *path, void *addr)
    {
        PyObject *output = NULL;

        if (path == NULL) {
            Py_DECREF(*(PyObject **)addr);
            *(PyObject **)addr = NULL;
            return 1;
        }

        if (PyBytes_Check(path)) {
            output = path;
            Py_INCREF(output);
        }
        else if (PyUnicode_Check(path)) {
            output = PyUnicode_EncodeFSDefault(path);
            if (!output)
                return 0;
        }
        else {
            PyErr_Format(PyExc_TypeError, "path should be str or bytes, not "
                "%.200s", _PyType_Name(Py_TYPE(path)));
            return 0;
        }

        if ((size_t)PyBytes_GET_SIZE(output) !=
                strlen(PyBytes_AS_STRING(output)))
        {
            PyErr_SetString(PyExc_ValueError, "embedded null byte");
            Py_DECREF(output);
            return 0;
        }
        
        *(PyObject **)addr = output;
        return Py_CLEANUP_SUPPORTED;
    }


    int
    PyUnicode_FSStringDecoder(PyObject *path, void *addr)
    {
        PyObject *output = NULL;

        if (arg == NULL) {
            Py_DECREF(*(PyObject **)addr);
            *(PyObject **)addr = NULL;
            return 1;
        }

        if (PyUnicode_Check(path)) {
            output = path;
            Py_INCREF(output);
        }
        else if (PyBytes_Check(path)) {
            output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path),
                        PyBytes_GET_SIZE(path));
            if (!output)
                return 0;
        }
        else {
            PyErr_Format(PyExc_TypeError, "path should be str or bytes, not "
                "%.200s", _PyType_Name(Py_TYPE(path)));
            return 0;
        }
        
        if (PyUnicode_READY(output) == -1) {
            Py_DECREF(output);
            return 0;
        }
        
        if (findchar(PyUnicode_DATA(output), PyUnicode_KIND(output),
                     PyUnicode_GET_LENGTH(output), 0, 1) >= 0) {
            PyErr_SetString(PyExc_ValueError, "embedded null character");
            Py_DECREF(output);
            return 0;
        }
        
        *(PyObject **)addr = output;
        return Py_CLEANUP_SUPPORTED;
    }

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue39461>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to