[Zope3-checkins] Re: [Checkins] SVN: Zope3/branches/3.3/ - fix for issue 517: intid might generate long instead of int which conflicts with btrees

Tim Peters tim.peters at gmail.com
Sat Jun 17 00:52:39 EDT 2006


[Christian Theune]
> Log message for revision 68700:
>    - fix for issue 517: intid might generate long instead of int which conflicts with btrees
>
>
> Changed:
>   U   Zope3/branches/3.3/doc/CHANGES.txt
>   U   Zope3/branches/3.3/src/zope/app/intid/__init__.py
>   U   Zope3/branches/3.3/src/zope/app/intid/tests.py
>
> -=-
> Modified: Zope3/branches/3.3/doc/CHANGES.txt
> ===================================================================
> --- Zope3/branches/3.3/doc/CHANGES.txt  2006-06-17 03:29:43 UTC (rev 68699)
> +++ Zope3/branches/3.3/doc/CHANGES.txt  2006-06-17 04:10:29 UTC (rev 68700)
> @@ -10,6 +10,9 @@
>
>      Bugfixes
>
> +      - Fixed issue 517: Bug in intid that doesn't respect that BTrees can not
> +        handle long.
> +
>        - Fixed issue 399: traversal of missing skins now give 404 / NotFound
>          instead of 505 / ComponentLookupError
>
>
> Modified: Zope3/branches/3.3/src/zope/app/intid/__init__.py
> ===================================================================
> --- Zope3/branches/3.3/src/zope/app/intid/__init__.py   2006-06-17 03:29:43 UTC (rev 68699)
> +++ Zope3/branches/3.3/src/zope/app/intid/__init__.py   2006-06-17 04:10:29 UTC (rev 68700)
> @@ -47,7 +47,10 @@
>      """
>      implements(IIntIds)
>
> -    _v_nextid = None
> +    _v_nextid = None
> +
> +    # Used for testability of random function
> +    __randint__ = random.randint
>
>      def __init__(self):
>          self.ids = OIBTree.OIBTree()
> @@ -97,11 +100,16 @@
>          """
>          while True:
>              if self._v_nextid is None:
> -                self._v_nextid = random.randint(0, 2**31)
> +                self._v_nextid = self.__randint__(0, 2**31)
>              uid = self._v_nextid
>              self._v_nextid += 1
> -            if uid not in self.refs:
> -                return uid
> +            try:
> +                if uid not in self.refs:
> +                    return uid
> +            except TypeError:
> +                # uid was a long instead of int and btree complained
> +                # we just try again
> +                pass
>              self._v_nextid = None

Allow me to suggest that a simpler fix would have been to replace:

                self._v_nextid = random.randint(0, 2**31)

with:

                self._v_nextid = int(random.randrange(2**31))

and that's all.  Using randint() with an upper bound of 2**31 was
simply wrong.  Using randrange() with that upper bound corrects that
mistake.  Unfortunatey, the int() is needed if (and only if) randrange
happens to return 2**31-1, which _fits_ in an int but is returned as a
long by randrange() due to a miserable platform-from-Mars portability
hack in Python's internal float->int conversion.

As a bonus, the suggested way should run faster than the original way
too (randint() calls randrange() under the covers, so using
randrange() directly removes a layer of Python-level function  call).


More information about the Zope3-Checkins mailing list