Wouldn't be better to revert (the part of) global variables moving?
I still don't see a benefit of it.
> To give a more concrete example: Py_DecodeLocale() is the recommanded
> function to decode bytes from the operating system, but this function
> calls PyMem_RawMalloc() which does crash before
> _PyRuntime_Initialize() is called. Is Py_DecodeLocale() used to
> initialize Python?
>
> For example, "void Py_SetProgramName(wchar_t *);" expects a text
> string, whereas main() gives argv as bytes. Calling
> Py_SetProgramName() from argv requires to decode bytes... So use
> Py_DecodeLocale()...
>
> Should we do something in Py_DecodeLocale()? Maybe crash if
> _PyRuntime_Initialize() wasn't called yet?
I think Py_DecodeLocale() should be usable before calling
Py_Initialize(). In the example in Doc/extending/extending.rst it is
used before Py_Initialize(). If the third-party code is based on this
example, it will crash now.
The Py_Initialize() is not complete. It mentions only
Py_SetProgramName(), Py_SetPythonHome() and Py_SetPath(). But in other
places it is documented that Py_SetStandardStreamEncoding(),
PyImport_AppendInittab(), PyImport_ExtendInittab() should be called
before Py_Initialize(). And the embedding examples call
Py_DecodeLocale() before Py_Initialize(). PyMem_RawMalloc(),
PyMem_RawFree() and PyInitFrozenExtensions() are called before
Py_Initialize() in Py_FrozenMain(). Also these functions call
_PyMem_RawStrdup().
Hence, the minimal set of functions that can be called before
Py_Initialize() is:
* Py_SetProgramName()
* Py_SetPythonHome()
* Py_SetPath()
* Py_SetStandardStreamEncoding()
* PyImport_AppendInittab()
* PyImport_ExtendInittab()
* Py_DecodeLocale()
* PyMem_RawMalloc()
* PyMem_RawFree()
* PyInitFrozenExtensions()
OK, in that case I think the answer to Victor's question is:
1. Breaking calling Py_DecodeLocale() before calling Py_Initialize()
is a compatibility break with the API implied by our own usage
examples, and we'll need to revert the breakage for 3.7, and ensure at
least one release's worth of DeprecationWarning before requiring
either the use of an alternative API (where the caller controls the
memory management), or else a new lower level pre-initialization API
(i.e. making `PyRuntime_Initialize` a public API)
2. We should provide a consolidated list of these functions in the C
API initialization docs
3. We should add more test cases to _testembed.c that ensure they all
work correctly prior to Py_Initialize (some of them are already tested
there, but definitely not all of them)
Cheers,
Nick.
--
Nick Coghlan | ncog...@gmail.com | Brisbane, Australia
There is a way to to control the memory manager. The caller should just
define their own PyMem_RawMalloc(), PyMem_RawFree(), etc. It seems to me
that the reasons of introducing these functions were:
1. Get around the implementation detail when malloc(0) could return
NULL. PyMem_RawMalloc() always should return an unique address (unless
error).
2. Allow the caller to control the memory management by providing their
own implementations.
Let use existing possibilities and not expand the API. I don't think the
deprecation and breaking compatibility are needed here.
OK, in that case I think the answer to Victor's question is:
1. Breaking calling Py_DecodeLocale() before calling Py_Initialize()
is a compatibility break with the API implied by our own usage
examples, and we'll need to revert the breakage for 3.7,
and ensure at
least one release's worth of DeprecationWarning before requiring
either the use of an alternative API (where the caller controls the
memory management), or else a new lower level pre-initialization API
(i.e. making `PyRuntime_Initialize` a public API)
2. We should provide a consolidated list of these functions in the C
API initialization docs
3. We should add more test cases to _testembed.c that ensure they all
work correctly prior to Py_Initialize (some of them are already tested
there, but definitely not all of them)
2017-11-22 12:04 GMT+01:00 Antoine Pitrou <soli...@pitrou.net>:
> IMHO this really needs a simple solution documented somewhere. Also,
> hopefully when you do the wrong thing, you get a clear error message to
> know how to fix your code?
Right now, calling PyMem_RawMalloc() before calling
_PyRuntime_Initialize() calls the function at address NULL, so you get
a segmentation fault.
Documenting the new requirements is part of the discussion, it's one
option how to fix this issue.
wchar_t *program = Py_DecodeLocale("spam", NULL);
Py_SetProgramName(program);
Py_Initialize();
Py_Finalize();
PyMem_RawFree(program);
Hi,
We are close to the 3.7a3 release and the bug is not fixed yet. I
propose to revert the changes on memory allocators right now, and take
time to design a proper fix which will respect all constraints.
https://github.com/python/cpython/pull/4532
Today, someone came to me on IRC to complain that calling
Py_DecodeLocale() does now crash on Python 3.7. He is doing tests to
embed Python on Android. Later he asks me about
PyImport_AppendInittab(), but I don't know this function. He told me
that it does crash in PyMem_Realloc()... But PyImport_AppendInittab()
must be called before Py_Initialize()...
It confirms that Python is embedded and that the C API is used before
Py_Initialize().
We don't know yet exactly how the the C API is used, which functions
are called before Py_Initialize().
Moreover, PEP 432 implementation is
still incomplete, and calling _PyRuntime_Initialize() is just not
possible, since it's a private API which is not exported...
- a consolidated list of *all* the APIs that can safely be called before Py_Initialize
This is a small list, 11 functions.