Mypy error creating a `CloudPath` instance
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! 😄
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....
I can confirm that the diagnostic is still present with cloudpathlib-0.15.1, which includes #330. (This is with mypy 1.5.1.)