[Python-Dev] threading.Semaphore()'s counter can become negative for non-ints

Guido van Rossum guido at python.org
Mon Jan 30 19:52:29 CET 2012


TB, what's your use case for passing a float to a semaphore?
Semaphores are conceptually tied to integers. You've kept arguing a
few times now that the workaround you need are clumsy, but you've not
explained why you're passing floats in the first place. A "fractional
resource" just doesn't sound like a real use case to me.

On Mon, Jan 30, 2012 at 10:40 AM, T.B. <bauertomer at gmail.com> wrote:
>
> On 2012-01-30 01:46, Victor Stinner wrote:
>>>
>>>
>>> But why would you want to pass a float? It seems like API abuse to me.
>>
>>
>> If something should be changed, Semaphore(arg) should raise a
>> TypeError if arg is not an integer.
>>
> Short version:
> I propose the the change to be
>
> -        while self._value == 0:
> +        while self._value < 1:
> This should not change the flow when Semaphore._value is an int.
>
> Longer explanation:
> I thought it is surprising to use math.floor() for threading.Semaphore, but
> now as you propose, we will need to use something like
> int(math.floor(value)) in Python2.x - which is even more surprising. That is
> because math.floor() (and round() for that matter) return a float object in
> Python2.x.
>
> Note: isinstance(4.0, numbers.Integral) is False, even in Python3.x, but
> until now 4.0 was valid as a value for Semaphore(). Also, using the builtin
> int()/math.trunc() on a float is probably not what you want here, but rather
> math.floor().
>
> The value argument given to threading.Semaphore() is really a duck (or an
> object) that can be compared to 0 and 1, incremented by 1 and decremented by
> 1. These are properties that fit float. Why should you force the entire
> builtin int behavior on that object?
>
> I agree that using a float as the counter smells bad, but at times you might
> have something like a fractional resource (which is different from a
> floating point number). In such cases Semaphore.acquire(), after the tiny
> patch above, can be thought as checking if you have at least one "unit of
> resource" available. If you do have at least one such resource - acquire it.
> This will make sure the invariant "The counter can never go below zero"
> holds.
>
> Regards,
> TB
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/guido%40python.org



-- 
--Guido van Rossum (python.org/~guido)


More information about the Python-Dev mailing list