Re: [Python-Dev] Removing PendingDeprecationWarning

2019-03-27 Thread Inada Naoki
On Mon, Mar 25, 2019 at 10:11 PM Inada Naoki  wrote:
>
> C, Rust, Java, Ruby, PHP, don't have PendingDeprecation.
> Programmers only need Deprecation.  Why programmers need PendingDeprecation
> only in Python?
>

Any comments about this?

I want to document PendingDeprecationWarning is deprecated [1].
May I merge the PR?  Should I start poll on discuss.python.org?

[1]: https://github.com/python/cpython/pull/12505/files

-- 
Inada Naoki  
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] BDFL-Delegate appointments for several PEPs

2019-03-27 Thread Petr Viktorin
On Sun, Mar 24, 2019 at 4:22 PM Mark Shannon  wrote:
>
> Hi Petr,
>
> Regarding PEPs 576 and 580.
> Over the new year, I did a thorough analysis of possible approaches to
> possible calling conventions for use in the CPython ecosystems and came
> up with a new PEP.
> The draft can be found here:
> https://github.com/markshannon/peps/blob/new-calling-convention/pep-.rst
>
> I was hoping to profile a branch with the various experimental changes
> cherry-picked together, but don't seemed to have found the time :(
>
> I'd like to have a testable branch, before formally submitting the PEP,
> but I'd thought you should be aware of the PEP.
>
> Cheers,
> Mark.

Hello Mark,
Thank you for letting me know! I wish I knew of this back in January,
when you committed the first draft. This is unfair to the competing
PEP, which is ready and was waiting for the new govenance. We have
lost three months that could be spent pondering the ideas in the
pre-PEP.
Do you think you will find the time to piece things together? Is there
anything that you already know should be changed?

Do you have any comments on [Jeroen's comparison]?

The pre-PEP is simpler then PEP 580, because it solves simpler issues.
I'll need to confirm that it won't paint us into a corner -- that
there's a way to address all the issues in PEP 579 in the future.

The pre-PEP claims speedups of 2% in initial experiments, with
expected overall performance gain of 4% for the standard benchmark
suite. That's pretty big.
As far as I can see, PEP 580 claims not much improvement in CPython,
but rather large improvements for extensions (Mistune with Cython).

The pre-PEP has a complication around offsetting arguments by 1 to
allow bound methods forward calls cheaply. I fear that this optimizes
for current usage with its limitations.
PEP 580's cc_parent allows bound methods to have access to the class,
and through that, the module object where they are defined and the
corresponding module state. To support this, vector calls would need a
two-argument offset.
(That seems to illustrate the main difference between the motivations
of the two PEPs: one focuses on extensibility; the other on optimizing
existing use cases.)

The pre-PEP's "any third-party class implementing the new call
interface will not be usable as a base class" looks quite limiting.



[Jeroen's comparison]:
https://mail.python.org/pipermail/python-dev/2018-July/154238.html
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PEP 576bis discussion

2019-03-27 Thread Jeroen Demeyer

By lack of a better name, I'm using the name PEP 576bis to refer to
https://github.com/markshannon/peps/blob/new-calling-convention/pep-.rst 
(This is why this should get a PEP number soon, even if the PEP is not 
completely done yet).


On 2019-03-27 14:50, Petr Viktorin wrote:

The pre-PEP is simpler then PEP 580, because it solves simpler issues.
I'll need to confirm that it won't paint us into a corner -- that
there's a way to address all the issues in PEP 579 in the future.


One potential issue is calling bound methods (in the duck typing sense) 
when the LOAD_METHOD optimization is *not* used. This would happen for 
example when storing a bound method object somewhere and then calling it 
(possibly repeatedly). Perhaps that's not a very common thing and we 
should just live with that. However, since __self__ is part of the PEP 
580 protocol, it allows calling a bound method object without any 
performance penalty compared to calling the underlying function directly.


Similarly, a follow-up of PEP 580 could allow zero-overhead calling of 
static/class methods (I didn't put this in PEP 580 because it's already 
too long).



As far as I can see, PEP 580 claims not much improvement in CPython,
but rather large improvements for extensions (Mistune with Cython).


Cython is indeed the main reason for PEP 580.


The pre-PEP has a complication around offsetting arguments by 1 to
allow bound methods forward calls cheaply.


I honestly don't understand what this "offset by one" means or why it's 
useful. It should be better explained in the PEP.



The pre-PEP's "any third-party class implementing the new call
interface will not be usable as a base class" looks quite limiting.


I agree, this is pretty bad. However, I don't think that there is a need 
for this limitation. PEP 580 solves this by only inheriting the 
Py_TPFLAGS_HAVE_CCALL flag in specific cases. PEP 576bis could do 
something similar.


Finally, I don't agree with this sentence from PEP 576bis: PEP 580 is 
specifically targetted at function-like objects, and doesn't support 
other callables like classes, partial functions, or proxies.


It's true that classes are not supported (and I wonder how PEP 576bis 
deals with that, it would be good to explain that more explicitly) but 
other callables are not a problem.



Jeroen.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Removing PendingDeprecationWarning

2019-03-27 Thread Steve Dower

On 27Mar2019 0324, Inada Naoki wrote:

On Mon, Mar 25, 2019 at 10:11 PM Inada Naoki  wrote:


C, Rust, Java, Ruby, PHP, don't have PendingDeprecation.
Programmers only need Deprecation.  Why programmers need PendingDeprecation
only in Python?



Any comments about this?

I want to document PendingDeprecationWarning is deprecated [1].
May I merge the PR?  Should I start poll on discuss.python.org?

[1]: https://github.com/python/cpython/pull/12505/files


There are two questions here:

1. Are we going to stop using it in CPython and the standard library?
2. Do we want everyone else to stop using it for their own purposes?

I think the first one is easy for us to answer (and personally, I don't 
care which way we go with it). However, deciding to stop using it 
ourselves is not the same as deprecating the class. So in this case, we 
would document that it is no longer used in CPython but is still 
available for other projects.


The second question is harder to answer, and in the absence of input 
from those who are already using it (or the absence of evidence that 
nobody else is using it), the best we can do is evaluate how much of a 
maintenance burden the class is.


In my opinion, it is a very low maintenance burden, and a very low 
cognitive burden on users, and so the cost of deprecating it on 
third-parties who are using it vastly outweighs the cost of leaving it 
alone.


If someone can show that either no third-parties are using it, or all 
those that do will probably never explicitly support Python 3.8 or 
later, or all those that do would prefer to stop using it, then I'll 
happily change my mind here. But right now, it seems like deprecating it 
will cause an unknown amount of churn for minimal benefit.


At most, I'd document it as "this will probably not survive to the next 
major change release, even though we aren't planning to do one yet" 
(much like the Py_UNICODE APIs). Ironically, PendingDeprecationWarning 
seems a pretty accurate way of indicating this state.


Cheers,
Steve
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Removing PendingDeprecationWarning

2019-03-27 Thread Paul Moore
On Wed, 27 Mar 2019 at 15:29, Steve Dower  wrote:
> If someone can show that either no third-parties are using it, or all
> those that do will probably never explicitly support Python 3.8 or
> later, or all those that do would prefer to stop using it, then I'll
> happily change my mind here. But right now, it seems like deprecating it
> will cause an unknown amount of churn for minimal benefit.

FWIW, https://searchcode.com/?q=PendingDeprecationWarning&lan=19 says
there are about 6.786 results. I haven't looked extensively, but
Django seems to be in there. The msgpack library that is vendored by
pip (ironically, maintained by INADA-San) also uses it in one place.

Personally, I don't think deprecation is worth the disruption.
Paul
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Removing PendingDeprecationWarning

2019-03-27 Thread Brett Cannon
On Wed, Mar 27, 2019 at 3:26 AM Inada Naoki  wrote:

> On Mon, Mar 25, 2019 at 10:11 PM Inada Naoki 
> wrote:
> >
> > C, Rust, Java, Ruby, PHP, don't have PendingDeprecation.
> > Programmers only need Deprecation.  Why programmers need
> PendingDeprecation
> > only in Python?
> >
>
> Any comments about this?
>

You know my views on this. :) Leave it and we start to consistently use if
for deprecations that are more than a release away from removal (and for
those not reading discuss.python.org, I proposed over there introducing a
warnings._deprecate() function for the stdlib which will do the right thing
based on sys.version_info() and the stated start/end for the deprecation).

It might also make sense to hold off on anything official until we decide
on something like PEP 387 and how we want to officially communicate
deprecations.

-Brett


>
> I want to document PendingDeprecationWarning is deprecated [1].
> May I merge the PR?  Should I start poll on discuss.python.org?
>
> [1]: https://github.com/python/cpython/pull/12505/files
>
> --
> Inada Naoki  
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/brett%40python.org
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] New Python Initialization API

2019-03-27 Thread Victor Stinner
Hi,

I would like to add a new C API to initialize Python. I would like
your opinion on the whole API before making it public. The code is
already implemented. Doc of the new API:

   https://pythondev.readthedocs.io/init_config.html


To make the API public, _PyWstrList, _PyInitError, _PyPreConfig,
_PyCoreConfig and related functions should be made public.

By the way, I would suggest to rename "_PyCoreConfig" to just
"PyConfig" :-) I don't think that "core init" vs "main init" is really
relevant: more about that below.


Let's start with two examples using the new API.

Example of simple initialization to enable isolated mode:

_PyCoreConfig config = _PyCoreConfig_INIT;
config.isolated = 1;

_PyInitError err = _Py_InitializeFromConfig(&config);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}
/* ... use Python API here ... */
Py_Finalize();

Example using the pre-initialization to enable the UTF-8 Mode (and use the
"legacy" Py_Initialize() function):

_PyPreConfig preconfig = _PyPreConfig_INIT;
preconfig.utf8_mode = 1;

_PyInitError err = _Py_PreInitialize(&preconfig);
if (_Py_INIT_FAILED(err)) {
_Py_ExitInitError(err);
}

/* at this point, Python will only speak UTF-8 */

Py_Initialize();
/* ... use Python API here ... */
Py_Finalize();

Since November 2017, I'm refactoring the Python Initialization code to
cleanup the code and prepare a new ("better") API to configure Python
Initialization. I just fixed the last issues that Nick Coghlan asked
me to fix (add a pre-initialization step: done, fix mojibake: done).
My work is inspired by Nick Coghlan's PEP 432, but it is not
implementing it directly. I had other motivations than Nick even if we
are somehow going towards the same direction.

Nick wants to get a half-initialized Python ("core init"), configure
Python using the Python API and Python objects, and then finish the
implementation ("main init").

I chose a different approach: put *everything* into a single C
structure (_PyCoreConfig) using C types. Using the structure, you
should be able to do what Nick wanted to do, but with C rather than
Python. Nick: please tell me if I'm wrong :-)

This work is also connected to Eric Snow's work on sub-interpreters
(PEP 554) and moving global variables into structures. For example,
I'm using his _PyRuntime structure to store a new "preconfig" state
(pre-initialization configuration, more about that below).

In November 2017, when I started to work on the Python Initialization
(bpo-32030), I identified the following problems:

* Many parts of the code were interdependent
* Code executed early in Py_Main() used the Python API before the Python API
  was fully initialized. Like code parsing -W command line option which
  used PyUnicode_FromWideChar() and PyList_Append().
* Error handling used Py_FatalError() which didn't let the caller to decide
  how to handle the error. Moreover, exit() was used to exit Python,
whereas libpython shouldn't do that: a library should not exit the
whole process! (imagine when Python is embedded inside an application)

One year and a half later, I implemented the following solutions:

* Py_Main() and Py_Initialize() code has been reorganized to respect
  priorities between global configuration variables (ex:
  Py_IgnoreEnvironmentFlag), environment variables (ex: PYTHONPATH), command
  line arguments (ex: -X utf8), configuration files (ex: pyenv.cfg), and the
  new _PyPreConfig and _PyCoreConfig structures which store the whole
  configuration.
* Python Initialization no longer uses the Python API but only C types
  like wchar_t* strings, a new _PyWstrList structure and PyMem_RawMalloc()
  memory allocator (PyMem_Malloc() is no longer used during init).
* The code has been modified to use a new _PyInitError structure. The caller
  of the top function gets control to cleanup everything before handling the
  error (display a fatal error message or simply exit Python).

The new _PyCoreConfig structure has the top-priority and provides a single
structure for all configuration parameters.

It becomes possible to override the code computing the "path configuration"
like sys.path to fully control where Python looks to import modules. It
becomes possible to use an empty list of paths to only allow builtin modules.

A new "pre-initialization" steps is responsible to configure the bare minimum
before the Python initialization: memory allocators and encodings
(LC_CTYPE locale
and the UTF-8 mode). The LC_CTYPE is no longer coerced and the UTF-8 Mode is
no longer enabled automatically depending on the user configuration to prevent
mojibake. Previously, calling Py_DecodeLocale() to get a Unicode wchar_t*
string from a bytes wchar* string created mojibake when called before
Py_Initialize() if the LC_CTYPE locale was coerced and/or if the UTF-8 Mode was
enabled.

The pre-initialization step ensures that the encodings and memory allocators
are well defined *before* P

Re: [Python-Dev] New Python Initialization API

2019-03-27 Thread Alexander Belopolsky
> To make the API public, _PyWstrList, _PyInitError, _PyPreConfig,
> _PyCoreConfig and related functions should be made public.

Would you consider making _Py_UnixMain public as well?

It is useful for high level embedding and not trivial for 3rd parties to
reimplement.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] New Python Initialization API

2019-03-27 Thread Steve Dower

On 27Mar2019 1048, Victor Stinner wrote:

Since November 2017, I'm refactoring the Python Initialization code to
cleanup the code and prepare a new ("better") API to configure Python
Initialization. I just fixed the last issues that Nick Coghlan asked
me to fix (add a pre-initialization step: done, fix mojibake: done).
My work is inspired by Nick Coghlan's PEP 432, but it is not
implementing it directly. I had other motivations than Nick even if we
are somehow going towards the same direction.


I this this should be its own PEP, since as you say it is not 
implementing the only PEP we have (or alternatively, maybe you should 
collaborate to update PEP 432 so that it reflects what you think we 
ought to be implementing).


Having formal writeups of both ideas is important to help decide between 
the two. It's not good to overrule a PEP by pretending that your change 
isn't big enough to need its own.


(Not trying to devalue the work you've been doing so far, since it's 
great! But internal changes are one thing, while updating the public, 
documented interfaces deserves a more thorough process.)


Cheers,
Steve
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] New Python Initialization API

2019-03-27 Thread Brett Cannon
On Wed, Mar 27, 2019 at 12:39 PM Steve Dower  wrote:

> On 27Mar2019 1048, Victor Stinner wrote:
> > Since November 2017, I'm refactoring the Python Initialization code to
> > cleanup the code and prepare a new ("better") API to configure Python
> > Initialization. I just fixed the last issues that Nick Coghlan asked
> > me to fix (add a pre-initialization step: done, fix mojibake: done).
> > My work is inspired by Nick Coghlan's PEP 432, but it is not
> > implementing it directly. I had other motivations than Nick even if we
> > are somehow going towards the same direction.
>
> I this this should be its own PEP, since as you say it is not
> implementing the only PEP we have (or alternatively, maybe you should
> collaborate to update PEP 432 so that it reflects what you think we
> ought to be implementing).
>

I agree that if this isn't doing what PEP 432 set out but going its own way
we should probably discuss in regards to 432.

-Brett


>
> Having formal writeups of both ideas is important to help decide between
> the two. It's not good to overrule a PEP by pretending that your change
> isn't big enough to need its own.
>
> (Not trying to devalue the work you've been doing so far, since it's
> great! But internal changes are one thing, while updating the public,
> documented interfaces deserves a more thorough process.)
>
> Cheers,
> Steve
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/brett%40python.org
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] BDFL-Delegate appointments for several PEPs

2019-03-27 Thread Jeroen Demeyer

On 2019-03-27 14:50, Petr Viktorin wrote:

The pre-PEP claims speedups of 2% in initial experiments, with
expected overall performance gain of 4% for the standard benchmark
suite. That's pretty big.


I re-did my earlier benchmarks for PEP 580 and these are the results:
https://gist.github.com/jdemeyer/f0d63be8f30dc34cc989cd11d43df248

In general, the PEP 580 timings seem slightly better than vanilla 
CPython, similar to what Mark got. I'm speculating that the speedup in 
both cases comes from the removal of type checks and dispatching 
depending on that, and instead using a single protocol that directly 
does what needs to be done.



Jeroen.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Rejecting PEP 502

2019-03-27 Thread Brett Cannon
https://www.python.org/dev/peps/pep-0502/

Thanks to Mike G. Miller for the informational PEP, but since the PEP was
written with an opinionated voice and the details of the PEP aren't
critical as they should be captured by PEP 498  anyway, we didn't think it
was worth trying to touch the PEP up to change its voice.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PEP 556 threaded garbage collection & linear recursion in gc

2019-03-27 Thread Gregory P. Smith
https://www.python.org/dev/peps/pep-0556/

This PEP is currently Deferred as nobody is actively working on a test
implementation.

A situation came up the other day where I *believe* this could've helped.

Scenario (admittedly not one most environments run into): A Python process
with a C++ extension module implementing a threaded server (threads spawned
by C++) that could call back into CPython within server request handlers.
(ie: how all threaded servers tend to work regardless of core loop
implementation language)

Python code in the application had done something (unknown to me, I didn't
dive into their code) that built up large enough presumably nested or
recursive data structures that the garbage collector, when triggered, would
wind up in very deep recursion.  This caused a stack overflow as the C++
spawned threads were only being given a 256k stack (to conserve virtual
address space - there can potentially be a _ton_ of threads in this code).

That had a C++ stack trace 1000+ levels deep repeating the pattern of

...
@ 0x564d59bd21de 32  func_dealloc
@ 0x564d59bce0c1 32  cell_dealloc
@ 0x564d5839db41 48  tupledealloc
@ 0x564d59bd21de 32  func_dealloc
@ 0x564d59bce0c1 32  cell_dealloc
@ 0x564d5839db41 48  tupledealloc
...

If our gc were done on a thread of its own spawned by Python, with a
typical normal larger default stack size (8mb) this would've been less
likely to trigger a crash (though obviously still possible if the recursion
is linear).

I know, there are obvious workarounds to this situation of all sorts.  My
point is more that synchronously triggering gc _within_ a thread that
happens to invoke the periodic "hey, lets do another gc run" logic the eval
loop is undesirable.

I'm not making any plans to work on an implementation for this PEP,
deferred seems accurate. Just dropping a note that I'd still be interested
in seeing something other than synchronous gc in arbitrary threads happen
when a process has multiple threads.

*Another* take away from this is that it *appears* possible to cause our gc
to go into linear recursion.  Yuck!  I'd file an issue on that, but doing
so requires making some example code to construct such a scenario first...

Food for thought in case these kinds of things are something anyone else
has encountered.

-Greg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 556 threaded garbage collection & linear recursion in gc

2019-03-27 Thread Tim Peters
[Gregory P. Smith ]
> ...
> A situation came up the other day where I believe this could've helped.
>
> Scenario (admittedly not one most environments run into): A Python process
> with a C++ extension module implementing a threaded server (threads
> spawned by C++) that could call back into CPython within server request
> handlers.  (ie: how all threaded servers tend to work regardless of core
> loop implementation language)
>
> Python code in the application had done something (unknown to me, I
> didn't dive into their code) that built up large enough presumably nested
> or recursive data structures that the garbage collector, when triggered,
> would wind up in very deep recursion.  This caused a stack overflow
>  as the C++ spawned threads were only being given a 256k stack (to
> conserve virtual address space - there can potentially be a _ton_ of
> threads in this code).
>
> That had a C++ stack trace 1000+ levels deep repeating the pattern of
>
> ...
> @ 0x564d59bd21de 32  func_dealloc
> @ 0x564d59bce0c1 32  cell_dealloc
> @ 0x564d5839db41 48  tupledealloc
> @ 0x564d59bd21de 32  func_dealloc
> @ 0x564d59bce0c1 32  cell_dealloc
> @ 0x564d5839db41 48  tupledealloc
> ...
>
> If our gc were done on a thread of its own spawned by Python, with a typical
> normal larger default stack size (8mb) this would've been less likely
> to trigger a crash (though obviously still possible if the recursion is 
> linear).

Just noting that gc is probably a red herring in that scenario.  gc
(cleverly!) determines the set of trash objects without needing any
recursive graph crawls.  And gc doesn't deallocate anything - not
directly.  It simply applies Py_DECREF to trash objects, once for each
PyObject* found pointing to them.  _If_ deallocation occurs as a
result, it's the same as if the user had done `del` on the appropriate
object manually.  The recursion then occurs in the chain of
XXX_dealloc calls, which in turn do more Py_DECREFs of their own, and
which have nothing in particular to do with gc.  Approximately the
same stack depth would be hit in a Python built without gc if the user
did the same sequence of `del`s by hand to break trash cycles.

The good news is that the "trashcan" mechanism - which predates gc -
was introduced to limit call depth in the presence of some potentially
unbounded chains of dealloc calls.  So teach trashcan about the
pattern here, and the stack depth problem goes away, with or without
gc.

The bad news is that the traschcan mechanism is excruciating, a
long-time source of subtle bugs of its own :-(

Note:  without actual code to run, it's possible that trashcan is
_already_ trying to limit stack depth in this specific case, but the
stack size is too small to accommodate the largest depth of recursive
calls trashcan is willing to allow before interfering.  Or some bug
snuck into trashcan, or its invoking code, that causes it to fail to
work as intended due to some unknown detail of the code above.
There's just no way to guess without code to provoke it.


> Another take away from this is that it appears possible to cause our gc
> to go into linear recursion.

As above, it's probably not gc, but deallocation as a side effect of
Py_DECREF dropping a refcount to 0.  gc is just one way Py_DECREF can
get invoked.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PEP 587: Python Initialization Configuration

2019-03-27 Thread Victor Stinner
Hi,

Since Steve Dower asked me to write a formal PEP for my proposal of a
new C API to initialize Python, here you have!

This new PEP will be shortly rendered as HTML at:
https://www.python.org/dev/peps/pep-0587/

The Rationale might be a little bit weak at this point and there are
still 3 small open questions, but the whole PEP should give you a
better overview of my proposal than my previous email :-)

I chose to start with a new PEP rather than updating PEP 432. I didn't
feel able to just "update" the PEP 432, my proposal is different. The
main difference between my PEP 587 and Nick Coghlan's PEP 432 is that
my PEP 587 only allows to configure Python *before* its
initialization, whereas Nick wanted to give control between its
"Initializing" and "Initialized" initialization phases. Moreover, my
PEP only uses C types rather Nick wanted to use Python types.

By setting the private PyConfig._init_main field to 1, my PEP 587
allows to stop Python initialization early to get a bare minimum
working Python only with builtin types and no importlib. If I
understood correctly, with my PEP, it remains possible to *extend*
Python C API later to implement what Nick wants. Nick: please correct
me if I'm wrong :-)

Victor


PEP: 587
Title: Python Initialization Configuration
Author: Victor Stinner 
Discussions-To: python-dev@python.org
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 27-Mar-2018
Python-Version: 3.8

Abstract


Add a new C API to configure the Python Initialization providing finer
control on the whole configuration and better error reporting.


Rationale
=

Python is highly configurable but its configuration evolved organically:
configuration parameters is scattered all around the code using
different ways to set them (mostly global configuration variables and
functions).  A straightforward and reliable way to configure Python is
needed. Some configuration parameters are not accessible from the C API,
or not easily.

The C API of Python 3.7 Initialization takes ``wchar_t*`` strings as
input whereas the Python filesystem encoding is set during the
initialization.


Python Initialization C API
===

This PEP proposes to add the following new structures, functions and
macros.

New structures (4):

* ``PyConfig``
* ``PyInitError``
* ``PyPreConfig``
* ``PyWideCharList``

New functions (8):

* ``Py_PreInitialize(config)``
* ``Py_PreInitializeFromArgs(config, argc, argv)``
* ``Py_PreInitializeFromWideArgs(config, argc, argv)``
* ``Py_InitializeFromConfig(config)``
* ``Py_InitializeFromArgs(config, argc, argv)``
* ``Py_InitializeFromWideArgs(config, argc, argv)``
* ``Py_UnixMain(argc, argv)``
* ``Py_ExitInitError(err)``

New macros (6):

* ``Py_INIT_OK()``
* ``Py_INIT_ERR(MSG)``
* ``Py_INIT_USER_ERR(MSG)``
* ``Py_INIT_NO_MEMORY()``
* ``Py_INIT_EXIT(EXITCODE)``
* ``Py_INIT_FAILED(err)``


PyWideCharList
--

``PyWideCharList`` is a list of ``wchar_t*`` strings.

Example to initialize a string from C static array::

static wchar_t* argv[2] = {
L"-c",
L"pass",
};
PyWideCharList config_argv = PyWideCharList_INIT;
config_argv.length = Py_ARRAY_LENGTH(argv);
config_argv.items = argv;

``PyWideCharList`` structure fields:

* ``length`` (``Py_ssize_t``)
* ``items`` (``wchar_t**``)

If *length* is non-zero, *items* must be non-NULL and all strings must
be non-NULL.

.. note::
   The "WideChar" name comes from the existing Python C API. Example:
   ``PyUnicode_FromWideChar(const wchar_t *str, Py_ssize_t size)``.

PyInitError
---

``PyInitError`` is a structure to store an error message or an exit code
for the Python Initialization.

Example::

PyInitError alloc(void **ptr, size_t size)
{
*ptr = PyMem_RawMalloc(size);
if (*ptr == NULL) {
return Py_INIT_NO_MEMORY();
}
return Py_INIT_OK();
}

int main(int argc, char **argv)
{
void *ptr;
PyInitError err = alloc(&ptr, 16);
if (Py_INIT_FAILED(err)) {
Py_ExitInitError(err);
}
PyMem_Free(ptr);
return 0;
}

``PyInitError`` fields:

* ``exitcode`` (``int``): if greater or equal to zero, argument passed to
  ``exit()``
* ``msg`` (``const char*``): error message
* ``prefix`` (``const char*``): string displayed before the message,
  usually rendered as ``prefix: msg``.
* ``user_err`` (int): if non-zero, the error is caused by the user
  configuration, otherwise it's an internal Python error.

Macro to create an error:

* ``Py_INIT_OK()``: success
* ``Py_INIT_NO_MEMORY()``: memory allocation failure (out of memory)
* ``Py_INIT_ERR(MSG)``: Python internal error
* ``Py_INIT_USER_ERR(MSG)``: error caused by user configuration
* ``Py_INIT_EXIT(STATUS)``: exit Python with the specified status

Other macros and functions:

* ``Py_INIT_FAILED(err)``: Is the result an error or an exit?
* ``Py_ExitInitError(err)``: call ``exit(status)`` for
  an error c

Re: [Python-Dev] New Python Initialization API

2019-03-27 Thread Victor Stinner
Le mer. 27 mars 2019 à 19:35, Alexander Belopolsky
 a écrit :
> Would you consider making _Py_UnixMain public as well?
>
> It is useful for high level embedding and not trivial for 3rd parties to 
> reimplement.

Right, Py_Main() is causing a lot of practice issues, especially
mojibake because of the C locale coercion (PEP 538) and UTF-8 Mode
(PEP 540): both added in Python 3.7. I added that to the Rationale of
my PEP 587.

I just fixed the mojibake issue in Python 3.8 by disabling C locale
coercion and UTF-8 Mode by default. I'm not sure if nor how Python 3.7
should be fixed in a minor 3.7.x release.

Making _Py_UnixMain() public has already been discussed here:
https://discuss.python.org/t/adding-char-based-apis-for-unix/916

My PEP 587 allows to pass command line arguments as bytes (char*) or
Unicode (wchar_t*).

Ok, I just added Py_UnixMain() to the PEP (just make it part of the public API).

Victor
-- 
Night gathers, and now my watch begins. It shall not end until my death.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] New Python Initialization API

2019-03-27 Thread Victor Stinner
Ah, I forgot to say that a major enhancement for the implementation is
that I wrote a lot of new unit tests for the existing Python
Initialization API. Python 3.7 has most of these tests. I wrote even
more tests for my new private initialization API ;-)

I wrote these tests to specify and validate the priority between the
different ways to configuration Python and "rules" (a parameter
setting other parameters):
https://github.com/python/peps/blob/master/pep-0587.rst#priority-and-rules

Victor

Le mer. 27 mars 2019 à 18:48, Victor Stinner  a écrit :
>
> Hi,
>
> I would like to add a new C API to initialize Python. I would like
> your opinion on the whole API before making it public. The code is
> already implemented. Doc of the new API:
>
>https://pythondev.readthedocs.io/init_config.html
>
>
> To make the API public, _PyWstrList, _PyInitError, _PyPreConfig,
> _PyCoreConfig and related functions should be made public.
>
> By the way, I would suggest to rename "_PyCoreConfig" to just
> "PyConfig" :-) I don't think that "core init" vs "main init" is really
> relevant: more about that below.
>
>
> Let's start with two examples using the new API.
>
> Example of simple initialization to enable isolated mode:
>
> _PyCoreConfig config = _PyCoreConfig_INIT;
> config.isolated = 1;
>
> _PyInitError err = _Py_InitializeFromConfig(&config);
> if (_Py_INIT_FAILED(err)) {
> _Py_ExitInitError(err);
> }
> /* ... use Python API here ... */
> Py_Finalize();
>
> Example using the pre-initialization to enable the UTF-8 Mode (and use the
> "legacy" Py_Initialize() function):
>
> _PyPreConfig preconfig = _PyPreConfig_INIT;
> preconfig.utf8_mode = 1;
>
> _PyInitError err = _Py_PreInitialize(&preconfig);
> if (_Py_INIT_FAILED(err)) {
> _Py_ExitInitError(err);
> }
>
> /* at this point, Python will only speak UTF-8 */
>
> Py_Initialize();
> /* ... use Python API here ... */
> Py_Finalize();
>
> Since November 2017, I'm refactoring the Python Initialization code to
> cleanup the code and prepare a new ("better") API to configure Python
> Initialization. I just fixed the last issues that Nick Coghlan asked
> me to fix (add a pre-initialization step: done, fix mojibake: done).
> My work is inspired by Nick Coghlan's PEP 432, but it is not
> implementing it directly. I had other motivations than Nick even if we
> are somehow going towards the same direction.
>
> Nick wants to get a half-initialized Python ("core init"), configure
> Python using the Python API and Python objects, and then finish the
> implementation ("main init").
>
> I chose a different approach: put *everything* into a single C
> structure (_PyCoreConfig) using C types. Using the structure, you
> should be able to do what Nick wanted to do, but with C rather than
> Python. Nick: please tell me if I'm wrong :-)
>
> This work is also connected to Eric Snow's work on sub-interpreters
> (PEP 554) and moving global variables into structures. For example,
> I'm using his _PyRuntime structure to store a new "preconfig" state
> (pre-initialization configuration, more about that below).
>
> In November 2017, when I started to work on the Python Initialization
> (bpo-32030), I identified the following problems:
>
> * Many parts of the code were interdependent
> * Code executed early in Py_Main() used the Python API before the Python API
>   was fully initialized. Like code parsing -W command line option which
>   used PyUnicode_FromWideChar() and PyList_Append().
> * Error handling used Py_FatalError() which didn't let the caller to decide
>   how to handle the error. Moreover, exit() was used to exit Python,
> whereas libpython shouldn't do that: a library should not exit the
> whole process! (imagine when Python is embedded inside an application)
>
> One year and a half later, I implemented the following solutions:
>
> * Py_Main() and Py_Initialize() code has been reorganized to respect
>   priorities between global configuration variables (ex:
>   Py_IgnoreEnvironmentFlag), environment variables (ex: PYTHONPATH), command
>   line arguments (ex: -X utf8), configuration files (ex: pyenv.cfg), and the
>   new _PyPreConfig and _PyCoreConfig structures which store the whole
>   configuration.
> * Python Initialization no longer uses the Python API but only C types
>   like wchar_t* strings, a new _PyWstrList structure and PyMem_RawMalloc()
>   memory allocator (PyMem_Malloc() is no longer used during init).
> * The code has been modified to use a new _PyInitError structure. The caller
>   of the top function gets control to cleanup everything before handling the
>   error (display a fatal error message or simply exit Python).
>
> The new _PyCoreConfig structure has the top-priority and provides a single
> structure for all configuration parameters.
>
> It becomes possible to override the code computing the "path configuration"
> like sys.path to fully control where Python looks to import modules. I

[Python-Dev] Mistake in 3.7.3 Changelog

2019-03-27 Thread Dima Tisnek
Hi list,

Sorry, I'm not sure where to post this.

The Changelog reads:

bpo-12477: Fix bug in parsermodule when parsing a state in a DFA that
has two or more arcs with labels of the same type. Patch by Pablo
Galindo.

The `12477` is actually a master github pull request number, not a
Python bug number.

Correct BPO is https://bugs.python.org/issue36256

Cheers,
d
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Removing PendingDeprecationWarning

2019-03-27 Thread Inada Naoki
On Thu, Mar 28, 2019 at 12:26 AM Steve Dower  wrote:
>
[snip]
> 2. Do we want everyone else to stop using it for their own purposes?
[snip]
>
> The second question is harder to answer, and in the absence of input
> from those who are already using it (or the absence of evidence that
> nobody else is using it), the best we can do is evaluate how much of a
> maintenance burden the class is.
>
> In my opinion, it is a very low maintenance burden, and a very low
> cognitive burden on users, and so the cost of deprecating it on
> third-parties who are using it vastly outweighs the cost of leaving it
> alone.

As of my personal experience,  I used PendingDeprecationWarning
because it was convention, not because it is useful.

I didn't know "right way" to chose DeprecationWarning or
PendingDeprecationWarning.
So I need to survey convention in CPython.

I think I'm not only alone.  Many developers may pay costs:

1. Confused by two warning class.
2. Survey convention
3. Follow the convention (replace PendingDeprecationWarning to
DeprecationWarning in N-1 release)

>
> If someone can show that either no third-parties are using it, or all
> those that do will probably never explicitly support Python 3.8 or
> later, or all those that do would prefer to stop using it, then I'll
> happily change my mind here. But right now, it seems like deprecating it
> will cause an unknown amount of churn for minimal benefit.
>

Even though "document only" deprecation?
I don't propose raising DeprecationWarning for use of PendingDeprecationWarning.

If you dislike document it as ".. deprecated:: 3.8", I'm OK to use "..
note::" directive.


> At most, I'd document it as "this will probably not survive to the next
> major change release, even though we aren't planning to do one yet"
> (much like the Py_UNICODE APIs). Ironically, PendingDeprecationWarning
> seems a pretty accurate way of indicating this state.
>
> Cheers,
> Steve

I think it is still confusing.  In case of Py_UNICODE, there are 10+ years until
"next major change release."  But it's not true for everytime.  If
there are only
two years until "next major version", we should absolutely use
DeprecationWarning.

And we used "document only deprecation" instead of PendingDeprecationWarning.
For example, array('u') have not raised PendingDeprecationWarning for long time.
Only document says "Deprecated since version 3.3, will be removed in
version 4.0." [1]

[1] https://docs.python.org/3/library/array.html

I prefer document only deprecation to PendingDeprecationWarning for somehting
"It will not removed in foreseeable future.  But it will probably
removed in the future."

Note that -Wd and testing tool enable both of PendingDeprecationWarning and
DeprecationWarning.  If we use PendingDeprecationWarning for them, it
will be too noisy.


I don't think it's worth enough to try "Make PendingDeprecationWarning
useful again!".
I want to document "PendingDeprecationWarning is not useful anymore".

-- 
Inada Naoki  
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Mistake in 3.7.3 Changelog

2019-03-27 Thread Ned Deily
On Mar 27, 2019, at 21:59, Dima Tisnek  wrote:
> The Changelog reads:
> 
> bpo-12477: Fix bug in parsermodule when parsing a state in a DFA that
> has two or more arcs with labels of the same type. Patch by Pablo
> Galindo.
> 
> The `12477` is actually a master github pull request number, not a
> Python bug number.
> 
> Correct BPO is https://bugs.python.org/issue36256

Thanks for the report!  I'll see that it gets fixed.

--
  Ned Deily
  n...@python.org -- []

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Mistake in 3.7.3 Changelog

2019-03-27 Thread Ned Deily
On Mar 27, 2019, at 22:37, Ned Deily  wrote:
> On Mar 27, 2019, at 21:59, Dima Tisnek  wrote:
>> Correct BPO is https://bugs.python.org/issue36256
> Thanks for the report!  I'll see that it gets fixed.

https://github.com/python/cpython/pull/12600

There were also a couple more in master/3.8:
https://github.com/python/cpython/pull/12599

The on-line docs for 3.7 and dev should reflect the changes within a few hours.

--
  Ned Deily
  n...@python.org -- []

___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] New Python Initialization API

2019-03-27 Thread Stephen J. Turnbull
Victor Stinner writes:

 > I just fixed the mojibake issue in Python 3.8 by disabling C locale
 > coercion and UTF-8 Mode by default. I'm not sure if nor how Python 3.7
 > should be fixed in a minor 3.7.x release.

That sounds like a potential regression.  Those two features were
added *and turned on by default* (which really means "if you detect
LC_TYPE=C, coerce") to relieve previously existing mojibake/
UnicodeError issues due to ASCII-only environments that are difficult
to configure (such as containers).  Turning them on by default was the
controversial part -- it was known that on or off, some environments
would have problems, and that's why they needed PEPs.  Do those issues
return now?  If so, where is the PEP rationale for defaulting to "on"
faulty?




___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 556 threaded garbage collection & linear recursion in gc

2019-03-27 Thread Gregory P. Smith
Good point, I hadn't considered that it was regular common ref count 0
dealloc chaining.  The processes unfortunately didn't have faulthandler
enabled so there wasn't much info from where in the python code it happened
(now fixed).  I'll see if anything looks particularly unusual next time I
hear of such a report.

-G

On Wed, Mar 27, 2019, 5:38 PM Tim Peters  wrote:

> [Gregory P. Smith ]
> > ...
> > A situation came up the other day where I believe this could've helped.
> >
> > Scenario (admittedly not one most environments run into): A Python
> process
> > with a C++ extension module implementing a threaded server (threads
> > spawned by C++) that could call back into CPython within server request
> > handlers.  (ie: how all threaded servers tend to work regardless of core
> > loop implementation language)
> >
> > Python code in the application had done something (unknown to me, I
> > didn't dive into their code) that built up large enough presumably nested
> > or recursive data structures that the garbage collector, when triggered,
> > would wind up in very deep recursion.  This caused a stack overflow
> >  as the C++ spawned threads were only being given a 256k stack (to
> > conserve virtual address space - there can potentially be a _ton_ of
> > threads in this code).
> >
> > That had a C++ stack trace 1000+ levels deep repeating the pattern of
> >
> > ...
> > @ 0x564d59bd21de 32  func_dealloc
> > @ 0x564d59bce0c1 32  cell_dealloc
> > @ 0x564d5839db41 48  tupledealloc
> > @ 0x564d59bd21de 32  func_dealloc
> > @ 0x564d59bce0c1 32  cell_dealloc
> > @ 0x564d5839db41 48  tupledealloc
> > ...
> >
> > If our gc were done on a thread of its own spawned by Python, with a
> typical
> > normal larger default stack size (8mb) this would've been less likely
> > to trigger a crash (though obviously still possible if the recursion is
> linear).
>
> Just noting that gc is probably a red herring in that scenario.  gc
> (cleverly!) determines the set of trash objects without needing any
> recursive graph crawls.  And gc doesn't deallocate anything - not
> directly.  It simply applies Py_DECREF to trash objects, once for each
> PyObject* found pointing to them.  _If_ deallocation occurs as a
> result, it's the same as if the user had done `del` on the appropriate
> object manually.  The recursion then occurs in the chain of
> XXX_dealloc calls, which in turn do more Py_DECREFs of their own, and
> which have nothing in particular to do with gc.  Approximately the
> same stack depth would be hit in a Python built without gc if the user
> did the same sequence of `del`s by hand to break trash cycles.
>
> The good news is that the "trashcan" mechanism - which predates gc -
> was introduced to limit call depth in the presence of some potentially
> unbounded chains of dealloc calls.  So teach trashcan about the
> pattern here, and the stack depth problem goes away, with or without
> gc.
>
> The bad news is that the traschcan mechanism is excruciating, a
> long-time source of subtle bugs of its own :-(
>
> Note:  without actual code to run, it's possible that trashcan is
> _already_ trying to limit stack depth in this specific case, but the
> stack size is too small to accommodate the largest depth of recursive
> calls trashcan is willing to allow before interfering.  Or some bug
> snuck into trashcan, or its invoking code, that causes it to fail to
> work as intended due to some unknown detail of the code above.
> There's just no way to guess without code to provoke it.
>
>
> > Another take away from this is that it appears possible to cause our gc
> > to go into linear recursion.
>
> As above, it's probably not gc, but deallocation as a side effect of
> Py_DECREF dropping a refcount to 0.  gc is just one way Py_DECREF can
> get invoked.
>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 556 threaded garbage collection & linear recursion in gc

2019-03-27 Thread Tim Peters
[Gregory P. Smith ]
> Good point, I hadn't considered that it was regular common ref
> count 0 dealloc chaining.

It pretty much has to be whenever you see a chain of XXX_dealloc
routines in a stack trace.  gcmodule.c never even looks at a
tp_dealloc slot directly, let alone directly invoke a deallocation
method.  That all happens indirectly, as a result of what Py_DECREF
does.  Then once you're first inside one tp_dealloc method, gc is
completely irrelevant - it's that tp_dealloc for the top-level
container does its own Py_DECREF on a contained container, which in
turn can do _its_ own Py_DECREF on one of its contained containers
 etc.  You can get an arbitrarily deep stack of XXX_dealloc calls
then, and there's really no other way to get that.

BTW,  "container" here is used in a very broad C-level sense, not a
high-level Python sense:  any PyObject that contains a pointer to a
PyObject is "a container" in the intended sense.

> The processes unfortunately didn't have faulthandler enabled so there wasn't
> much info from where in the python code it happened (now fixed).

It's quite possible that the top-level container was Py_DECREF'ed by
code in gcmodule.c.  But gc gets blamed at first for a lot of stuff
that's not actually its fault ;-)

>  I'll see if anything looks particularly unusual next time I hear of such a 
> report.

The trashcan mechanism is the one and only hack in the code intended
to stop unbounded XXX_dealloc stacks, so that's what needs looking at.
Alas, it's hard to work with because it's so very low-level, and
there's nothing portable that can be relied on about stack sizes or
requirements across platforms or compilers.

Some possibilities:

- The trashcan code is buggy.

- The  maximum container dealloc stack depth trashcan intends to allow
(PyTrash_UNWIND_LEVEL = 50) is too large for the C stack a thread gets
under this app on this platform using this compiler.

- One or more of the specific container types involved in this app's
dealloc chain doesn't use the trashcan gimmick at all, so is invisible
to trashcan's count of how deep the call stack has gotten.

For example, cell_dealloc was in your stack trace, but I see no use of
trashcan code in that function (Py_TRASHCAN_SAFE_BEGIN /
Py_TRASHCAN_SAFE_END).  So the trashcan hack has no idea that
cell_dealloc calls are on the stack.

And likewise for func_dealloc.- looks like calls to that are also
invisible to the trashcan.

tupledealloc is cool, though.

IIRC, Christian Tismer introduced the trashcan because code only he
wrote ;-) was blowing the stack when very deeply nested lists and/or
tuples became trash.

>From a quick scan of the current code, looks like it was later added
to only a few types that aren't container types in the Python sense.

Which may or may not matter here.  Your stack trace showed a
tupledealloc in one of every three slots, so even if two of every
three slots were invisible to the traschcan, the call stack "should
have been" limited to a maximum of about PyTrash_UNWIND_LEVEL  * 3 =
150 XXX_dealloc functions.  But you saw a stack 1000+ levels deep.  So
something else that isn't immediately apparent is also going on.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com