Staging
v0.8.1
https://github.com/python/cpython
Revision e41bfd15dd148627b4f39c2a5837bddd8894d345 authored by Terry Jan Reedy on 30 November 2020, 17:09:43 UTC, committed by GitHub on 30 November 2020, 17:09:43 UTC
restart_subprocess is a method of self, the pyshell.InteractiveInterpreter instance. The latter does not have an interp attribute redundantly referring to itself. (The PyShell instance does have an interp attribute, referring to the InteractiveInterpreter instance.)
1 parent 0be9ce3
Raw File
Tip revision: e41bfd15dd148627b4f39c2a5837bddd8894d345 authored by Terry Jan Reedy on 30 November 2020, 17:09:43 UTC
bpo-42508: Remove bogus idlelib.pyshell.ModifiedInterpreter attribute (GH-23570)
Tip revision: e41bfd1
_scproxy.c
/*
 * Helper method for urllib to fetch the proxy configuration settings
 * using the SystemConfiguration framework.
 */
#include <Python.h>
#include <SystemConfiguration/SystemConfiguration.h>

static int32_t
cfnum_to_int32(CFNumberRef num)
{
    int32_t result;

    CFNumberGetValue(num, kCFNumberSInt32Type, &result);
    return result;
}

static PyObject*
cfstring_to_pystring(CFStringRef ref)
{
    const char* s;

    s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8);
    if (s) {
        return PyUnicode_DecodeUTF8(
                        s, strlen(s), NULL);

    } else {
        CFIndex len = CFStringGetLength(ref);
        Boolean ok;
        PyObject* result;
        char* buf;

        buf = PyMem_Malloc(len*4);
        if (buf == NULL) {
            PyErr_NoMemory();
            return NULL;
        }

        ok = CFStringGetCString(ref,
                        buf, len * 4,
                        kCFStringEncodingUTF8);
        if (!ok) {
            PyMem_Free(buf);
            return NULL;
        } else {
            result = PyUnicode_DecodeUTF8(
                            buf, strlen(buf), NULL);
            PyMem_Free(buf);
        }
        return result;
    }
}


static PyObject*
get_proxy_settings(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored))
{
    CFDictionaryRef proxyDict = NULL;
    CFNumberRef aNum = NULL;
    CFArrayRef anArray = NULL;
    PyObject* result = NULL;
    PyObject* v;
    int r;

    Py_BEGIN_ALLOW_THREADS
    proxyDict = SCDynamicStoreCopyProxies(NULL);
    Py_END_ALLOW_THREADS

    if (!proxyDict) {
        Py_RETURN_NONE;
    }

    result = PyDict_New();
    if (result == NULL) goto error;

    aNum = CFDictionaryGetValue(proxyDict,
        kSCPropNetProxiesExcludeSimpleHostnames);
    if (aNum == NULL) {
        v = PyBool_FromLong(0);
    } else {
        v = PyBool_FromLong(cfnum_to_int32(aNum));
    }

    if (v == NULL) goto error;

    r = PyDict_SetItemString(result, "exclude_simple", v);
    Py_DECREF(v); v = NULL;
    if (r == -1) goto error;

    anArray = CFDictionaryGetValue(proxyDict,
                    kSCPropNetProxiesExceptionsList);
    if (anArray != NULL) {
        CFIndex len = CFArrayGetCount(anArray);
        CFIndex i;
        v = PyTuple_New(len);
        if (v == NULL) goto error;

        r = PyDict_SetItemString(result, "exceptions", v);
        Py_DECREF(v);
        if (r == -1) goto error;

        for (i = 0; i < len; i++) {
            CFStringRef aString = NULL;

            aString = CFArrayGetValueAtIndex(anArray, i);
            if (aString == NULL) {
                PyTuple_SetItem(v, i, Py_None);
                Py_INCREF(Py_None);
            } else {
                PyObject* t = cfstring_to_pystring(aString);
                if (!t) {
                    PyTuple_SetItem(v, i, Py_None);
                    Py_INCREF(Py_None);
                } else {
                    PyTuple_SetItem(v, i, t);
                }
            }
        }
    }

    CFRelease(proxyDict);
    return result;

error:
    if (proxyDict)  CFRelease(proxyDict);
    Py_XDECREF(result);
    return NULL;
}

static int
set_proxy(PyObject* proxies, const char* proto, CFDictionaryRef proxyDict,
                CFStringRef enabledKey,
                CFStringRef hostKey, CFStringRef portKey)
{
    CFNumberRef aNum;

    aNum = CFDictionaryGetValue(proxyDict, enabledKey);
    if (aNum && cfnum_to_int32(aNum)) {
        CFStringRef hostString;

        hostString = CFDictionaryGetValue(proxyDict, hostKey);
        aNum = CFDictionaryGetValue(proxyDict, portKey);

        if (hostString) {
            int r;
            PyObject* h = cfstring_to_pystring(hostString);
            PyObject* v;
            if (h) {
                if (aNum) {
                    int32_t port = cfnum_to_int32(aNum);
                    v = PyUnicode_FromFormat("http://%U:%ld",
                        h, (long)port);
                } else {
                    v = PyUnicode_FromFormat("http://%U", h);
                }
                Py_DECREF(h);
                if (!v) return -1;
                r = PyDict_SetItemString(proxies, proto,
                    v);
                Py_DECREF(v);
                return r;
            }
        }

    }
    return 0;
}



static PyObject*
get_proxies(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored))
{
    PyObject* result = NULL;
    int r;
    CFDictionaryRef proxyDict = NULL;

    Py_BEGIN_ALLOW_THREADS
    proxyDict = SCDynamicStoreCopyProxies(NULL);
    Py_END_ALLOW_THREADS

    if (proxyDict == NULL) {
        return PyDict_New();
    }

    result = PyDict_New();
    if (result == NULL) goto error;

    r = set_proxy(result, "http", proxyDict,
        kSCPropNetProxiesHTTPEnable,
        kSCPropNetProxiesHTTPProxy,
        kSCPropNetProxiesHTTPPort);
    if (r == -1) goto error;
    r = set_proxy(result, "https", proxyDict,
        kSCPropNetProxiesHTTPSEnable,
        kSCPropNetProxiesHTTPSProxy,
        kSCPropNetProxiesHTTPSPort);
    if (r == -1) goto error;
    r = set_proxy(result, "ftp", proxyDict,
        kSCPropNetProxiesFTPEnable,
        kSCPropNetProxiesFTPProxy,
        kSCPropNetProxiesFTPPort);
    if (r == -1) goto error;
    r = set_proxy(result, "gopher", proxyDict,
        kSCPropNetProxiesGopherEnable,
        kSCPropNetProxiesGopherProxy,
        kSCPropNetProxiesGopherPort);
    if (r == -1) goto error;

    CFRelease(proxyDict);
    return result;
error:
    if (proxyDict)  CFRelease(proxyDict);
    Py_XDECREF(result);
    return NULL;
}

static PyMethodDef mod_methods[] = {
    {
        "_get_proxy_settings",
        get_proxy_settings,
        METH_NOARGS,
        NULL,
    },
    {
        "_get_proxies",
        get_proxies,
        METH_NOARGS,
        NULL,
    },
    { 0, 0, 0, 0 }
};

static PyModuleDef_Slot _scproxy_slots[] = {
    {0, NULL}
};

static struct PyModuleDef _scproxy_module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_scproxy",
    .m_size = 0,
    .m_methods = mod_methods,
    .m_slots = _scproxy_slots,
};

#ifdef __cplusplus
extern "C" {
#endif

PyMODINIT_FUNC
PyInit__scproxy(void)
{
    return PyModuleDef_Init(&_scproxy_module);
}

#ifdef __cplusplus
}
#endif
back to top