cloudpathlib icon indicating copy to clipboard operation
cloudpathlib copied to clipboard

Mypy error creating a `CloudPath` instance

Open connorbrinton opened this issue 2 years ago • 3 comments

Description

Currently, type-checking a very simple script that uses cloudpathlib with Mypy fails with an error.

Script:

from cloudpathlib import CloudPath

path = CloudPath("s3://abc/xyz")

Mypy error:

test.py:3: error: Cannot instantiate abstract class "CloudPath" with abstract attributes "drive", "is_dir", "is_file", "mkdir" and "touch"  [abstract]

Cause

I believe this is a result of the fact that Mypy doesn't yet understand the __call__ method on metaclasses.

Workarounds

Specific Subclass

One way to avoid this error is for end users to directly use implementation-specific CloudPath subclasses. The following script produces no Mypy errors:

from cloudpathlib import S3Path

path = S3Path("s3://abc/xyz")

This slightly limits portability of end user scripts, but is one possible way to avoid the error.

Ignore Directive

The error can also be ignored with a # type: ignore[abstract] directive:

from cloudpathlib import CloudPath

path = CloudPath("s3://abc/xyz")  # type: ignore[abstract]

New Method

Lastly, some changes could be made to how CloudPath instances are constructed to work around this issue. However, this would introduce a new way of instantiating CloudPath instances, which could be confusing.

One option would be to add a CloudPath.from_url class method, which would just return CloudPath(url). This way, the Mypy error could be ignored in the cloudpathlib codebase rather than user code.

Another option would be to implement cloud provider-specific dispatching in the new CloudPath.from_url class method, then have CloudPathMeta.__call__ delegate to CloudPath.from_url for its implementation. This wouldn't require any new ignore directives in the cloudpathlib codebase.

In any case, I didn't find any issues describing this behavior elsewhere, so hopefully this is helpful to others who run into this same issue in the future 🙂

Thanks for maintaining cloudpathlib! 😄

connorbrinton avatar May 08 '23 14:05 connorbrinton

Thanks for the detailed report @connorbrinton. I'd be curious if #330 helps with this issue or not.

Hopefully there's an upstream mypy fix for __call__ because the ergonomics of the existing API are nice as is....

pjbull avatar May 25 '23 18:05 pjbull

I can confirm that the diagnostic is still present with cloudpathlib-0.15.1, which includes #330. (This is with mypy 1.5.1.)

jmarshall avatar Aug 23 '23 01:08 jmarshall