Re: [Python-Dev] PEP-419: Protecting cleanup statements from interruptions

2012-04-08 Thread Paul Colomiets
Hi Antoine,

On Mon, Apr 9, 2012 at 12:06 AM, Antoine Pitrou  wrote:
>
> Hello Paul,
>
> Thanks for the PEP and the description of the various issues.
>
>> An example implementation of a SIGINT handler that interrupts safely
>> might look like::
>>
>>     import inspect, sys, functools
>>
>>     def sigint_handler(sig, frame):
>>         if inspect.getcleanupframe(frame) is None:
>>             raise KeyboardInterrupt()
>>         sys.setcleanuphook(functools.partial(sigint_handler, 0))
>
> It is not clear whether you are proposing this for the default signal
> handler, or only as an example that third-party libraries or frameworks
> could implement.
>

Only as an example. The reason is in "Modifying KeyboardInterrupt"
section under "Unresolved Issues". So it might be changed if there
is demand.

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


Re: [Python-Dev] this is why we shouldn't call it a "monotonic clock" (was: PEP 418 is too divisive and confusing and should be postponed)

2012-04-08 Thread Guido van Rossum
On Sun, Apr 8, 2012 at 5:00 PM, Victor Stinner  wrote:
>> IOW "What's good enough for sleep() is good enough for
>> user-implemented timeouts and scheduling." as a way to reach at least
>> one decision for a platform with agreed-upon cross-platform
>> characteristics that are useful.
>
> sleep() is implemented in the kernel. The kernel is notified when a
> clock is set, and so can choose how to handle time adjustement. Most
> "sleeping" functions use the system clock but don't care of clock
> adjustement.

We're going around in circles. I'm not asking what sleep does, I want
on principle a timer that does the same thing as sleep(), regardless
of how sleep() works. So if on some OS sleep() uses the same algorithm
as CLOCK_MONOTONIC_RAW, I want my timer to use that too. But if on
some other OS sleep() uses CLOCK_MONOTONIC, I want my timer there to
use that. And if on some OS sleep() is buggy and uses the time-of-day
clock, well, I wouldn't mind if my timer used the same thing.

>> I personally have a need for one potentially different clock -- to
>> measure short intervals for benchmarks and profiling. This might be
>> called time.performancetimer()?
>
> I deferred this topic because it is unclear to me if such timer has to
> count elapsed time during a sleep or not. For example, time.clock()
> does on UNIX, whereas it doesn't on Windows.

I will declare that that was a mistake in clock(), but one that's too
late to fix, because fixing it would break too many programs (those on
*nix that use it to measure CPU time, and those on Windows that use it
to measure real time).

>You may need two clocks
> for this:
>  * time.perf_counter(): high-resolution timer for benchmarking, count
> time elasped during a sleep
>  * time.process_time(): High-resolution (?) per-process timer from the
> CPU. (other possible names: time.process_cpu_time() or
> time.cpu_time())

TBH I don't need another timer that measures CPU time (not even on
Windows). In a sense, measuring CPU time is a relic from the age of
mainframes and timesharing, where CPU time was the most precious
resource (and in some cases the unit in which other resources were
expressed for accounting purposes). In modern days, it's much more
likely that the time you're measuring is somehow related to how long a
use has to wait for some result (e.g. web response times) and here
"wait time" is just as real as CPU time.

> On Windows, GetProcessTimes() has not a "high-resolution": it has a
> accuracy of 1 ms in the best case. QueryPerformanceCounter() counts
> time elapsed during a sleep, I don't know for GetProcessTimes.

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] this is why we shouldn't call it a "monotonic clock" (was: PEP 418 is too divisive and confusing and should be postponed)

2012-04-08 Thread Cameron Simpson
On 09Apr2012 02:00, Victor Stinner  wrote:
| > I personally have a need for one potentially different clock -- to
| > measure short intervals for benchmarks and profiling. This might be
| > called time.performancetimer()?
| 
| I deferred this topic because it is unclear to me if such timer has to
| count elapsed time during a sleep or not. For example, time.clock()
| does on UNIX, whereas it doesn't on Windows. You may need two clocks
| for this:
|  * time.perf_counter(): high-resolution timer for benchmarking, count
| time elasped during a sleep

For POSIX, sounds like CLOCK_MONOTONIC_RAW to me.

|  * time.process_time(): High-resolution (?) per-process timer from the
| CPU. (other possible names: time.process_cpu_time() or
| time.cpu_time())

POSIX offers CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID that
seem to suit this need, depending on your threading situation (and what
you're measuring).

| On Windows, GetProcessTimes() has not a "high-resolution": it has a
| accuracy of 1 ms in the best case.

This page:
  
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683223%28v=vs.85%29.aspx
says "100-nanosecond time units".

Am I going to the wrong place to learn about these functions?
-- 
Cameron Simpson  DoD#743
http://www.cskk.ezoshosting.com/cs/

I distrust a research person who is always obviously busy on a task.
- Robert Frosch, VP, GM Research
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] an alternative to embedding policy in PEP 418

2012-04-08 Thread Lennart Regebro
On Fri, Apr 6, 2012 at 23:26, Ethan Furman  wrote:
> Huh?  Your point is that all APIs are less than ideal because you have to
> read the docs to know for certain how they work?

No.

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


Re: [Python-Dev] this is why we shouldn't call it a "monotonic clock" (was: PEP 418 is too divisive and confusing and should be postponed)

2012-04-08 Thread Victor Stinner
> IOW "What's good enough for sleep() is good enough for
> user-implemented timeouts and scheduling." as a way to reach at least
> one decision for a platform with agreed-upon cross-platform
> characteristics that are useful.

sleep() is implemented in the kernel. The kernel is notified when a
clock is set, and so can choose how to handle time adjustement. Most
"sleeping" functions use the system clock but don't care of clock
adjustement.

> I personally have a need for one potentially different clock -- to
> measure short intervals for benchmarks and profiling. This might be
> called time.performancetimer()?

I deferred this topic because it is unclear to me if such timer has to
count elapsed time during a sleep or not. For example, time.clock()
does on UNIX, whereas it doesn't on Windows. You may need two clocks
for this:
 * time.perf_counter(): high-resolution timer for benchmarking, count
time elasped during a sleep
 * time.process_time(): High-resolution (?) per-process timer from the
CPU. (other possible names: time.process_cpu_time() or
time.cpu_time())

On Windows, GetProcessTimes() has not a "high-resolution": it has a
accuracy of 1 ms in the best case. QueryPerformanceCounter() counts
time elapsed during a sleep, I don't know for GetProcessTimes.

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


Re: [Python-Dev] PEP-419: Protecting cleanup statements from interruptions

2012-04-08 Thread Benjamin Peterson
2012/4/8 Paul Colomiets :
> Function 'sys.setcleanuphook'
> -
>
> A new function for the ``sys`` module is proposed.  This function sets
> a callback which is executed every time ``f_in_cleanup`` becomes
> false.  Callbacks get a frame object as their sole argument, so that
> they can figure out where they are called from.

Calling a function every time you leave a finally block? Isn't that a
bit expensive?


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


Re: [Python-Dev] PEP-419: Protecting cleanup statements from interruptions

2012-04-08 Thread Antoine Pitrou

Hello Paul,

Thanks for the PEP and the description of the various issues.

> An example implementation of a SIGINT handler that interrupts safely
> might look like::
> 
> import inspect, sys, functools
> 
> def sigint_handler(sig, frame):
> if inspect.getcleanupframe(frame) is None:
> raise KeyboardInterrupt()
> sys.setcleanuphook(functools.partial(sigint_handler, 0))

It is not clear whether you are proposing this for the default signal
handler, or only as an example that third-party libraries or frameworks
could implement.

Regards

Antoine.


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


[Python-Dev] PEP-419: Protecting cleanup statements from interruptions

2012-04-08 Thread Paul Colomiets
Hi,

I present my first PEP.

http://www.python.org/dev/peps/pep-0419/

Added text to the end of email for easier reference. Comments are welcome.

-- 
Paul



PEP: 419
Title: Protecting cleanup statements from interruptions
Version: $Revision$
Last-Modified: $Date$
Author: Paul Colomiets 
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 06-Apr-2012
Python-Version: 3.3


Abstract


This PEP proposes a way to protect Python code from being interrupted
inside a finally clause or during context manager cleanup.


Rationale
=

Python has two nice ways to do cleanup.  One is a ``finally``
statement and the other is a context manager (usually called using a
``with`` statement).  However, neither is protected from interruption
by ``KeyboardInterrupt`` or ``GeneratorExit`` caused by
``generator.throw()``.  For example::

lock.acquire()
try:
print('starting')
do_something()
finally:
print('finished')
lock.release()

If ``KeyboardInterrupt`` occurs just after the second ``print()``
call, the lock will not be released.  Similarly, the following code
using the ``with`` statement is affected::

from threading import Lock

class MyLock:

def __init__(self):
self._lock_impl = Lock()

def __enter__(self):
self._lock_impl.acquire()
print("LOCKED")

def __exit__(self):
print("UNLOCKING")
self._lock_impl.release()

lock = MyLock()
with lock:
do_something

If ``KeyboardInterrupt`` occurs near any of the ``print()`` calls, the
lock will never be released.


Coroutine Use Case
--

A similar case occurs with coroutines.  Usually coroutine libraries
want to interrupt the coroutine with a timeout.  The
``generator.throw()`` method works for this use case, but there is no
way of knowing if the coroutine is currently suspended from inside a
``finally`` clause.

An example that uses yield-based coroutines follows.  The code looks
similar using any of the popular coroutine libraries Monocle [1]_,
Bluelet [2]_, or Twisted [3]_. ::

def run_locked():
yield connection.sendall('LOCK')
try:
yield do_something()
yield do_something_else()
finally:
yield connection.sendall('UNLOCK')

with timeout(5):
yield run_locked()

In the example above, ``yield something`` means to pause executing the
current coroutine and to execute coroutine ``something`` until it
finishes execution.  Therefore the coroutine library itself needs to
maintain a stack of generators.  The ``connection.sendall()`` call waits
until the socket is writable and does a similar thing to what
``socket.sendall()`` does.

The ``with`` statement ensures that all code is executed within 5
seconds timeout.  It does so by registering a callback in the main
loop, which calls ``generator.throw()`` on the top-most frame in the
coroutine stack when a timeout happens.

The ``greenlets`` extension works in a similar way, except that it
doesn't need ``yield`` to enter a new stack frame.  Otherwise
considerations are similar.


Specification
=

Frame Flag 'f_in_cleanup'
-

A new flag on the frame object is proposed.  It is set to ``True`` if
this frame is currently executing a ``finally`` clause.  Internally,
the flag must be implemented as a counter of nested finally statements
currently being executed.

The internal counter also needs to be incremented during execution of
the ``SETUP_WITH`` and ``WITH_CLEANUP`` bytecodes, and decremented
when execution for these bytecodes is finished.  This allows to also
protect ``__enter__()`` and ``__exit__()`` methods.


Function 'sys.setcleanuphook'
-

A new function for the ``sys`` module is proposed.  This function sets
a callback which is executed every time ``f_in_cleanup`` becomes
false.  Callbacks get a frame object as their sole argument, so that
they can figure out where they are called from.

The setting is thread local and must be stored in the
``PyThreadState`` structure.


Inspect Module Enhancements
---

Two new functions are proposed for the ``inspect`` module:
``isframeincleanup()`` and ``getcleanupframe()``.

``isframeincleanup()``, given a frame or generator object as its sole
argument, returns the value of the ``f_in_cleanup`` attribute of a
frame itself or of the ``gi_frame`` attribute of a generator.

``getcleanupframe()``, given a frame object as its sole argument,
returns the innermost frame which has a true value of
``f_in_cleanup``, or ``None`` if no frames in the stack have a nonzero
value for that attribute.  It starts to inspect from the specified
frame and walks to outer frames using ``f_back`` pointers, just like
``getouterframes()`` does.


Example
===

An example implementation of a SIGINT handler that interrupts safely
might look like::

import inspect,

Re: [Python-Dev] this is why we shouldn't call it a "monotonic clock" (was: PEP 418 is too divisive and confusing and should be postponed)

2012-04-08 Thread Antoine Pitrou
On Sun, 8 Apr 2012 07:29:30 -0700
Guido van Rossum  wrote:
> 
> What to name it can't be decided this way, although I might put
> forward time.sleeptimer().

interval_timer() ?
I would suggest timer() simply, but it's too close to time().

> I personally have a need for one potentially different clock -- to
> measure short intervals for benchmarks and profiling. This might be
> called time.performancetimer()?

It's called perf_counter() in the PEP:
http://www.python.org/dev/peps/pep-0418/#deferred-api-time-perf-counter

Regards

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


Re: [Python-Dev] this is why we shouldn't call it a "monotonic clock" (was: PEP 418 is too divisive and confusing and should be postponed)

2012-04-08 Thread Guido van Rossum
On Sun, Apr 8, 2012 at 3:42 AM, Antoine Pitrou  wrote:
>
>> | I made the same suggestion earlier but I don't know that anyone did
>> | anything with it. :-( It would be nice to know what clock sleep() uses
>> | on each of the major platforms.
>>
>> I saw it but didn't know what I could do with it, or even if it can be
>> found out in any very general sense.
>>
>> Looking at nanosleep(2) on a recent Linux system says:
>
> time.sleep() uses select(), not nanosleep().
> select() is not specified to use a particular clock. However, since it
> takes a timeout rather than a deadline, it would be reasonable for it
> to use a non-adjustable clock :-)
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html

Still, my hope was to cut short a bunch of discussion by declaring
that on every platform, one of the timers available should match the
one used by sleep(), select() and the like -- assuming they all use
the same timer underneath in a typical OS, even though (due to
standardization at different times by different standards bodies) they
aren't all specified the same.

IOW "What's good enough for sleep() is good enough for
user-implemented timeouts and scheduling." as a way to reach at least
one decision for a platform with agreed-upon cross-platform
characteristics that are useful.

What to name it can't be decided this way, although I might put
forward time.sleeptimer().

I personally have a need for one potentially different clock -- to
measure short intervals for benchmarks and profiling. This might be
called time.performancetimer()?

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] this is why we shouldn't call it a "monotonic clock" (was: PEP 418 is too divisive and confusing and should be postponed)

2012-04-08 Thread Antoine Pitrou

> | I made the same suggestion earlier but I don't know that anyone did
> | anything with it. :-( It would be nice to know what clock sleep() uses
> | on each of the major platforms.
> 
> I saw it but didn't know what I could do with it, or even if it can be
> found out in any very general sense.
> 
> Looking at nanosleep(2) on a recent Linux system says:

time.sleep() uses select(), not nanosleep().
select() is not specified to use a particular clock. However, since it
takes a timeout rather than a deadline, it would be reasonable for it
to use a non-adjustable clock :-)
http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html

Regards

Antoine.


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