-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
autotest: Add a VSIFile wrapper class #8222
Conversation
swig/include/python/gdal_python.i
Outdated
self._binary = "b" in mode | ||
self._encoding = encoding | ||
|
||
self._fp = VSIFOpenL(self._path, self._mode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably throw an exception is None is returned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, also switched to VSIFOpenExL
to capture the error message
swig/include/python/gdal_python.i
Outdated
return self | ||
|
||
def __next__(self): | ||
chunk_size = 1024 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably that CPLReadLineL() could be used to avoid this reimplementatoin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
If it's helpful, here's an implementation we have been using at Koordinates for a while, with a set of tests: feel free to crib anything that's useful. I've licensed it as MIT. Any questions most welcome. https://gist.github.com/rcoup/5f4b49149ca26084eed4dccfd1b12895
|
Fantastic, thank you! |
I have not forgotten about this. I'm leaning towards moving it to |
The GDAL project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 28 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
8532886
to
6a5158c
Compare
autotest/pymod/gdaltest.py
Outdated
gdal.VSIFWriteL(x, 1, len(x), self._fp) | ||
|
||
def seek(self, offset, whence=0): | ||
gdal.VSIFSeekL(self._fp, offset, whence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to be careful here. Due to VSIFSeekL() taking only unsigned offsets, negative seeking with SEEK_CUR must be emulated doing VSIFSeekL(fp, VSIFTellL(fp) + offset, SEEK_SET)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where should the emulation happen?
VSIFile.seek
gdal.VSIFSeekL
(via%pythonprepend%
)gdal.VSIFSeekL
(via a new wrapper function incpl_i
. The signature here already uses signed offsets, so it seems reasonable that it should handle them correctly)
I'm still scratching my head a bit as to why the tests using negative seek work correctly as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gdal.VSIFSeekL
(via a new wrapper function incpl_i
. The signature here already uses signed offsets, so it seems reasonable that it should handle them correctly)
sounds good here. By the way, I've just realized yesterday, that is is not needed to use a "wrapper_foo" + %rename tricks. You can directly create a inline function with the target name. cf 5bcbc5c#diff-56ee4d91557b7ba46f850e46abbdc73e617c981c662a47a27d00eaef97136061R972
I'm still scratching my head a bit as to why the tests using negative seek work correctly as-is.
I suppose that the negative offsets get turned into unsigned values within SWIG .cpp code, and then unsigned overflow on additions within the virtual file system implementations accidentally lead to the correct result. But we'd better not rely on that. In particular the CI sanitize target and our configuration of OSSFuzz errors out on unsigned integer overflows, as they are most of the time bugs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added code to handle negative values in afe7ca8. I think the wrapper_
and %rename
are needed in this case because the function name exposed by SWIG is the same as the underlying function name.
afe7ca8
to
8e7f2c9
Compare
autotest/pymod/gdaltest.py
Outdated
assert type(x) is str | ||
x = x.encode(self._encoding) | ||
|
||
gdal.VSIFWriteL(x, 1, len(x), self._fp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably assert the returned value to be len(x) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, and to be consistent, we should check the return code of VSIFSeekL
and throw an exception on failure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should check the return code of
VSIFSeekL
and throw an exception on failure?
sounds good
Co-authored-by: Even Rouault <even.rouault@spatialys.com>
What does this PR do?
This PR adds a
gdal.vsi_open()
function that returns a file-like object, allowing virtual files to be used as "regular" Python files in some cases. For example, a zipped CSV can be read using the Pythoncsv
module:Still need to correctly handle different linebreak/OS combinations, ensure errors are raised when accessing a closed file, handle append mode (or raise error), and probably other things.
What are related issues/pull requests?
Tasklist