microsoft / pyright

Static Type Checker for Python
Other
13.15k stars 1.4k forks source link

Support inline script metadata on a pipx shebang #8902

Closed martin-braun closed 2 weeks ago

martin-braun commented 2 weeks ago

Is your feature request related to a problem? Please describe. There is a PEP for inline script metadata which is not part of Python yet, however pipx has already implemented it. Using pipx run, the following script successfully runs:

#!/usr/bin/env pipx run

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

import requests
from rich.pretty import pprint

resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])

# vi: ft=python

Pyright allows to explore the package in the virtual environment, but it fails to understand that they are not missing, since they are included as inline dependencies.

image

When I hover the imports, I get:

  • Import "requests" could not be resolved from source (Pyright reportMissingModuleSource)
  • Import "rich.pretty" could not be resolved (Pyright reportMissingImports)

Describe the solution you’d like See that I am using pipx in my shebang, and start to parsing the inline script metadata properly. Later, when Python has implemented this directly, you can just remove the shebang check again.

martin-braun commented 2 weeks ago

Current dirty workaround is to put this below the shebang:

# pyright: reportMissingModuleSource=false, reportMissingImports=false
erictraut commented 2 weeks ago

In general, this won't work for static analysis tools like pyright. The only reason this happens to (kind of) work for requests is because pyright happens to bundle type stubs (from typeshed) for this library. If you try to do this with most libraries, there will be no type information for pyright.

If you want to use static analysis tools like pyright, I recommend not using this new facility or using a real venv (with the script's dependencies properly installed) when you're doing your development. If you don't want to do this, the workaround you suggested is reasonable, but you won't have any type information for most dependencies.

martin-braun commented 1 week ago

@erictraut Thanks for looking into it and you are right, request was a false positive, none of my dependencies work.

From a consumer point of view this is still a very frustrating result. I know venv can solve it, but the reason why I explore programming Python with pipx run is it allows me to write simple script files that rely on non pre-installed modules, which is a blessing. I understand that I can have a solution that uses venv only for development and pipx run for the distributed version, but it's super redundant, causes a bloated development environment for simple scripting and so on.

I wish there was a way to make it work regardless, at least after running pipx run once, so that the dependencies are downloaded and available.