Skip to content

Commit c84d3e8

Browse files
Евгений БлиновЕвгений Блинов
authored andcommitted
A new part about changing directories
1 parent 87a14ac commit c84d3e8

1 file changed

Lines changed: 39 additions & 68 deletions

File tree

README.md

Lines changed: 39 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Suby is a small wrapper around the [subprocess](https://docs.python.org/3/librar
3535
- [**Quick start**](#quick-start)
3636
- [**Run subprocess and look at the result**](#run-subprocess-and-look-at-the-result)
3737
- [**Command parsing**](#command-parsing)
38+
- [**Managing directory and environment variables**](#managing-directory-and-environment-variables)
3839
- [**Output**](#output)
3940
- [**Logging**](#logging)
4041
- [**Exceptions**](#exceptions)
@@ -146,6 +147,44 @@ Note that this only affects string arguments that go through `shlex` splitting.
146147
</details>
147148

148149

150+
## Managing directory and environment variables
151+
152+
By default, all commands are executed in the same directory and with the same environment variables as the parent process. However, this can be changed.
153+
154+
Pass a string or a `Path` object containing the directory path as the `directory` argument to change the directory itself:
155+
156+
```python
157+
from pathlib import Path
158+
159+
run(
160+
'python -c "import os; print(os.getcwd())"',
161+
directory=Path('project'),
162+
)
163+
```
164+
165+
Relative paths are resolved from the parent process's current working directory at the moment `run` is called, so values like `.`, `..`, and `./../.././project/` are valid when they point to an existing directory:
166+
167+
```python
168+
run('python -c "import os; print(os.getcwd())"', directory='./project/')
169+
```
170+
171+
`directory` is separate from [command parsing](#command-parsing). It is not split with `shlex`, and it is not affected by `split` or `double_backslash`. A directory path containing spaces is passed as one directory path:
172+
173+
```python
174+
run('python -c pass', directory='project with spaces')
175+
```
176+
177+
`directory` does not perform shell-style expansion. If you want a path under your home directory, expand it yourself:
178+
179+
```python
180+
from pathlib import Path
181+
182+
run('python -c pass', directory=Path.home())
183+
```
184+
185+
> ⚠️ If the directory is “broken” — for example, if it does not exist, or if there is a file at the specified path instead of a directory — a `suby.errors.WrongDirectoryError` exception will be raised. This exception will not be [caught](#exceptions) if `catch_exceptions=True` is used.
186+
187+
149188
## Output
150189

151190
By default, the `stdout` and `stderr` of the subprocess are forwarded to the `stdout` and `stderr` of the current process. Reading from the subprocess is continuous, and output is flushed each time a full line is read. `suby` reads `stdout` and `stderr` in separate threads so that neither stream blocks the other.
@@ -423,71 +462,3 @@ except EnvironmentVariablesConflict as error:
423462
```
424463

425464
On `Windows`, environment variable names are handled case-insensitively. On other platforms, names are case-sensitive.
426-
427-
428-
## Changing directories
429-
430-
By default, a subprocess starts in the same current working directory as the current process. Pass `directory` when the command should run somewhere else:
431-
432-
```python
433-
from pathlib import Path
434-
435-
run(
436-
'python -c "import os; print(os.getcwd())"',
437-
directory=Path('project'),
438-
)
439-
```
440-
441-
The directory must already exist. Passing `directory` changes only the subprocess working directory; it does not change the current process directory:
442-
443-
```python
444-
from pathlib import Path
445-
446-
before = Path.cwd()
447-
run('python -c pass', directory='project')
448-
assert Path.cwd() == before
449-
```
450-
451-
The `directory` argument accepts a string or a `Path` object. Relative paths are resolved from the parent process's current working directory at the moment `run` is called, so values like `.`, `..`, and `./../.././project/` are valid when they point to an existing directory:
452-
453-
```python
454-
run('python -c "import os; print(os.getcwd())"', directory='./project/')
455-
```
456-
457-
`directory` is separate from command parsing. It is not split with `shlex`, and it is not affected by `split` or `double_backslash`. A directory path containing spaces is passed as one directory path:
458-
459-
```python
460-
run('python -c pass', directory='project with spaces')
461-
```
462-
463-
`directory` does not perform shell-style expansion. If you want a path under your home directory, expand it yourself:
464-
465-
```python
466-
from pathlib import Path
467-
468-
run('python -c pass', directory=Path.home())
469-
```
470-
471-
Invalid directories raise `WrongDirectoryError` before the subprocess is started:
472-
473-
```python
474-
from suby import WrongDirectoryError
475-
476-
try:
477-
run('python -c pass', directory='missing-directory')
478-
except WrongDirectoryError as error:
479-
print(error)
480-
#> The directory 'missing-directory' does not exist.
481-
```
482-
483-
`catch_exceptions=True` does not hide invalid directory arguments, because those errors are raised before subprocess execution begins:
484-
485-
```python
486-
from suby import WrongDirectoryError
487-
488-
try:
489-
run('python -c pass', directory='missing-directory', catch_exceptions=True)
490-
except WrongDirectoryError as error:
491-
print(error)
492-
#> The directory 'missing-directory' does not exist.
493-
```

0 commit comments

Comments
 (0)