In asyncio, does the event_loop still running after run_until_complete returned?

2018-04-02 Thread jfong
I am new to the asyncio subject, just trying to figure out how to use it. Below 
is the script I use for testing:
-
# asyncio_cancel_task2.py

import asyncio

@asyncio.coroutine
def task_func():
print('in task_func, sleeping')
try:
yield from asyncio.sleep(1)
except asyncio.CancelledError:
print('task_func was canceled')
raise
print('return result')
return 'the result'

def task_canceller(task):
task.cancel()
print('canceled the task')

@asyncio.coroutine
def main(loop):
print('first, scheduling a task')
task = loop.create_task(task_func())
print('second, scheduling its cancellation')
loop.call_later(0.5, task_canceller, task)
try:
print('waiting task to complete')
yield from task
except asyncio.CancelledError:
print('main() also sees task as canceled')


event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main(event_loop))
finally:
print('wait 3 seconds before closing event_loop')
asyncio.sleep(3)
print('event_loop was closed')
event_loop.close()
---

It schedules two tasks, the task_func and the task_canceller, in main. Before 
the task_func completed, the task_canceller was fired to cancel it. Hence its 
output below seems reasonable.

D:\Works\Python>py
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio_cancel_task2
first, scheduling a task
second, scheduling its cancellation
waiting task to complete
in task_func, sleeping
canceled the task
task_func was canceled
main() also sees task as canceled
wait 3 seconds before closing event_loop
event_loop was closed
>>>

Then, I changed the call_later delay from 0.5 to 1.5, expect it to be called 
after the task_func completed and before the event loop closed. The output 
seems not quite right. Why the task_canceller hasn't been called?

>>> import asyncio_cancel_task2
first, scheduling a task
second, scheduling its cancellation
waiting task to complete
in task_func, sleeping
return result
wait 3 seconds before closing event_loop
event_loop was closed
>>>

Best Regards,
Jach Fong

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Beta release of pip version 10

2018-04-02 Thread Paul Moore
Unfortunately there was an issue in one of the release files (the CA
Certificate bundle contained Windows line endings instead of Unix line
endings) which caused crashes on older versions of MacOS. As a result
we have just released 10.0.0b2, fixing this issue.

Anyone on older MacOS versions who have had problems with the 10.0.0b1
release should upgrade to 10.0.0b2.

Thanks,
Paul

On 31 March 2018 at 12:11, Paul Moore  wrote:
> On behalf of the PyPA, I am pleased to announce that a beta release
> 10.0.0b1 of pip has just been released for testing by the community.
> We're planning on a final release in 2 weeks' time, over the weekend
> of 14/15 April.
>
> To install pip 10.0.0.b1, you can run
>
> python -m pip install --upgrade --pre pip
>
> (obviously, you should not do this in a production environment!)
>
> We would be grateful for all testing that users could do, to ensure
> that when pip 10 is released it's as solid as we can make it.
>
> Highlights of the new release:
>
> * Python 2.6 is no longer supported - if you need pip on Python 2.6,
> you should stay on pip 9, which is the last version to support Python
> 2.6.
> * Support for PEP 518, which allows projects to specify what packages
> they require in order to build from source. (PEP 518 support is
> currently limited, with full support coming in future versions - see
> the documentation for details).
> * Significant improvements in Unicode handling for non-ASCII locales on 
> Windows.
> * A new "pip config" command.
> * The default upgrade strategy has become "only-if-needed"
> * Many bug fixes and minor improvements.
>
> In addition, the previously announced reorganisation of pip's
> internals has now taken place. Unless you are the author of code that
> imports the pip module (or a user of such code), this change will not
> affect you. If you are, please report the issue to the author of the
> affected code (refer them to
> https://mail.python.org/pipermail/distutils-sig/2017-October/031642.html
> for the details of the announcement).
>
> Please note that there is a minor issue with the NEWS file for this
> release - the new features in 10.0.0b1 are reported as being for
> "9.0.3 (2018-03-31)".
>
> If you discover any bugs while testing the new release, please report
> them at https://github.com/pypa/pip/issues.
>
> Thanks to everyone who put so much effort into the new release. Many
> of the contributions came from community members, whether in the form
> of code, participation in design discussions, or bug reports. The pip
> development team is extremely grateful to everyone in the community
> for their contributions.
>
> Thanks,
> Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: In asyncio, does the event_loop still running after run_until_complete returned?

2018-04-02 Thread Ian Kelly
On Mon, Apr 2, 2018 at 5:32 AM,   wrote:
> I am new to the asyncio subject, just trying to figure out how to use it. 
> Below is the script I use for testing:
> -
> # asyncio_cancel_task2.py
>
> import asyncio
>
> @asyncio.coroutine
> def task_func():
> print('in task_func, sleeping')
> try:
> yield from asyncio.sleep(1)
> except asyncio.CancelledError:
> print('task_func was canceled')
> raise
> print('return result')
> return 'the result'
>
> def task_canceller(task):
> task.cancel()
> print('canceled the task')
>
> @asyncio.coroutine
> def main(loop):
> print('first, scheduling a task')
> task = loop.create_task(task_func())
> print('second, scheduling its cancellation')
> loop.call_later(0.5, task_canceller, task)
> try:
> print('waiting task to complete')
> yield from task
> except asyncio.CancelledError:
> print('main() also sees task as canceled')
>
>
> event_loop = asyncio.get_event_loop()
> try:
> event_loop.run_until_complete(main(event_loop))
> finally:
> print('wait 3 seconds before closing event_loop')
> asyncio.sleep(3)

This won't actually wait 3 seconds. It just instantiates a sleep
coroutine and then discards it. Inside the event loop you would need
to await or yield from it. Outside the event loop, in order to sleep
you have to block the thread, e.g. using time.sleep. That said, there
is no reason to wait before closing the event loop.

> print('event_loop was closed')
> event_loop.close()
> ---
>
> It schedules two tasks, the task_func and the task_canceller, in main. Before 
> the task_func completed, the task_canceller was fired to cancel it. Hence its 
> output below seems reasonable.
>
> D:\Works\Python>py
> Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit 
> (Intel)] on win32
> Type "help", "copyright", "credits" or "license" for more information.
 import asyncio_cancel_task2
> first, scheduling a task
> second, scheduling its cancellation
> waiting task to complete
> in task_func, sleeping
> canceled the task
> task_func was canceled
> main() also sees task as canceled
> wait 3 seconds before closing event_loop
> event_loop was closed

>
> Then, I changed the call_later delay from 0.5 to 1.5, expect it to be called 
> after the task_func completed and before the event loop closed. The output 
> seems not quite right. Why the task_canceller hasn't been called?
>
 import asyncio_cancel_task2
> first, scheduling a task
> second, scheduling its cancellation
> waiting task to complete
> in task_func, sleeping
> return result
> wait 3 seconds before closing event_loop
> event_loop was closed


Because, as your thread title suggests, after run_until_complete
returns, the event loop is not running. How could it? It needs a
thread to run on, but it doesn't create one, so whenever it returns
from running it is relinquishing the thread and can't do anything
unless it gets it back, since that thread is now running outer code.
If you want to, you can restart the event loop by calling one of the
run methods again; everything that was previously scheduled and
everything that was scheduled after it stopped will remain scheduled.

So, you can't have the event loop running in the background while also
doing things within the code that started the loop in the same thread.
If you really want this you can create a second thread to run the
event loop on. However it is usually better to do that sort of thing
within a coroutine running in the event loop, since single-threaded
concurrency is the whole point of asyncio. The code that started the
event loop will then only be used for cleanup after it terminates.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: In asyncio, does the event_loop still running after run_until_complete returned?

2018-04-02 Thread jfong
Ian於 2018年4月2日星期一 UTC+8下午9時37分08秒寫道:
> On Mon, Apr 2, 2018 at 5:32 AM,   wrote:
> > I am new to the asyncio subject, just trying to figure out how to use it. 
> > Below is the script I use for testing:
> > -
> > # asyncio_cancel_task2.py
> >
> > import asyncio
> >
> > @asyncio.coroutine
> > def task_func():
> > print('in task_func, sleeping')
> > try:
> > yield from asyncio.sleep(1)
> > except asyncio.CancelledError:
> > print('task_func was canceled')
> > raise
> > print('return result')
> > return 'the result'
> >
> > def task_canceller(task):
> > task.cancel()
> > print('canceled the task')
> >
> > @asyncio.coroutine
> > def main(loop):
> > print('first, scheduling a task')
> > task = loop.create_task(task_func())
> > print('second, scheduling its cancellation')
> > loop.call_later(0.5, task_canceller, task)
> > try:
> > print('waiting task to complete')
> > yield from task
> > except asyncio.CancelledError:
> > print('main() also sees task as canceled')
> >
> >
> > event_loop = asyncio.get_event_loop()
> > try:
> > event_loop.run_until_complete(main(event_loop))
> > finally:
> > print('wait 3 seconds before closing event_loop')
> > asyncio.sleep(3)
> 
> This won't actually wait 3 seconds. It just instantiates a sleep
> coroutine and then discards it. Inside the event loop you would need
> to await or yield from it. Outside the event loop, in order to sleep
> you have to block the thread, e.g. using time.sleep. That said, there
> is no reason to wait before closing the event loop.
> 
Thank you for reminding my mistake. I shouldn't use asyncio.sleep there.

> > print('event_loop was closed')
> > event_loop.close()
> > ---
> >
> > It schedules two tasks, the task_func and the task_canceller, in main. 
> > Before the task_func completed, the task_canceller was fired to cancel it. 
> > Hence its output below seems reasonable.
> >
> > D:\Works\Python>py
> > Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 
> > bit (Intel)] on win32
> > Type "help", "copyright", "credits" or "license" for more information.
>  import asyncio_cancel_task2
> > first, scheduling a task
> > second, scheduling its cancellation
> > waiting task to complete
> > in task_func, sleeping
> > canceled the task
> > task_func was canceled
> > main() also sees task as canceled
> > wait 3 seconds before closing event_loop
> > event_loop was closed
> 
> >
> > Then, I changed the call_later delay from 0.5 to 1.5, expect it to be 
> > called after the task_func completed and before the event loop closed. The 
> > output seems not quite right. Why the task_canceller hasn't been called?
> >
>  import asyncio_cancel_task2
> > first, scheduling a task
> > second, scheduling its cancellation
> > waiting task to complete
> > in task_func, sleeping
> > return result
> > wait 3 seconds before closing event_loop
> > event_loop was closed
> 
> 
> Because, as your thread title suggests, after run_until_complete
> returns, the event loop is not running. How could it? It needs a
> thread to run on, but it doesn't create one, so whenever it returns
> from running it is relinquishing the thread and can't do anything
> unless it gets it back, since that thread is now running outer code.
> If you want to, you can restart the event loop by calling one of the
> run methods again; everything that was previously scheduled and
> everything that was scheduled after it stopped will remain scheduled.
> 
I also do a quick check, with call_later delay keeps at 1.5, to see what the 
event loop status is after run_until_complete returns. Strangely, both 
is_closed and is_running return a False.

try:
event_loop.run_until_complete(main(event_loop))
finally:
print(event_loop.is_closed())  # print(event_loop.is_running())


It's not closed(OK, the event_loop.close hasn't be executed yet) and neither 
it's running(quote your words, "it is relinquishing the thread and can't do 
anything")!

Event loop, coroutine, task, yield from, ...etc, all these words' interaction 
makes asyncio has more mystery than I think:-(

> So, you can't have the event loop running in the background while also
> doing things within the code that started the loop in the same thread.
> If you really want this you can create a second thread to run the
> event loop on. However it is usually better to do that sort of thing
> within a coroutine running in the event loop, since single-threaded
> concurrency is the whole point of asyncio. The code that started the
> event loop will then only be used for cleanup after it terminates.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: In asyncio, does the event_loop still running after run_until_complete returned?

2018-04-02 Thread Ian Kelly
On Mon, Apr 2, 2018 at 9:01 PM,   wrote:
> I also do a quick check, with call_later delay keeps at 1.5, to see what the 
> event loop status is after run_until_complete returns. Strangely, both 
> is_closed and is_running return a False.
>
> try:
> event_loop.run_until_complete(main(event_loop))
> finally:
> print(event_loop.is_closed())  # print(event_loop.is_running())
> 
>
> It's not closed(OK, the event_loop.close hasn't be executed yet) and neither 
> it's running(quote your words, "it is relinquishing the thread and can't do 
> anything")!

Correct.

> Event loop, coroutine, task, yield from, ...etc, all these words' interaction 
> makes asyncio has more mystery than I think:-(

If it helps to demystify things, here is a simplified version of what
run_until_complete actually does:

def run_until_complete(self, future):
"""Run until the Future is done.

If the argument is a coroutine, it is wrapped in a Task.

Return the Future's result, or raise its exception.
"""
   future = tasks.ensure_future(future, loop=self)
future.add_done_callback(self.stop)
self.run_forever()
future.remove_done_callback(self.stop)
return future.result()

def run_forever(self):
"""Run until stop() is called."""
   try:
events._set_running_loop(self)
while True:
self._run_once()
if self._stopping:
break
finally:
self._stopping = False
events._set_running_loop(None)

def stop(self):
"""Stop running the event loop.

Every callback already scheduled will still run.  This simply informs
run_forever to stop looping after a complete iteration.
"""
self._stopping = True

run_until_complete sets up a callback on its argument that will stop
the loop, and then it calls run_forever. The key thing to note is that
inside run_forever, there is an actual while loop. This is the heart
of the "event loop". On every iteration of the loop, it checks what
callbacks need to be called and what coroutines need to be resumed.
Then it checks whether it should stop, by breaking out of the loop.

In order for run_until_complete to return, run_forever must first
return. In order for run_forever to return, the loop in its body must
be broken out of. Therefore, when run_forever or run_until_complete
return, the loop can no longer be running. This is all that I mean
when I say it relinquishes the thread: the function that contains the
loop had to return, and therefore the loop is stopped.
-- 
https://mail.python.org/mailman/listinfo/python-list