Author steve.dower
Recipients eric.snow, grahamd, ncoghlan, pitrou, steve.dower, vstinner
Date 2019-02-14.00:09:07
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1550102948.01.0.552595371281.issue22213@roundup.psfhosted.org>
In-reply-to
Content
Thanks, Victor, that's great information.

> Memory allocator, context, different structures for configuration... it's really not an easy topic :-( There are so many constraints put into a single API!

This is why I'm keen to design the ideal *user* API first (that is, write the examples of how you would use it) and then figure out how we can make it fit. It's kind of the opposite approach from what you've been doing to adapt the existing code to suit particular needs.

For example, imagine instead of all the PySet*() functions followed by Py_Initialize() you could do this:

    PyObject *runtime = PyRuntime_Create();
    /* optional calls */
    PyRuntime_SetAllocators(runtime, &my_malloc, &my_realloc, &my_free);
    PyRuntime_SetHashSeed(runtime, 12345);

    /* sets this as the current runtime via a thread local */
    auto old_runtime = PyRuntime_Activate(runtime);
    assert(old_runtime == NULL)

    /* pretend triple quoting works in C for a minute ;) */
    const char *init = """
    import os.path
    import sys

    sys.executable = argv0
    sys.prefix = os.path.dirname(argv0)
    sys.path = [os.getcwd(), sys.prefix, os.path.join(sys.prefix, "Lib")]

    pyvenv = os.path.join(sys.prefix, "pyvenv.cfg")
    try:
        with open(pyvenv, "r", encoding="utf-8") as f:  # *only* utf-8 support at this stage
            for line in f:
                if line.startswith("home"):
                    sys.path.append(line.partition("=")[2].strip())
                    break
    except FileNotFoundError:
        pass

    if sys.platform == "win32":
        sys.stdout = open("CONOUT$", "w", encoding="utf-8")
    else:
        # no idea if this is right, but you get the idea
        sys.stdout = open("/dev/tty", "w", encoding="utf-8")
    """;

    PyObject *globals = PyDict_New();
    /* only UTF-8 support at this stage */
    PyDict_SetItemString(globals, "argv0", PyUnicode_FromString(argv[0]));
    PyRuntime_Initialize(runtime, init_code, globals);
    Py_DECREF(globals);

    /* now we've initialised, loading codecs will succeed if we can find them or fail if not,
     * so we'd have to do cleanup to avoid depending on them without the user being able to
     * avoid it... */

    PyEval_EvalString("open('file.txt', 'w', encoding='gb18030').close()");

    /* may as well reuse DECREF for consistency */
    Py_DECREF(runtime);

Maybe it's a terrible idea? Honestly I'd be inclined to do other big changes at the same time (make PyObject opaque and interface driven, for example).

My point is that if the goal is to "move the existing internals around" then that's all we'll ever achieve. If we can say "the goal is to make this example work" then we'll be able to do much more.
History
Date User Action Args
2019-02-14 00:09:08steve.dowersetrecipients: + steve.dower, ncoghlan, pitrou, vstinner, grahamd, eric.snow
2019-02-14 00:09:08steve.dowersetmessageid: <1550102948.01.0.552595371281.issue22213@roundup.psfhosted.org>
2019-02-14 00:09:08steve.dowerlinkissue22213 messages
2019-02-14 00:09:07steve.dowercreate