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
uproot.open(filename, "w") and uproot.open(filename, mode="w") fail #758
Comments
I labeled this as a bug from the API design perspective. At the very least, if you do not accept the keyword |
You're looking for up.recreate? |
This is true. Unhandled options ought to raise an error, and I think it was originally designed to do that (always popping that dict and dealing with On handling To clarify "such a vast difference between opening a ROOT file for reading and opening a ROOT file for writing," I specifically mean ROOT files because of the way that they act as filesystems in a file. (The same is true of HDF5, and h5py also does not follow Python's Although now that I think about it,
On the third hand, I'm thinking this wouldn't be a good interface after all. It looks like Python's Since readers and writers have such different feature sets, creating them with different functions more clearly separates the ways you can configure those different feature sets. But maybe, in addition to raising errors on unrecognized |
:-)
I can only disagree from my naive user perspective. We want to avoid surprise, no? uproot.open looks at first glance like the familiar builtin open. Yes, I am ignoring all the complicated keywords that it has, which I never needed so far. You are telling me, that the familiar pattern that I learned - I can use open to read and write files with mode="r" and mode="w" - only works halfway. Now I have to remember that this familiar pattern does not work with uproot. The pattern is broken and that's extra mental load for me. The Zen of Python says: There should be one-- and preferably only one --obvious way to do it. For a ROOT user, it may be obvious to call recreate, but using "recreate" for writing was already artificial and pattern breaking in the ROOT days. Using In general, I believe that design should be guided - but not dictated - by implementation. The implementation follows the design, not the other way round. I think it is fair to raise an error in uproot.open when users try to pass options that don't work for writing files. I haven't looked into the details, maybe you are right and mixing all the options of recreate into open would be bad, but maybe you don't have to do that. Maybe you can have a basic If that still does not convince you, then please use the signature |
On Uproot's open/recreate split: I believe this is a case that was guided by implementation. The separation between read-code and write-code is pretty stark; arguably, they could have been two libraries. (Uproot and Downroot?) Maybe the original problem was naming the entry function On ROOT's original TFile: I'm not convinced that a function that opens a filesystem-like database should follow the semantics of a byte- or codepoint-level
We should consider marking some arguments as keyword-only across the whole codebase. It wasn't done before because it was written to be compatible with Python 2, but that support was removed a long time ago. Turning arguments into keyword-only arguments is a backward-incompatible change, but that's allowed before the release of version 5.0.0 in December. And we should find out why extra arguments are not raising errors. I haven't forgotten that. |
uproot 4.3.7
When opening a root file for writing, the call to
uproot.open(filename, mode="w")
fails with this error messageIt looks like
mode="w"
is ignored. This is not pythonic. By providinguproot.open
you are suggesting that you mimic the interface of theopen
command, which is used in several places in the Python stdlib (builtins open, gzip.open, lzma.open, ...). But then you should also mimics the signature of the stdlib version as much as possible. Calling uproot.open with mode="w" should forward to uproot.recreate.uproot.open(filename, "w")
fails with a different error, because the next positional argument after path is notmode
, butobject_cache
. To fix this,mode
should be added as the second argument after path oruproot.open
should reject positional arguments afterpath
with the signatureopen(path, *, object_cache=...)
The text was updated successfully, but these errors were encountered: