Skip to content

Path arguments must be passed to os.fspath() #658

@jimmy-lt

Description

@jimmy-lt

Take the following task:

from pathlib import Path
from invoke import task


@task
def cd(ctx, path):
    with ctx.cd(Path(path)):
        ctx.run(f"echo {path}")

invoke will fail with the following obscure error:

$ inv cd .
Traceback (most recent call last):
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/config.py", line 111, in __getattr__
    return self._get(key)
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/config.py", line 176, in _get
    value = self._config[key]
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/config.py", line 167, in __getitem__
    return self._get(key)
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/config.py", line 176, in _get
    value = self._config[key]
KeyError: 'cwd'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/share/virtualenvs/inv-Li_05Nqg/bin/inv", line 10, in <module>
    sys.exit(program.run())
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/program.py", line 384, in run
    self.execute()
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/program.py", line 566, in execute
    executor.execute(*self.tasks)
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/executor.py", line 129, in execute
    result = call.task(*args, **call.kwargs)
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/tasks.py", line 127, in __call__
    result = self.body(*args, **kwargs)
  File "/home/spack/workspace/py/inv/tasks.py", line 8, in cd
    ctx.run(f"echo {path}")
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/context.py", line 94, in run
    return self._run(runner, command, **kwargs)
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/context.py", line 100, in _run
    command = self._prefix_commands(command)
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/context.py", line 242, in _prefix_commands
    current_directory = self.cwd
  File "/share/virtualenvs/inv-Li_05Nqg/lib/python3.7/site-packages/invoke/config.py", line 123, in __getattr__
    raise AttributeError(err)
AttributeError: No attribute or config key found for 'cwd'

Valid keys: ['run', 'runners', 'sudo', 'tasks', 'timeouts']

Valid real attributes: ['cd', 'clear', 'config', 'cwd', 'from_data', 'pop', 'popitem', 'prefix', 'run', 'setdefault', 'sudo', 'update']

This is due to invoke.context.Context.cd adding any given path directly to command_cwds and invoke.context.Context.cwd treating any value in there as a string.

Since Python 3.6, any object can represent a path by implementing the __fspath__() abstract method.

Since then, when dealing with any path object, it is now required to call os.fspath() in order to get the str or bytes representation of the path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions