[Python-Dev] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Victor Stinner
Hi,

tzickel reported a reference cycle bug in multiprocessing which keeps
threads and processes alive:

   https://bugs.python.org/issue34172

He wrote a fix which has been merged in 3.6, 3.7 and master branches.
But Pablo Galindo noticed that the fix breaks the following code (he
added "I found the weird code in the example in several projects."):

import multiprocessing

def the_test():
print("Begin")
for x in multiprocessing.Pool().imap(int,
["4", "3"]):
print(x)
print("End")

the_test()

Pablo proposed to add a strong reference to the Pool from
multiprocessing iterators:
https://bugs.python.org/issue35378

I blocked his pull request because I see this change as a risk of new
reference cycles. Since we are close to 3.6 and 3.7 releases, I
decided to revert the multiprocessing fix instead.

Pablo's issue35378 evolved to add a weak reference in iterators to try
to detect when the Pool is destroyed: raise an exception from the
iterator, if possible.

Then a discussion started on how the multiprocessing API is supposed
to be used and about the lifetime of multiprocessing objects.

I would prefer to make the multiprocessing API stricter: Python
shouldn't try to guess how long an object is going to live. The API
user has to *explicitly* release resources.

tzickel noted that the documentations says:

   "When the pool object is garbage collected terminate() will be
called immediately."

And that multiprocessing rely on the garbage collector to release
resources, especially using multiprocessing.util.Finalize tool:

class Finalize(object):
'''
Class which supports object finalization using weakrefs
'''
def __init__(self, obj, callback, ...):
...
if obj is not None:
self._weakref = weakref.ref(obj, self)
else:
assert exitpriority is not None
...
_finalizer_registry[self._key] = self

I propose to start to emit ResourceWarning in Python 3.8 when objects
are not released explicitly. I wrote a first change to emit
ResourceWarning in the Pool object:

   https://bugs.python.org/issue35424
   https://github.com/python/cpython/pull/10974

By the way, I'm surprised that "with pool:" doesn't release all
resources. An additional "pool.join()" is needed to ensure that all
resources are released. It's a little bit surprising to have to emit a
ResourceWarning if join() has not been called, even if the code uses
"with pool:".

I don't know well the multiprocessing API, so I'm not sure in which
directions we should go: best effort to support strange legacy code
with "implicit object lifetime", or become stricter in Python 3.8?

>From a technical point of view, I would prefer to become stricter.
Relying on the garbage collector means that the code is going to
behave badly on PyPy which uses a different garbage collector
implementation :-(

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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Antoine Pitrou


Hi,

On Tue, 11 Dec 2018 15:21:31 +0100
Victor Stinner  wrote:
> 
> Pablo's issue35378 evolved to add a weak reference in iterators to try
> to detect when the Pool is destroyed: raise an exception from the
> iterator, if possible.

That's an ok fix for me.

> By the way, I'm surprised that "with pool:" doesn't release all
> resources.

That's not a problem, as long as the destructor _does_ release
resources.

> From a technical point of view, I would prefer to become stricter.

Using "with pool:" is fine, we shouldn't start raising a warning for it.

What you are proposing here starts to smell like an anti-pattern to
me.  Python _is_ a garbage-collected language, so by definition, there
_are_ going to be resources that are automatically collected when an
object disappears.  If I'm allocating a 2GB bytes object, then PyPy may
delay the deallocation much longer than CPython.  Do you propose we add
a release() method to bytes objects to avoid this issue (and emit a
warning for people who don't call release() on bytes objects)?

You can't change the language's philosophy.  We warn about open files
because those have user-visible consequences (such as unflushed
buffers, or not being able to delete the file on Windows).  If there is
no user-visible consequence to not calling join() on a Pool, then we
shouldn't warn about it.

Regards

Antoine.


___
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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Victor Stinner
Le mar. 11 déc. 2018 à 16:14, Antoine Pitrou  a écrit :
> What you are proposing here starts to smell like an anti-pattern to
> me.  Python _is_ a garbage-collected language, so by definition, there
> _are_ going to be resources that are automatically collected when an
> object disappears.  If I'm allocating a 2GB bytes object, then PyPy may
> delay the deallocation much longer than CPython.  Do you propose we add
> a release() method to bytes objects to avoid this issue (and emit a
> warning for people who don't call release() on bytes objects)?

We are not talking about simple strings, but processes and threads.

> You can't change the language's philosophy.  We warn about open files
> because those have user-visible consequences (such as unflushed
> buffers, or not being able to delete the file on Windows).  If there is
> no user-visible consequence to not calling join() on a Pool, then we
> shouldn't warn about it.

"user-visible consequences" are that resources are kept alive longer
than I would expect. When I use a context manager, I expect that
Python will magically releases everything for me.

For example, "with subprocess.Popen() as popen: ..." ensures that all
pipes are closed and the process completes, before we exit the block.

Another example, "with open() as fp: ..." ensures that the file
descriptor is closed before we exit the block.

I modified subprocess.Popen.__del__() in Python 3.6 to emit a
ResourceWarning if the subprocess is still running, to suggest the
developer to explicitly manage the resource (ex: call .wait()).

I prefer to explicitly manager resources like processes and threads
since they can exit with error: killed by a signal, waitpid() failure
(exit status already read by a different function), etc. I prefer to
control where the error occurs. I hate when Python logs strange error
during shutdown. Logging errors during shutdown is too late: for
example, the log triggers a new error because a stdlib module has been
cleared. That's why we need hacks like "_warn=warnings.warn" below:

class Popen(object):
...
def __del__(self, _maxsize=sys.maxsize, _warn=warnings.warn):
...
if self.returncode is None:
_warn("subprocess %s is still running" % self.pid,
  ResourceWarning, source=self)
...

Victor
___
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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Paul Moore
On Tue, 11 Dec 2018 at 15:13, Antoine Pitrou  wrote:
> On Tue, 11 Dec 2018 15:21:31 +0100
> Victor Stinner  wrote:
> >
> > Pablo's issue35378 evolved to add a weak reference in iterators to try
> > to detect when the Pool is destroyed: raise an exception from the
> > iterator, if possible.
>
> That's an ok fix for me.
>
> > By the way, I'm surprised that "with pool:" doesn't release all
> > resources.
>
> That's not a problem, as long as the destructor _does_ release
> resources.
>
> > From a technical point of view, I would prefer to become stricter.
>
> Using "with pool:" is fine, we shouldn't start raising a warning for it.
>
> What you are proposing here starts to smell like an anti-pattern to
> me.  Python _is_ a garbage-collected language, so by definition, there
> _are_ going to be resources that are automatically collected when an
> object disappears.  If I'm allocating a 2GB bytes object, then PyPy may
> delay the deallocation much longer than CPython.  Do you propose we add
> a release() method to bytes objects to avoid this issue (and emit a
> warning for people who don't call release() on bytes objects)?
>
> You can't change the language's philosophy.  We warn about open files
> because those have user-visible consequences (such as unflushed
> buffers, or not being able to delete the file on Windows).  If there is
> no user-visible consequence to not calling join() on a Pool, then we
> shouldn't warn about it.

I agree with Antoine here.

On Tue, 11 Dec 2018 15:21:31 +0100 Victor Stinner  wrote:
> The API user has to *explicitly* release resources.

That's definitely not Python's philosophy. In Python, users should not
have to worry about resource management themselves, that's the job of
the language runtime. We provide the "with" construct so that when
users *want* to manage resources explicitly (because there is an
impact outside of the Python runtime's control, for example) then they
can do so. But leaving resource management to the runtime is
completely fine.

> I propose to start to emit ResourceWarning in Python 3.8 when objects are not 
> released explicitly.

Strong -1 on this.

> I don't know well the multiprocessing API

Nor do I, but I'm against making fundamental design changes such as
you propose *without* a deep understanding of the multiprocessing API.
If you feel sufficiently strongly that the current design is wrong,
then you should understand the principles and reasons behind that
design before trying to change it.

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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Antoine Pitrou
On Tue, 11 Dec 2018 16:33:54 +0100
Victor Stinner  wrote:
> Le mar. 11 déc. 2018 à 16:14, Antoine Pitrou  a écrit :
> > What you are proposing here starts to smell like an anti-pattern to
> > me.  Python _is_ a garbage-collected language, so by definition, there
> > _are_ going to be resources that are automatically collected when an
> > object disappears.  If I'm allocating a 2GB bytes object, then PyPy may
> > delay the deallocation much longer than CPython.  Do you propose we add
> > a release() method to bytes objects to avoid this issue (and emit a
> > warning for people who don't call release() on bytes objects)?  
> 
> We are not talking about simple strings, but processes and threads.

Right, but do those have an impact on the program's correctness, or
simply on its performance (or memory consumption)?

> "user-visible consequences" are that resources are kept alive longer
> than I would expect. When I use a context manager, I expect that
> Python will magically releases everything for me.

I think there's a balancing act here: between "with pool" releasing
everything, and not taking too much time to execute the __exit__ method.
Currently, threads and processes may finish quietly between __exit__
and __del__, without adding significant latencies to your program's
execution.

> I prefer to explicitly manager resources like processes and threads
> since they can exit with error: killed by a signal, waitpid() failure
> (exit status already read by a different function), etc.

But multiprocessing.Pool manages them implicitly _by design_.  People
who want to manage processes explicitly can use the Process class
directly ;-)

Regards

Antoine.
___
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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Victor Stinner
Le mar. 11 déc. 2018 à 17:06, Antoine Pitrou  a écrit :
> > We are not talking about simple strings, but processes and threads.
>
> Right, but do those have an impact on the program's correctness, or
> simply on its performance (or memory consumption)?

Performance.

I made a similar change in the socketserver: server_close() now waits
until child processes (ForkingMixIn) and threads (ThreadingMixIn)
complete:

* https://bugs.python.org/issue31233
* https://bugs.python.org/issue31151

I added an opt-in option "block_on_close" to get Python 3.6 behavior
on server_close():

https://bugs.python.org/issue33540

I don't know if these changes are similar to my questions about
multiprocessing API, since socketserver didn't expose the list of
processes/threads and doesn't provide a method to wait until they
complete. Well... ForkingMixIn has an *undocumented*
collect_children() which is non-blocking by default (I added a
keyword-only 'blocking' parameter).


Another example: the close() method of an asyncio event loop doesn't
wait until threads/processes complete:

"asyncio: BaseEventLoop.close() shutdowns the executor without waiting
causing leak of dangling threads"
https://bugs.python.org/issue34037

It's unclear to me how this issue should be fixed.

Victor
___
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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Antoine Pitrou
On Tue, 11 Dec 2018 17:22:49 +0100
Victor Stinner  wrote:
> Le mar. 11 déc. 2018 à 17:06, Antoine Pitrou  a écrit :
> > > We are not talking about simple strings, but processes and threads.  
> >
> > Right, but do those have an impact on the program's correctness, or
> > simply on its performance (or memory consumption)?  
> 
> Performance.

Well, at least we shouldn't emit ResourceWarning for performance issues.
So if someone used "with pool:", they shouldn't get a ResourceWarning
afterwards, even if some threads are still not finished running.

> I don't know if these changes are similar to my questions about
> multiprocessing API, since socketserver didn't expose the list of
> processes/threads and doesn't provide a method to wait until they
> complete. Well... ForkingMixIn has an *undocumented*
> collect_children() which is non-blocking by default (I added a
> keyword-only 'blocking' parameter).

socketserver is not the same as a multiprocessing Pool *at all*.  The
usage will be vastly different between the two.  Just because we did
this change for socketserver is not enough of a reason to do it for
multiprocessing too.

> Another example: the close() method of an asyncio event loop doesn't
> wait until threads/processes complete:
> 
> "asyncio: BaseEventLoop.close() shutdowns the executor without waiting
> causing leak of dangling threads"
> https://bugs.python.org/issue34037

It's not a leak though, it's a resource that's collected a bit later.
It may annoy the test machinery (and this could be a reason to add
private or public APIs to help finish the threads), but it shouldn't be
an actual issue for user code.

Here as well, I think you should be careful not to introduce annoyances
(unwanted latencies) in user code.

Regards

Antoine.
___
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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Pablo Galindo Salgado
> > Pablo's issue35378 evolved to add a weak reference in iterators to try
> > to detect when the Pool is destroyed: raise an exception from the
> > iterator, if possible.

> That's an ok fix for me.

I am playing with weakreferences inside the iterator and result objects,
but this may not be enough/a complete solution. For example, take the
code of ApplyResult.get:

def get(self, timeout=None):
if self._pool() is None:   # self._pool is a weakref
raise RuntimeError("The pool is dead. Aborting") <--- new code
self.wait(timeout)

It can be that the pool is alive when we check for it (self._pool() is
None) but while
the code is waiting with no timeout (timeout=None) the pool dies,
effectively leaving the
program deadlocked with no error.

--

I agree that misusage of the pool should not be encouraged but in this
situation the fact that
this code hangs:

import multiprocessing

for x in multiprocessing.Pool().imap(int, ["4", "3"]):
print(x)


is a bit worriying because although is incorrect and an abuse of the
API, users can do this easily with
no error message other than a misterious hang. I have found this on
several places and people were
very confused because usually the interpreter throws some kind of
error indication. In my humble opinion,
we should try to avoid hanging as a consequence of the misusage, whatever we do.

Pablo
___
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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Paul Moore
On Tue, 11 Dec 2018 at 17:50, Pablo Galindo Salgado  wrote:
> I agree that misusage of the pool should not be encouraged but in this 
> situation the fact that
> this code hangs:
>
> import multiprocessing
>
> for x in multiprocessing.Pool().imap(int, ["4", "3"]):
> print(x)
>
>
> is a bit worriying because although is incorrect and an abuse of the API, 
> users can do this easily with
> no error message other than a misterious hang.

OK, so the first problem here (to me, at least) is that it's not
obvious *why* this code is incorrect and an abuse of the API. It takes
a reasonable amount of thinking about the problem to notice that the
Pool object isn't retained, but the iterator returned from imap is.
And when the pool is collected, the worker processes are terminated,
causing the hang, as the worker never sends a result back to the main
process. But it's not obvious to me why the pool is collected before
the imap method has completed.

As I understand it, originally the code worked because the pool
*didn't* call terminate() when collected. Now it does, and we have a
problem. I'm not *entirely* sure why, if the pool is terminated, the
wait in the iterator doesn't terminate immediately with some sort of
"process being waited on died" error, but let's assume there are good
reasons for that (as I mentioned before, I'm not an expert in
multiprocessing, so I'm OK with assuming that the original design,
done by people who *are* experts, is sound :-))

Your original solution would have added a strong reference back to the
pool from the iterator. At first glance, that seems like a reasonable
solution to me. Victor is worried about the "risk of new reference
cycles". But reference cycles are not a problem - we have the cyclic
GC precisely to deal with them. So I'd like to see a better
justification for rejecting that solution than "there might be
reference cycles". But in response to that, you made the iterator have
a weak reference back to the pool. That's flawed because it doesn't
prevent the pool being terminated - as you say, the deadlock is still
present.

> I have found this on several places and people were
> very confused because usually the interpreter throws some kind of error 
> indication. In my humble opinion,
> we should try to avoid hanging as a consequence of the misusage, whatever we 
> do.

I agree with this. But that implies to me that we should be holding a
strong reference to the pool,

As a (somewhat weak) analogy, consider

for n in map(int, ["1", "2"]):
print(n)

That won't fail if the list gets collected, because map keeps a
reference to the list. My intuition would be that the Pool().imap
example would hold a reference to the pool on essentially the same
basis.

The more I think about this, the more I struggle to see Victor's logic
for rejecting your original solution. And I *certainly* don't see why
this issue should justify changing the whole API to require users to
explicitly manage pool lifetimes.

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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Pablo Galindo Salgado
>
> Your original solution would have added a strong reference back to the
> pool from the iterator. At first glance, that seems like a reasonable
> solution to me. Victor is worried about the "risk of new reference
> cycles". But reference cycles are not a problem - we have the cyclic
> GC precisely to deal with them. So I'd like to see a better
> justification for rejecting that solution than "there might be
> reference cycles". But in response to that, you made the iterator have
> a weak reference back to the pool. That's flawed because it doesn't
> prevent the pool being terminated - as you say, the deadlock is still
> present.


Just to be clear: I am in favour of the strong reference, but I also
understand the "danger" (leaking the pool until the pool's generation
reaches the threshold and the gc runs) and that is the reason I was
experimenting with the weakreference.

On Tue, 11 Dec 2018 at 18:37, Paul Moore  wrote:

> On Tue, 11 Dec 2018 at 17:50, Pablo Galindo Salgado 
> wrote:
> > I agree that misusage of the pool should not be encouraged but in this
> situation the fact that
> > this code hangs:
> >
> > import multiprocessing
> >
> > for x in multiprocessing.Pool().imap(int, ["4", "3"]):
> > print(x)
> >
> >
> > is a bit worriying because although is incorrect and an abuse of the
> API, users can do this easily with
> > no error message other than a misterious hang.
>
> OK, so the first problem here (to me, at least) is that it's not
> obvious *why* this code is incorrect and an abuse of the API. It takes
> a reasonable amount of thinking about the problem to notice that the
> Pool object isn't retained, but the iterator returned from imap is.
> And when the pool is collected, the worker processes are terminated,
> causing the hang, as the worker never sends a result back to the main
> process. But it's not obvious to me why the pool is collected before
> the imap method has completed.
>
> As I understand it, originally the code worked because the pool
> *didn't* call terminate() when collected. Now it does, and we have a
> problem. I'm not *entirely* sure why, if the pool is terminated, the
> wait in the iterator doesn't terminate immediately with some sort of
> "process being waited on died" error, but let's assume there are good
> reasons for that (as I mentioned before, I'm not an expert in
> multiprocessing, so I'm OK with assuming that the original design,
> done by people who *are* experts, is sound :-))
>
> Your original solution would have added a strong reference back to the
> pool from the iterator. At first glance, that seems like a reasonable
> solution to me. Victor is worried about the "risk of new reference
> cycles". But reference cycles are not a problem - we have the cyclic
> GC precisely to deal with them. So I'd like to see a better
> justification for rejecting that solution than "there might be
> reference cycles". But in response to that, you made the iterator have
> a weak reference back to the pool. That's flawed because it doesn't
> prevent the pool being terminated - as you say, the deadlock is still
> present.
>
> > I have found this on several places and people were
> > very confused because usually the interpreter throws some kind of error
> indication. In my humble opinion,
> > we should try to avoid hanging as a consequence of the misusage,
> whatever we do.
>
> I agree with this. But that implies to me that we should be holding a
> strong reference to the pool,
>
> As a (somewhat weak) analogy, consider
>
> for n in map(int, ["1", "2"]):
> print(n)
>
> That won't fail if the list gets collected, because map keeps a
> reference to the list. My intuition would be that the Pool().imap
> example would hold a reference to the pool on essentially the same
> basis.
>
> The more I think about this, the more I struggle to see Victor's logic
> for rejecting your original solution. And I *certainly* don't see why
> this issue should justify changing the whole API to require users to
> explicitly manage pool lifetimes.
>
> 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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Nathaniel Smith
On Tue, Dec 11, 2018, 07:13 Antoine Pitrou 
> What you are proposing here starts to smell like an anti-pattern to
> me.  Python _is_ a garbage-collected language, so by definition, there
> _are_ going to be resources that are automatically collected when an
> object disappears.  If I'm allocating a 2GB bytes object, then PyPy may
> delay the deallocation much longer than CPython.  Do you propose we add
> a release() method to bytes objects to avoid this issue (and emit a
> warning for people who don't call release() on bytes objects)?
>

I know this question is rhetorical, but it does actually have a principled
answer. Memory is a special resource, because the GC has a complete picture
of memory use in the program, and if there's a danger of running out of
memory then the GC will detect that and quickly run a collection before
anyone has a chance to notice. But it doesn't know about other resources
like descriptors, threads, processes, etc., so it can't detect or prevent
unbounded leaks of these resources.

Therefore, in a classic GC-ed language, bytes() doesn't need to be
explicitly released, but all other kinds of resources do. And according to
the language spec, Python is a classic GC-ed language.

But things are complicated, because CPython isn't a classic GC-ed language,
exactly. In practice it's a sort of hybrid RAII/GC language. People
regularly write programs that on the refcount quick-release semantics for
correctness. A quick way to check: the only thing a reference cycle does is
make CPython start acting like an ordinary GC-ed language, so if you're
worrying about reference cycles, that's a strong sign that you're writing
CPython, not Python.

This puts libraries like multiprocessing in a tricky position, because some
users are writing CPython, and some are writing Python, and the two groups
have contradictory expectations for how resource management should be
handled, yet somehow we have to make both groups happy.

I don't know what multiprocessing should do here, but I certainly admire
the problem :-).

-n

>
___
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] 3.7.2rc1 and 3.6.8rc1 cutoffs ahead, last 3.6.x bugfix release!

2018-12-11 Thread Ned Deily
https://discuss.python.org/t/3-7-2rc1-and-3-6-8rc1-cutoffs-ahead-last-3-6-x-bugfix-release/510/3?u=nad


OK, thanks to a lot of hard work by many of you, I think we are ready to
start the manufacturing of **3.7.2rc1** and **3.6.8rc1**.

For the **3.7 branch**, as usual feel free to continue to merge the
usual changes appropriate for a `bugfix` branch; unless otherwise marked
and agreed on as a **release blocker** for 3.7.2 final, any new 3.7
merges will be released in 3.7.3.

For the **3.6 branch**, as announced 3.6.8 is planned to be **the last
bugfix release** for the 3.6 series; future 3.6.x releases will be as
needed and contain **only security fixes** and source only. Of course,
if any release blocker regressions show up after 3.6.8rc1, we will
consider merging fixes for them. This means that, **as of now, the 3.6
branch is no longer open to normal bugfixes**, only security fixes and
release blocker regressions fixes and only with the approval of the
release manager. Therefore, as we have done with previous branches
moving to security-fix mode, merges to the 3.6 branch on the `cpython`
GitHub repo are now restricted to the release managers. If you feel a
change to 3.6 is needed either because it is a **release blocker
regression** in 3.6.8 or because it is a **security issue**, please
ensure there is a bpo issue describing the problem, mark it as **release
blocker** priority, and submit the necessary PR. At some point, on or
after the 3.6.8 release, we will be going through the open 3.6 PRs, open
PRs with the `needs backport to 3.6` label, and bpo issues marked for
3.6 and updating or closing them as needed. **Please do not mark new PRs
with the** `needs backport to 3.6` **label** unless you feel the
proposed change meets one of the criteria above.

Thanks for your help!

--
  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] Usage of the multiprocessing API and object lifetime

2018-12-11 Thread Antoine Pitrou
On Tue, 11 Dec 2018 11:48:24 -0800
Nathaniel Smith  wrote:
> 
> I know this question is rhetorical, but it does actually have a principled
> answer. Memory is a special resource, because the GC has a complete picture
> of memory use in the program, and if there's a danger of running out of
> memory then the GC will detect that and quickly run a collection before
> anyone has a chance to notice. But it doesn't know about other resources
> like descriptors, threads, processes, etc., so it can't detect or prevent
> unbounded leaks of these resources.
> 
> Therefore, in a classic GC-ed language, bytes() doesn't need to be
> explicitly released, but all other kinds of resources do.

I would disagree here.  You may /like/ to release other kinds of
resources explicitly, but you don't /need/ to.  It is actually obvious
for things such as mutexes which, while the GC doesn't know about
them, are small system resources.  And nobody's asking Python to add a
method to deterministically destroy the mutex that's inside a Lock
object (*).
(also, calling Lock.release() already does something else :-))

Arguably, things are more complicated for things like threads and
processes.  But here we are talking not about threads and processes
themselves, but about an abstraction (the Pool object) that
is /designed/ to hide threads and processes in favour of higher level
semantics organized around the idea of task submission.  One important
characteristic here is that, when the pool is idle, those threads and
processes aren't holding important resources (user-allocated resources)
alive (**).  The idle pool just has a bookkeeping overhead.

Usually, people don't really care how exactly a Pool manages its helper
threads and worker processes (it has both at the same time), and they
are fine with the internal bookkeeping overhead.  For the people who
care (***), the Pool.join() method is there to be called.

(*) actually, it's not a mutex, it's a semaphore

(**) unless the user sets a global variable from an executing
task, which I think of as an anti-pattern :-)

(***) for example because they used the anti-pattern above :-)

Regards

Antoine.
___
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] [RELEASE] Python 3.7.2rc1 and 3.6.8rc1 now available for testing

2018-12-11 Thread Ned Deily
https://blog.python.org/2018/12/python-372rc1-and-368rc1-now-available.html


Python 3.7.2rc1 and 3.6.8rc1 are now available. 3.7.2rc1 is the release
preview of the next maintenance release of Python 3.7, the latest
feature release of Python. 3.6.8rc1 is the release preview of the next
and last maintenance release of Python 3.6, the previous feature
release of Python. Assuming no critical problems are found prior to
2018-12-20, no code changes are planned between these release
candidates and the final releases. These release candidates are
intended to give you the opportunity to test the new security and bug
fixes in 3.7.2 and 3.6.8. We strongly encourage you to test your
projects and report issues found to bugs.python.org as soon as
possible. Please keep in mind that these are preview releases and,
thus, their use is not recommended for production environments.

You can find these releases and more information here:
https://www.python.org/downloads/release/python-372rc1/
https://www.python.org/downloads/release/python-368rc1/


--
  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