Define __fspath__() for NamedTemporaryFile and TemporaryDirectory

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? :-) -- Antoine Pietri

On Thu, 8 Jun 2017 at 08:27 Ethan Furman <ethan@stoneleaf.us> wrote:
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 06/16/2017 10:36 AM, Thomas Jollans wrote:
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:
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 06/16/2017 01:37 PM, Alexandre Brault wrote:
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

On Thu, 8 Jun 2017 at 08:27 Ethan Furman <ethan@stoneleaf.us> wrote:
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 06/16/2017 10:36 AM, Thomas Jollans wrote:
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:
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 06/16/2017 01:37 PM, Alexandre Brault wrote:
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
participants (6)
-
Alexandre Brault
-
Antoine Pietri
-
Brett Cannon
-
Ethan Furman
-
Juancarlo Añez
-
Thomas Jollans