You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a feature request, for mypy to enhance its static evaluation for boolean expressions involving sys.platform/sys.version_info to also handle expressions like hasattr(module_object, "constant string").
typeshed contains if sys.platform == ... checks that try to approximate the runtime availability. Example
then mypy statically evaluates these checks, so it knows which functions/constants/etc. are available
So that works about as well as anything could. The static approximations aren't always exactly correct (e.g. the epoll example linked above gives the wrong answer on illumos), but they're "good enough" and can be improved over time if they cause problems.
Now we're trying to figure out how to add type annotations, and it's super awkward. So far our best attempt for the basic platform differences looks like:
ifsys.platform=="win32":
...
elifsys.platform=="linux"or (notTYPE_CHECKINGandhasattr(select, "epoll")):
...
# At type-checking time, assume that all platforms that aren't win32 or linux are some kind of BSDelifTYPE_CHECKINGor (notTYPE_CHECKINGandhasattr(select, "kqueue")):
...
else:
raiseNotImplementedError
This has a few problems:
it's complex and awkward
it requires manually duplicating information that's already in typeshed
it requires manually propagating any typeshed changes into our project (which seems plausible, since typeshed often contains rough approximations for platform-specific stuff)
it requires copy/pasting this whole complex construct in multiple places around our code-base
This is a bit frustrating. It would be nice if mypy could just understand if hasattr(select, "epoll") and do the right thing. It already has all the information it needs to do that.
The text was updated successfully, but these errors were encountered:
Not sure if this was suggested before, or how hard it will be, but a generalization would be to:
Type getattr(obj, "attr"), where attr is a single str Literal, as obj.attr if attr statically exists on obj, and Any otherwise (could have a strictness flag which turns it into an attr-defined error).
Type getattr(obj, "attr", default), where attr is a single str Literal, as obj.attr if attr statically exists on obj, and the type of default otherwise.
This is generally useful (I wanted it a few times). For the feature-checking use case you could do if getattr(select, 'epoll', None) is not None.
@bluetech I think that should be discussed in a separate issue. In particular, this isn't about how expressions are typed, but about which expressions mypy will evaluate statically when deciding to entirely skip over a block of code, and currently that set of expressions is very limited (basically just and/or/TYPE_CHECKING/sys.platform/sys.version_info).
For the feature-checking use case you could do if getattr(select, 'epoll', None) is not None.
This would require a lot of additional complexity in the skip-over-statically-evaluable-branches code, and it's not at all clear that you'd even want to skip type-checking code inside a if guarded by getattr. There's a reason my proposal is restricted to just the pattern hasattr(module_object, "literal string"), only :-)
This is a feature request, for mypy to enhance its static evaluation for boolean expressions involving
sys.platform
/sys.version_info
to also handle expressions likehasattr(module_object, "constant string")
.background
A common idiom in the standard library is to have functions/constants/etc. that are only exposed on certain platforms. For example,
select.epoll
only exists on Linux and illumos,socket.fromshare
only exists on Windows, andos.preadv
only exists on "Linux 2.6.30 and newer, FreeBSD 6.0 and newer, OpenBSD 2.7 and newer".Currently, the way mypy handles these cases is:
if sys.platform == ...
checks that try to approximate the runtime availability. ExampleSo that works about as well as anything could. The static approximations aren't always exactly correct (e.g. the
epoll
example linked above gives the wrong answer on illumos), but they're "good enough" and can be improved over time if they cause problems.the problem
Say we have a library which wants to use or expose certain features in its API depending on whether or not the standard library exposes those features. For example, in Trio we define our
IOManager
class differently depending on whetherselect.epoll
andselect.kqueue
exist, and we export atrio.socket.fromshare
function iff there's asocket.fromshare
.Now we're trying to figure out how to add type annotations, and it's super awkward. So far our best attempt for the basic platform differences looks like:
This has a few problems:
This is a bit frustrating. It would be nice if mypy could just understand
if hasattr(select, "epoll")
and do the right thing. It already has all the information it needs to do that.The text was updated successfully, but these errors were encountered: