Skip to content
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

Code is unreachable when testing for os.name #470

Closed
GriceTurrble opened this issue Oct 8, 2020 · 5 comments
Closed

Code is unreachable when testing for os.name #470

GriceTurrble opened this issue Oct 8, 2020 · 5 comments

Comments

@GriceTurrble
Copy link

Environment data

  • Language Server version: 2020.9.8
  • OS and version: Windows 10 (relevant!)
  • Python version (& distribution if applicable, e.g. Anaconda): 3.7.6

Expected behaviour

Developing a server process with management commands that should only be run on posix systems. When I test for OS type using if os.name == 'nt', code below that block should show up as normal, with the assumption that it will be reached on a posix server.

Ideally, Pylance should not be marking any code as unreachable when using the os.name check: it cannot account for which system the code is expected to run on other than the development box where I'm writing it.

Actual behaviour

If a return or similar statement is used in the code block for os.name == 'nt', Pylance marks code below that block as "unreachable" when writing on a Windows system.

The same occurs in reverse, as well: if I use if os.name == 'posix', it will mark the inner code block as "unreachable" when writing on a Windows system.

Logs

Following is printed to Python Language server logs immediately after uncommenting the return statement in below snippet:

Background analysis message: setFileOpened
Background analysis message: markFilesDirty
Background analysis message: getSemanticTokens
[BG(1)] parsing: path/to/manage.py (17ms)
[BG(1)] binding: path/to/manage.py (1ms)
[FG] parsing: path/to/manage.py (4ms)
[FG] binding: path/to/manage.py (1ms)
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange
Background analysis message: analyze
[BG(1)] analyzing: path/to/manage.py ...
[BG(1)]   checking: path/to/manage.py (11ms)
[BG(1)] analyzing: path/to/manage.py (11ms)
Background analysis message: resumeAnalysis
Background analysis message: getDiagnosticsForRange
Background analysis message: getDiagnosticsForRange

Code Snippet / Additional information

# manage.py

if os.name == "nt":
    print("  Error: untested on Windows systems. No action taken.")
    return

# All code below here is marked "unreachable"
print("Hi, we're on a posix system")
@github-actions github-actions bot added the triage label Oct 8, 2020
@erictraut
Copy link
Contributor

By default, Pylance assumes that you will run your program on the same platform as the development environment. This is generally a good assumption and allows for the most accurate completion suggestions, especially in cases where there are platform-specific functions and methods.

If you are developing your code for cross-platform execution or for a platform other than the development environment, you can configure Pylance to assume otherwise. To do this, you will need to create a pyrightconfig.json file and specify a pythonPlatform configuration setting as documented here. If you want the code to run on all platforms, you can define `pythonPlatform" to be "All" (or any other value that does not match a specific platform).

@GriceTurrble
Copy link
Author

Noted, thanks!

@wxllow
Copy link

wxllow commented Aug 2, 2022

How come things like platform.system() are reachable but not os.name??

@erictraut
Copy link
Contributor

PEP 484 indicates that type checkers are supposed to understand "simple version and platform checks". The exact expression forms were not specified at the time PEP 484 was authored, but in the years since then, that list has been standardized and adopted by all Python type checkers, code analyzers, and typeshed type stubs. It includes:

  • bool literal expressions False or True
  • sys.version_info checks of the form sys.version_info >= (x, y) (where x and y are integer literals) or sys.version_info[0] >= x
  • sys.platform checks of the form sys.platform != 'X' where X is a string literal
  • os.name == 'X' where X is a string literal
  • The constant typing.TYPE_CHECKING
  • Combinations of the above forms that are combined with operators or, and and not

You will see these forms used consistently in typeshed stubs that describe behaviors that differ between Python versions or platforms.

The list doesn't include platform.system() or other expression forms.

@wxllow
Copy link

wxllow commented Aug 2, 2022

@erictraut ohh thank you for the info!

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

4 participants