Skip to content

Commit f406a95

Browse files
Will-Tylerjeromekelleher
authored andcommitted
Use pipe when output file descriptor is not available
1 parent 6b9f88c commit f406a95

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

vcztools/_vcztoolsmodule.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,22 @@ static PyObject *
480480
VcfEncoder_encode_all(VcfEncoder *self, PyObject *args)
481481
{
482482
bool allowed_threads = false;
483+
int output_fd;
484+
int is_pipe;
485+
FILE* file = NULL;
483486

484487
if (VcfEncoder_check_state(self) != 0) {
485488
goto out;
486489
}
490+
if (!PyArg_ParseTuple(args, "ip", &output_fd, &is_pipe)) {
491+
goto out;
492+
}
493+
494+
file = fdopen(output_fd, "w");
495+
496+
if (file == NULL) {
497+
goto out;
498+
}
487499

488500
Py_BEGIN_ALLOW_THREADS
489501
allowed_threads = true;
@@ -512,14 +524,22 @@ VcfEncoder_encode_all(VcfEncoder *self, PyObject *args)
512524
goto out;
513525
}
514526
} else {
515-
puts(buf);
527+
fputs(buf, file);
528+
fputc('\n', file);
516529
PyMem_RawFree(buf);
517530
break;
518531
} // if (line_length < 0)
519532
} // while (true)
520533
}
521534

522535
out:
536+
if (file != NULL) {
537+
fflush(file);
538+
539+
if (is_pipe) {
540+
fclose(file);
541+
}
542+
}
523543
if (allowed_threads) {
524544
Py_END_ALLOW_THREADS
525545
}

vcztools/vcf_writer.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import concurrent.futures
22
import functools
33
import io
4+
import os
45
import re
56
import sys
67
from datetime import datetime
@@ -415,7 +416,21 @@ def c_chunk_to_vcf(
415416
if preceding_future:
416417
concurrent.futures.wait((preceding_future,))
417418

418-
encoder.encode_all()
419+
output = output or sys.stdout
420+
pipe = None
421+
try:
422+
output_fd = output.fileno()
423+
except OSError:
424+
pipe = os.pipe()
425+
output_fd = pipe[1]
426+
427+
output.flush()
428+
encoder.encode_all(output_fd, bool(pipe))
429+
430+
if pipe:
431+
with io.FileIO(pipe[0], closefd=True) as pipe_reader:
432+
output.write(pipe_reader.read().decode("ascii"))
433+
output.flush()
419434

420435

421436
def _generate_header(ds, original_header, sample_ids, *, no_version: bool = False):

0 commit comments

Comments
 (0)