Skip to content

Typing – Traversable vs MultiplexedPath return value of files() #286

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

Closed
frenzymadness opened this issue Aug 2, 2023 · 1 comment
Closed

Comments

@frenzymadness
Copy link

Related to: python/cpython#106614 and #263

I see two possible workarounds for the mentioned issue:

str((files("jupyterlab_server.test_data") / "dummy").parent)

or

str(files("jupyterlab_server.test_data")._paths[0])

but both have issues with typing because the signature of files function is:

def files(anchor: Optional[Anchor] = None) -> Traversable:

In my specific case, files always returns MultiplexedPath so both workarounds are fine but mypy complains about it because Traversable neither has _paths not parent attributes.

When I tried to change the return value in the annotation from Traversable to MultiplexedPath mypy did not complain about it so it seems that the function cannot return anything else than MultiplexedPath. Is that correct? Would it make sense to make the type annotation more specific?

@jaraco
Copy link
Member

jaraco commented Aug 7, 2023

It's possible the current implementation of importlib resources will only return a MultiplexedPath, but the interface is extensible, with alternate resource providers directed to return objects conforming to the more general Traversable protocol.

But when I look at the code, the only reader that returns a MultiplexedPath is a NamespaceReader. That makes me think that other readers probably don't return MultiplexedPath.

Indeed, a standard module will return a pathlib.Path:

 draft @ mkdir foo
 draft @ touch foo/__init__.py
 draft @ pip-run importlib_resources
Python 3.11.4 (main, Jun 20 2023, 17:23:00) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import importlib_resources as res
>>> res.files('foo')
PosixPath('/Users/jaraco/draft/foo')

And ZipReader returns a ZipPath:

return ZipPath(self.archive, self.prefix)

mypy did not complain

Probably the reason it did not complain is that the type annotations are incomplete. Still, mypy should have been smart enough to detect that a FileReader by dint of being a TraversableResources will return a Traversable for files(), which may not be a MultiplexedPath.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants