By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,931 Members | 2,015 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,931 IT Pros & Developers. It's quick & easy.

Minor bug in tempfile module (possibly __doc__ error)

P: n/a


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

May 9 '07 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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
May 9 '07 #2

P: n/a
Dennis Lee Bieber <wl*****@ix.netcom.comwrote:
On Wed, 09 May 2007 06:50:38 -0000, "James T. Dennis"
<ja******@idiom.comdeclaimed 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

May 10 '07 #3

P: n/a
Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
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

May 10 '07 #4

P: n/a
In <1178779520.887569@smirk>, James T. Dennis wrote:
Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
>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
May 10 '07 #5

P: n/a
James T. Dennis <ja******@idiom.comscribis:
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:/tmpcat foo.py
tst = "foo"
def getTst(arg):
return "%s-%s" % (tst,arg)
0:tolot@jupiter:/tmpcat bar.py
import foo
foo.tst = "bar"
print foo.getTst("testing")
0:tolot@jupiter:/tmppython 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
May 10 '07 #6

P: n/a
Marc Christiansen <us****@solar-empire.dewrote:
James T. Dennis <ja******@idiom.comscribis:
>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:/tmpcat foo.py
tst = "foo"
def getTst(arg):
return "%s-%s" % (tst,arg)
0:tolot@jupiter:/tmpcat bar.py
import foo
foo.tst = "bar"
print foo.getTst("testing")
0:tolot@jupiter:/tmppython 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

May 10 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.