diff --git a/README.md b/README.md index dce7ee2..2947958 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,9 @@ By default Pyright for Python is set to target a specific pyright version and ne If you would rather not have to update your installation every time a new pyright release is created then you can automatically use the latest available pyright version by setting the environment variable `PYRIGHT_PYTHON_FORCE_VERSION` to `latest`. +To force the use of bundled pyright version and skip the automatic version check at start-up, +set the environment variable `PYRIGHT_PYTHON_OFFLINE` to a truthy value, e.g. 1, t, on, or true. + ## Configuration You can configure Pyright for Python using environment variables. diff --git a/src/pyright/_utils.py b/src/pyright/_utils.py index aba347f..df0ee2d 100644 --- a/src/pyright/_utils.py +++ b/src/pyright/_utils.py @@ -34,16 +34,26 @@ def install_pyright(args: tuple[object, ...], *, quiet: bool | None) -> Path: which are used to determine whether or not certain warnings / logs will be printed. """ version = _get_configured_pyright_version() - if version == 'latest': - version = node.latest('pyright') - else: - if _should_warn_version(args=args, quiet=quiet): + + use_bundled = env_to_bool('PYRIGHT_PYTHON_USE_BUNDLED_PYRIGHT', default=True) + offline_mode = env_to_bool('PYRIGHT_PYTHON_OFFLINE', default=False) + if offline_mode: + if version != __pyright_version__ or not use_bundled: print( - f'WARNING: there is a new pyright version available (v{version} -> v{get_latest_version()}).\n' - + 'Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`\n' + f'Offline mode: unable to use a pyright version other than the bundled one ({__pyright_version__}).\n' + + 'Please remove incompatible PYRIGHT_PYTHON_* environment variables', + file=sys.stderr, ) + sys.exit(1) + elif version == 'latest': + version = node.latest('pyright') + elif _should_warn_version(args=args, quiet=quiet): + print( + f'WARNING: there is a new pyright version available (v{version} -> v{get_latest_version()}).\n' + + 'Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`\n' + ) - if version == __pyright_version__ and env_to_bool('PYRIGHT_PYTHON_USE_BUNDLED_PYRIGHT', default=True): + if version == __pyright_version__ and use_bundled: bundled_path = Path(__file__).parent.joinpath('dist') if bundled_path.exists(): log.debug('using bundled pyright at %s', bundled_path) diff --git a/tests/test_main.py b/tests/test_main.py index d3735f0..e37efb5 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -185,7 +185,6 @@ def test_output_json_no_warning() -> None: @network def test_ignore_warnings_config_no_warning() -> None: - """If the --outputjson flag is set then no warning is emitted""" proc = subprocess.run( [sys.executable, '-m', 'pyright', '--version'], check=True, @@ -201,6 +200,28 @@ def test_ignore_warnings_config_no_warning() -> None: assert 'WARNING: there is a new pyright version available' not in output +@pytest.mark.xfail( + condition=sys.platform != 'linux', + reason='Network namespace isolation requires Linux', +) +def test_offline_mode_ok() -> None: + is_root = os.geteuid() == 0 + user_ns = () if is_root else ('--user', '--map-root-user') + proc = subprocess.run( + ['unshare', *user_ns, '--net', sys.executable, '-m', 'pyright', '--version'], + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=dict( + os.environ, + PYRIGHT_PYTHON_OFFLINE='1', + ), + ) + assert not proc.stderr + match = assert_matches(VERSION_REGEX, proc.stdout.decode('utf-8')) + assert match.group(1) == __pyright_version__ + + @network def test_nodeenv() -> None: """Ensure nodeenv is successfully downloaded and used"""