I am trying to change directories in my python program within a context manager. using invoke.context.Context
seems like the proper way to do it, got from the Fabric documentation and using a regular with os.chdir
will not work.
However, when I try to do something such as
from invoke import Context
with Context.cd("/etc"):
subprocess.run(["ls"])
I get an error back that says:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-40b28af3213a> in <module>
----> 1 with Context.cd("/etc"):
2 subprocess.run(["ls"])
3
~/miniconda3/envs/python3/lib/python3.7/contextlib.py in helper(*args, **kwds)
237 @wraps(func)
238 def helper(*args, **kwds):
--> 239 return _GeneratorContextManager(func, args, kwds)
240 return helper
241
~/miniconda3/envs/python3/lib/python3.7/contextlib.py in __init__(self, func, args, kwds)
80
81 def __init__(self, func, args, kwds):
---> 82 self.gen = func(*args, **kwds)
83 self.func, self.args, self.kwds = func, args, kwds
84 # Issue 19330: ensure context manager instances have good docstrings
TypeError: cd() missing 1 required positional argument: 'path'
The documentation makes this seem correct (http://docs.pyinvoke.org/en/latest/api/context.html#invoke.context.Context), but i'm a little lost.
Any advice is helpful.
Looking at the documentation, it seems like you're supposed to create your own instance of Context
, instead of using the Context
class directly.
They also use the run()
method on the Context instance instead of subprocess.run()
.
Try this:
from invoke import Context
c = Context()
with c.cd("/etc"):
c.run("ls")