msg139548 - (view) |
Author: Ulrich Eckhardt (eckhardt) |
Date: 2011-07-01 06:45 |
For reference, see the thread on the users' mailinglist/newsgroup from 2011-06-29 "how to call a function for evry 10 seconds" and the thread on the developers' mailinglist from 2011-06-30 "time.sleep(-1) behaviour". The problem is how negative arguments to time.sleep() are handled. Python 2.x (tested 2.5 and 2.7) implementations on MS Windows seems to have a 32-bit underflow while converting the given argument to the DWORD that is passed to win32's Sleep() function. This causes a small negative value to sleep for a long time. On Linux, using Python 2.6, you get an IOError instead. While an error is better than blocking effectively forever, the use of an IOError to signal the wrong argument is at least confusing. I guess it is an artifact of the implementation, but that shouldn't be visible prominently. IMHH, both versions should raise a ValueError to signal invalid arguments. However, there was also the suggestion to simply treat negative values as zero, after all time.sleep() is already documented to possibly sleep longer than specified. |
|
|
msg139558 - (view) |
Author: STINNER Victor (vstinner) *  |
Date: 2011-07-01 09:33 |
I think that time.sleep() should behave as select.select() (issue #11757, commit 3982be773b54) and signal.sigtimedwait(): raise a ValueError if the timeout is negative. A good reason to always raise an error is that floatsleep() has different implementations. Especially, the select() implementation behaves differently depending on the platform: negative timeout raises an error (select.error(22, 'Invalid argument')) or returns immediatly. Attached patch raises an error if the time length is negative. It avoids the integer overflow in the Windows implementation. |
|
|
msg139559 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2011-07-01 09:34 |
I agree with the ValueError suggestion. Since it would slightly change existing behaviour, it can only be done in a feature release (3.3). According to Google Code Search, deliberate uses of sleep(-1) are almost non-existent: http://www.google.com/codesearch#search/&q=%22sleep%28-1%29%22%20lang:python&type=cs |
|
|
msg139560 - (view) |
Author: STINNER Victor (vstinner) *  |
Date: 2011-07-01 09:41 |
> According to Google Code Search, deliberate uses of sleep(-1) > are almost non-existent: The search gives two results, in pycaf and a plone installer (in "compilezpy.py"). I don't know what is the expected behaviour: "infinite" sleep? wait for a SIGINT signal? I'm ok to only change this in Python 3.3, it's not a good idea to introduce subtle differences in minor Python releases. |
|
|
msg139563 - (view) |
Author: STINNER Victor (vstinner) *  |
Date: 2011-07-01 10:26 |
See also #12462, I found something weird in the signal handling of floatsleep(). |
|
|
msg139573 - (view) |
Author: STINNER Victor (vstinner) *  |
Date: 2011-07-01 12:48 |
Tim Lesher on python-dev: "On the Windows side, Sleep(-1) as "infinite" is correct and documented: http://msdn.microsoft.com/en-us/library/ms686298(v=vs.85).aspx" Wine defines INFINITE using "#define INFINITE 0xFFFFFFFF": http://source.winehq.org/source/include/winbase.h -1 becomes INFINITE because of an integer overflow (because of a cast from double to *unsigned* long). time.sleep(-2) doesn't sleep for an infinite time, but for more than 136 years (maybe more in 64 bits?): >>> print(datetime.timedelta(seconds=-2 & 0xFFFFFFFF)) 49710 days, 6:28:14 What is the usecase of Sleep(INFINITE)? Wait a signal or wait another event? Because other platforms don't support the INFINITE timeout, I suggest to always raise an error to have the same behaviour on all platforms. On POSIX, you can use pause(), sigwait(), select() or other functions to wait a signal for example. If we something something like that on Windows, we need a new function, but not a magic time.sleep(-1) please. |
|
|
msg139901 - (view) |
Author: Roundup Robot (python-dev)  |
Date: 2011-07-05 20:00 |
New changeset 0e5485634817 by Victor Stinner in branch 'default': Issue #12459: time.sleep() now raises a ValueError if the sleep length is http://hg.python.org/cpython/rev/0e5485634817 |
|
|
msg139902 - (view) |
Author: STINNER Victor (vstinner) *  |
Date: 2011-07-05 20:01 |
Tim Lesher agreed to raise an exception ("That makes sense. Better to be consistent within the time API--I know the different semantics of time.clock() have confused people around here."), so I think that everybody agreed to raise an exception. I commited my commit, let close this issue. |
|
|