Hello everyone!
A very common pattern when dealing with temporary files is code like this:
with tempfile.TemporaryDirectory() as tmpdir: tmp_path = tmpdir.name
os.chmod(tmp_path) os.foobar(tmp_path) open(tmp_path).read(barquux)
PEP 519 (https://www.python.org/dev/peps/pep-0519/) introduced the concept of "path-like objects", objects that define a __fspath__() method. Most of the standard library has been adapted so that the functions accept path-like objects.
My proposal is to define __fspath__() for TemporaryDirectory and NamedTemporaryFile so that we can pass those directly to the library functions instead of having to use the .name attribute explicitely.
Thoughts? :-)
On 06/08/2017 06:42 AM, Antoine Pietri wrote:
Hello everyone!
A very common pattern when dealing with temporary files is code like this:
with tempfile.TemporaryDirectory() as tmpdir: tmp_path = tmpdir.name os.chmod(tmp_path) os.foobar(tmp_path) open(tmp_path).read(barquux)
PEP 519 (https://www.python.org/dev/peps/pep-0519/) introduced the concept of "path-like objects", objects that define a __fspath__() method. Most of the standard library has been adapted so that the functions accept path-like objects.
My proposal is to define __fspath__() for TemporaryDirectory and NamedTemporaryFile so that we can pass those directly to the library functions instead of having to use the .name attribute explicitely.
Thoughts? :-)
Good idea. Check bugs.python.org to see if there is already an issue for this, and if not create one! :)
-- ~Ethan~
On Thu, 8 Jun 2017 at 08:27 Ethan Furman ethan@stoneleaf.us wrote:
On 06/08/2017 06:42 AM, Antoine Pietri wrote:
Hello everyone!
A very common pattern when dealing with temporary files is code like
this:
with tempfile.TemporaryDirectory() as tmpdir: tmp_path = tmpdir.name os.chmod(tmp_path) os.foobar(tmp_path) open(tmp_path).read(barquux)
PEP 519 (https://www.python.org/dev/peps/pep-0519/) introduced the concept of "path-like objects", objects that define a __fspath__() method. Most of the standard library has been adapted so that the functions accept path-like objects.
My proposal is to define __fspath__() for TemporaryDirectory and NamedTemporaryFile so that we can pass those directly to the library functions instead of having to use the .name attribute explicitely.
Thoughts? :-)
Good idea. Check bugs.python.org to see if there is already an issue for this, and if not create one! :)
Already exists, been discussed, and rejected: https://bugs.python.org/issue29447 .
On 06/08/2017 12:22 PM, Brett Cannon wrote:
Already exists, been discussed, and rejected: https://bugs.python.org/issue29447 .
Ah, right, because the returned object is not a file path. Makes sense.
-- ~Ethan~
On Thu, Jun 8, 2017 at 9:42 AM, Antoine Pietri antoine.pietri1@gmail.com wrote:
My proposal is to define __fspath__() for TemporaryDirectory and NamedTemporaryFile so that we can pass those directly to the library functions instead of having to use the .name attribute explicitely.
+1
On 08/06/17 15:42, Antoine Pietri wrote:
Hello everyone!
A very common pattern when dealing with temporary files is code like this:
with tempfile.TemporaryDirectory() as tmpdir: tmp_path = tmpdir.name os.chmod(tmp_path) os.foobar(tmp_path) open(tmp_path).read(barquux)
Is it?
py> import tempfile py> with tempfile.TemporaryDirectory() as tmpdir: ... print(tmpdir, type(tmpdir)) ... /tmp/tmp2kiqzmi9 <class 'str'> py>
PEP 519 (https://www.python.org/dev/peps/pep-0519/) introduced the concept of "path-like objects", objects that define a __fspath__() method. Most of the standard library has been adapted so that the functions accept path-like objects.
My proposal is to define __fspath__() for TemporaryDirectory and NamedTemporaryFile so that we can pass those directly to the library functions instead of having to use the .name attribute explicitely.
Thoughts? :-)
On 06/16/2017 10:36 AM, Thomas Jollans wrote:
On 08/06/17 15:42, Antoine Pietri wrote:
Hello everyone!
A very common pattern when dealing with temporary files is code like this:
with tempfile.TemporaryDirectory() as tmpdir: tmp_path = tmpdir.name os.chmod(tmp_path) os.foobar(tmp_path) open(tmp_path).read(barquux)
Is it?
py> import tempfile py> with tempfile.TemporaryDirectory() as tmpdir: ... print(tmpdir, type(tmpdir)) ... /tmp/tmp2kiqzmi9 <class 'str'> py>
Interesting... on 3.4 and 3.5 I get:
--> import tempfile
--> tempfile.TemporaryDirectory() <TemporaryDirectory '/tmp/tmpy32czx2v'>
--> with tempfile.TemporaryDirectory() as tmpdir: ... tmpdir ... '/tmp/tmpo63icqfe'
So a <TemporaryDirectory> if used directly, and a <str> if used as a context manager. I don't have a copy of 3.6 nor the future 3.7 handy, so maybe it changed there?
-- ~Ethan~
On 16/06/17 22:21, Ethan Furman wrote:
On 06/16/2017 10:36 AM, Thomas Jollans wrote:
On 08/06/17 15:42, Antoine Pietri wrote:
Hello everyone!
A very common pattern when dealing with temporary files is code like this:
with tempfile.TemporaryDirectory() as tmpdir: tmp_path = tmpdir.name os.chmod(tmp_path) os.foobar(tmp_path) open(tmp_path).read(barquux)
Is it?
py> import tempfile py> with tempfile.TemporaryDirectory() as tmpdir: ... print(tmpdir, type(tmpdir)) ... /tmp/tmp2kiqzmi9 <class 'str'> py>
Interesting... on 3.4 and 3.5 I get:
--> import tempfile
--> tempfile.TemporaryDirectory() <TemporaryDirectory '/tmp/tmpy32czx2v'>
--> with tempfile.TemporaryDirectory() as tmpdir: ... tmpdir ... '/tmp/tmpo63icqfe'
So a <TemporaryDirectory> if used directly, and a <str> if used as a context manager. I don't have a copy of 3.6 nor the future 3.7 handy, so maybe it changed there?
No, this is still the same in py37.
The point is that Antoine's code example does not work (in any Python).
For NamedTemporaryFile, the situation is different:
py> import tempfile py> import os.path py> py> tf1 = tempfile.NamedTemporaryFile() py> tf1.name '/tmp/tmpotcmslpp' py> os.path.exists(tf1.name) True py> with tf1 as tf2: ... print(tf2) ... print(tf2 is tf1) ... <tempfile._TemporaryFileWrapper object at 0x7f7327506a18> True py> os.path.exists(tf1.name) False py>
I was wondering about this since the objection that we're dealing with a file object and not a path does not apply for TemporaryDirectory - however, if used "the right way" with a context manager the issue simply doesn't exist.
-- Thomas
On 2017-06-16 04:21 PM, Ethan Furman wrote:
On 06/16/2017 10:36 AM, Thomas Jollans wrote:
On 08/06/17 15:42, Antoine Pietri wrote:
Hello everyone!
A very common pattern when dealing with temporary files is code like this:
with tempfile.TemporaryDirectory() as tmpdir: tmp_path = tmpdir.name os.chmod(tmp_path) os.foobar(tmp_path) open(tmp_path).read(barquux)
Is it?
py> import tempfile py> with tempfile.TemporaryDirectory() as tmpdir: ... print(tmpdir, type(tmpdir)) ... /tmp/tmp2kiqzmi9 <class 'str'> py>
Interesting... on 3.4 and 3.5 I get:
--> import tempfile
--> tempfile.TemporaryDirectory() <TemporaryDirectory '/tmp/tmpy32czx2v'>
--> with tempfile.TemporaryDirectory() as tmpdir: ... tmpdir ... '/tmp/tmpo63icqfe'
So a <TemporaryDirectory> if used directly, and a <str> if used as a context manager. I don't have a copy of 3.6 nor the future 3.7 handy, so maybe it changed there?
-- ~Ethan~
The code in master has the context manager return `self.name`. This behaviour has (based on looking at the 3.2 tag where TemporaryDirectory was added) always been used.
Alex
On 06/16/2017 01:37 PM, Alexandre Brault wrote:
So a <TemporaryDirectory> if used directly, and a <str> if used as a context manager. I don't have a copy of 3.6 nor the future 3.7 handy, so maybe it changed there?
The code in master has the context manager return `self.name`. This behaviour has (based on looking at the 3.2 tag where TemporaryDirectory was added) always been used.
It is an often overlooked fact that a context manager is free to return anything, not just itself. So TemporaryDirectory can create the folder, return the name of the folder, and remove the folder on exit. So no need for the "extract the name from the object" dance. Interestingly enough, that is what the docs say [1].
Pretty cool.
-- ~Ethan~
[1] https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryDirectory