Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Idea: allow assert with platform or version check at top of file #5308

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
gvanrossum opened this issue Jul 3, 2018 · 13 comments
Closed

Idea: allow assert with platform or version check at top of file #5308

gvanrossum opened this issue Jul 3, 2018 · 13 comments

Comments

@gvanrossum
Copy link
Member

Some files only work for certain platforms, but sometimes it's inconvenient to move the file to a location where it'll only be picked up for that platform. And yet the file doesn't type check cleanly on another platform (or ditto for Python versions).

We could enclose the entire file in if sys.platform == 'win32': but that seems overkill (and adding the indentation makes for an awkward diff). I propose an alternative that would have the same effect: assert sys.platform == 'win32'.

@JelleZijlstra
Copy link
Member

I like it.

Another (minor) problem with the approach of enclosing the entire file in if ...: is that mypy won't flag imports of the file, only attempts to use names from it. In other words, if we're using the if ...: approach and I'm not on Windows, I would not get an error for import only_on_windows, but only for only_on_windows.some_function(). This could be confusing for users.

@msullivan
Copy link
Collaborator

I think this is a good idea.

We also probably want to support this related idiom:

if sys.platform == 'linux':
    # stuff
elif sys.platform == 'darwin':
    # other stuff
else:
    assert False, "unsupported"

@emmatyping
Copy link
Member

@msullivan We already support platform checks. So if I run this:

import sys
if sys.platform == 'darwin':
    def f() -> str:
        return ''
else:
    assert False, "unsupported"
    
reveal_type(f)

on Linux, I get f is Any, as the name is not defined on Linux/Windows. Are you suggesting that there be an error on the line with assert False?

@gvanrossum
Copy link
Member Author

I think giving an error when mypy finds a reachable assert False is going to cause a lot of false positives. And detecting sequences of if-elif-elif-else where all tests are sys.platform checks seems complicated and not worth it.

Anyway, I just rechecked our original use case, and there we would actually want mypy to be silent if it finds a file containing assert sys.platform == 'win32' and the platform isn't 'win32'. The reason is that we statically compute a list of files to pass to mypy, and this file is always in it (the static computation is way too stupid to understand sys.platform checks). And on a non-win32 platform the contents of the file won't type-check at all (it imports other win32-specific modules, but since it is itself a win32-specific module, it doesn't wrap those in sys.platform checks). And the code that imports the module is inside a sys.platform check. And finally we don't want to edit the file to indent everything by an extra level and inserting a sys.platform check at the top, but we're fine adding a single assert at the top.

So really all I want is for mypy to silently ignore the rest of a file when it encounters a top-level assert with a sys.platform check in it.

@msullivan
Copy link
Collaborator

@ethanhs When I check that, I get:

lol.py:8: error: Revealed type is 'Any'
lol.py:8: error: Name 'f' is not defined

I don't mean giving an error on assert False, I mean suppressing the f not defined error (by not checking it).

This is prompted by a request from an internal user trying to run mypy on multiple platforms with some code that looks like what I had above.
But if supporting it directly is a pain we can easily require adding a toplevel assert, if we implement that.

@JukkaL
Copy link
Collaborator

JukkaL commented Jul 6, 2018

I like the top-level assert idea. It looks like this is something we should prioritize?

@gvanrossum
Copy link
Member Author

gvanrossum commented Jul 6, 2018 via email

@ilevkivskyi
Copy link
Member

This keeps coming, so I am raising priority to high.

@gvanrossum
Copy link
Member Author

To be clear, the implementation we're looking for is

for mypy to silently ignore the rest of a file when it encounters a top-level assert with a [non-matching] sys.platform check in it

@gvanrossum gvanrossum self-assigned this Nov 14, 2018
@gvanrossum
Copy link
Member Author

Would it be really lame if I implemented this only if the assert occurs at the top level in a file, without any indentation (i.e. not inside e.g. if, and certainly not inside a function)?

@JukkaL
Copy link
Collaborator

JukkaL commented Nov 14, 2018

Would it be really lame if I implemented this only if the assert occurs at the top level in a file, without any indentation

If that would be much easier implement than supporting this everywhere, I don' think that it would very lame. We'd just need to document it as a very specific feature -- ignoring the whole file (or anything after the assert) on some platform(s).

@gvanrossum
Copy link
Member Author

I think it would be much easier. In semanal_pass1.py we can just truncate the list of defs when we encounter such an assert.

gvanrossum pushed a commit to gvanrossum/mypy that referenced this issue Nov 14, 2018
- A top-level assert has no indentation.

- An always-false condition is a check for sys.platform or
  sys.version_info or a condition derived from MYPY or from a name
  passed to --always-false; `assert False` doesn't count (!).

Fixes python#5308
gvanrossum added a commit that referenced this issue Nov 15, 2018
- An always-false condition is a check for `sys.platform` or
  `sys.version_info` or a condition derived from `MYPY` or
 `typing.TYPE_CHECKING` or from a name passed to
  `--always-false`. Note that `assert False` doesn't count (!).

Fixes #5308
@ofek
Copy link

ofek commented May 1, 2025

What do we think about this? #19013

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

No branches or pull requests

7 participants