pyfilesystem2: Bad namespacing, imports breaks setuptools
fs.dropboxfs is implemented using fs
as a namespace package. This causes it to misbehave when importing from fs
for several reasons:
fs
declares itself as a namespace package. According to the setuptools documentation here,
A) only namespace packages are supposed to contain the __import__('pkg_resources')...
B) they must not contain executable code aside from that import.
We violate both of those rules, thus resulting in weird exceptions like this:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/dargueta/dev/goodrx-data-scripts/airflow_dags/grx/third_party/dropbox.py", line 6, in <module>
from fs.dropboxfs import DropboxFS
File "/Users/dargueta/.pyenv/versions/2.7.15/envs/gds/lib/python2.7/site-packages/fs/dropboxfs/__init__.py", line 1, in <module>
from .dropboxfs import DropboxFile
File "/Users/dargueta/.pyenv/versions/2.7.15/envs/gds/lib/python2.7/site-packages/fs/dropboxfs/dropboxfs.py", line 12, in <module>
from fs.base import FS
File "/Users/dargueta/.pyenv/versions/2.7.15/envs/gds/lib/python2.7/site-packages/fs/base.py", line 24, in <module>
from . import copy, errors, fsencode, iotools, move, tools, walk, wildcard
ImportError: cannot import name fsencode
cannot import name fsencode
Changing that line to these two fixes the problem:
from . import copy, errors, iotools, move, tools, walk, wildcard
from ._fscompat import fsencode
There’s a similar issue in fs.test
:
# Broken
from fs import ResourceType, Seek
# Works
from fs.enums import ResourceType, Seek
It appears these are the only two places in the repo we do this. Fixing these imports gets us a separate weird error in code using fs.dropboxfs
but that may be unrelated.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 23 (17 by maintainers)
Not at all! We all learned something.
I recommend against publishing filesystems in the
fs
namespace. I can see the attraction of namespace packages, there is an appealing elegance about it. But in practice it’s a real pain to work with. Particularly in development. Namespace packages don’t play well with installing packages in editable mode for instance.So the official recommendations don’t use namespace packages. The only bit of magic required is the
entry_points
argument in setup.py which makes the filesystem available as an opener. In all other respects, you can publish a filesystem as any other Python module.That said, there are several
fs.
namespace packages on PyPi and AFAIK they work just fine. So I’d be surprised if there was some fundamental breakage there.I’ll do a deep dive in to namespace packages at some point, so I can properly evaluate @dargueta 's PR. In the meantime, our resident namespaces expert is @althonos If he’s not too busy, he might be able to shed some light on this.