-
Notifications
You must be signed in to change notification settings - Fork 3
FileBinaryRead: file is already closed #209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@danjac Thanks for the bug report! I suspect this bug exists because django's BaseCommand has a two-phase parse/execute execution pathway and we've stuffed click's single phase pathway into it which results in some redundant work - for example two contexts are constructed. Click's file type closes the file on context destruction. I really consider this a click design flaw because parse/execute should be independent exposed but chainable processes - but I doubt click is going to change at this point so we probably need to come up with a workaround. I do not want to inject special case code for these types because working equivalent behavior is easy (see below) and the most correct solution would be to avoid the redundant contexts. This will be more difficult to solve behind Django's interface, so I might not be able to get to it for a bit. In the mean time it's probably best to avoid these types anyway. This implementation is a similar level of verbosity and also fully encapsulates file/open close. The above code puts the responsibility on the caller to close the file when invoked directly as a function (not through the CLI or call_command): An equivalent example: app = Typer()
@app.command()
def handle(self, file: Path) -> None:
"""Print out file"""
for chunk in file.open("rb"):
print(chunk) An example that encapsulates handle ownership more fully: app = Typer()
@app.command()
def handle(self, file: Path) -> None:
"""Print out file"""
with open(file, "rb") as f:
for chunk in f:
print(chunk) |
Blocked by #210 |
Unfortunately I also need to be able to pipe streams to the command as well as use file paths, so for example |
@danjac Weirdly the pipe use case actually works. I'll see what I can do. |
@danjac I don't want to rush this fix because it's delicate. In the meantime here's an easy workaround that works for the pipe and argument case: app = Typer()
@app.command()
def handle(self, file: typer.FileBinaryRead) -> None:
"""Print out file"""
if file.closed:
file = open(file.name, "rb")
for chunk in file:
print(chunk) |
Makes sense, thanks! |
Trying to run this command using
FileBinaryRead
e.g../manage.py my_command path_to_file.txt
ValueError: I/O operation on closed file
In the Typer docs this should work: https://typer.tiangolo.com/tutorial/parameter-types/file/#filebinaryread
The text was updated successfully, but these errors were encountered: