files.put() - incompatibility when `src` is `StringIO` and `dest` is a directory
I was using file.put() with a directory destination and switched it to a file.template(). That resulted in the following traceback:
File "/home/rsyring/.local/pipx/venvs/kilo/lib/python3.11/site-packages/pyinfra/operations/files.py", line 938, in put
dest = unix_path_join(dest, os.path.basename(src))
^^^^^^^^^^^^^^^^^^^^^
File "<frozen posixpath>", line 142, in basename
TypeError: expected str, bytes or os.PathLike object, not StringIO
Once I figured out what was going on, the fix was to specify the dest as a file path, which makes sense.
Requests:
- A better error message indicating the root problem, i.e. "When using IO-like object for
srca directory can not be used as thedest." - Maybe not worth the effort, but when using
files.template()and the dest is a directory, source the file name from the src file and add that to the dest before callingfiles.put(). Removing '.j2' or '.jinja' if present on the src filename.
An assert statement was added as part of #1082:
https://github.com/pyinfra-dev/pyinfra/blob/9ce7ac44ef6e9d5d8d8a926836e8d294cccbff29/pyinfra/operations/files.py#L854-L856
The following code now causes an AssertionError:
from pyinfra.operations import files
files.template(name='Template', src='template.j2', dest='/tmp')
However, the error message could (or should, imho) certainly be improved.
Maybe not worth the effort, but when using files.template() and the dest is a directory, source the file name from the src file and add that to the dest before calling files.put(). Removing '.j2' or '.jinja' if present on the src filename.
@Fizzadar What is your take on that? Makes sense or is that a bit too much "magic"?