[ python-Bugs-901605 ] random.seed not initialized as advertised

SourceForge.net noreply at sourceforge.net
Sat Feb 21 03:58:07 EST 2004


Bugs item #901605, was opened at 2004-02-21 05:45
Message generated for change (Comment added) made by phr
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=901605&group_id=5470

Category: Python Library
Group: Python 2.2.2
Status: Closed
Resolution: Invalid
Priority: 5
Submitted By: paul rubin (phr)
Assigned to: Raymond Hettinger (rhettinger)
Summary: random.seed not initialized as advertised

Initial Comment:
The doc for random.seed(x) says: Optional argument x
can be any hashable object. If x is omitted or None,
current system time is used; current system time is
also used to initialize the generator when the module
is first imported. 

In fact the random module calls the seed function with
x=None when a Random object is instantiated, not with
the current system time as the docs indicate.  You can
tell this by doing something like:

  import random
  class myrand(random.Random):
    def seed(x): 
       print x
       random.Random.seed(x)  
  a = myrand()

and you'll see it prints None.  Initializing with None
may be reasonable behavior, but it doesn't match the
docs.  So either the code or the doc should be updated.


----------------------------------------------------------------------

>Comment By: paul rubin (phr)
Date: 2004-02-21 08:58

Message:
Logged In: YES 
user_id=72053

1. When it says how the generator is initialized when the
module is first loaded, that's describing the caller.  If
you're saying behavior of the caller should be documented
elsewhere than on the docs of a particular method, that's
fine; but remember that this doc supposedly describes the
Random class, and part of the behavior of that class is that
its initializer calls self.seed with an arg of None.  That's
undocumented behavior, and undocumented behavior is never a
good thing.  So it should be documented one way or another,
maybe as a description for the Random.__init__ method.

2. I don't know how you can say that most people haven't
misinterpreted the current wording.  The only way anyone
will find out if they misinterpreted it is if they try to
subclass Random on the basis of the doc (rather than on
additional knowledge), and how many people go around doing
that?  I'm the first one that I know of, and I
misinterpreted the doc.

----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-02-21 08:35

Message:
Logged In: YES 
user_id=80475

We should not make this change for several reasons:

* you're describing the behavior of the caller, not the
callee.  the quoted docs are for the seed() method which
appropriately describes what it does with the arguments, not
how it  
is called by Random.__init__()

* The current wording is simple, direct, and has not been
misinterpreted by most people.  Expanding it to the more
convoluted wording would, IMO, make it less clear to most
people.  In the docs, if you explain something to death,
they become harder to understand.  Details are good, but
going on to describe how you would subclass and override for
one particular effect is a distracting digression.

* Having a method describe how it is called is a recipe for
the docs not getting updated in the future.  If I change the
instantiation behavior without changing seed, I would not
normally re-examine the doc string for seed().



----------------------------------------------------------------------

Comment By: paul rubin (phr)
Date: 2004-02-21 08:18

Message:
Logged In: YES 
user_id=72053

It says "; current system time is also used to initialize
the generator when the module is first imported. "  That
sugests (but doesn't state) that the module is passing the
current time to the generator, rather than that the
generator is initializing
itself with the current time.
 
Proposed new wording: ".  When a new generator is
instantiated, its inititialization method calls the seed
operation with a parameter of None.  The seed method then
uses the current time to initialize the generator as
described above.  If you subclass Random, your seed
operation can use some different method to create a default
seed on being initialized with None."


----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2004-02-21 08:04

Message:
Logged In: YES 
user_id=31435

Paul, please suggest exact wording that wouldn't confuse 
you.  The docs seem clear to me, and I haven't heard anyone 
else express confusion on this point.  How are you reading

"Optional argument x an be any hashable object. If x is 
omitted or None, current system time is used."

?  I don't see how it can be misread.  What did you think it 
meant?  That if you passed None, the None would get 
magically mutated in-place to become current system time?  
And that if you didn't pass anything, an argument consisting 
of current system time would be magically invented?  If so, 
that's creative <wink>.

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2004-02-21 07:54

Message:
Logged In: YES 
user_id=31435

I don't believe we'd change this behavior -- it's intentional 
that the default seeding varies each time you run a program.  
Subclasses aren't an argument against this:  a subclass isn't 
required to mimic a base class's behavior in all respects.  If it 
were, there would be darn little point to having subclasses 
<wink>.

----------------------------------------------------------------------

Comment By: paul rubin (phr)
Date: 2004-02-21 07:52

Message:
Logged In: YES 
user_id=72053

If that's what the docs are trying to say, they're unclear
and should be updated.

----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-02-21 07:46

Message:
Logged In: YES 
user_id=80475

I believe you are misreading the docs.  They describe what
Random.seed() DOES with the arguments, not HOW it is called.

The code for seed() shows that if the argument is None, it
calls time.time() and uses that as the seed value:

"""
        if a is None:
            # Initialize from current time
            import time
            a = long(time.time() * 256)

        if type(a) not in (type(3), type(3L)):
            a = hash(a)

        a, x = divmod(a, 30268)
        a, y = divmod(a, 30306)
        a, z = divmod(a, 30322)
        self._seed = int(x)+1, int(y)+1, int(z)+1

        self.gauss_next = None
"""

I understand that this behavior (which DOES match the
documentation) may be inconvenient if you override the
seed() method.  You are pretty much forced to add a few
lines of code to replicate seed's documented behavior.

If the module were being rewritten from scratch, this
behavior would be factored out.  However, it has been this
way since the dawn of time and is not sufficiently painful
to warrant a change.  Or, more accurately put, changing it
would cause more discomfort than it would save (i.e. the
huge existing code base takes priority here).

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2004-02-21 07:39

Message:
Logged In: YES 
user_id=31435

The docs are correct.  They say that calling seed() with no 
argument is the same as calling seed(None), and that's true, 
and it's also true that both cases end up using current 
system time.  That happens because the implementation of 
seed() special-cases argument None, but the docs describe 
behavior, not implementation details.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=901605&group_id=5470



More information about the Python-bugs-list mailing list