Skip to content

Commit 6e66c2c

Browse files
authored
Merge pull request bwhmather#119 from AndydeCleyre/feature/stdin-stdout
Implement stdin-stdout operation with '-' file argument
2 parents f89be62 + 39593a8 commit 6e66c2c

File tree

3 files changed

+70
-17
lines changed

3 files changed

+70
-17
lines changed

src/ssort/_files.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def find_python_files(
5757
paths_set = set()
5858
for pattern in patterns:
5959
path = pathlib.Path(pattern)
60-
if not path.is_dir():
60+
if str(path) == "-" or not path.is_dir():
6161
subpaths = [path]
6262
else:
6363
subpaths = [

src/ssort/_main.py

+40-16
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ def main():
4040
"needs to be changed. Otherwise returns 1.",
4141
)
4242
parser.add_argument(
43-
"files", nargs="*", help="One or more python files to sort"
43+
"files",
44+
nargs="*",
45+
help="One or more python files to sort, or '-' for stdin.",
4446
)
4547

4648
args = parser.parse_args()
@@ -56,20 +58,29 @@ def main():
5658
for path in find_python_files(args.files):
5759
errors = False
5860

59-
try:
60-
original_bytes = path.read_bytes()
61-
except FileNotFoundError:
62-
sys.stderr.write(f"ERROR: {escape_path(path)} does not exist\n")
63-
unsortable += 1
64-
continue
65-
except IsADirectoryError:
66-
sys.stderr.write(f"ERROR: {escape_path(path)} is a directory\n")
67-
unsortable += 1
68-
continue
69-
except PermissionError:
70-
sys.stderr.write(f"ERROR: {escape_path(path)} is not readable\n")
71-
unsortable += 1
72-
continue
61+
if str(path) == "-":
62+
original_bytes = sys.stdin.buffer.read()
63+
else:
64+
try:
65+
original_bytes = path.read_bytes()
66+
except FileNotFoundError:
67+
sys.stderr.write(
68+
f"ERROR: {escape_path(path)} does not exist\n"
69+
)
70+
unsortable += 1
71+
continue
72+
except IsADirectoryError:
73+
sys.stderr.write(
74+
f"ERROR: {escape_path(path)} is a directory\n"
75+
)
76+
unsortable += 1
77+
continue
78+
except PermissionError:
79+
sys.stderr.write(
80+
f"ERROR: {escape_path(path)} is not readable\n"
81+
)
82+
unsortable += 1
83+
continue
7384

7485
# The logic for converting from bytes to text is duplicated in `ssort`
7586
# and here because we need access to the text to be able to compute a
@@ -80,6 +91,8 @@ def main():
8091
sys.stderr.write(
8192
f"ERROR: unknown encoding, {exc.encoding!r}, in {escape_path(path)}\n"
8293
)
94+
if str(path) == "-":
95+
sys.stdout.buffer.write(original_bytes)
8396
unsortable += 1
8497
continue
8598

@@ -89,6 +102,8 @@ def main():
89102
sys.stderr.write(
90103
f"ERROR: encoding error in {escape_path(path)}: {exc}\n"
91104
)
105+
if str(path) == "-":
106+
sys.stdout.buffer.write(original_bytes)
92107
unsortable += 1
93108
continue
94109

@@ -129,10 +144,14 @@ def _on_wildcard_import(**kwargs):
129144
)
130145

131146
if errors:
147+
if str(path) == "-":
148+
sys.stdout.buffer.write(original_bytes)
132149
unsortable += 1
133150
continue
134151

135152
except Exception as e:
153+
if str(path) == "-":
154+
sys.stdout.buffer.write(original_bytes)
136155
raise Exception(f"ERROR while sorting {path}\n") from e
137156

138157
if original != updated:
@@ -154,8 +173,13 @@ def _on_wildcard_import(**kwargs):
154173
updated_bytes = re.sub("\n", newline, updated_bytes)
155174
updated_bytes = updated_bytes.encode(encoding)
156175

157-
path.write_bytes(updated_bytes)
176+
if str(path) == "-":
177+
sys.stdout.buffer.write(updated_bytes)
178+
else:
179+
path.write_bytes(updated_bytes)
158180
else:
181+
if str(path) == "-" and not args.check:
182+
sys.stdout.buffer.write(original_bytes)
159183
unchanged += 1
160184

161185
if args.show_diff:

tests/test_executable.py

+29
Original file line numberDiff line numberDiff line change
@@ -420,3 +420,32 @@ def test_ssort_run_module():
420420
module_output = module_result.stderr.splitlines(keepends=True)
421421

422422
assert module_output == entrypoint_output
423+
424+
425+
@pytest.mark.parametrize(
426+
("stdin", "stdout"),
427+
(
428+
(_unsorted, _good),
429+
(_good, _good),
430+
(_encoding, _encoding),
431+
(_character, _character),
432+
(_syntax, _syntax),
433+
(_resolution, _resolution),
434+
(_double_resolution, _double_resolution),
435+
),
436+
ids=(
437+
"unsorted",
438+
"good",
439+
"encoding",
440+
"character",
441+
"syntax",
442+
"resolution",
443+
"double_resolution",
444+
),
445+
)
446+
def test_ssort_stdin(stdin, stdout):
447+
for command in [(sys.executable, "-m", "ssort"), ("ssort",)]:
448+
result = subprocess.run(
449+
[*command, "-"], capture_output=True, input=stdin
450+
)
451+
assert result.stdout == stdout

0 commit comments

Comments
 (0)