-
Notifications
You must be signed in to change notification settings - Fork 8
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
Update filesystem datastore to async/await #13
Conversation
…should now be exposed and `datastore.core.*` only needed by internal stuff
assert len(sn) == length | ||
except TypeError: | ||
pass | ||
for sn in self.stores: |
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.
Nice!
__version__ = "0.3.6" | ||
__author__ = "Juan Batiz-Benet, Alexander Schlarb" | ||
__email__ = "juan@benet.ai, alexander@ninetailed.ninja" | ||
__all__ = ( |
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.
Nice work exposing those Classes directly.
|
||
from .core.objectstore import NullDatastore as ObjectNullDatastore | ||
from .core.objectstore import DictDatastore as ObjectDictDatastore | ||
|
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 will also have to expose FileSystemDatastore and FileReader
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.
My thought was that the filesystem datastore has to be explicitly imported using datastore.filesystem
as it is not needed if another datastore (like leveldb or the in-memory dict one) is used.
FileReader
is just an implementation detail of how the datastore manages to return its datastore.abc.ReceiveStream
. Its not really meant to be used directly.
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.
Okay 👍
else: | ||
buf = await self._file.read(DEFAULT_BUFFER_SIZE) | ||
|
||
if len(buf) == 0: |
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.
Is it necessary to call .aclose() here? Won't the user explicitly call it?
And if we are already calling .aclose(), when the user explicitly calls .aclose(), wont there be some kind of error, saying that it is already closed?
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.
Calling .aclose()
here ensures that the file automatically be closed in an
async for chunk in await datastore.get("whatever"):
…
kind of scenario. Otherwise the calling code would have to look like this:
async with await datastore.get("whatever") as file:
async for chunk in file:
…
… or the file descriptor would leak.
Calling aclose
several times is not an error:
If the resource is already closed, then this method should silently succeed.
datastore/filesystem/filesystem.py
Outdated
# Try to remove parent directories if they are empty | ||
try: | ||
parent = path.parent | ||
while str(parent).startswith(self.root_path + os.path.sep) \ |
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.
I didn't understand the logic here, so no comments
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.
It tries to rmdir
parent directories as long as
- that directory is a subdirectory of the
root_path
- that is: the directory path starts with the string
<…/some/root/path>/
- that is: the directory path starts with the string
- and the directory's parent is not the directory itself again
- this guards against the case of the root directory being the current directory (
.
) whose.parent
property is also.
(I'm am not sure anymore if this isn't subsumed the first rule however as".".startswith("./")
isFalse
either way…?
- this guards against the case of the root directory being the current directory (
I probably should a comment to the code about this, shouldn't I?
@Alexander255 Sorry for the delay in reviewing. I went through all the files. They look good to me. Some of the code snippets in the doc comments have incorrect imports. But I think we can fix them later on. Can we, in a future commit, shift all the test files to a separate folder outside? Please correct me if I am wrong:
|
@AliabbasMerchant I fixed travis problems in ntninja#1. @Alexander255 made changes you'd suggested. |
@AliabbasMerchant: Thank you for your review, better late than never I guess! 🙂
I think so, but they should be skipped in the test suite. I created #14 to document what I think
@swixx did that but it's waiting for this to be merged.
Created #16 about this.
Sure, now that the tests (almost) only use the public API, I seeno reason to keep them in those folders.
Yes to both.
No, mypy is only a dependency for type checking. It is not used during testing or in the final package otherwise. (However the stdlib If you are referring to this change. This is about forcing mypy to be downloaded in source form, so that mypy_run.py can monkey patch the use of some extra typing definitions into the mypy validator. (The previous form was incorrect and caused issues.) |
Great!
Yes, I was referring to that change. Got it 👍 Lets merge this! Then we can merge the Travis part that @swixx did, and #16 |
@AliabbasMerchant: Ok, I'll merge this once I added that comment to the filesystem.py source file. (Also I realized that the Probably later this evening or tomorrow. |
Okay. |
…tories should be used along with an explanation of what actually happens when this is done
try: | ||
parent = path.parent | ||
while str(parent).startswith(self.root_path + os.path.sep) \ | ||
# Attempt to remove all parent directories as long as the | ||
# parent directory 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.
Got it! Thanks!
It was a wise decision to use pathlib 👍
datastore
API again, everything important should now be exposed anddatastore.core.*
only needed by internal stuff