Minor bug in tempfile module (possibly __doc__ error)

Discussion in 'Python' started by James T. Dennis, May 9, 2007.

  1. Tonight I discovered something odd in the __doc__ for tempfile
    as shipped with Python 2.4.4 and 2.5: it says:

    This module also provides some data items to the user:

    TMP_MAX - maximum number of names that will be tried before
    giving up.
    template - the default prefix for all temporary names.
    You may change this to control the default prefix.

    ... which would lead one to think that the following code would work:

    >>> import tempfile
    >>> tempfile.template = 'mytest'
    >>> tf = tempfile.NamedTemporaryFile()
    >>> tf.name

    '/tmp/mytest-XXXXXX'

    It doesn't.

    In fact I realized, after reading through tempfile.py in /usr/lib/...
    that the following also doesn't "work" like I'd expect:

    # foo.py
    tst = "foo"
    def getTst(arg):
    return "foo-%s" % arg


    # bar.py
    import foo
    foo.tst = "bar"
    print foo.getTst("testing")

    foo-testing <<<----- NOT "bar-testing"

    Now I would feel like a real idiot if I'd come across that in the
    foo/bar case here ... because I clearly don't understand quite *why*
    I can't "monkey patch" this value. I would ... but I don't.

    First, I wouldn't have written code like this foo/bar stuff; except
    to test my hypothesis about why changes to tempfile.template don't
    actually affect the values seen by functions in the tempfile namespace.

    Secondly, the author(s) of the tempfile module apparently didn't
    understand this either. And no one else even noticed that the __doc__
    is wrong (or at least misleading -- since the only way I can see to
    change tempfile.template is to edit the .py file!

    So, I don't feel like an idiot. But I am curious ...

    ... why can't I change that value in that other namespace? Is it
    a closure? (Or like a closure?) Where is this particular aspect
    of the import/namespace semantics documented?


    --
    Jim Dennis,
    Starshine: Signed, Sealed, Delivered
     
    James T. Dennis, May 9, 2007
    #1
    1. Advertising

  2. In <1178693438.689184@smirk>, James T. Dennis wrote:

    > Tonight I discovered something odd in the __doc__ for tempfile
    > as shipped with Python 2.4.4 and 2.5: it says:
    >
    > This module also provides some data items to the user:
    >
    > TMP_MAX - maximum number of names that will be tried before
    > giving up.
    > template - the default prefix for all temporary names.
    > You may change this to control the default prefix.
    >
    > ... which would lead one to think that the following code would work:
    >
    > >>> import tempfile
    > >>> tempfile.template = 'mytest'
    > >>> tf = tempfile.NamedTemporaryFile()
    > >>> tf.name

    > '/tmp/mytest-XXXXXX'
    >
    > It doesn't.


    The source says:

    __all__ = [
    "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
    "mkstemp", "mkdtemp", # low level safe interfaces
    "mktemp", # deprecated unsafe interface
    "TMP_MAX", "gettempprefix", # constants
    "tempdir", "gettempdir"
    ]

    Maybe the doc should be clearer in saying "constants" too.

    > Secondly, the author(s) of the tempfile module apparently didn't
    > understand this either. And no one else even noticed that the __doc__
    > is wrong (or at least misleading -- since the only way I can see to
    > change tempfile.template is to edit the .py file!


    You can change it by simply assigning to the name:

    In [15]: tempfile.template = 'spam'

    In [16]: tempfile.template
    Out[16]: 'spam'

    If you want to change the outcome of the functions and objects then simply
    give the prefix as argument.

    In [21]: tempfile.mktemp(prefix='eggs')
    Out[21]: '/tmp/eggsBqiqZD'

    In [22]: a = tempfile.NamedTemporaryFile(prefix='eric')

    In [23]: a.name
    Out[23]: '/tmp/ericHcns14'

    > ... why can't I change that value in that other namespace? Is it
    > a closure? (Or like a closure?) Where is this particular aspect
    > of the import/namespace semantics documented?


    You *can* change it, but it is not used by the code in that module.

    Ciao,
    Marc 'BlackJack' Rintsch
     
    Marc 'BlackJack' Rintsch, May 9, 2007
    #2
    1. Advertising

  3. On Wed, 09 May 2007 06:50:38 -0000, "James T. Dennis"
    <> declaimed the following in comp.lang.python:


    > In fact I realized, after reading through tempfile.py in /usr/lib/...
    > that the following also doesn't "work" like I'd expect:
    >

    No idea of the tempfile problem, but...

    > # foo.py
    > tst = "foo"
    > def getTst(arg):
    > return "foo-%s" % arg


    This return is using a literal "foo-". Change it to

    return "%s-%s" % (tst, arg)

    and try again.

    >
    >
    > # bar.py
    > import foo
    > foo.tst = "bar"
    > print foo.getTst("testing")
    >
    > foo-testing <<<----- NOT "bar-testing"
    >

    Just what I would expect when returning a string literal, and not a
    variable reference.

    --
    Wulfraed Dennis Lee Bieber KD6MOG

    HTTP://wlfraed.home.netcom.com/
    (Bestiaria Support Staff: )
    HTTP://www.bestiaria.com/
     
    Dennis Lee Bieber, May 9, 2007
    #3
  4. Dennis Lee Bieber <> wrote:
    > On Wed, 09 May 2007 06:50:38 -0000, "James T. Dennis"
    > <> declaimed the following in comp.lang.python:



    >> In fact I realized, after reading through tempfile.py in /usr/lib/...
    >> that the following also doesn't "work" like I'd expect:
    >>

    > No idea of the tempfile problem, but...
    >
    >> # foo.py
    >> tst = "foo"
    >> def getTst(arg):
    >> return "foo-%s" % arg


    > This return is using a literal "foo-". Change it to


    > return "%s-%s" % (tst, arg)


    Sorry that was a retyping bug in my posting ... not in
    my sample code which was on another system.

    > and try again.


    Try it yourself. As I said ... the value of tst in your
    name space will be changed, but the value returned by functions
    in the imported module will still use the old value!


    --
    Jim Dennis,
    Starshine: Signed, Sealed, Delivered
     
    James T. Dennis, May 10, 2007
    #4
  5. Marc 'BlackJack' Rintsch <> wrote:
    > In <1178693438.689184@smirk>, James T. Dennis wrote:


    >> Tonight I discovered something odd in the __doc__ for tempfile
    >> as shipped with Python 2.4.4 and 2.5: it says:
    >>
    >> This module also provides some data items to the user:
    >>
    >> TMP_MAX - maximum number of names that will be tried before
    >> giving up.
    >> template - the default prefix for all temporary names.
    >> You may change this to control the default prefix.
    >>
    >> ... which would lead one to think that the following code would work:
    >>
    >> >>> import tempfile
    >> >>> tempfile.template = 'mytest'
    >> >>> tf = tempfile.NamedTemporaryFile()
    >> >>> tf.name

    >> '/tmp/mytest-XXXXXX'
    >>
    >> It doesn't.


    > The source says:


    > __all__ = [
    > "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
    > "mkstemp", "mkdtemp", # low level safe interfaces
    > "mktemp", # deprecated unsafe interface
    > "TMP_MAX", "gettempprefix", # constants
    > "tempdir", "gettempdir"
    > ]


    > Maybe the doc should be clearer in saying "constants" too.


    >> Secondly, the author(s) of the tempfile module apparently didn't
    >> understand this either. And no one else even noticed that the __doc__
    >> is wrong (or at least misleading -- since the only way I can see to
    >> change tempfile.template is to edit the .py file!


    > You can change it by simply assigning to the name:


    > In [15]: tempfile.template = 'spam'


    > In [16]: tempfile.template
    > Out[16]: 'spam'


    I know you can change it. But changing it in your namespace
    doesn't change the results returned by the functions called
    from the module.

    > If you want to change the outcome of the functions and objects then simply
    > give the prefix as argument.


    I know how to provide the prefix arguments and that was
    never the issue.

    The issue was twofold:

    The docs are wrong (or at least confusing/misleading)

    I don't quite understand how this name/variable in
    my namespace (__main__) is able to change the value
    while the functions in the module still hold the old
    value.

    --
    Jim Dennis,
    Starshine: Signed, Sealed, Delivered
     
    James T. Dennis, May 10, 2007
    #5
  6. In <1178779520.887569@smirk>, James T. Dennis wrote:

    > Marc 'BlackJack' Rintsch <> wrote:
    >> In <1178693438.689184@smirk>, James T. Dennis wrote:

    >
    >> You can change it by simply assigning to the name:

    >
    >> In [15]: tempfile.template = 'spam'

    >
    >> In [16]: tempfile.template
    >> Out[16]: 'spam'

    >
    > I know you can change it. But changing it in your namespace
    > doesn't change the results returned by the functions called
    > from the module.


    I'm not changing it in my namespace but in the namespace of the `tempfile`
    module.

    > I don't quite understand how this name/variable in
    > my namespace (__main__) is able to change the value
    > while the functions in the module still hold the old
    > value.


    Default arguments are evaluated *once* when the ``def`` is executed and
    not at every function call.

    Ciao,
    Marc 'BlackJack' Rintsch
     
    Marc 'BlackJack' Rintsch, May 10, 2007
    #6
  7. James T. Dennis <> scribis:
    > In fact I realized, after reading through tempfile.py in /usr/lib/...
    > that the following also doesn't "work" like I'd expect:
    >
    > # foo.py
    > tst = "foo"
    > def getTst(arg):

    If I change this line:
    > return "foo-%s" % arg

    to:
    return "%s-%s" % (tst, arg)

    > # bar.py
    > import foo
    > foo.tst = "bar"
    > print foo.getTst("testing")
    >
    > foo-testing <<<----- NOT "bar-testing"

    Then "python bar.py" prints "bar-testing".

    0:tolot@jupiter:/tmp> cat foo.py
    tst = "foo"
    def getTst(arg):
    return "%s-%s" % (tst,arg)
    0:tolot@jupiter:/tmp> cat bar.py
    import foo
    foo.tst = "bar"
    print foo.getTst("testing")
    0:tolot@jupiter:/tmp> python bar.py
    bar-testing

    And regarding the tempfile.template problem, this looks like a bug.
    Because all functions in tempfile taking a prefix argument use "def
    function(... , prefix=template, ...)", only the value of template at
    import time matters.

    AdiaÅ­, Marc
     
    Marc Christiansen, May 10, 2007
    #7
  8. Marc Christiansen <> wrote:
    > James T. Dennis <> scribis:
    >> In fact I realized, after reading through tempfile.py in /usr/lib/...
    >> that the following also doesn't "work" like I'd expect:


    >> # foo.py
    >> tst = "foo"
    >> def getTst(arg):

    > If I change this line:
    >> return "foo-%s" % arg

    > to:
    > return "%s-%s" % (tst, arg)


    >> # bar.py
    >> import foo
    >> foo.tst = "bar"
    >> print foo.getTst("testing")


    >> foo-testing <<<----- NOT "bar-testing"

    > Then "python bar.py" prints "bar-testing".


    > 0:tolot@jupiter:/tmp> cat foo.py
    > tst = "foo"
    > def getTst(arg):
    > return "%s-%s" % (tst,arg)
    > 0:tolot@jupiter:/tmp> cat bar.py
    > import foo
    > foo.tst = "bar"
    > print foo.getTst("testing")
    > 0:tolot@jupiter:/tmp> python bar.py
    > bar-testing


    > And regarding the tempfile.template problem, this looks like a bug.
    > Because all functions in tempfile taking a prefix argument use "def
    > function(... , prefix=template, ...)", only the value of template at
    > import time matters.


    > Adia?, Marc


    I suppose my real sample code was def getTst(arg=tst):

    Oddly I've never come across that (the fact that defaulted arguments are
    evaluated during function definition) in my own coding and I guess there
    are two reasons for that: I try to avoid global variables and I usually
    use defaulted variables of the form:

    def (foo=None):
    if foo is None:
    foo = self.default_foo




    --
    Jim Dennis,
    Starshine: Signed, Sealed, Delivered
     
    James T. Dennis, May 10, 2007
    #8
  9. On Thu, 10 May 2007 06:41:16 -0000, "James T. Dennis"
    <> declaimed the following in comp.lang.python:


    >
    > Sorry that was a retyping bug in my posting ... not in
    > my sample code which was on another system.
    >
    > > and try again.

    >
    > Try it yourself. As I said ... the value of tst in your
    > name space will be changed, but the value returned by functions
    > in the imported module will still use the old value!


    Works for me...

    # foo.py

    tst = "foo"

    def getTst(arg):
    return "%s-%s" % (tst, arg)
    -=-=-=-=-
    # bar.py

    import foo

    print foo.getTst("Before assignment")

    foo.tst = "bar"

    print foo.getTst("After assignment")
    -=-=-=-=-
    >pythonw -u "bar.py"

    foo-Before assignment
    bar-After assignment
    >Exit code: 0

    --
    Wulfraed Dennis Lee Bieber KD6MOG

    HTTP://wlfraed.home.netcom.com/
    (Bestiaria Support Staff: )
    HTTP://www.bestiaria.com/
     
    Dennis Lee Bieber, May 11, 2007
    #9
  10. On Thu, 10 May 2007 17:30:49 -0000, "James T. Dennis"
    <> declaimed the following in comp.lang.python:


    > I suppose my real sample code was def getTst(arg=tst):
    >

    Ah, now that is the chameleonic equine of Oz.... I think it's been
    an FAQ for a decade now.
    --
    Wulfraed Dennis Lee Bieber KD6MOG

    HTTP://wlfraed.home.netcom.com/
    (Bestiaria Support Staff: )
    HTTP://www.bestiaria.com/
     
    Dennis Lee Bieber, May 11, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Trevor Taylor

    __doc__ of current function?

    Trevor Taylor, Sep 2, 2004, in forum: Python
    Replies:
    3
    Views:
    622
    Sean Ross
    Sep 2, 2004
  2. David Isaac

    property __doc__

    David Isaac, Jul 1, 2006, in forum: Python
    Replies:
    1
    Views:
    359
    Robert Kern
    Jul 1, 2006
  3. Gabriel Genellina

    __doc__ in compiled script

    Gabriel Genellina, Nov 2, 2006, in forum: Python
    Replies:
    5
    Views:
    298
    Peter Otten
    Nov 3, 2006
  4. David
    Replies:
    2
    Views:
    580
    David
    Feb 11, 2010
  5. Alex van der Spek

    Difference between tempfile and spooled tempfile?

    Alex van der Spek, Apr 5, 2012, in forum: Python
    Replies:
    2
    Views:
    377
    Steve Howell
    Apr 5, 2012
Loading...

Share This Page