-
-
Notifications
You must be signed in to change notification settings - Fork 173
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
Make scandir an optional dependency #44
Conversation
fs/osfs.py
Outdated
} | ||
} | ||
if 'details' in namespaces: | ||
stat_result = os.stat(entry_path) |
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.
Could you cache this os.stat
call? It could potentially be called several time. And perhaps you can use the stat
structure rather than isdir
on L412, because that will do a stat under the hood.
fs/osfs.py
Outdated
def _scandir(self, path, namespaces=None): | ||
|
||
|
||
def _scandir_c(self, path, namespaces=None): |
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'd like to suggest a slightly different way of doing the conditional.
try:
import scandir
except ImportError:
scandir = None
class OSFS:
if scandir:
def _scandir(self, path, namespaces=None, page=None):
# with scandir implementation
else:
def _scandir(self, path, namespaces=None, page=None):
# without scandir implementation
I think that's a little tidier than having separate _scandir_c
and scandir_py
functions. What do you think?
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.
At first that's what I wanted to do, but for the sake of testing it's easier to have the two methods accessible at all times, since your way involves reloading the module while mocking an import to be able to access the other implementation. But I'll give it a shot anyway.
setup.py
Outdated
@@ -37,7 +37,7 @@ | |||
description="Python's filesystem abstraction layer", | |||
install_requires=REQUIREMENTS, | |||
extras_require={ | |||
":python_version<'3.5'": ['scandir~=1.5'], | |||
"scandir : python_version < '3.5'": ['scandir~=1.5'], |
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 just merges a PR that might conflict with this. You might have to resolve it.
tests/test_osfs.py
Outdated
class TestOSFSScandir(OSFSTestBase, unittest.TestCase): | ||
|
||
def test_scandir_purepython(self): | ||
with mock.patch.object(self.fs, '_scandir', self.fs._scandir_py): |
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 think I see why you have the 2 functions defined now. I think you can modif tox.ini
file to have separate environments for with and without the scandir module. Otherwise its not going to include this in coverage.
Thanks! I concur. Only thing that concerns me is that scandir won't be installed on automatically in environments that it would easily install on. I guess that would just need to be documented. |
I'll try to resolve the conflicts shortly. For the automatic installation of scandir, I tried to search if there was a way to specify "default-but-not-mandatory" requirements, but no luck with that. At some point I thought restricting the installation of The # setup.py
import sys
import warnings
if sys.implementation.name == "cpython" and sys.version < "3.5":
try:
import scandir
except ImportError:
warnings.warn("Consider installing scandir blah blah blah...") |
Done, you can merge when you want. I added another environment to |
Brilliant. Thanks. |
Hi,
I just noticed while trying to install
fs
on thealpine-python
Docker image that it hadscandir
as a hard requirement. Sincescandir
is a C extension, this meant that 1. implementations other than CPython couldn't use Pyfilesystem2, and that 2. it required C compilation, so minimal builds needed to have both a C compiler and Python headers installed, both of which can weigh a lot.With the edits in that PR, the
scandir
module will be used if it can be found (eitherscandir
is installed or the version is superior to 3.5). In other cases, plainos.listdir
module will be used.