Message335484
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. |
|
Date |
User |
Action |
Args |
2019-02-14 00:09:08 | steve.dower | set | recipients:
+ steve.dower, ncoghlan, pitrou, vstinner, grahamd, eric.snow |
2019-02-14 00:09:08 | steve.dower | set | messageid: <1550102948.01.0.552595371281.issue22213@roundup.psfhosted.org> |
2019-02-14 00:09:08 | steve.dower | link | issue22213 messages |
2019-02-14 00:09:07 | steve.dower | create | |
|