diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index c63a588df..4859b8b94 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -2,6 +2,7 @@ name: 'Validation' env: NODE_VERSION: '16' # Shipped with VS Code. + PYTHON_VERSION: 3.11 on: push: @@ -111,6 +112,48 @@ jobs: run: npm test working-directory: packages/pyright-internal + # Install python so we can create a VENV for tests + - name: Use Python ${{env.PYTHON_VERSION}} + uses: actions/setup-python@v4 + id: install_python + with: + python-version: ${{env.PYTHON_VERSION}} + + - name: Create Venv + run: | + ${{ steps.install_python.outputs.python-path }} -m venv .venv + + - name: Activate and install pytest (linux) + if: runner.os != 'Windows' + run: | + source .venv/bin/activate + python -m pip install pytest + python -c "import sys;print('python_venv_path=' + sys.executable)" >> $GITHUB_ENV + + - name: Activate and install pytest (windows) + if: runner.os == 'Windows' + run: | + .venv\scripts\activate + python -m pip install pytest + python -c "import sys;print('python_venv_path=' + sys.executable)" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Echo python_venv_path + run: | + echo python_venv_path=${{env.python_venv_path}} + + - name: Run import tests with venv + env: + CI_IMPORT_TEST_VENVPATH: '../../' + CI_IMPORT_TEST_VENV: '.venv' + run: npm run test:imports + working-directory: packages/pyright-internal + + - name: Run import tests with pythonpath + env: + CI_IMPORT_TEST_PYTHONPATH: ${{env.python_venv_path}} + run: npm run test:imports + working-directory: packages/pyright-internal + build: runs-on: ubuntu-latest name: Build diff --git a/.gitignore b/.gitignore index d31a03c4b..6d9fd0bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -122,4 +122,7 @@ junit.xml # OS files .DS_Store -Thumbs.db \ No newline at end of file +Thumbs.db + +# Potential venv +.venv \ No newline at end of file diff --git a/docs/configuration.md b/docs/configuration.md index 76a1cea8c..c0fbe378a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -58,7 +58,9 @@ The following settings control pyright’s diagnostic output (warnings or errors **deprecateTypingAliases** [boolean]: PEP 585 indicates that aliases to types in standard collections that were introduced solely to support generics are deprecated as of Python 3.9. This switch controls whether these are treated as deprecated. This applies only when pythonVersion is 3.9 or newer. The default value for this setting is `false` but may be switched to `true` in the future. - **enableExperimentalFeatures** [boolean]: Enables a set of experimental (mostly undocumented) features that correspond to proposed or exploratory changes to the Python typing standard. These features will likely change or be removed, so they should not be used except for experimentation purposes. + **enableExperimentalFeatures** [boolean]: Enables a set of experimental (mostly undocumented) features that correspond to proposed or exploratory changes to the Python typing standard. These features will likely change or be removed, so they should not be used except for experimentation purposes. The default value for this setting is `false`. + + **disableBytesTypePromotions** [boolean]: Disables legacy behavior where `bytearray` and `memoryview` are considered subtypes of `bytes`. [PEP 688](https://peps.python.org/pep-0688/#no-special-meaning-for-bytes) deprecates this behavior, but this switch is provided to restore the older behavior. The default value for this setting is `false`. **reportGeneralTypeIssues** [boolean or string, optional]: Generate or suppress diagnostics for general type inconsistencies, unsupported operations, argument/parameter mismatches, etc. This covers all of the basic type-checking rules not covered by other rules. It does not include syntax errors. The default value for this setting is `"error"`. @@ -184,7 +186,7 @@ The following settings control pyright’s diagnostic output (warnings or errors **reportMatchNotExhaustive** [boolean or string, optional]: Generate or suppress diagnostics for a `match` statement that does not provide cases that exhaustively match against all potential types of the target expression. The default value for this setting is `"none"`. - **reportImplicitOverride** [boolean or string, optional]: Generate or suppress diagnostics for overridden methods in a class that are missing an explicit `@override` decorator. + **reportImplicitOverride** [boolean or string, optional]: Generate or suppress diagnostics for overridden methods in a class that are missing an explicit `@override` decorator. The default value for this setting is `"none"`. **reportShadowedImports** [boolean or string, optional]: Generate or suppress diagnostics for files that are overriding a module in the stdlib. The default value for this setting is `"none"`. @@ -303,6 +305,7 @@ The following table lists the default severity levels for each diagnostic rule w | analyzeUnannotatedFunctions | true | true | true | | strictParameterNoneValue | true | true | true | | enableTypeIgnoreComments | true | true | true | +| disableBytesTypePromotions | false | false | true | | strictListInference | false | false | true | | strictDictionaryInference | false | false | true | | strictSetInference | false | false | true | diff --git a/docs/features.md b/docs/features.md index a5373a889..d260cc8ed 100644 --- a/docs/features.md +++ b/docs/features.md @@ -34,7 +34,9 @@ Pyright supports [configuration files](configuration.md) that provide granular c * [PEP 696](https://www.python.org/dev/peps/pep-0696/) (draft) type defaults for TypeVarLikes * [PEP 698](https://www.python.org/dev/peps/pep-0698/) override decorator for static typing * [PEP 702](https://www.python.org/dev/peps/pep-0702/) (draft) marking deprecations +* [PEP 705](https://www.python.org/dev/peps/pep-0705/) (draft) TypedDict: read-only items * [PEP 712](https://www.python.org/dev/peps/pep-0712/) (draft) converter parameter on dataclasses.field +* [PEP 724](https://www.python.org/dev/peps/pep-0724/) (draft) stricter type guards * Type inference for function return values, instance variables, class variables, and globals * Type guards that understand conditional code flow constructs like if/else statements diff --git a/docs/import-resolution.md b/docs/import-resolution.md index e118b4122..0e1741ce4 100644 --- a/docs/import-resolution.md +++ b/docs/import-resolution.md @@ -41,19 +41,9 @@ Pyright uses the following mechanisms (in priority order) to determine which Pyt ### Editable installs -[PEP 660](https://peps.python.org/pep-0660/) enables build backends (e.g. setuptools) to -use import hooks to direct the [import machinery](https://docs.python.org/3/reference/import.html) -to the package’s source files rather than using a `.pth` file. Import hooks can provide -an editable installation that is a more accurate representation of your real installation. -However, because resolving module locations using an import hook requires executing Python -code, they are not usable by Pyright and other static analysis tools. Therefore, if your -editable install is configured to use import hooks, Pyright will be unable to find the -corresponding source files. - -If you want to use static analysis tools with an editable install, you should configure -the editable install to use `.pth` files instead of import hooks. See your build backend’s -documentation for details on how to do this. We have provided some basic information for -common build backends below. +[PEP 660](https://peps.python.org/pep-0660/) enables build backends (e.g. setuptools) to use import hooks to direct the [import machinery](https://docs.python.org/3/reference/import.html) to the package’s source files rather than putting the path to those files in a `.pth` file. Import hooks can provide an editable installation that is a more accurate representation of your real installation. However, because resolving module locations using an import hook requires executing Python code, they are not usable by Pyright and other static analysis tools. Therefore, if your editable install is configured to use import hooks, Pyright will be unable to find the corresponding source files. + +If you want to use static analysis tools with an editable install, you should configure the editable install to use `.pth` files that contain file paths rather than executable lines (prefixed with `import`) that install import hooks. See your build backend’s documentation for details on how to do this. We have provided some basic information for common build backends below. #### Setuptools Setuptools currently supports two ways to request: diff --git a/docs/mypy-comparison.md b/docs/mypy-comparison.md index a380b1572..8bf0bd5a1 100644 --- a/docs/mypy-comparison.md +++ b/docs/mypy-comparison.md @@ -152,7 +152,6 @@ Pyright supports several built-in type guards that mypy does not currently suppo The following expression forms are not currently supported by mypy as type guards: * `x == L` and `x != L` (where L is an expression with a literal type) -* `len(x) == L` and `len(x) != L` (where x is tuple and L is a literal integer) * `x in y` or `x not in y` (where y is instance of list, set, frozenset, deque, tuple, dict, defaultdict, or OrderedDict) * `bool(x)` (where x is any expression that is statically verifiable to be truthy or falsey in all cases) diff --git a/docs/settings.md b/docs/settings.md index 8f0d0e804..7f93f767e 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -18,8 +18,14 @@ The Pyright language server honors the following settings. **python.analysis.diagnosticSeverityOverrides** [map]: Allows a user to override the severity levels for individual diagnostic rules. "reportXXX" rules in the type check diagnostics settings in [configuration](configuration.md#type-check-diagnostics-settings) are supported. Use the rule name as a key and one of "error," "warning," "information," "true," "false," or "none" as value. +**python.analysis.exclude** [array of paths]: Paths of directories or files that should not be included. This can be overridden in the configuration file. + **python.analysis.extraPaths** [array of paths]: Paths to add to the default execution environment extra paths if there are no execution environments defined in the config file. +**python.analysis.ignore** [array of paths]: Paths of directories or files whose diagnostic output (errors and warnings) should be suppressed. This can be overridden in the configuration file. + +**python.analysis.include** [array of paths]: Paths of directories or files that should be included. This can be overridden in the configuration file. + **python.analysis.logLevel** ["Error", "Warning", "Information", or "Trace"]: Level of logging for Output panel. The default value for this option is "Information". **python.analysis.stubPath** [path]: Path to directory containing custom type stub files. diff --git a/docs/type-concepts-advanced.md b/docs/type-concepts-advanced.md index ba7bd8963..69e072c2d 100644 --- a/docs/type-concepts-advanced.md +++ b/docs/type-concepts-advanced.md @@ -71,7 +71,7 @@ In addition to assignment-based type narrowing, Pyright supports the following t * `x[I] == V` and `x[I] != V` (where I and V are literal expressions and x is a known-length tuple that is distinguished by the index indicated by I) * `x[I] is B` and `x[I] is not B` (where I is a literal expression, B is a `bool` or enum literal, and x is a known-length tuple that is distinguished by the index indicated by I) * `x[I] is None` and `x[I] is not None` (where I is a literal expression and x is a known-length tuple that is distinguished by the index indicated by I) -* `len(x) == L` and `len(x) != L` (where x is tuple and L is a literal integer) +* `len(x) == L` and `len(x) != L` (where x is tuple and L is an expression that evaluates to an int literal type) * `x in y` or `x not in y` (where y is instance of list, set, frozenset, deque, tuple, dict, defaultdict, or OrderedDict) * `S in D` and `S not in D` (where S is a string literal and D is a TypedDict) * `isinstance(x, T)` (where T is a type or a tuple of types) @@ -319,7 +319,7 @@ Some functions or methods can return one of several different types. In cases wh [PEP 484](https://www.python.org/dev/peps/pep-0484/#function-method-overloading) introduced the `@overload` decorator and described how it can be used, but the PEP did not specify precisely how a type checker should choose the “best” overload. Pyright uses the following rules. -1. Pyright first filters the list of overloads based on simple “arity” (number of arguments) and keyword argument matching. For example, if one overload requires two position arguments but only one positional argument is supplied by the caller, that overload is eliminated from consideration. Likewise, if the call includes a keyword argument but no corresponding parameter is included in the overload, it is eliminated from consideration. +1. Pyright first filters the list of overloads based on simple “arity” (number of arguments) and keyword argument matching. For example, if one overload requires two positional arguments but only one positional argument is supplied by the caller, that overload is eliminated from consideration. Likewise, if the call includes a keyword argument but no corresponding parameter is included in the overload, it is eliminated from consideration. 2. Pyright next considers the types of the arguments and compares them to the declared types of the corresponding parameters. If the types do not match for a given overload, that overload is eliminated from consideration. Bidirectional type inference is used to determine the types of the argument expressions. @@ -329,7 +329,7 @@ Some functions or methods can return one of several different types. In cases wh Exception 1: When an `*args` (unpacked) argument matches a `*args` parameter in one of the overload signatures, this overrides the normal order-based rule. Exception 2: When two or more overloads match because an argument evaluates to `Any` or `Unknown`, the matching overload is ambiguous. In this case, pyright examines the return types of the remaining overloads and eliminates types that are duplicates or are subsumed by (i.e. proper subtypes of) other types in the list. If only one type remains after this coalescing step, that type is used. If more than one type remains after this coalescing step, the type of the call expression evaluates to `Unknown`. For example, if two overloads are matched due to an argument that evaluates to `Any`, and those two overloads have return types of `str` and `LiteralString`, pyright will coalesce this to just `str` because `LiteralString` is a proper subtype of `str`. If the two overloads have return types of `str` and `bytes`, the call expression will evaluate to `Unknown` because `str` and `bytes` have no overlap. -5. If no overloads remain, Pyright considers whether any of the arguments are union types. If so, these union types are expanded into their constituent subtypes, and the entire process of overload matching is repeated with the expanded argument types. If two or more overloads match, the union of their respective return types form the final return type for the call expression. +5. If no overloads remain, Pyright considers whether any of the arguments are union types. If so, these union types are expanded into their constituent subtypes, and the entire process of overload matching is repeated with the expanded argument types. If two or more overloads match, the union of their respective return types form the final return type for the call expression. This "union expansion" can result in a combinatoric explosion if many arguments evaluate to union types. For example, if four arguments are present, and they all evaluate to unions that expand to ten subtypes, this could result in 10^4 combinations. Pyright expands unions for arguments left to right and halts expansion when the number of signatures exceeds 64. 6. If no overloads remain and all unions have been expanded, a diagnostic is generated indicating that the supplied arguments are incompatible with all overload signatures. diff --git a/lerna.json b/lerna.json index 986cdcf78..c3ad27c1e 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "1.1.328", + "version": "1.1.334", "command": { "version": { "push": false, diff --git a/packages/pyright-internal/package-lock.json b/packages/pyright-internal/package-lock.json index 0b330fa16..7342ce189 100644 --- a/packages/pyright-internal/package-lock.json +++ b/packages/pyright-internal/package-lock.json @@ -1,12 +1,12 @@ { "name": "pyright-internal", - "version": "1.1.328", + "version": "1.1.334", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "pyright-internal", - "version": "1.1.328", + "version": "1.1.334", "license": "MIT", "dependencies": { "@iarna/toml": "2.2.5", @@ -53,17 +53,74 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { "version": "7.22.9", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", @@ -110,12 +167,12 @@ "dev": true }, "node_modules/@babel/generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz", - "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -144,22 +201,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -251,9 +308,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -283,13 +340,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -353,9 +410,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", - "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -542,33 +599,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", - "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.7", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -577,13 +634,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -4008,12 +4065,56 @@ } }, "@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/compat-data": { @@ -4054,12 +4155,12 @@ } }, "@babel/generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz", - "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "requires": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -4079,19 +4180,19 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { @@ -4156,9 +4257,9 @@ "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -4179,13 +4280,13 @@ } }, "@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -4233,9 +4334,9 @@ } }, "@babel/parser": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", - "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -4365,42 +4466,42 @@ } }, "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.22.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", - "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.7", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, diff --git a/packages/pyright-internal/package.json b/packages/pyright-internal/package.json index 1de6cbf9d..e3b14c116 100644 --- a/packages/pyright-internal/package.json +++ b/packages/pyright-internal/package.json @@ -2,7 +2,7 @@ "name": "pyright-internal", "displayName": "pyright", "description": "Type checker for the Python language", - "version": "1.1.328", + "version": "1.1.334", "license": "MIT", "private": true, "files": [ @@ -12,7 +12,8 @@ "build": "tsc", "clean": "shx rm -rf ./dist ./out", "test": "jest --forceExit", - "test:coverage": "jest --forceExit --reporters=jest-junit --reporters=default --coverage --coverageReporters=cobertura --coverageReporters=html --coverageReporters=json" + "test:coverage": "jest --forceExit --reporters=jest-junit --reporters=default --coverage --coverageReporters=cobertura --coverageReporters=html --coverageReporters=json", + "test:imports": "jest importResolver.test --forceExit --runInBand" }, "dependencies": { "@iarna/toml": "2.2.5", diff --git a/packages/pyright-internal/src/analyzer/analyzerFileInfo.ts b/packages/pyright-internal/src/analyzer/analyzerFileInfo.ts index b1a5cac64..785871346 100644 --- a/packages/pyright-internal/src/analyzer/analyzerFileInfo.ts +++ b/packages/pyright-internal/src/analyzer/analyzerFileInfo.ts @@ -57,6 +57,7 @@ export interface AnalyzerFileInfo { isStubFile: boolean; isTypingStubFile: boolean; isTypingExtensionsStubFile: boolean; + isTypeshedStubFile: boolean; isBuiltInStubFile: boolean; isInPyTypedPackage: boolean; ipythonMode: IPythonMode; diff --git a/packages/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts b/packages/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts index a43d5ac10..d40d71100 100644 --- a/packages/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts +++ b/packages/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts @@ -15,7 +15,6 @@ import { Diagnostic } from '../common/diagnostic'; import { FileDiagnostics } from '../common/diagnosticSink'; import { Range } from '../common/textRange'; import { AnalysisCompleteCallback, analyzeProgram } from './analysis'; -import { CacheManager } from './cacheManager'; import { ImportResolver } from './importResolver'; import { MaxAnalysisTime, OpenFileOptions, Program } from './program'; import { ServiceProvider } from '../common/serviceProvider'; @@ -41,8 +40,7 @@ export class BackgroundAnalysisProgram { private _importResolver: ImportResolver, private _backgroundAnalysis?: BackgroundAnalysisBase, private readonly _maxAnalysisTime?: MaxAnalysisTime, - private readonly _disableChecker?: boolean, - cacheManager?: CacheManager + private readonly _disableChecker?: boolean ) { this._program = new Program( this.importResolver, @@ -50,7 +48,6 @@ export class BackgroundAnalysisProgram { this._serviceProvider, undefined, this._disableChecker, - cacheManager, serviceId ); } @@ -166,7 +163,11 @@ export class BackgroundAnalysisProgram { ); } - analyzeFile(filePath: string, token: CancellationToken): boolean { + async analyzeFile(filePath: string, token: CancellationToken): Promise { + if (this._backgroundAnalysis) { + return this._backgroundAnalysis.analyzeFile(filePath, token); + } + return this._program.analyzeFile(filePath, token); } @@ -276,6 +277,5 @@ export type BackgroundAnalysisProgramFactory = ( configOptions: ConfigOptions, importResolver: ImportResolver, backgroundAnalysis?: BackgroundAnalysisBase, - maxAnalysisTime?: MaxAnalysisTime, - cacheManager?: CacheManager + maxAnalysisTime?: MaxAnalysisTime ) => BackgroundAnalysisProgram; diff --git a/packages/pyright-internal/src/analyzer/binder.ts b/packages/pyright-internal/src/analyzer/binder.ts index 385f86020..638cdb24a 100644 --- a/packages/pyright-internal/src/analyzer/binder.ts +++ b/packages/pyright-internal/src/analyzer/binder.ts @@ -644,16 +644,7 @@ export class Binder extends ParseTreeWalker { this._disableTrueFalseTargets(() => { this.walk(node.leftExpression); - // Sort all keyword arguments to the end of the parameter list. This is - // necessary because all positional arguments (including *args) are evaluated - // prior to any keyword arguments at runtime. - const positionalArgs = node.arguments.filter( - (arg) => !arg.name && arg.argumentCategory !== ArgumentCategory.UnpackedDictionary - ); - const keywordArgs = node.arguments.filter( - (arg) => !!arg.name || arg.argumentCategory === ArgumentCategory.UnpackedDictionary - ); - const sortedArgs = positionalArgs.concat(keywordArgs); + const sortedArgs = ParseTreeUtils.getArgumentsByRuntimeOrder(node); sortedArgs.forEach((argNode) => { if (this._currentFlowNode) { diff --git a/packages/pyright-internal/src/analyzer/cacheManager.ts b/packages/pyright-internal/src/analyzer/cacheManager.ts index 63e2299f8..3e23fb6fb 100644 --- a/packages/pyright-internal/src/analyzer/cacheManager.ts +++ b/packages/pyright-internal/src/analyzer/cacheManager.ts @@ -100,3 +100,16 @@ export class CacheManager { return `${Math.round(bytes / (1024 * 1024))}MB`; } } + +export namespace CacheManager { + export function is(obj: any): obj is CacheManager { + return ( + obj.registerCacheOwner !== undefined && + obj.unregisterCacheOwner !== undefined && + obj.pauseTracking !== undefined && + obj.getCacheUsage !== undefined && + obj.emptyCache !== undefined && + obj.getUsedHeapRatio !== undefined + ); + } +} diff --git a/packages/pyright-internal/src/analyzer/checker.ts b/packages/pyright-internal/src/analyzer/checker.ts index b5afb2fa7..4b9bf06bd 100644 --- a/packages/pyright-internal/src/analyzer/checker.ts +++ b/packages/pyright-internal/src/analyzer/checker.ts @@ -113,7 +113,7 @@ import { Symbol } from './symbol'; import * as SymbolNameUtils from './symbolNameUtils'; import { getLastTypedDeclaredForSymbol } from './symbolUtils'; import { maxCodeComplexity } from './typeEvaluator'; -import { FunctionTypeResult, TypeEvaluator, TypeResult } from './typeEvaluatorTypes'; +import { FunctionTypeResult, MemberAccessDeprecationInfo, TypeEvaluator, TypeResult } from './typeEvaluatorTypes'; import { getElementTypeForContainerNarrowing, isIsinstanceFilterSubclass, @@ -139,6 +139,7 @@ import { getTypeVarScopeId, isLiteralType, isLiteralTypeOrUnion, + isNoneInstance, isPartlyUnknown, isProperty, isTupleClass, @@ -146,6 +147,7 @@ import { lookUpClassMember, mapSubtypes, partiallySpecializeType, + selfSpecializeClass, transformPossibleRecursiveTypeAlias, } from './typeUtils'; import { TypeVarContext } from './typeVarContext'; @@ -155,7 +157,6 @@ import { ClassTypeFlags, FunctionType, FunctionTypeFlags, - NoneType, OverloadedFunctionType, Type, TypeBase, @@ -171,7 +172,6 @@ import { isInstantiableClass, isModule, isNever, - isNoneInstance, isOverloadedFunction, isParamSpec, isPossiblyUnbound, @@ -331,15 +331,14 @@ export class Checker extends ParseTreeWalker { this._validateProtocolTypeParamVariance(node, classTypeResult.classType); } - // Skip the overrides check for stub files. Many of the built-in - // typeshed stub files trigger this diagnostic. Also skip the slots - // check because class variables declared in a stub file are - // interpreted as instance variables. + // Skip the slots check because class variables declared in a stub + // file are interpreted as instance variables. if (!this._fileInfo.isStubFile) { - this._validateBaseClassOverrides(classTypeResult.classType); this._validateSlotsClassVarConflict(classTypeResult.classType); } + this._validateBaseClassOverrides(classTypeResult.classType); + this._validateMultipleInheritanceBaseClasses(classTypeResult.classType, node.name); this._validateMultipleInheritanceCompatibility(classTypeResult.classType, node.name); @@ -875,7 +874,7 @@ export class Checker extends ParseTreeWalker { returnTypeResult = this._evaluator.getTypeResult(node.returnExpression) ?? { type: UnknownType.create() }; } else { // There is no return expression, so "None" is assumed. - returnTypeResult = { type: NoneType.createInstance() }; + returnTypeResult = { type: this._evaluator.getNoneType() }; } // If the enclosing function is async and a generator, the return @@ -996,8 +995,14 @@ export class Checker extends ParseTreeWalker { } override visitYield(node: YieldNode) { - const yieldType = node.expression ? this._evaluator.getType(node.expression) : NoneType.createInstance(); - this._validateYieldType(node, yieldType || UnknownType.create()); + const yieldTypeResult = node.expression + ? this._evaluator.getTypeResult(node.expression) + : { type: this._evaluator.getNoneType() }; + this._validateYieldType( + node, + yieldTypeResult?.type ?? UnknownType.create(), + yieldTypeResult?.expectedTypeDiagAddendum + ); return true; } @@ -1028,7 +1033,7 @@ export class Checker extends ParseTreeWalker { } } - this._validateYieldType(node, yieldType, sendType); + this._validateYieldType(node, yieldType, /* expectedDiagAddendum */ undefined, sendType); return true; } @@ -1418,7 +1423,7 @@ export class Checker extends ParseTreeWalker { // Report the use of a deprecated symbol. const type = this._evaluator.getType(node); - this._reportDeprecatedUse(node, type); + this._reportDeprecatedUseForType(node, type); return true; } @@ -1434,15 +1439,20 @@ export class Checker extends ParseTreeWalker { } override visitMemberAccess(node: MemberAccessNode) { - const type = this._evaluator.getType(node); + const typeResult = this._evaluator.getTypeResult(node); + const type = typeResult?.type ?? UnknownType.create(); const leftExprType = this._evaluator.getType(node.leftExpression); - this._reportDeprecatedUse( + this._reportDeprecatedUseForType( node.memberName, type, leftExprType && isModule(leftExprType) && leftExprType.moduleName === 'typing' ); + if (typeResult?.memberAccessDeprecationInfo) { + this._reportDeprecatedUseForMemberAccess(node.memberName, typeResult.memberAccessDeprecationInfo); + } + this._conditionallyReportPrivateUsage(node.memberName); // Walk the leftExpression but not the memberName. @@ -1538,7 +1548,7 @@ export class Checker extends ParseTreeWalker { } const type = this._evaluator.getType(node.alias ?? node.name); - this._reportDeprecatedUse(node.name, type, isImportFromTyping); + this._reportDeprecatedUseForType(node.name, type, isImportFromTyping); return false; } @@ -1668,10 +1678,10 @@ export class Checker extends ParseTreeWalker { } // Invoke the __bool__ method on the type. - const boolReturnType = this._evaluator.getTypeOfMagicMethodReturn( + const boolReturnType = this._evaluator.getTypeOfMagicMethodCall( expandedSubtype, - [], '__bool__', + [], node, /* inferenceContext */ undefined ); @@ -1950,7 +1960,7 @@ export class Checker extends ParseTreeWalker { doForEachSubtype(leftType, (subtype) => { subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype); - if (this._evaluator.assignType(subtype, NoneType.createInstance())) { + if (this._evaluator.assignType(subtype, this._evaluator.getNoneType())) { foundMatchForNone = true; } }); @@ -2867,7 +2877,10 @@ export class Checker extends ParseTreeWalker { for (const paramList of this._typeParameterLists) { for (const param of paramList.parameters) { const symbol = AnalyzerNodeInfo.getTypeParameterSymbol(param.name); - assert(symbol); + if (!symbol) { + // This can happen if the code is unreachable. + return; + } if (!accessedSymbolSet.has(symbol.id)) { const decls = symbol.getDeclarations(); @@ -3510,6 +3523,8 @@ export class Checker extends ParseTreeWalker { return transformPossibleRecursiveTypeAlias(subtype); }); + arg0Type = this._evaluator.expandPromotionTypes(node, arg0Type); + const arg1Type = this._evaluator.getType(node.arguments[1].valueExpression); if (!arg1Type) { return; @@ -3655,6 +3670,7 @@ export class Checker extends ParseTreeWalker { const filterIsSuperclass = isIsinstanceFilterSuperclass( this._evaluator, varType, + varType, filterType, filterType, isInstanceCheck @@ -3663,7 +3679,6 @@ export class Checker extends ParseTreeWalker { this._evaluator, varType, filterType, - filterType, isInstanceCheck ); @@ -3771,23 +3786,19 @@ export class Checker extends ParseTreeWalker { break; case TypeCategory.Class: - // If it's a class, make sure that it has not been given explicit - // type arguments. This will result in a TypeError exception. - if (subtype.isTypeArgumentExplicit && !subtype.includeSubclasses) { + if (isNoneInstance(subtype)) { isSupported = false; - } - break; - - case TypeCategory.None: - if (!isInstanceCheck) { + } else if (subtype.isTypeArgumentExplicit && !subtype.includeSubclasses) { + // If it's a class, make sure that it has not been given explicit + // type arguments. This will result in a TypeError exception. isSupported = false; - } else { - isSupported = TypeBase.isInstantiable(subtype); } break; case TypeCategory.Function: - isSupported = TypeBase.isInstantiable(subtype); + if (!TypeBase.isInstantiable(subtype) || subtype.isCallableWithTypeArgs) { + isSupported = false; + } break; case TypeCategory.Union: @@ -3824,7 +3835,33 @@ export class Checker extends ParseTreeWalker { return false; } - private _reportDeprecatedUse(node: NameNode, type: Type | undefined, isImportFromTyping = false) { + private _reportDeprecatedUseForMemberAccess(node: NameNode, info: MemberAccessDeprecationInfo) { + let errorMessage: string | undefined; + + if (info.accessType === 'property') { + if (info.accessMethod === 'get') { + errorMessage = Localizer.Diagnostic.deprecatedPropertyGetter().format({ name: node.value }); + } else if (info.accessMethod === 'set') { + errorMessage = Localizer.Diagnostic.deprecatedPropertySetter().format({ name: node.value }); + } else { + errorMessage = Localizer.Diagnostic.deprecatedPropertyDeleter().format({ name: node.value }); + } + } else if (info.accessType === 'descriptor') { + if (info.accessMethod === 'get') { + errorMessage = Localizer.Diagnostic.deprecatedDescriptorGetter().format({ name: node.value }); + } else if (info.accessMethod === 'set') { + errorMessage = Localizer.Diagnostic.deprecatedDescriptorSetter().format({ name: node.value }); + } else { + errorMessage = Localizer.Diagnostic.deprecatedDescriptorDeleter().format({ name: node.value }); + } + } + + if (errorMessage) { + this._reportDeprecatedDiagnostic(node, errorMessage, info.deprecationMessage); + } + } + + private _reportDeprecatedUseForType(node: NameNode, type: Type | undefined, isImportFromTyping = false) { if (!type) { return; } @@ -3923,21 +3960,7 @@ export class Checker extends ParseTreeWalker { }); if (errorMessage) { - const diag = new DiagnosticAddendum(); - if (deprecatedMessage) { - diag.addMessage(deprecatedMessage); - } - - if (this._fileInfo.diagnosticRuleSet.reportDeprecated === 'none') { - this._evaluator.addDeprecated(errorMessage + diag.getString(), node); - } else { - this._evaluator.addDiagnostic( - this._fileInfo.diagnosticRuleSet.reportDeprecated, - DiagnosticRule.reportDeprecated, - errorMessage + diag.getString(), - node - ); - } + this._reportDeprecatedDiagnostic(node, errorMessage, deprecatedMessage); } if (this._fileInfo.diagnosticRuleSet.deprecateTypingAliases) { @@ -3976,6 +3999,24 @@ export class Checker extends ParseTreeWalker { } } + private _reportDeprecatedDiagnostic(node: ParseNode, diagnosticMessage: string, deprecatedMessage?: string) { + const diag = new DiagnosticAddendum(); + if (deprecatedMessage) { + diag.addMessage(deprecatedMessage); + } + + if (this._fileInfo.diagnosticRuleSet.reportDeprecated === 'none') { + this._evaluator.addDeprecated(diagnosticMessage + diag.getString(), node); + } else { + this._evaluator.addDiagnostic( + this._fileInfo.diagnosticRuleSet.reportDeprecated, + DiagnosticRule.reportDeprecated, + diagnosticMessage + diag.getString(), + node + ); + } + } + private _reportUnboundName(node: NameNode) { if (this._fileInfo.diagnosticRuleSet.reportUnboundVariable === 'none') { return; @@ -4431,7 +4472,7 @@ export class Checker extends ParseTreeWalker { const diagAddendum = new DiagnosticAddendum(); // If the declared type isn't compatible with 'None', flag an error. - if (!this._evaluator.assignType(declaredReturnType, NoneType.createInstance(), diagAddendum)) { + if (!this._evaluator.assignType(declaredReturnType, this._evaluator.getNoneType(), diagAddendum)) { // If the function consists entirely of "...", assume that it's // an abstract method or a protocol method and don't require that // the return type matches. This check can also be skipped for an overload. @@ -5099,8 +5140,6 @@ export class Checker extends ParseTreeWalker { classType, newMemberType, /* memberClass */ undefined, - /* errorNode */ undefined, - /* recursionCount */ undefined, /* treatConstructorAsClassMember */ true ); if (!newMemberType) { @@ -5280,11 +5319,6 @@ export class Checker extends ParseTreeWalker { const matchingMroObject = ClassType.cloneAsInstance(matchingMroClass); const baseClassMroObject = ClassType.cloneAsInstance(specializedBaseClassMroClass); - // If the types match exactly, we can shortcut the remainder of the MRO chain. - // if (isTypeSame(matchingMroObject, baseClassMroObject)) { - // break; - // } - if (!this._evaluator.assignType(matchingMroObject, baseClassMroObject)) { const diag = new DiagnosticAddendum(); const baseClassObject = convertToInstance(baseClass); @@ -5732,9 +5766,13 @@ export class Checker extends ParseTreeWalker { return; } + const baseClass = baseClassAndSymbol.classType; + const childClassSelf = selfSpecializeClass(childClassType); + const baseType = partiallySpecializeType( this._evaluator.getEffectiveTypeOfSymbol(baseClassAndSymbol.symbol), - baseClassAndSymbol.classType + baseClass, + ClassType.cloneAsInstance(childClassSelf) ); if (isFunction(baseType) || isOverloadedFunction(baseType)) { @@ -5749,9 +5787,13 @@ export class Checker extends ParseTreeWalker { const enforceParamNameMatch = !SymbolNameUtils.isDunderName(memberName); // Don't check certain magic functions or private symbols. + // Also, skip this check if the class is a TypedDict. The methods for a TypedDict + // are synthesized, and they can result in many overloads. We assume they + // are correct and will not produce any errors. if ( !exemptMethods.some((exempt) => exempt === memberName) && - !SymbolNameUtils.isPrivateName(memberName) + !SymbolNameUtils.isPrivateName(memberName) && + !ClassType.isTypedDictClass(childClassType) ) { if ( !this._evaluator.validateOverrideMethod( @@ -5772,7 +5814,7 @@ export class Checker extends ParseTreeWalker { DiagnosticRule.reportIncompatibleMethodOverride, Localizer.Diagnostic.incompatibleMethodOverride().format({ name: memberName, - className: baseClassAndSymbol.classType.details.name, + className: baseClass.details.name, }) + diagAddendum.getString(), decl.type === DeclarationType.Function ? decl.node.name : decl.node ); @@ -5797,7 +5839,7 @@ export class Checker extends ParseTreeWalker { const diag = this._evaluator.addError( Localizer.Diagnostic.finalMethodOverride().format({ name: memberName, - className: baseClassAndSymbol.classType.details.name, + className: baseClass.details.name, }), decl.node.name ); @@ -5817,7 +5859,7 @@ export class Checker extends ParseTreeWalker { // Special-case overrides of methods in '_TypedDict', since // TypedDict attributes aren't manifest as attributes but rather // as named keys. - if (!ClassType.isBuiltIn(baseClassAndSymbol.classType, '_TypedDict')) { + if (!ClassType.isBuiltIn(baseClass, '_TypedDict')) { const decls = overrideSymbol.getDeclarations(); if (decls.length > 0) { const lastDecl = decls[decls.length - 1]; @@ -5826,7 +5868,7 @@ export class Checker extends ParseTreeWalker { DiagnosticRule.reportIncompatibleMethodOverride, Localizer.Diagnostic.methodOverridden().format({ name: memberName, - className: baseClassAndSymbol.classType.details.name, + className: baseClass.details.name, type: this._evaluator.printType(overrideType), }), lastDecl.node @@ -5853,7 +5895,7 @@ export class Checker extends ParseTreeWalker { DiagnosticRule.reportIncompatibleMethodOverride, Localizer.Diagnostic.propertyOverridden().format({ name: memberName, - className: baseClassAndSymbol.classType.details.name, + className: baseClass.details.name, }), decls[decls.length - 1].node ); @@ -5861,7 +5903,7 @@ export class Checker extends ParseTreeWalker { } else { const basePropFields = (baseType as ClassType).details.fields; const subclassPropFields = (overrideType as ClassType).details.fields; - const baseClassType = baseClassAndSymbol.classType; + const baseClassType = baseClass; ['fget', 'fset', 'fdel'].forEach((methodName) => { const diagAddendum = new DiagnosticAddendum(); @@ -5962,7 +6004,18 @@ export class Checker extends ParseTreeWalker { // Verify that the override type is assignable to (same or narrower than) // the declared type of the base symbol. - const isInvariant = primaryDecl?.type === DeclarationType.Variable && !primaryDecl.isFinal; + let isInvariant = primaryDecl?.type === DeclarationType.Variable && !primaryDecl.isFinal; + + // If the entry is a member of a frozen dataclass, it is immutable, + // so it does not need to be invariant. + if (ClassType.isFrozenDataClass(baseClass) && baseClass.details.dataClassEntries) { + const dataclassEntry = baseClass.details.dataClassEntries.find( + (entry) => entry.name === memberName + ); + if (dataclassEntry) { + isInvariant = false; + } + } let diagAddendum = new DiagnosticAddendum(); if ( @@ -5991,7 +6044,7 @@ export class Checker extends ParseTreeWalker { DiagnosticRule.reportIncompatibleVariableOverride, Localizer.Diagnostic.symbolOverridden().format({ name: memberName, - className: baseClassAndSymbol.classType.details.name, + className: baseClass.details.name, }) + diagAddendum.getString(), getNameNodeForDeclaration(lastDecl) ?? lastDecl.node ); @@ -6016,7 +6069,7 @@ export class Checker extends ParseTreeWalker { DiagnosticRule.reportIncompatibleVariableOverride, Localizer.Diagnostic.variableFinalOverride().format({ name: memberName, - className: baseClassAndSymbol.classType.details.name, + className: baseClass.details.name, }), lastDecl.node ); @@ -6062,7 +6115,7 @@ export class Checker extends ParseTreeWalker { DiagnosticRule.reportIncompatibleVariableOverride, unformattedMessage.format({ name: memberName, - className: baseClassAndSymbol.classType.details.name, + className: baseClass.details.name, }), getNameNodeForDeclaration(lastDecl) ?? lastDecl.node ); @@ -6391,7 +6444,12 @@ export class Checker extends ParseTreeWalker { // Determines whether a yield or yield from node is compatible with the // return type annotation of the containing function. - private _validateYieldType(node: YieldNode | YieldFromNode, yieldType: Type, sendType?: Type) { + private _validateYieldType( + node: YieldNode | YieldFromNode, + yieldType: Type, + expectedDiagAddendum?: DiagnosticAddendum, + sendType?: Type + ) { const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(node); if (!enclosingFunctionNode || !enclosingFunctionNode.returnTypeAnnotation) { return; @@ -6455,8 +6513,10 @@ export class Checker extends ParseTreeWalker { this._evaluator.addDiagnostic( this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, - errorMessage.format({ yieldType: this._evaluator.printType(yieldType) }) + diagAddendum.getString(), - node.expression ?? node + errorMessage.format({ yieldType: this._evaluator.printType(yieldType) }) + + (expectedDiagAddendum?.getString() ?? diagAddendum.getString()), + node.expression ?? node, + expectedDiagAddendum?.getEffectiveTextRange() ?? node.expression ?? node ); } } @@ -6493,7 +6553,8 @@ export class Checker extends ParseTreeWalker { this._evaluator.getTypeOfIterator( { type: exceptionType }, /* isAsync */ false, - /* errorNode */ undefined + /* errorNode */ except.typeExpression, + /* emitNotIterableError */ false )?.type ?? UnknownType.create(); doForEachSubtype(iterableType, (subtype) => { diff --git a/packages/pyright-internal/src/analyzer/codeFlowEngine.ts b/packages/pyright-internal/src/analyzer/codeFlowEngine.ts index ed7c8af5b..af518b239 100644 --- a/packages/pyright-internal/src/analyzer/codeFlowEngine.ts +++ b/packages/pyright-internal/src/analyzer/codeFlowEngine.ts @@ -44,7 +44,6 @@ import { EvaluatorFlags, TypeEvaluator, TypeResult } from './typeEvaluatorTypes' import { getTypeNarrowingCallback } from './typeGuards'; import { ClassType, - cleanIncompleteUnknown, combineTypes, FunctionType, isClass, @@ -65,6 +64,7 @@ import { } from './types'; import { ClassMemberLookupFlags, + cleanIncompleteUnknown, derivesFromStdlibClass, doForEachSubtype, isIncompleteUnknown, @@ -83,7 +83,6 @@ export interface FlowNodeTypeResult { export interface FlowNodeTypeOptions { isTypeAtStartIncomplete?: boolean; - skipNoReturnCallAnalysis?: boolean; skipConditionalNarrowing?: boolean; } @@ -431,7 +430,7 @@ export function getCodeFlowEngine( // If this function returns a "NoReturn" type, that means // it always raises an exception or otherwise doesn't return, // so we can assume that the code before this is unreachable. - if (!options?.skipNoReturnCallAnalysis && isCallNoReturn(evaluator, callFlowNode)) { + if (isCallNoReturn(evaluator, callFlowNode)) { return setCacheEntry(curFlowNode, /* type */ undefined, /* isIncomplete */ false); } @@ -454,6 +453,14 @@ export function getCodeFlowEngine( // Is this a special "unbind" assignment? If so, // we can handle it immediately without any further evaluation. if (curFlowNode.flags & FlowFlags.Unbind) { + // Don't treat unbound assignments to indexed expressions (i.e. "del x[0]") + // as true deletions. The most common use case for "del x[0]" is in a list, + // and the list class treats this as an element deletion, not an assignment. + if (reference.nodeType === ParseNodeType.Index) { + // No need to explore further. + return setCacheEntry(curFlowNode, undefined, /* isIncomplete */ false); + } + return setCacheEntry(curFlowNode, UnboundType.create(), /* isIncomplete */ false); } @@ -986,12 +993,17 @@ export function getCodeFlowEngine( } let effectiveType = cacheEntry.type; + let cleanedIncompleteUnknowns = false; if (sawIncomplete) { // If there is an incomplete "Unknown" type within a union type, remove // it. Otherwise we might end up resolving the cycle with a type // that includes an undesirable unknown. if (effectiveType) { - effectiveType = cleanIncompleteUnknown(effectiveType); + const cleanedType = cleanIncompleteUnknown(effectiveType); + if (cleanedType !== effectiveType) { + effectiveType = cleanedType; + cleanedIncompleteUnknowns = true; + } } } @@ -1002,10 +1014,12 @@ export function getCodeFlowEngine( // up the stack will be able to produce a valid type. let reportIncomplete = sawIncomplete; if ( + sawIncomplete && !sawPending && effectiveType && !isIncompleteUnknown(effectiveType) && - !firstAntecedentTypeIsIncomplete + !firstAntecedentTypeIsIncomplete && + !cleanedIncompleteUnknowns ) { // Bump the generation count because we need to recalculate // other incomplete types based on this now-complete type. diff --git a/packages/pyright-internal/src/analyzer/codeFlowUtils.ts b/packages/pyright-internal/src/analyzer/codeFlowUtils.ts index 4d925c203..18500af65 100644 --- a/packages/pyright-internal/src/analyzer/codeFlowUtils.ts +++ b/packages/pyright-internal/src/analyzer/codeFlowUtils.ts @@ -345,8 +345,12 @@ export function formatControlFlowGraph(flowNode: FlowNode) { const above = lane > 0 ? connectors[column][lane - 1] : 0; let connector = connectors[column][lane]; if (!connector) { - if (left & Connection.Right) connector |= Connection.LeftRight; - if (above & Connection.Down) connector |= Connection.UpDown; + if (left & Connection.Right) { + connector |= Connection.LeftRight; + } + if (above & Connection.Down) { + connector |= Connection.UpDown; + } connectors[column][lane] = connector; } } diff --git a/packages/pyright-internal/src/analyzer/constraintSolver.ts b/packages/pyright-internal/src/analyzer/constraintSolver.ts index 712e7abee..14ef720fa 100644 --- a/packages/pyright-internal/src/analyzer/constraintSolver.ts +++ b/packages/pyright-internal/src/analyzer/constraintSolver.ts @@ -18,6 +18,7 @@ import { combineTypes, FunctionParameter, FunctionType, + FunctionTypeFlags, isAny, isAnyOrUnknown, isClass, @@ -32,7 +33,6 @@ import { isUnpacked, isUnpackedClass, isVariadicTypeVar, - NoneType, TupleTypeArgument, Type, TypeBase, @@ -60,13 +60,17 @@ import { transformExpectedType, transformPossibleRecursiveTypeAlias, } from './typeUtils'; -import { TypeVarContext } from './typeVarContext'; +import { TypeVarContext, TypeVarSignatureContext } from './typeVarContext'; // As we widen the narrow bound of a type variable, we may end up with // many subtypes. For performance reasons, we need to cap this at some // point. This constant determines the cap. const maxSubtypeCountForTypeVarNarrowBound = 64; +// This debugging switch enables logging of the TypeVarContext before and +// after it is updated by the constraint solver. +const logTypeVarContextUpdates = false; + // Assigns the source type to the dest type var in the type var context. If an existing // type is already associated with that type var name, it attempts to either widen or // narrow the type (depending on the value of the isContravariant parameter). The goal is @@ -82,7 +86,20 @@ export function assignTypeToTypeVar( flags = AssignTypeFlags.Default, recursionCount = 0 ): boolean { + if (logTypeVarContextUpdates) { + const indent = ' '.repeat(recursionCount * 2); + console.log(`${indent}`); + console.log(`${indent}assignTypeToTypeVar called with`); + console.log(`${indent}destType: ${evaluator.printType(destType)}`); + console.log(`${indent}srcType: ${evaluator.printType(srcType)}`); + console.log(`${indent}flags: ${flags}`); + console.log(`${indent}scopes: ${(typeVarContext.getSolveForScopes() || []).join(', ')}`); + console.log(`${indent}pre-call context #${typeVarContext.getId()}: `); + logTypeVarContext(evaluator, typeVarContext, indent); + } + let isTypeVarInScope = true; + const isInvariant = (flags & AssignTypeFlags.EnforceInvariance) !== 0; const isContravariant = (flags & AssignTypeFlags.ReverseTypeVarMatching) !== 0; // If the TypeVar doesn't have a scope ID, then it's being used @@ -111,7 +128,7 @@ export function assignTypeToTypeVar( // Never or NoReturn is always assignable to all type variables unless // we're enforcing invariance. - if (isNever(srcType) && (flags & AssignTypeFlags.EnforceInvariance) === 0) { + if (isNever(srcType) && !isInvariant) { return true; } @@ -189,206 +206,31 @@ export function assignTypeToTypeVar( srcType = AnyType.create(); } - const curEntry = typeVarContext.getPrimarySignature().getTypeVar(destType); - const curNarrowTypeBound = curEntry?.narrowBound; - - let curWideTypeBound = curEntry?.wideBound; - if (!curWideTypeBound && !destType.details.isSynthesizedSelf) { - curWideTypeBound = destType.details.boundType; - } - // Handle the constrained case. This case needs to be handled specially // because type narrowing isn't used in this case. For example, if the // source type is "Literal[1]" and the constraint list includes the type // "float", the resulting type is float. if (destType.details.constraints.length > 0) { - let constrainedType: Type | undefined; - const concreteSrcType = evaluator.makeTopLevelTypeVarsConcrete(srcType); - - if (isTypeVar(srcType)) { - if ( - evaluator.assignType( - destType, - concreteSrcType, - /* diag */ undefined, - new TypeVarContext(destType.scopeId), - /* srcTypeVarContext */ undefined, - AssignTypeFlags.Default, - recursionCount - ) - ) { - constrainedType = srcType; - - // If the source and dest are both instantiables (type[T]), then - // we need to convert to an instance (T). - if (TypeBase.isInstantiable(srcType)) { - constrainedType = convertToInstance(srcType, /* includeSubclasses */ false); - } - } - } else { - let isCompatible = true; - - // Subtypes that are not conditionally dependent on the dest type var - // must all map to the same constraint. For example, Union[str, bytes] - // cannot be assigned to AnyStr. - let unconditionalConstraintIndex: number | undefined; - - // Find the narrowest constrained type that is compatible. - constrainedType = mapSubtypes(concreteSrcType, (srcSubtype) => { - let constrainedSubtype: Type | undefined; - - if (isAnyOrUnknown(srcSubtype)) { - return srcSubtype; - } - - let constraintIndexUsed: number | undefined; - destType.details.constraints.forEach((constraint, i) => { - const adjustedConstraint = TypeBase.isInstantiable(destType) - ? convertToInstantiable(constraint) - : constraint; - if ( - evaluator.assignType( - adjustedConstraint, - srcSubtype, - /* diag */ undefined, - /* destTypeVarContext */ undefined, - /* srcTypeVarContext */ undefined, - AssignTypeFlags.Default, - recursionCount - ) - ) { - if ( - !constrainedSubtype || - evaluator.assignType( - TypeBase.isInstantiable(destType) - ? convertToInstantiable(constrainedSubtype) - : constrainedSubtype, - adjustedConstraint, - /* diag */ undefined, - /* destTypeVarContext */ undefined, - /* srcTypeVarContext */ undefined, - AssignTypeFlags.Default, - recursionCount - ) - ) { - constrainedSubtype = addConditionToType(constraint, getTypeCondition(srcSubtype)); - constraintIndexUsed = i; - } - } - }); - - if (!constrainedSubtype) { - // We found a source subtype that is not compatible with the dest. - // This is OK if we're handling the contravariant case because only - // one subtype needs to be assignable in that case. - if (!isContravariant) { - isCompatible = false; - } - } - - // If this subtype isn't conditional, make sure it maps to the same - // constraint index as previous unconditional subtypes. - if (constraintIndexUsed !== undefined && !getTypeCondition(srcSubtype)) { - if ( - unconditionalConstraintIndex !== undefined && - unconditionalConstraintIndex !== constraintIndexUsed - ) { - isCompatible = false; - } - - unconditionalConstraintIndex = constraintIndexUsed; - } - - return constrainedSubtype; - }); - - if (isNever(constrainedType) || !isCompatible) { - constrainedType = undefined; - } - - // If the type is a union, see if the entire union is assignable to one - // of the constraints. - if (!constrainedType && isUnion(concreteSrcType)) { - constrainedType = destType.details.constraints.find((constraint) => { - const adjustedConstraint = TypeBase.isInstantiable(destType) - ? convertToInstantiable(constraint) - : constraint; - return evaluator.assignType( - adjustedConstraint, - concreteSrcType, - /* diag */ undefined, - /* destTypeVarContext */ undefined, - /* srcTypeVarContext */ undefined, - AssignTypeFlags.Default, - recursionCount - ); - }); - } - } - - // If there was no constrained type that was assignable - // or there were multiple types that were assignable and they - // are not conditional, it's an error. - if (!constrainedType) { - diag?.addMessage( - Localizer.DiagnosticAddendum.typeConstrainedTypeVar().format({ - type: evaluator.printType(srcType), - name: destType.details.name, - }) - ); - return false; - } - - if (curNarrowTypeBound && !isAnyOrUnknown(curNarrowTypeBound)) { - if ( - !evaluator.assignType( - curNarrowTypeBound, - constrainedType, - /* diag */ undefined, - /* destTypeVarContext */ undefined, - /* srcTypeVarContext */ undefined, - AssignTypeFlags.Default, - recursionCount - ) - ) { - // Handle the case where one of the constrained types is a wider - // version of another constrained type that was previously assigned - // to the type variable. - if ( - evaluator.assignType( - constrainedType, - curNarrowTypeBound, - /* diag */ undefined, - /* destTypeVarContext */ undefined, - /* srcTypeVarContext */ undefined, - AssignTypeFlags.Default, - recursionCount - ) - ) { - if (!typeVarContext.isLocked() && isTypeVarInScope) { - updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curWideTypeBound); - } - } else { - diag?.addMessage( - Localizer.DiagnosticAddendum.typeConstrainedTypeVar().format({ - type: evaluator.printType(constrainedType), - name: evaluator.printType(curNarrowTypeBound), - }) - ); - return false; - } - } - } else { - // Assign the type to the type var. - if (!typeVarContext.isLocked() && isTypeVarInScope) { - updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curWideTypeBound); - } - } - - return true; + return assignTypeToConstrainedTypeVar( + evaluator, + destType, + srcType, + diag, + typeVarContext, + flags, + isTypeVarInScope, + recursionCount + ); } // Handle the unconstrained (but possibly bound) case. + const curEntry = typeVarContext.getPrimarySignature().getTypeVar(destType); + + let curWideTypeBound = curEntry?.wideBound; + if (!curWideTypeBound && !destType.details.isSynthesizedSelf) { + curWideTypeBound = destType.details.boundType; + } + const curNarrowTypeBound = curEntry?.narrowBound; let newNarrowTypeBound = curNarrowTypeBound; let newWideTypeBound = curWideTypeBound; const diagAddendum = diag ? new DiagnosticAddendum() : undefined; @@ -445,7 +287,7 @@ export function assignTypeToTypeVar( // narrow type bound, wide type bound or both. Don't overwrite // an existing entry. if (!curEntry) { - if ((flags & AssignTypeFlags.EnforceInvariance) !== 0) { + if (isInvariant) { newNarrowTypeBound = adjSrcType; newWideTypeBound = adjSrcType; } else if (isContravariant) { @@ -456,7 +298,7 @@ export function assignTypeToTypeVar( } } else if (isContravariant) { // Update the wide type bound. - if (!curWideTypeBound) { + if (!curWideTypeBound || isTypeSame(destType, curWideTypeBound)) { newWideTypeBound = adjSrcType; } else if (!isTypeSame(curWideTypeBound, adjSrcType, {}, recursionCount)) { if ( @@ -523,7 +365,7 @@ export function assignTypeToTypeVar( } } } else { - if (!curNarrowTypeBound) { + if (!curNarrowTypeBound || isTypeSame(destType, curNarrowTypeBound)) { // There was previously no narrow bound. We've now established one. newNarrowTypeBound = adjSrcType; } else if (!isTypeSame(curNarrowTypeBound, adjSrcType, {}, recursionCount)) { @@ -606,7 +448,6 @@ export function assignTypeToTypeVar( isUnion(curSolvedNarrowTypeBound) && curSolvedNarrowTypeBound.subtypes.length > maxSubtypesForInferredType && (destType as TypeVarType).details.boundType !== undefined && - objectType && isClassInstance(objectType) ) { newNarrowTypeBound = combineTypes( @@ -725,6 +566,13 @@ export function assignTypeToTypeVar( ); } + if (logTypeVarContextUpdates) { + const indent = ' '.repeat(recursionCount * 2); + console.log(`${indent}`); + console.log(`${indent}post-call context #${typeVarContext.getId()}: `); + logTypeVarContext(evaluator, typeVarContext, indent); + } + return true; } @@ -760,6 +608,206 @@ export function updateTypeVarType( typeVarContext.setTypeVarType(destType, narrowTypeBound, narrowTypeBoundNoLiterals, wideTypeBound); } +function assignTypeToConstrainedTypeVar( + evaluator: TypeEvaluator, + destType: TypeVarType, + srcType: Type, + diag: DiagnosticAddendum | undefined, + typeVarContext: TypeVarContext, + flags: AssignTypeFlags, + isTypeVarInScope: boolean, + recursionCount: number +) { + let constrainedType: Type | undefined; + const concreteSrcType = evaluator.makeTopLevelTypeVarsConcrete(srcType); + const curEntry = typeVarContext.getPrimarySignature().getTypeVar(destType); + + const curWideTypeBound = curEntry?.wideBound; + const curNarrowTypeBound = curEntry?.narrowBound; + + if (isTypeVar(srcType)) { + if ( + evaluator.assignType( + destType, + concreteSrcType, + /* diag */ undefined, + new TypeVarContext(destType.scopeId), + /* srcTypeVarContext */ undefined, + AssignTypeFlags.Default, + recursionCount + ) + ) { + constrainedType = srcType; + + // If the source and dest are both instantiables (type[T]), then + // we need to convert to an instance (T). + if (TypeBase.isInstantiable(srcType)) { + constrainedType = convertToInstance(srcType, /* includeSubclasses */ false); + } + } + } else { + let isCompatible = true; + + // Subtypes that are not conditionally dependent on the dest type var + // must all map to the same constraint. For example, Union[str, bytes] + // cannot be assigned to AnyStr. + let unconditionalConstraintIndex: number | undefined; + + // Find the narrowest constrained type that is compatible. + constrainedType = mapSubtypes(concreteSrcType, (srcSubtype) => { + let constrainedSubtype: Type | undefined; + + if (isAnyOrUnknown(srcSubtype)) { + return srcSubtype; + } + + let constraintIndexUsed: number | undefined; + destType.details.constraints.forEach((constraint, i) => { + const adjustedConstraint = TypeBase.isInstantiable(destType) + ? convertToInstantiable(constraint) + : constraint; + if ( + evaluator.assignType( + adjustedConstraint, + srcSubtype, + /* diag */ undefined, + /* destTypeVarContext */ undefined, + /* srcTypeVarContext */ undefined, + AssignTypeFlags.Default, + recursionCount + ) + ) { + if ( + !constrainedSubtype || + evaluator.assignType( + TypeBase.isInstantiable(destType) + ? convertToInstantiable(constrainedSubtype) + : constrainedSubtype, + adjustedConstraint, + /* diag */ undefined, + /* destTypeVarContext */ undefined, + /* srcTypeVarContext */ undefined, + AssignTypeFlags.Default, + recursionCount + ) + ) { + constrainedSubtype = addConditionToType(constraint, getTypeCondition(srcSubtype)); + constraintIndexUsed = i; + } + } + }); + + if (!constrainedSubtype) { + // We found a source subtype that is not compatible with the dest. + // This is OK if we're handling the contravariant case because only + // one subtype needs to be assignable in that case. + if ((flags & AssignTypeFlags.ReverseTypeVarMatching) === 0) { + isCompatible = false; + } + } + + // If this subtype isn't conditional, make sure it maps to the same + // constraint index as previous unconditional subtypes. + if (constraintIndexUsed !== undefined && !getTypeCondition(srcSubtype)) { + if ( + unconditionalConstraintIndex !== undefined && + unconditionalConstraintIndex !== constraintIndexUsed + ) { + isCompatible = false; + } + + unconditionalConstraintIndex = constraintIndexUsed; + } + + return constrainedSubtype; + }); + + if (isNever(constrainedType) || !isCompatible) { + constrainedType = undefined; + } + + // If the type is a union, see if the entire union is assignable to one + // of the constraints. + if (!constrainedType && isUnion(concreteSrcType)) { + constrainedType = destType.details.constraints.find((constraint) => { + const adjustedConstraint = TypeBase.isInstantiable(destType) + ? convertToInstantiable(constraint) + : constraint; + return evaluator.assignType( + adjustedConstraint, + concreteSrcType, + /* diag */ undefined, + /* destTypeVarContext */ undefined, + /* srcTypeVarContext */ undefined, + AssignTypeFlags.Default, + recursionCount + ); + }); + } + } + + // If there was no constrained type that was assignable + // or there were multiple types that were assignable and they + // are not conditional, it's an error. + if (!constrainedType) { + diag?.addMessage( + Localizer.DiagnosticAddendum.typeConstrainedTypeVar().format({ + type: evaluator.printType(srcType), + name: destType.details.name, + }) + ); + return false; + } + + if (curNarrowTypeBound && !isAnyOrUnknown(curNarrowTypeBound)) { + if ( + !evaluator.assignType( + curNarrowTypeBound, + constrainedType, + /* diag */ undefined, + /* destTypeVarContext */ undefined, + /* srcTypeVarContext */ undefined, + AssignTypeFlags.Default, + recursionCount + ) + ) { + // Handle the case where one of the constrained types is a wider + // version of another constrained type that was previously assigned + // to the type variable. + if ( + evaluator.assignType( + constrainedType, + curNarrowTypeBound, + /* diag */ undefined, + /* destTypeVarContext */ undefined, + /* srcTypeVarContext */ undefined, + AssignTypeFlags.Default, + recursionCount + ) + ) { + if (!typeVarContext.isLocked() && isTypeVarInScope) { + updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curWideTypeBound); + } + } else { + diag?.addMessage( + Localizer.DiagnosticAddendum.typeConstrainedTypeVar().format({ + type: evaluator.printType(constrainedType), + name: evaluator.printType(curNarrowTypeBound), + }) + ); + return false; + } + } + } else { + // Assign the type to the type var. + if (!typeVarContext.isLocked() && isTypeVarInScope) { + updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curWideTypeBound); + } + } + + return true; +} + function assignTypeToParamSpec( evaluator: TypeEvaluator, destType: TypeVarType, @@ -782,7 +830,7 @@ function assignTypeToParamSpec( } } else { if (!typeVarContext.isLocked() && typeVarContext.hasSolveForScope(destType.scopeId)) { - typeVarContext.setTypeVarType(destType, convertTypeToParamSpecValue(srcType)); + signatureContext.setTypeVarType(destType, convertTypeToParamSpecValue(srcType)); } return; } @@ -795,32 +843,59 @@ function assignTypeToParamSpec( isNameSynthesized: p.isNameSynthesized, hasDefault: !!p.hasDefault, defaultValueExpression: p.defaultValueExpression, + hasDeclaredType: p.hasDeclaredType, type: FunctionType.getEffectiveParameterType(functionSrcType, index), }; return param; }); + const newFunction = FunctionType.createInstance( + '', + '', + '', + srcType.details.flags | FunctionTypeFlags.ParamSpecValue + ); + parameters.forEach((param) => { + FunctionType.addParameter(newFunction, param); + }); + newFunction.details.typeVarScopeId = srcType.details.typeVarScopeId; + newFunction.details.constructorTypeVarScopeId = srcType.details.constructorTypeVarScopeId; + newFunction.details.paramSpecTypeVarScopeId = srcType.details.paramSpecTypeVarScopeId; + newFunction.details.docString = srcType.details.docString; + newFunction.details.deprecatedMessage = srcType.details.deprecatedMessage; + newFunction.details.paramSpec = srcType.details.paramSpec; + + let updateContextWithNewFunction = false; + const existingType = signatureContext.getParamSpecType(destType); if (existingType) { if ( isTypeSame( - existingType.details.paramSpec ?? NoneType.createInstance(), - srcType.details.paramSpec ?? NoneType.createInstance() + existingType.details.paramSpec ?? evaluator.getNoneType(), + srcType.details.paramSpec ?? evaluator.getNoneType() ) ) { // Convert the remaining portion of the signature to a function // for comparison purposes. const existingFunction = convertParamSpecValueToType(existingType, /* omitParamSpec */ true); - const assignedFunction = FunctionType.createInstance('', '', '', srcType.details.flags); - parameters.forEach((param) => { - FunctionType.addParameter(assignedFunction, param); - }); - assignedFunction.details.typeVarScopeId = srcType.details.typeVarScopeId; + // Should we narrow the type? if ( evaluator.assignType( existingFunction, - assignedFunction, + newFunction, + /* diag */ undefined, + /* destTypeVarContext */ undefined, + /* srcTypeVarContext */ undefined, + AssignTypeFlags.SkipFunctionReturnTypeCheck, + recursionCount + ) + ) { + updateContextWithNewFunction = true; + } else if ( + evaluator.assignType( + newFunction, + existingFunction, /* diag */ undefined, /* destTypeVarContext */ undefined, /* srcTypeVarContext */ undefined, @@ -828,22 +903,18 @@ function assignTypeToParamSpec( recursionCount ) ) { + // The existing function is already narrower than the new function, so + // no need to narrow it further. return; } } } else { + updateContextWithNewFunction = true; + } + + if (updateContextWithNewFunction) { if (!typeVarContext.isLocked() && typeVarContext.hasSolveForScope(destType.scopeId)) { - const newFunction = FunctionType.createInstance('', '', '', srcType.details.flags); - parameters.forEach((param) => { - FunctionType.addParameter(newFunction, param); - }); - newFunction.details.typeVarScopeId = srcType.details.typeVarScopeId; - newFunction.details.constructorTypeVarScopeId = srcType.details.constructorTypeVarScopeId; - newFunction.details.paramSpecTypeVarScopeId = srcType.details.paramSpecTypeVarScopeId; - newFunction.details.docString = srcType.details.docString; - newFunction.details.deprecatedMessage = srcType.details.deprecatedMessage; - newFunction.details.paramSpec = srcType.details.paramSpec; - typeVarContext.setTypeVarType(destType, newFunction); + signatureContext.setTypeVarType(destType, newFunction); } return; } @@ -861,6 +932,13 @@ function assignTypeToParamSpec( isAssignable = false; }); + if (logTypeVarContextUpdates) { + const indent = ' '.repeat(recursionCount * 2); + console.log(`${indent}`); + console.log(`${indent}post-call typeVarContext: `); + logTypeVarContext(evaluator, typeVarContext, indent); + } + return isAssignable; } @@ -957,6 +1035,9 @@ export function populateTypeVarContextBasedOnExpectedType( const synthExpectedTypeArgs = ClassType.getTypeParameters(expectedType).map((typeParam, index) => { const typeVar = TypeVarType.createInstance(`__dest${index}`); typeVar.details.isSynthesized = true; + if (typeParam.details.isParamSpec) { + typeVar.details.isParamSpec = true; + } // Use invariance here so we set the narrow and wide values on the TypeVar. typeVar.details.declaredVariance = Variance.Invariant; @@ -970,11 +1051,14 @@ export function populateTypeVarContextBasedOnExpectedType( ); // For each type param in the target type, create a placeholder type variable. - const typeArgs = ClassType.getTypeParameters(type).map((_, index) => { + const typeArgs = ClassType.getTypeParameters(type).map((typeParam, index) => { const typeVar = TypeVarType.createInstance(`__source${index}`); typeVar.details.isSynthesized = true; typeVar.details.synthesizedIndex = index; typeVar.details.isExemptFromBoundCheck = true; + if (typeParam.details.isParamSpec) { + typeVar.details.isParamSpec = true; + } return TypeVarType.cloneAsInScopePlaceholder(typeVar); }); @@ -998,24 +1082,30 @@ export function populateTypeVarContextBasedOnExpectedType( // If the resulting type is a union, try to find a matching type var and move // the remaining subtypes to the "otherSubtypes" array. - if (synthTypeVar && isUnion(synthTypeVar)) { - let foundSynthTypeVar: TypeVarType | undefined; + if (synthTypeVar) { + if (typeVar.details.isParamSpec && isFunction(synthTypeVar)) { + synthTypeVar = convertParamSpecValueToType(synthTypeVar); + } - synthTypeVar.subtypes.forEach((subtype) => { - if ( - isTypeVar(subtype) && - subtype.details.isSynthesized && - subtype.details.synthesizedIndex !== undefined && - !foundSynthTypeVar - ) { - foundSynthTypeVar = subtype; - } else { - otherSubtypes.push(subtype); - } - }); + if (isUnion(synthTypeVar)) { + let foundSynthTypeVar: TypeVarType | undefined; + + synthTypeVar.subtypes.forEach((subtype) => { + if ( + isTypeVar(subtype) && + subtype.details.isSynthesized && + subtype.details.synthesizedIndex !== undefined && + !foundSynthTypeVar + ) { + foundSynthTypeVar = subtype; + } else { + otherSubtypes.push(subtype); + } + }); - if (foundSynthTypeVar) { - synthTypeVar = foundSynthTypeVar; + if (foundSynthTypeVar) { + synthTypeVar = foundSynthTypeVar; + } } } @@ -1140,3 +1230,48 @@ function stripLiteralValueForUnpackedTuple(evaluator: TypeEvaluator, type: Type) return specializeTupleClass(type, tupleTypeArgs, /* isTypeArgumentExplicit */ true, /* isUnpackedTuple */ true); } + +// This function is used for debugging only. It dumps the current contents of +// the TypeVarContext to the console. +function logTypeVarContext(evaluator: TypeEvaluator, typeVarContext: TypeVarContext, indent: string) { + const signatureContextCount = typeVarContext.getSignatureContexts().length; + if (signatureContextCount === 0) { + console.log(`${indent} no signatures`); + } else if (signatureContextCount === 1) { + logTypeVarSignatureContext(evaluator, typeVarContext.getSignatureContexts()[0], `${indent} `); + } else { + typeVarContext.doForEachSignatureContext((context, signatureIndex) => { + console.log(`${indent} signature ${signatureIndex}`); + logTypeVarSignatureContext(evaluator, context, `${indent} `); + }); + } +} + +function logTypeVarSignatureContext(evaluator: TypeEvaluator, context: TypeVarSignatureContext, indent: string) { + let loggedConstraint = false; + + context.getTypeVars().forEach((entry) => { + const typeVarName = `${indent}${entry.typeVar.details.name}`; + const narrowBound = entry.narrowBoundNoLiterals ?? entry.narrowBound; + const wideBound = entry.wideBound; + + // Log the narrow and wide bounds. + if (narrowBound && wideBound && isTypeSame(narrowBound, wideBound)) { + console.log(`${typeVarName} = ${evaluator.printType(narrowBound)}`); + loggedConstraint = true; + } else { + if (narrowBound) { + console.log(`${typeVarName} ≤ ${evaluator.printType(narrowBound)}`); + loggedConstraint = true; + } + if (wideBound) { + console.log(`${typeVarName} ≥ ${evaluator.printType(wideBound)}`); + loggedConstraint = true; + } + } + }); + + if (!loggedConstraint) { + console.log(`${indent}no constraints`); + } +} diff --git a/packages/pyright-internal/src/analyzer/constructors.ts b/packages/pyright-internal/src/analyzer/constructors.ts index 18ffb5aca..174800371 100644 --- a/packages/pyright-internal/src/analyzer/constructors.ts +++ b/packages/pyright-internal/src/analyzer/constructors.ts @@ -100,14 +100,13 @@ export function validateConstructorArguments( const newMethodTypeResult = evaluator.getTypeOfClassMemberName( errorNode, type, - /* isAccessedThroughObject */ false, '__new__', { method: 'get' }, /* diag */ undefined, MemberAccessFlags.AccessClassMembersOnly | MemberAccessFlags.SkipObjectBaseClass | - MemberAccessFlags.TreatConstructorAsClassMethod, - type + MemberAccessFlags.SkipAttributeAccessOverride | + MemberAccessFlags.TreatConstructorAsClassMethod ); const useConstructorTransform = hasConstructorTransform(type); @@ -271,13 +270,15 @@ function validateNewAndInitMethods( } // Determine whether the class overrides the object.__init__ method. - initMethodTypeResult = evaluator.getTypeOfObjectMember( + initMethodTypeResult = evaluator.getTypeOfClassMemberName( errorNode, initMethodBindToType, '__init__', { method: 'get' }, /* diag */ undefined, - MemberAccessFlags.SkipObjectBaseClass | MemberAccessFlags.SkipAttributeAccessOverride + MemberAccessFlags.AccessClassMembersOnly | + MemberAccessFlags.SkipObjectBaseClass | + MemberAccessFlags.SkipAttributeAccessOverride ); // Validate __init__ if it's present. @@ -602,14 +603,16 @@ function validateFallbackConstructorCall( // It's OK if the argument list consists only of `*args` and `**kwargs`. if (argList.length > 0 && argList.some((arg) => arg.argumentCategory === ArgumentCategory.Simple)) { - const fileInfo = getFileInfo(errorNode); - evaluator.addDiagnostic( - fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, - DiagnosticRule.reportGeneralTypeIssues, - Localizer.Diagnostic.constructorNoArgs().format({ type: type.aliasName || type.details.name }), - errorNode - ); - reportedErrors = true; + if (!type.includeSubclasses) { + const fileInfo = getFileInfo(errorNode); + evaluator.addDiagnostic( + fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, + DiagnosticRule.reportGeneralTypeIssues, + Localizer.Diagnostic.constructorNoArgs().format({ type: type.aliasName || type.details.name }), + errorNode + ); + reportedErrors = true; + } } if (!inferenceContext && type.typeArguments) { @@ -657,12 +660,11 @@ function validateMetaclassCall( if (metaclass && isInstantiableClass(metaclass) && !ClassType.isSameGenericClass(metaclass, type)) { const metaclassCallMethodInfo = evaluator.getTypeOfClassMemberName( errorNode, - metaclass, - /* isAccessedThroughObject */ true, + ClassType.cloneAsInstance(metaclass), '__call__', { method: 'get' }, /* diag */ undefined, - MemberAccessFlags.ConsiderMetaclassOnly | + MemberAccessFlags.AccessClassMembersOnly | MemberAccessFlags.SkipTypeBaseClass | MemberAccessFlags.SkipAttributeAccessOverride, type @@ -799,14 +801,17 @@ export function createFunctionFromConstructor( objectType, initSubtype, /* memberClass */ undefined, - /* errorNode */ undefined, + /* treatConstructorAsClassMember */ undefined, + /* selfType */ undefined, + /* diag */ undefined, recursionCount ) as FunctionType | undefined; if (constructorFunction) { constructorFunction = FunctionType.clone(constructorFunction); constructorFunction.details.declaredReturnType = objectType; - constructorFunction.details.typeVarScopeId = initSubtype.details.typeVarScopeId; + constructorFunction.details.name = ''; + constructorFunction.details.fullName = ''; if (constructorFunction.specializedTypes) { constructorFunction.specializedTypes.returnType = objectType; @@ -859,9 +864,10 @@ export function createFunctionFromConstructor( classType, newSubtype, /* memberClass */ undefined, - /* errorNode */ undefined, - recursionCount, - /* treatConstructorAsClassMember */ true + /* treatConstructorAsClassMember */ true, + /* selfType */ undefined, + /* diag */ undefined, + recursionCount ) as FunctionType | undefined; if (constructorFunction) { diff --git a/packages/pyright-internal/src/analyzer/dataClasses.ts b/packages/pyright-internal/src/analyzer/dataClasses.ts index b9a0bfc3e..d0c7b6ae6 100644 --- a/packages/pyright-internal/src/analyzer/dataClasses.ts +++ b/packages/pyright-internal/src/analyzer/dataClasses.ts @@ -49,7 +49,6 @@ import { isFunction, isInstantiableClass, isOverloadedFunction, - NoneType, OverloadedFunctionType, TupleTypeArgument, Type, @@ -107,7 +106,7 @@ export function synthesizeDataClassMethods( hasDeclaredType: true, }; FunctionType.addParameter(initType, selfParam); - initType.details.declaredReturnType = NoneType.createInstance(); + initType.details.declaredReturnType = evaluator.getNoneType(); // Maintain a list of all dataclass entries (including // those from inherited classes) plus a list of only those @@ -650,7 +649,7 @@ export function synthesizeDataClassMethods( '__hash__', Symbol.createWithType( SymbolFlags.ClassMember | SymbolFlags.IgnoredForOverrideChecks, - NoneType.createInstance() + evaluator.getNoneType() ) ); } @@ -867,7 +866,7 @@ function getDescriptorForConverterField( type: setType, hasDeclaredType: true, }); - setFunction.details.declaredReturnType = NoneType.createInstance(); + setFunction.details.declaredReturnType = evaluator.getNoneType(); const setSymbol = Symbol.createWithType(SymbolFlags.ClassMember, setFunction); fields.set('__set__', setSymbol); diff --git a/packages/pyright-internal/src/analyzer/decorators.ts b/packages/pyright-internal/src/analyzer/decorators.ts index ed0742aa2..519d45d3a 100644 --- a/packages/pyright-internal/src/analyzer/decorators.ts +++ b/packages/pyright-internal/src/analyzer/decorators.ts @@ -26,6 +26,7 @@ import { validateDataClassTransformDecorator, } from './dataClasses'; import { DeclarationType, FunctionDeclaration } from './declaration'; +import { convertDocStringToPlainText } from './docStringConversion'; import { clonePropertyWithDeleter, clonePropertyWithSetter, @@ -49,11 +50,21 @@ import { isOverloadedFunction, } from './types'; +interface FunctionDecoratorInfo { + flags: FunctionTypeFlags; + deprecationMessage: string | undefined; +} + // Scans through the decorators to find a few built-in decorators // that affect the function flags. -export function getFunctionFlagsFromDecorators(evaluator: TypeEvaluator, node: FunctionNode, isInClass: boolean) { +export function getFunctionInfoFromDecorators( + evaluator: TypeEvaluator, + node: FunctionNode, + isInClass: boolean +): FunctionDecoratorInfo { const fileInfo = getFileInfo(node); let flags = FunctionTypeFlags.None; + let deprecationMessage: string | undefined; if (isInClass) { // The "__new__" magic method is not an instance method. @@ -75,6 +86,28 @@ export function getFunctionFlagsFromDecorators(evaluator: TypeEvaluator, node: F let evaluatorFlags = fileInfo.isStubFile ? EvaluatorFlags.AllowForwardReferences : EvaluatorFlags.None; if (decoratorNode.expression.nodeType !== ParseNodeType.Call) { evaluatorFlags |= EvaluatorFlags.CallBaseDefaults; + } else { + if (decoratorNode.expression.nodeType === ParseNodeType.Call) { + const decoratorCallType = evaluator.getTypeOfExpression( + decoratorNode.expression.leftExpression, + evaluatorFlags | EvaluatorFlags.CallBaseDefaults + ).type; + + if (isFunction(decoratorCallType)) { + if (decoratorCallType.details.builtInName === 'deprecated') { + deprecationMessage = getCustomDeprecationMessage(decoratorNode); + } + } + + if (isOverloadedFunction(decoratorCallType)) { + if ( + decoratorCallType.overloads.length > 0 && + decoratorCallType.overloads[0].details.builtInName === 'deprecated' + ) { + deprecationMessage = getCustomDeprecationMessage(decoratorNode); + } + } + } } const decoratorTypeResult = evaluator.getTypeOfExpression(decoratorNode.expression, evaluatorFlags); @@ -91,6 +124,14 @@ export function getFunctionFlagsFromDecorators(evaluator: TypeEvaluator, node: F flags |= FunctionTypeFlags.Overridden; } else if (decoratorType.details.builtInName === 'type_check_only') { flags |= FunctionTypeFlags.TypeCheckOnly; + } else if (decoratorType.details.builtInName === 'overload') { + flags |= FunctionTypeFlags.Overloaded; + } else if (decoratorType.details.builtInName === 'deprecated') { + deprecationMessage = getCustomDeprecationMessage(decoratorNode); + } + } else if (isOverloadedFunction(decoratorType)) { + if (decoratorType.overloads.length > 0 && decoratorType.overloads[0].details.builtInName === 'deprecated') { + deprecationMessage = getCustomDeprecationMessage(decoratorNode); } } else if (isInstantiableClass(decoratorType)) { if (ClassType.isBuiltIn(decoratorType, 'staticmethod')) { @@ -105,7 +146,7 @@ export function getFunctionFlagsFromDecorators(evaluator: TypeEvaluator, node: F } } - return flags; + return { flags, deprecationMessage }; } // Transforms the input function type into an output type based on the @@ -160,13 +201,6 @@ export function applyFunctionDecorator( } if (decoratorCallType.details.builtInName === 'deprecated') { - const deprecationMessage = getCustomDeprecationMessage(decoratorNode); - undecoratedType.details.deprecatedMessage = deprecationMessage; - - if (isFunction(inputFunctionType)) { - inputFunctionType.details.deprecatedMessage = deprecationMessage; - } - return inputFunctionType; } } @@ -176,7 +210,6 @@ export function applyFunctionDecorator( decoratorCallType.overloads.length > 0 && decoratorCallType.overloads[0].details.builtInName === 'deprecated' ) { - undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode); return inputFunctionType; } } @@ -186,12 +219,10 @@ export function applyFunctionDecorator( // Check for some built-in decorator types with known semantics. if (isFunction(decoratorType)) { - if (decoratorType.details.builtInName === 'abstractmethod') { - return inputFunctionType; - } - - if (decoratorType.details.builtInName === 'deprecated') { - undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode); + if ( + decoratorType.details.builtInName === 'abstractmethod' || + decoratorType.details.builtInName === 'deprecated' + ) { return inputFunctionType; } @@ -228,7 +259,6 @@ export function applyFunctionDecorator( } } else if (isOverloadedFunction(decoratorType)) { if (decoratorType.overloads.length > 0 && decoratorType.overloads[0].details.builtInName === 'deprecated') { - undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode); return inputFunctionType; } } else if (isInstantiableClass(decoratorType)) { @@ -351,11 +381,6 @@ export function applyClassDecorator( ); return inputClassType; } - - if (decoratorType.overloads.length > 0 && decoratorType.overloads[0].details.builtInName === 'deprecated') { - originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode); - return inputClassType; - } } else if (isFunction(decoratorType)) { if (decoratorType.details.builtInName === 'final') { originalClassType.details.flags |= ClassTypeFlags.Final; @@ -371,11 +396,6 @@ export function applyClassDecorator( return inputClassType; } - if (decoratorType.details.builtInName === 'deprecated') { - originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode); - return inputClassType; - } - if (decoratorType.details.builtInName === 'runtime_checkable') { originalClassType.details.flags |= ClassTypeFlags.RuntimeCheckable; @@ -607,7 +627,8 @@ function getCustomDeprecationMessage(decorator: DecoratorNode): string { decorator.expression.arguments[0].valueExpression.nodeType === ParseNodeType.StringList && decorator.expression.arguments[0].valueExpression.strings.length === 1 ) { - return decorator.expression.arguments[0].valueExpression.strings[0].value; + const message = decorator.expression.arguments[0].valueExpression.strings[0].value; + return convertDocStringToPlainText(message); } return ''; diff --git a/packages/pyright-internal/src/analyzer/enums.ts b/packages/pyright-internal/src/analyzer/enums.ts index c8c45a902..87e60c93c 100644 --- a/packages/pyright-internal/src/analyzer/enums.ts +++ b/packages/pyright-internal/src/analyzer/enums.ts @@ -27,7 +27,7 @@ import { } from './parseTreeUtils'; import { Symbol, SymbolFlags } from './symbol'; import { isSingleDunderName } from './symbolNameUtils'; -import { FunctionArgument, TypeEvaluator } from './typeEvaluatorTypes'; +import { FunctionArgument, TypeEvaluator, TypeResult } from './typeEvaluatorTypes'; import { enumerateLiteralsForType } from './typeGuards'; import { ClassMemberLookupFlags, computeMroLinearization, lookUpClassMember } from './typeUtils'; import { @@ -345,8 +345,12 @@ export function transformTypeForPossibleEnumClass( // a special case. if (isUnpackedTuple) { valueType = - evaluator.getTypeOfIterator({ type: valueType }, /* isAsync */ false, /* errorNode */ undefined) - ?.type ?? UnknownType.create(); + evaluator.getTypeOfIterator( + { type: valueType }, + /* isAsync */ false, + node, + /* emitNotIterableError */ false + )?.type ?? UnknownType.create(); } } @@ -394,9 +398,9 @@ export function getTypeOfEnumMember( classType: ClassType, memberName: string, isIncomplete: boolean -) { +): TypeResult | undefined { // Handle the special case of 'name' and 'value' members within an enum. - if (!ClassType.isEnumClass(classType)) { + if (!isClassInstance(classType) || !ClassType.isEnumClass(classType)) { return undefined; } diff --git a/packages/pyright-internal/src/analyzer/importResolver.ts b/packages/pyright-internal/src/analyzer/importResolver.ts index 920c4e95e..f8c34e98a 100644 --- a/packages/pyright-internal/src/analyzer/importResolver.ts +++ b/packages/pyright-internal/src/analyzer/importResolver.ts @@ -38,6 +38,8 @@ import { tryStat, } from '../common/pathUtils'; import { PythonVersion, versionFromString } from '../common/pythonVersion'; +import { ServiceProvider } from '../common/serviceProvider'; +import { ServiceKeys } from '../common/serviceProviderExtensions'; import * as StringUtils from '../common/stringUtils'; import { equateStringsCaseInsensitive } from '../common/stringUtils'; import { isIdentifierChar, isIdentifierStartChar } from '../parser/characters'; @@ -48,8 +50,6 @@ import { PyTypedInfo, getPyTypedInfo } from './pyTypedUtils'; import * as PythonPathUtils from './pythonPathUtils'; import * as SymbolNameUtils from './symbolNameUtils'; import { isDunderName } from './symbolNameUtils'; -import { ServiceProvider } from '../common/serviceProvider'; -import { ServiceKeys } from '../common/serviceProviderExtensions'; export interface ImportedModuleDescriptor { leadingDots: number; @@ -64,6 +64,11 @@ export interface ModuleNameAndType { isLocalTypingsFile: boolean; } +export interface ModuleImportInfo extends ModuleNameAndType { + isTypeshedFile: boolean; + isThirdPartyPyTypedPresent: boolean; +} + export interface ModuleNameInfoFromPath { moduleName: string; containsInvalidCharacters?: boolean; @@ -111,7 +116,7 @@ const allowPartialResolutionForThirdPartyPackages = false; export class ImportResolver { private _cachedPythonSearchPaths: { paths: string[]; failureInfo: string[] } | undefined; private _cachedImportResults = new Map(); - private _cachedModuleNameResults = new Map>(); + private _cachedModuleNameResults = new Map>(); private _cachedTypeshedRoot: string | undefined; private _cachedTypeshedStdLibPath: string | undefined; private _cachedTypeshedStdLibModuleVersions: Map | undefined; @@ -136,7 +141,7 @@ export class ImportResolver { invalidateCache() { this._cachedImportResults = new Map(); - this._cachedModuleNameResults = new Map>(); + this._cachedModuleNameResults = new Map>(); this.cachedParentImportResults.reset(); this._stdlibModules = undefined; @@ -309,10 +314,18 @@ export class ImportResolver { // Returns the module name (of the form X.Y.Z) that needs to be imported // from the current context to access the module with the specified file path. // In a sense, it's performing the inverse of resolveImport. - getModuleNameForImport(filePath: string, execEnv: ExecutionEnvironment, allowInvalidModuleName = false) { + getModuleNameForImport( + filePath: string, + execEnv: ExecutionEnvironment, + allowInvalidModuleName = false, + detectPyTyped = false + ) { // Cache results of the reverse of resolveImport as we cache resolveImport. - const cache = getOrAdd(this._cachedModuleNameResults, execEnv.root, () => new Map()); - return getOrAdd(cache, filePath, () => this._getModuleNameForImport(filePath, execEnv, allowInvalidModuleName)); + const cache = getOrAdd(this._cachedModuleNameResults, execEnv.root, () => new Map()); + const key = `${allowInvalidModuleName}.${detectPyTyped}.${filePath}`; + return getOrAdd(cache, key, () => + this._getModuleNameForImport(filePath, execEnv, allowInvalidModuleName, detectPyTyped) + ); } getTypeshedStdLibPath(execEnv: ExecutionEnvironment) { @@ -1045,11 +1058,14 @@ export class ImportResolver { private _getModuleNameForImport( filePath: string, execEnv: ExecutionEnvironment, - allowInvalidModuleName: boolean - ): ModuleNameAndType { + allowInvalidModuleName: boolean, + detectPyTyped: boolean + ): ModuleImportInfo { let moduleName: string | undefined; let importType = ImportType.BuiltIn; let isLocalTypingsFile = false; + let isThirdPartyPyTypedPresent = false; + let isTypeshedFile = false; const importFailureInfo: string[] = []; @@ -1083,7 +1099,13 @@ export class ImportResolver { [] ) ) { - return { moduleName, importType, isLocalTypingsFile }; + return { + moduleName, + importType, + isTypeshedFile: true, + isLocalTypingsFile, + isThirdPartyPyTypedPresent, + }; } } } @@ -1161,6 +1183,7 @@ export class ImportResolver { if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) { moduleName = candidateModuleName; importType = ImportType.ThirdParty; + isTypeshedFile = true; } } @@ -1173,6 +1196,7 @@ export class ImportResolver { if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) { moduleName = candidateModuleName; importType = ImportType.ThirdParty; + isTypeshedFile = true; } } @@ -1192,21 +1216,56 @@ export class ImportResolver { if (!moduleName || (candidateModuleName && candidateModuleName.length < moduleName.length)) { moduleName = candidateModuleName; importType = ImportType.ThirdParty; + isTypeshedFile = false; } } } } + if (detectPyTyped && importType === ImportType.ThirdParty) { + const root = this.getParentImportResolutionRoot(filePath, execEnv.root); + + // Go up directories one by one looking for a py.typed file. + let current = ensureTrailingDirectorySeparator(getDirectoryPath(filePath)); + while (this._shouldWalkUp(current, root, execEnv)) { + if (this.fileExistsCached(combinePaths(current, 'py.typed'))) { + const pyTypedInfo = getPyTypedInfo(this.fileSystem, current); + if (pyTypedInfo && !pyTypedInfo.isPartiallyTyped) { + isThirdPartyPyTypedPresent = true; + } + break; + } + + let success; + [success, current] = this._tryWalkUp(current); + if (!success) { + break; + } + } + } + if (moduleName) { - return { moduleName, importType, isLocalTypingsFile }; + return { moduleName, importType, isTypeshedFile, isLocalTypingsFile, isThirdPartyPyTypedPresent }; } if (allowInvalidModuleName && moduleNameWithInvalidCharacters) { - return { moduleName: moduleNameWithInvalidCharacters, importType, isLocalTypingsFile }; + return { + moduleName: moduleNameWithInvalidCharacters, + isTypeshedFile, + importType, + isLocalTypingsFile, + isThirdPartyPyTypedPresent, + }; } // We didn't find any module name. - return { moduleName: '', importType: ImportType.Local, isLocalTypingsFile }; + return { + moduleName: '', + isTypeshedFile, + importType: ImportType.Local, + isLocalTypingsFile, + isThirdPartyPyTypedPresent, + }; } private _invalidateFileSystemCache() { diff --git a/packages/pyright-internal/src/analyzer/namedTuples.ts b/packages/pyright-internal/src/analyzer/namedTuples.ts index 07b953908..dde8b9f1e 100644 --- a/packages/pyright-internal/src/analyzer/namedTuples.ts +++ b/packages/pyright-internal/src/analyzer/namedTuples.ts @@ -40,7 +40,6 @@ import { FunctionParameter, FunctionType, FunctionTypeFlags, - NoneType, TupleTypeArgument, Type, UnknownType, @@ -348,7 +347,7 @@ export function createNamedTupleType( const initType = FunctionType.createSynthesizedInstance('__init__'); FunctionType.addParameter(initType, selfParameter); FunctionType.addDefaultParameters(initType); - initType.details.declaredReturnType = NoneType.createInstance(); + initType.details.declaredReturnType = evaluator.getNoneType(); classFields.set('__new__', Symbol.createWithType(SymbolFlags.ClassMember, constructorType)); classFields.set('__init__', Symbol.createWithType(SymbolFlags.ClassMember, initType)); @@ -430,7 +429,11 @@ export function updateNamedTupleBaseClass( } // Create a copy of the NamedTuple class that replaces the tuple base class. - const clonedNamedTupleClass = ClassType.cloneForSpecialization(baseClass, [], isTypeArgumentExplicit); + const clonedNamedTupleClass = ClassType.cloneForSpecialization( + baseClass, + /* typeArguments */ undefined, + isTypeArgumentExplicit + ); clonedNamedTupleClass.details = { ...clonedNamedTupleClass.details }; clonedNamedTupleClass.details.baseClasses = clonedNamedTupleClass.details.baseClasses.map( diff --git a/packages/pyright-internal/src/analyzer/operations.ts b/packages/pyright-internal/src/analyzer/operations.ts index 2cc53e973..2de916e65 100644 --- a/packages/pyright-internal/src/analyzer/operations.ts +++ b/packages/pyright-internal/src/analyzer/operations.ts @@ -22,14 +22,16 @@ import { } from '../parser/parseNodes'; import { OperatorType } from '../parser/tokenizerTypes'; import { getFileInfo } from './analyzerNodeInfo'; -import { isWithinLoop, operatorSupportsChaining, printOperator } from './parseTreeUtils'; +import { getEnclosingLambda, isWithinLoop, operatorSupportsChaining, printOperator } from './parseTreeUtils'; import { evaluateStaticBoolExpression } from './staticExpressions'; import { EvaluatorFlags, TypeEvaluator, TypeResult } from './typeEvaluatorTypes'; import { InferenceContext, + convertToInstantiable, getLiteralTypeClassName, getTypeCondition, getUnionSubtypeCount, + isNoneInstance, isOptionalType, isTupleClass, isUnboundedTupleClass, @@ -38,12 +40,12 @@ import { makeInferenceContext, mapSubtypes, preserveUnknown, + removeNoneFromUnion, specializeTupleClass, } from './typeUtils'; import { ClassType, NeverType, - NoneType, Type, TypeBase, UnknownType, @@ -54,10 +56,8 @@ import { isFunction, isInstantiableClass, isNever, - isNoneInstance, isOverloadedFunction, isUnion, - removeNoneFromUnion, } from './types'; // Maps binary operators to the magic methods that implement them. @@ -177,10 +177,10 @@ export function validateBinaryOperation( return preserveUnknown(leftSubtype, rightSubtypeExpanded); } - let returnType = evaluator.getTypeOfMagicMethodReturn( + let returnType = evaluator.getTypeOfMagicMethodCall( rightSubtypeExpanded, - [{ type: leftSubtype, isIncomplete: leftTypeResult.isIncomplete }], '__contains__', + [{ type: leftSubtype, isIncomplete: leftTypeResult.isIncomplete }], errorNode, /* inferenceContext */ undefined ); @@ -191,7 +191,8 @@ export function validateBinaryOperation( const iteratorType = evaluator.getTypeOfIterator( { type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }, /* isAsync */ false, - /* errorNode */ undefined + errorNode, + /* emitNotIterableError */ false )?.type; if (iteratorType && evaluator.assignType(iteratorType, leftSubtype)) { @@ -384,20 +385,20 @@ export function validateBinaryOperation( } const magicMethodName = binaryOperatorMap[operator][0]; - let resultType = evaluator.getTypeOfMagicMethodReturn( + let resultType = evaluator.getTypeOfMagicMethodCall( convertFunctionToObject(evaluator, leftSubtypeUnexpanded), - [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, + [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], errorNode, inferenceContext ); if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) { // Try the expanded left type. - resultType = evaluator.getTypeOfMagicMethodReturn( + resultType = evaluator.getTypeOfMagicMethodCall( convertFunctionToObject(evaluator, leftSubtypeExpanded), - [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, + [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], errorNode, inferenceContext ); @@ -405,10 +406,10 @@ export function validateBinaryOperation( if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) { // Try the expanded left and right type. - resultType = evaluator.getTypeOfMagicMethodReturn( + resultType = evaluator.getTypeOfMagicMethodCall( convertFunctionToObject(evaluator, leftSubtypeExpanded), - [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, + [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], errorNode, inferenceContext ); @@ -417,25 +418,25 @@ export function validateBinaryOperation( if (!resultType) { // Try the alternate form (swapping right and left). const altMagicMethodName = binaryOperatorMap[operator][1]; - resultType = evaluator.getTypeOfMagicMethodReturn( + resultType = evaluator.getTypeOfMagicMethodCall( convertFunctionToObject(evaluator, rightSubtypeUnexpanded), - [{ type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, + [{ type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }], errorNode, inferenceContext ); if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) { // Try the expanded right type. - resultType = evaluator.getTypeOfMagicMethodReturn( + resultType = evaluator.getTypeOfMagicMethodCall( convertFunctionToObject(evaluator, rightSubtypeExpanded), + altMagicMethodName, [ { type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete, }, ], - altMagicMethodName, errorNode, inferenceContext ); @@ -443,10 +444,10 @@ export function validateBinaryOperation( if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) { // Try the expanded right and left type. - resultType = evaluator.getTypeOfMagicMethodReturn( + resultType = evaluator.getTypeOfMagicMethodCall( convertFunctionToObject(evaluator, rightSubtypeExpanded), - [{ type: leftSubtypeExpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, + [{ type: leftSubtypeExpanded, isIncomplete: leftTypeResult.isIncomplete }], errorNode, inferenceContext ); @@ -587,9 +588,9 @@ export function getTypeOfBinaryOperation( // with something else. Even though "None" will normally be interpreted // as the None singleton object in contexts where a type annotation isn't // assumed, we'll allow it here. - adjustedRightType = NoneType.createType(); + adjustedRightType = convertToInstantiable(evaluator.getNoneType()); } else if (!isNoneInstance(rightType) && isNoneInstance(leftType)) { - adjustedLeftType = NoneType.createType(); + adjustedLeftType = convertToInstantiable(evaluator.getNoneType()); } if (isUnionableType([adjustedLeftType, adjustedRightType])) { @@ -695,8 +696,10 @@ export function getTypeOfBinaryOperation( const diag = new DiagnosticAddendum(); // Don't use literal math if either of the operation is within a loop - // because the literal values may change each time. - const isLiteralMathAllowed = !isWithinLoop(node); + // because the literal values may change each time. We also don't want to + // apply literal math within the body of a lambda because they are often + // used as callbacks where the value changes each time they are called. + const isLiteralMathAllowed = !isWithinLoop(node) && !getEnclosingLambda(node); // Don't special-case tuple __add__ if the left type is a union. This // can result in an infinite loop if we keep creating new tuple types @@ -823,20 +826,20 @@ export function getTypeOfAugmentedAssignment( } const magicMethodName = operatorMap[node.operator][0]; - let returnType = evaluator.getTypeOfMagicMethodReturn( + let returnType = evaluator.getTypeOfMagicMethodCall( leftSubtypeUnexpanded, - [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, + [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], node, inferenceContext ); if (!returnType && leftSubtypeUnexpanded !== leftSubtypeExpanded) { // Try with the expanded left type. - returnType = evaluator.getTypeOfMagicMethodReturn( + returnType = evaluator.getTypeOfMagicMethodCall( leftSubtypeExpanded, - [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, + [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], node, inferenceContext ); @@ -844,10 +847,10 @@ export function getTypeOfAugmentedAssignment( if (!returnType && rightSubtypeUnexpanded !== rightSubtypeExpanded) { // Try with the expanded left and right type. - returnType = evaluator.getTypeOfMagicMethodReturn( + returnType = evaluator.getTypeOfMagicMethodCall( leftSubtypeExpanded, - [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, + [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], node, inferenceContext ); @@ -995,7 +998,7 @@ export function getTypeOfUnaryOperation( type = exprType; } else { const magicMethodName = unaryOperatorMap[node.operator]; - type = evaluator.getTypeOfMagicMethodReturn(exprType, [], magicMethodName, node, inferenceContext); + type = evaluator.getTypeOfMagicMethodCall(exprType, magicMethodName, [], node, inferenceContext); } if (!type) { @@ -1106,10 +1109,7 @@ function customMetaclassSupportsMethod(type: Type, methodName: string): boolean // to an object instance. function convertFunctionToObject(evaluator: TypeEvaluator, type: Type) { if (isFunction(type) || isOverloadedFunction(type)) { - const objectType = evaluator.getObjectType(); - if (objectType) { - return objectType; - } + return evaluator.getObjectType(); } return type; diff --git a/packages/pyright-internal/src/analyzer/packageTypeVerifier.ts b/packages/pyright-internal/src/analyzer/packageTypeVerifier.ts index aafb4e482..426faae9c 100644 --- a/packages/pyright-internal/src/analyzer/packageTypeVerifier.ts +++ b/packages/pyright-internal/src/analyzer/packageTypeVerifier.ts @@ -710,7 +710,6 @@ export class PackageTypeVerifier { switch (type.category) { case TypeCategory.Unbound: case TypeCategory.Any: - case TypeCategory.None: case TypeCategory.Never: case TypeCategory.TypeVar: break; @@ -1293,7 +1292,6 @@ export class PackageTypeVerifier { switch (type.category) { case TypeCategory.Unbound: case TypeCategory.Any: - case TypeCategory.None: case TypeCategory.Never: case TypeCategory.TypeVar: break; diff --git a/packages/pyright-internal/src/analyzer/parseTreeUtils.ts b/packages/pyright-internal/src/analyzer/parseTreeUtils.ts index d0135ef8b..e99eedc89 100644 --- a/packages/pyright-internal/src/analyzer/parseTreeUtils.ts +++ b/packages/pyright-internal/src/analyzer/parseTreeUtils.ts @@ -679,6 +679,29 @@ export function getEnclosingFunction(node: ParseNode): FunctionNode | undefined return undefined; } +// This is similar to getEnclosingFunction except that it uses evaluation +// scopes rather than the parse tree to determine whether the specified node +// is within the scope. That means if the node is within a class decorator +// (for example), it will be considered part of its parent node rather than +// the class node. +export function getEnclosingFunctionEvaluationScope(node: ParseNode): FunctionNode | undefined { + let curNode = getEvaluationScopeNode(node); + + while (curNode) { + if (curNode.nodeType === ParseNodeType.Function) { + return curNode; + } + + if (curNode.nodeType === ParseNodeType.Class || !curNode.parent) { + return undefined; + } + + curNode = getEvaluationScopeNode(curNode.parent); + } + + return undefined; +} + export function getEnclosingLambda(node: ParseNode): LambdaNode | undefined { let curNode = node.parent; while (curNode) { @@ -942,6 +965,19 @@ export function getTypeAnnotationNode(node: ParseNode): TypeAnnotationNode | und return undefined; } +// In general, arguments passed to a call are evaluated by the runtime in +// left-to-right order. There is one exception, however, when an unpacked +// iterable is used after a keyword argument. +export function getArgumentsByRuntimeOrder(node: CallNode) { + const positionalArgs = node.arguments.filter( + (arg) => !arg.name && arg.argumentCategory !== ArgumentCategory.UnpackedDictionary + ); + const keywordArgs = node.arguments.filter( + (arg) => !!arg.name || arg.argumentCategory === ArgumentCategory.UnpackedDictionary + ); + return positionalArgs.concat(keywordArgs); +} + // PEP 591 spells out certain limited cases where an assignment target // can be annotated with a "Final" annotation. This function determines // whether Final is allowed for the specified node. @@ -1572,6 +1608,11 @@ export function getEnclosingParameter(node: ParseNode): ParameterNode | undefine if (curNode.nodeType === ParseNodeType.Parameter) { return curNode; } + + if (curNode.nodeType === ParseNodeType.Function) { + return undefined; + } + curNode = curNode.parent; } diff --git a/packages/pyright-internal/src/analyzer/patternMatching.ts b/packages/pyright-internal/src/analyzer/patternMatching.ts index 55e11f92f..6854ccb7d 100644 --- a/packages/pyright-internal/src/analyzer/patternMatching.ts +++ b/packages/pyright-internal/src/analyzer/patternMatching.ts @@ -48,7 +48,6 @@ import { isClassInstance, isInstantiableClass, isNever, - isNoneInstance, isSameWithoutLiteralValue, isTypeSame, isUnknown, @@ -68,6 +67,7 @@ import { getTypeVarScopeId, isLiteralType, isMetaclassInstance, + isNoneInstance, isPartlyUnknown, isTupleClass, isUnboundedTupleClass, @@ -288,6 +288,11 @@ function narrowTypeBasedOnSequencePattern( } }); + // If the pattern is an empty sequence, use the entry types. + if (pattern.entries.length === 0 && entry.entryTypes.length > 0) { + narrowedEntryTypes.push(combineTypes(entry.entryTypes)); + } + if (!isPositiveTest) { // If the positive case is a definite match, the negative case can // eliminate this subtype entirely. @@ -653,9 +658,17 @@ function narrowTypeBasedOnClassPattern( // If this is a class (but not a type alias that refers to a class), // specialize it with Unknown type arguments. if (isClass(exprType) && !exprType.typeAliasInfo) { + exprType = ClassType.cloneRemoveTypePromotions(exprType); exprType = specializeClassType(exprType); } + // Are there any positional arguments? If so, try to get the mappings for + // these arguments by fetching the __match_args__ symbol from the class. + let positionalArgNames: string[] = []; + if (pattern.arguments.some((arg) => !arg.name) && isInstantiableClass(exprType)) { + positionalArgNames = getPositionalMatchArgNames(evaluator, exprType); + } + if (!isPositiveTest) { // Don't attempt to narrow if the class type is a more complex type (e.g. a TypeVar or union). if (!isInstantiableClass(exprType)) { @@ -676,7 +689,7 @@ function narrowTypeBasedOnClassPattern( const isPatternMetaclass = isMetaclassInstance(classInstance); return evaluator.mapSubtypesExpandTypeVars( - type, + evaluator.expandPromotionTypes(pattern, type), /* conditionFilter */ undefined, (subjectSubtypeExpanded, subjectSubtypeUnexpanded) => { // Handle the case where the class pattern references type() or a subtype thereof @@ -729,15 +742,6 @@ function narrowTypeBasedOnClassPattern( } } - // Are there any positional arguments? If so, try to get the mappings for - // these arguments by fetching the __match_args__ symbol from the class. - let positionalArgNames: string[] = []; - if (pattern.arguments.some((arg) => !arg.name)) { - if (isClass(subjectSubtypeExpanded)) { - positionalArgNames = getPositionalMatchArgNames(evaluator, subjectSubtypeExpanded); - } - } - for (let index = 0; index < pattern.arguments.length; index++) { const narrowedArgType = narrowTypeOfClassPatternArgument( evaluator, @@ -910,7 +914,27 @@ function narrowTypeBasedOnClassPattern( // Some built-in classes are treated as special cases for the class pattern // if a positional argument is used. function isClassSpecialCaseForClassPattern(classType: ClassType) { - return classPatternSpecialCases.some((className) => classType.details.fullName === className); + if (classPatternSpecialCases.some((className) => classType.details.fullName === className)) { + return true; + } + + // If the class supplies its own `__match_args__`, it's not a special case. + const matchArgsMemberInfo = lookUpClassMember(classType, '__match_args__'); + if (matchArgsMemberInfo) { + return false; + } + + // If the class derives from a built-in class, it is considered a special case. + for (const mroClass of classType.details.mro) { + if ( + isClass(mroClass) && + classPatternSpecialCases.some((className) => mroClass.details.fullName === className) + ) { + return true; + } + } + + return false; } // Narrows the pattern provided for a class pattern argument. @@ -1056,10 +1080,10 @@ function narrowTypeBasedOnValuePattern( // Determine if assignment is supported for this combination of // value subtype and matching subtype. const returnType = evaluator.useSpeculativeMode(pattern.expression, () => - evaluator.getTypeOfMagicMethodReturn( + evaluator.getTypeOfMagicMethodCall( valueSubtypeExpanded, - [{ type: subjectSubtypeExpanded }], '__eq__', + [{ type: subjectSubtypeExpanded }], pattern.expression, /* expectedType */ undefined ) @@ -1648,18 +1672,11 @@ export function validateClassPattern(evaluator: TypeEvaluator, pattern: PatternC ); } } else { - const isBuiltIn = classPatternSpecialCases.some((className) => exprType.details.fullName === className); + const isBuiltIn = isClassSpecialCaseForClassPattern(exprType); - // If it's a special-case builtin class, only one positional argument is allowed. + // If it's a special-case builtin class, only positional arguments are allowed. if (isBuiltIn) { - if (pattern.arguments.length > 1) { - evaluator.addDiagnostic( - getFileInfo(pattern).diagnosticRuleSet.reportGeneralTypeIssues, - DiagnosticRule.reportGeneralTypeIssues, - Localizer.Diagnostic.classPatternBuiltInArgCount(), - pattern.arguments[1] - ); - } else if (pattern.arguments.length === 1 && pattern.arguments[0].name) { + if (pattern.arguments.length === 1 && pattern.arguments[0].name) { evaluator.addDiagnostic( getFileInfo(pattern).diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, @@ -1668,6 +1685,36 @@ export function validateClassPattern(evaluator: TypeEvaluator, pattern: PatternC ); } } + + // Emits an error if the supplied number of positional patterns is less than + // expected for the given subject type. + let positionalPatternCount = pattern.arguments.findIndex((arg) => arg.name !== undefined); + if (positionalPatternCount < 0) { + positionalPatternCount = pattern.arguments.length; + } + + let expectedPatternCount = 1; + if (!isBuiltIn) { + let positionalArgNames: string[] = []; + if (pattern.arguments.some((arg) => !arg.name)) { + positionalArgNames = getPositionalMatchArgNames(evaluator, exprType); + } + + expectedPatternCount = positionalArgNames.length; + } + + if (positionalPatternCount > expectedPatternCount) { + evaluator.addDiagnostic( + getFileInfo(pattern).diagnosticRuleSet.reportGeneralTypeIssues, + DiagnosticRule.reportGeneralTypeIssues, + Localizer.Diagnostic.classPatternPositionalArgCount().format({ + type: exprType.details.name, + expected: expectedPatternCount, + received: positionalPatternCount, + }), + pattern.arguments[expectedPatternCount] + ); + } } } diff --git a/packages/pyright-internal/src/analyzer/program.ts b/packages/pyright-internal/src/analyzer/program.ts index ff86c2871..83d608fe5 100644 --- a/packages/pyright-internal/src/analyzer/program.ts +++ b/packages/pyright-internal/src/analyzer/program.ts @@ -19,8 +19,7 @@ import { assert } from '../common/debug'; import { Diagnostic } from '../common/diagnostic'; import { FileDiagnostics } from '../common/diagnosticSink'; import { FileEditAction } from '../common/editAction'; -import { EditableProgram, Extensions, ProgramView } from '../common/extensibility'; -import { FileSystem } from '../common/fileSystem'; +import { EditableProgram, ProgramView } from '../common/extensibility'; import { LogTracker } from '../common/logTracker'; import { combinePaths, @@ -47,6 +46,7 @@ import { ImportResult, ImportType } from './importResult'; import { getDocString } from './parseTreeUtils'; import { Scope } from './scope'; import { IPythonMode, SourceFile, SourceFileEditMode } from './sourceFile'; +import { SourceFileInfo } from './sourceFileInfo'; import { createChainedByList, isUserCode, verifyNoCyclesInChainedFiles } from './sourceFileInfoUtils'; import { SourceMapper } from './sourceMapper'; import { Symbol } from './symbol'; @@ -56,7 +56,6 @@ import { createTypeEvaluatorWithTracker } from './typeEvaluatorWithTracker'; import { PrintTypeFlags } from './typePrinter'; import { TypeStubWriter } from './typeStubWriter'; import { Type } from './types'; -import { SourceFileInfo } from './sourceFileInfo'; const _maxImportDepth = 256; @@ -84,7 +83,7 @@ export type PreCheckCallback = (parseResults: ParseResults, evaluator: TypeEvalu export interface ISourceFileFactory { createSourceFile( - fs: FileSystem, + serviceProvider: ServiceProvider, filePath: string, moduleName: string, isThirdPartyImport: boolean, @@ -171,7 +170,6 @@ export class Program { readonly serviceProvider: ServiceProvider, logTracker?: LogTracker, private _disableChecker?: boolean, - cacheManager?: CacheManager, id?: string ) { this._console = serviceProvider.tryGet(ServiceKeys.console) || new StandardConsole(); @@ -180,7 +178,7 @@ export class Program { this._configOptions = initialConfigOptions; this._sourceFileFactory = serviceProvider.sourceFileFactory(); - this._cacheManager = cacheManager ?? new CacheManager(); + this._cacheManager = serviceProvider.tryGet(ServiceKeys.cacheManager) ?? new CacheManager(); this._cacheManager.registerCacheOwner(this); this._createNewEvaluator(); @@ -274,6 +272,11 @@ export class Program { } } + if (mutatedFiles.length > 0) { + // All cache is invalid now. + this._createNewEvaluator(); + } + return edits; } @@ -352,7 +355,8 @@ export class Program { addTrackedFile(filePath: string, isThirdPartyImport = false, isInPyTypedPackage = false): SourceFile { let sourceFileInfo = this.getSourceFileInfo(filePath); - const importName = this._getImportNameForFile(filePath); + const moduleImportInfo = this._getModuleImportInfoForFile(filePath); + const importName = moduleImportInfo.moduleName; if (sourceFileInfo) { // The module name may have changed based on updates to the @@ -363,7 +367,7 @@ export class Program { } const sourceFile = this._sourceFileFactory.createSourceFile( - this.fileSystem, + this.serviceProvider, filePath, importName, isThirdPartyImport, @@ -389,11 +393,11 @@ export class Program { setFileOpened(filePath: string, version: number | null, contents: string, options?: OpenFileOptions) { let sourceFileInfo = this.getSourceFileInfo(filePath); if (!sourceFileInfo) { - const importName = this._getImportNameForFile(filePath); + const moduleImportInfo = this._getModuleImportInfoForFile(filePath); const sourceFile = this._sourceFileFactory.createSourceFile( - this.fileSystem, + this.serviceProvider, filePath, - importName, + moduleImportInfo.moduleName, /* isThirdPartyImport */ false, /* isInPyTypedPackage */ false, this._editModeTracker, @@ -716,7 +720,11 @@ export class Program { } getParseResults(filePath: string): ParseResults | undefined { - return this.getBoundSourceFile(filePath)?.getParseResults(); + return this.getBoundSourceFileInfo( + filePath, + /* content */ undefined, + /* force */ true + )?.sourceFile.getParseResults(); } handleMemoryHighUsage() { @@ -992,7 +1000,8 @@ export class Program { this._createNewEvaluator(); this._discardCachedParseResults(); this._parsedFileCount = 0; - Extensions.getProgramExtensions(this.rootPath).forEach((e) => (e.clearCache ? e.clearCache() : null)); + + this.serviceProvider.tryGet(ServiceKeys.stateMutationListeners)?.forEach((l) => l.clearCache?.()); } private _handleMemoryHighUsage() { @@ -1428,11 +1437,11 @@ export class Program { // of the program. let importedFileInfo = this.getSourceFileInfo(importInfo.path); if (!importedFileInfo) { - const importName = this._getImportNameForFile(importInfo.path); + const moduleImportInfo = this._getModuleImportInfoForFile(importInfo.path); const sourceFile = new SourceFile( - this.fileSystem, + this.serviceProvider, importInfo.path, - importName, + moduleImportInfo.moduleName, importInfo.isThirdPartyImport, importInfo.isPyTypedPresent, this._editModeTracker, @@ -1474,16 +1483,6 @@ export class Program { sourceFileInfo.builtinsImport = this.getSourceFileInfo(resolvedBuiltinsPath); } - // Resolve the ipython display import for the file. This needs to be - // analyzed before the file can be analyzed. - sourceFileInfo.ipythonDisplayImport = undefined; - const ipythonDisplayImport = sourceFileInfo.sourceFile.getIPythonDisplayImport(); - if (ipythonDisplayImport && ipythonDisplayImport.isImportFound) { - const resolvedIPythonDisplayPath = - ipythonDisplayImport.resolvedPaths[ipythonDisplayImport.resolvedPaths.length - 1]; - sourceFileInfo.ipythonDisplayImport = this.getSourceFileInfo(resolvedIPythonDisplayPath); - } - return filesAdded; } @@ -1528,7 +1527,7 @@ export class Program { return flags; } - private _getImportNameForFile(filePath: string) { + private _getModuleImportInfoForFile(filePath: string) { // We allow illegal module names (e.g. names that include "-" in them) // because we want a unique name for each module even if it cannot be // imported through an "import" statement. It's important to have a @@ -1538,9 +1537,11 @@ export class Program { const moduleNameAndType = this._importResolver.getModuleNameForImport( filePath, this._configOptions.getDefaultExecEnvironment(), - /* allowIllegalModuleName */ true + /* allowIllegalModuleName */ true, + /* detectPyTyped */ false ); - return moduleNameAndType.moduleName; + + return moduleNameAndType; } // A "shadowed" file is a python source file that has been added to the program because @@ -1566,11 +1567,11 @@ export class Program { } private _createInterimFileInfo(filePath: string) { - const importName = this._getImportNameForFile(filePath); + const moduleImportInfo = this._getModuleImportInfoForFile(filePath); const sourceFile = this._sourceFileFactory.createSourceFile( - this.fileSystem, + this.serviceProvider, filePath, - importName, + moduleImportInfo.moduleName, /* isThirdPartyImport */ false, /* isInPyTypedPackage */ false, this._editModeTracker, @@ -1646,7 +1647,7 @@ export class Program { } private _getImplicitImports(file: SourceFileInfo) { - // If file is not parsed, then chainedSourceFile, ipythonDisplayImport, + // If file is not parsed, then chainedSourceFile, // builtinsImport might not exist or incorrect. // They will be added when _parseFile is called and _updateSourceFileImports ran. if (file.builtinsImport === file) { @@ -1661,7 +1662,7 @@ export class Program { return input; }; - return tryReturn(file.chainedSourceFile) ?? tryReturn(file.ipythonDisplayImport) ?? file.builtinsImport; + return tryReturn(file.chainedSourceFile) ?? file.builtinsImport; } private _bindImplicitImports(fileToAnalyze: SourceFileInfo, skipFileNeededCheck?: boolean) { @@ -1740,10 +1741,9 @@ export class Program { } // If it is not builtin module itself, we need to parse and bind - // the ipython display import if required. Otherwise, get builtin module. + // the builtin module. builtinsScope = getScopeIfAvailable(fileToAnalyze.chainedSourceFile) ?? - getScopeIfAvailable(fileToAnalyze.ipythonDisplayImport) ?? getScopeIfAvailable(fileToAnalyze.builtinsImport); } diff --git a/packages/pyright-internal/src/analyzer/properties.ts b/packages/pyright-internal/src/analyzer/properties.ts index 146ab05b3..698dad562 100644 --- a/packages/pyright-internal/src/analyzer/properties.ts +++ b/packages/pyright-internal/src/analyzer/properties.ts @@ -23,11 +23,12 @@ import { FunctionType, FunctionTypeFlags, isAnyOrUnknown, + isClass, isFunction, isInstantiableClass, isTypeSame, isTypeVar, - NoneType, + ModuleType, OverloadedFunctionType, Type, UnknownType, @@ -281,7 +282,7 @@ function addGetMethodToPropertySymbolTable(evaluator: TypeEvaluator, propertyObj FunctionType.addParameter(getFunction1, { category: ParameterCategory.Simple, name: 'obj', - type: NoneType.createInstance(), + type: evaluator.getNoneType(), hasDeclaredType: true, }); FunctionType.addParameter(getFunction1, { @@ -296,6 +297,7 @@ function addGetMethodToPropertySymbolTable(evaluator: TypeEvaluator, propertyObj ? FunctionType.getSpecializedReturnType(fget) : propertyObject; getFunction1.details.declaration = fget.details.declaration; + getFunction1.details.deprecatedMessage = fget.details.deprecatedMessage; // Override the scope ID since we're using parameter types from the // decorated function. @@ -328,6 +330,7 @@ function addGetMethodToPropertySymbolTable(evaluator: TypeEvaluator, propertyObj }); getFunction2.details.declaredReturnType = FunctionType.getSpecializedReturnType(fget); getFunction2.details.declaration = fget.details.declaration; + getFunction2.details.deprecatedMessage = fget.details.deprecatedMessage; // Override the scope ID since we're using parameter types from the // decorated function. @@ -361,15 +364,16 @@ function addSetMethodToPropertySymbolTable(evaluator: TypeEvaluator, propertyObj FunctionType.addParameter(setFunction, { category: ParameterCategory.Simple, name: 'obj', - type: combineTypes([objType, NoneType.createInstance()]), + type: combineTypes([objType, evaluator.getNoneType()]), hasDeclaredType: true, }); - setFunction.details.declaredReturnType = NoneType.createInstance(); + setFunction.details.declaredReturnType = evaluator.getNoneType(); // Adopt the TypeVarScopeId of the fset function in case it has any // TypeVars that need to be solved. setFunction.details.typeVarScopeId = getTypeVarScopeId(fset); + setFunction.details.deprecatedMessage = fset.details.deprecatedMessage; let setParamType: Type = UnknownType.create(); @@ -404,6 +408,7 @@ function addDelMethodToPropertySymbolTable(evaluator: TypeEvaluator, propertyObj // Adopt the TypeVarScopeId of the fdel function in case it has any // TypeVars that need to be solved. delFunction.details.typeVarScopeId = getTypeVarScopeId(fdel); + delFunction.details.deprecatedMessage = fdel.details.deprecatedMessage; let objType = fdel.details.parameters.length > 0 ? fdel.details.parameters[0].type : AnyType.create(); @@ -414,10 +419,10 @@ function addDelMethodToPropertySymbolTable(evaluator: TypeEvaluator, propertyObj FunctionType.addParameter(delFunction, { category: ParameterCategory.Simple, name: 'obj', - type: combineTypes([objType, NoneType.createInstance()]), + type: combineTypes([objType, evaluator.getNoneType()]), hasDeclaredType: true, }); - delFunction.details.declaredReturnType = NoneType.createInstance(); + delFunction.details.declaredReturnType = evaluator.getNoneType(); const delSymbol = Symbol.createWithType(SymbolFlags.ClassMember, delFunction); fields.set('__delete__', delSymbol); } @@ -473,13 +478,13 @@ export function assignProperty( destPropertyType: ClassType, srcPropertyType: ClassType, destClass: ClassType, - srcClass: ClassType, + srcClass: ClassType | ModuleType, diag: DiagnosticAddendum | undefined, typeVarContext?: TypeVarContext, selfTypeVarContext?: TypeVarContext, recursionCount = 0 ): boolean { - const srcObjectToBind = ClassType.cloneAsInstance(srcClass); + const srcObjectToBind = isClass(srcClass) ? ClassType.cloneAsInstance(srcClass) : undefined; const destObjectToBind = ClassType.cloneAsInstance(destClass); let isAssignable = true; const accessors: { name: string; missingDiagMsg: () => string; incompatibleDiagMsg: () => string }[] = [ @@ -515,7 +520,9 @@ export function assignProperty( } evaluator.inferReturnTypeIfNecessary(srcAccessType); - srcAccessType = partiallySpecializeType(srcAccessType, srcClass) as FunctionType; + if (isClass(srcClass)) { + srcAccessType = partiallySpecializeType(srcAccessType, srcClass) as FunctionType; + } evaluator.inferReturnTypeIfNecessary(destAccessType); destAccessType = partiallySpecializeType(destAccessType, destClass) as FunctionType; @@ -544,14 +551,18 @@ export function assignProperty( destObjectToBind, destAccessType, /* memberClass */ undefined, - /* errorNode */ undefined, + /* treatConstructorAsClassMember */ undefined, + /* firstParamType */ undefined, + /* diag */ undefined, recursionCount ); const boundSrcAccessType = evaluator.bindFunctionToClassOrObject( srcObjectToBind, srcAccessType, /* memberClass */ undefined, - /* errorNode */ undefined, + /* treatConstructorAsClassMember */ undefined, + /* firstParamType */ undefined, + /* diag */ undefined, recursionCount ); diff --git a/packages/pyright-internal/src/analyzer/protocols.ts b/packages/pyright-internal/src/analyzer/protocols.ts index 6f9b21ef0..1bbbd3575 100644 --- a/packages/pyright-internal/src/analyzer/protocols.ts +++ b/packages/pyright-internal/src/analyzer/protocols.ts @@ -8,23 +8,26 @@ * (structural subtyping) classes. */ +import { assert } from '../common/debug'; import { DiagnosticAddendum } from '../common/diagnostic'; import { Localizer } from '../localization/localize'; import { assignTypeToTypeVar } from './constraintSolver'; import { DeclarationType } from './declaration'; import { assignProperty } from './properties'; +import { Symbol } from './symbol'; import { getLastTypedDeclaredForSymbol } from './symbolUtils'; import { TypeEvaluator } from './typeEvaluatorTypes'; import { ClassType, + FunctionType, isClass, isClassInstance, isFunction, isInstantiableClass, isOverloadedFunction, isTypeSame, - maxTypeRecursionCount, ModuleType, + OverloadedFunctionType, ProtocolCompatibility, Type, UnknownType, @@ -32,8 +35,8 @@ import { import { applySolvedTypeVars, AssignTypeFlags, - buildTypeVarContextFromSpecializedClass, ClassMember, + ClassMemberLookupFlags, containsLiteralType, getTypeVarScopeId, lookUpClassMember, @@ -69,11 +72,6 @@ export function assignClassToProtocol( ): boolean { const enforceInvariance = (flags & AssignTypeFlags.EnforceInvariance) !== 0; - if (recursionCount > maxTypeRecursionCount) { - return true; - } - recursionCount++; - // Use a stack of pending protocol class evaluations to detect recursion. // This can happen when a protocol class refers to itself. if ( @@ -136,6 +134,28 @@ export function assignClassToProtocol( return isCompatible; } +export function assignModuleToProtocol( + evaluator: TypeEvaluator, + destType: ClassType, + srcType: ModuleType, + diag: DiagnosticAddendum | undefined, + destTypeVarContext: TypeVarContext | undefined, + flags: AssignTypeFlags, + recursionCount: number +): boolean { + return assignClassToProtocolInternal( + evaluator, + destType, + srcType, + diag, + destTypeVarContext, + /* srcTypeVarContext */ undefined, + flags, + /* treatSourceAsInstantiable */ false, + recursionCount + ); +} + // Looks up the protocol compatibility in the cache. If it's not found, // return undefined. function getProtocolCompatibility( @@ -194,7 +214,7 @@ function setProtocolCompatibility( function assignClassToProtocolInternal( evaluator: TypeEvaluator, destType: ClassType, - srcType: ClassType, + srcType: ClassType | ModuleType, diag: DiagnosticAddendum | undefined, destTypeVarContext: TypeVarContext | undefined, srcTypeVarContext: TypeVarContext | undefined, @@ -214,7 +234,7 @@ function assignClassToProtocolInternal( // If the source is a TypedDict, use the _TypedDict placeholder class // instead. We don't want to use the TypedDict members for protocol // comparison. - if (ClassType.isTypedDictClass(srcType)) { + if (isClass(srcType) && ClassType.isTypedDictClass(srcType)) { const typedDictClassType = evaluator.getTypedDictClassType(); if (typedDictClassType && isInstantiableClass(typedDictClassType)) { srcType = typedDictClassType; @@ -223,7 +243,6 @@ function assignClassToProtocolInternal( let typesAreConsistent = true; const checkedSymbolSet = new Set(); - const srcClassTypeVarContext = buildTypeVarContextFromSpecializedClass(srcType); let assignTypeFlags = flags & AssignTypeFlags.OverloadOverlapCheck; assignTypeFlags |= containsLiteralType(srcType, /* includeTypeArgs */ true) @@ -241,19 +260,20 @@ function assignClassToProtocolInternal( return; } - mroClass.details.fields.forEach((symbol, name) => { + mroClass.details.fields.forEach((destSymbol, name) => { // If we've already determined that the types are not consistent and the caller // hasn't requested detailed diagnostic output, we can shortcut the remainder. if (!typesAreConsistent && !diag) { return; } - if (!symbol.isClassMember() || symbol.isIgnoredForProtocolMatch() || checkedSymbolSet.has(name)) { + if (!destSymbol.isClassMember() || destSymbol.isIgnoredForProtocolMatch() || checkedSymbolSet.has(name)) { return; } let isMemberFromMetaclass = false; let srcMemberInfo: ClassMember | undefined; + let srcSymbol: Symbol | undefined; // Special-case the `__class_getitem__` for normal protocol comparison. // This is a convention agreed upon by typeshed maintainers. @@ -271,120 +291,147 @@ function assignClassToProtocolInternal( // be checked again even if it is declared by a subclass. checkedSymbolSet.add(name); - // Look in the metaclass first if we're treating the source as an instantiable class. - if ( - treatSourceAsInstantiable && - srcType.details.effectiveMetaclass && - isInstantiableClass(srcType.details.effectiveMetaclass) - ) { - srcMemberInfo = lookUpClassMember(srcType.details.effectiveMetaclass, name); - if (srcMemberInfo) { - srcClassTypeVarContext.addSolveForScope(getTypeVarScopeId(srcType.details.effectiveMetaclass)); - isMemberFromMetaclass = true; - } + let destMemberType = evaluator.getDeclaredTypeOfSymbol(destSymbol)?.type; + if (!destMemberType) { + return; } - if (!srcMemberInfo) { - srcMemberInfo = lookUpClassMember(srcType, name); - } + let srcMemberType: Type; + let isSrcReadOnly = false; - if (!srcMemberInfo) { - diag?.addMessage(Localizer.DiagnosticAddendum.protocolMemberMissing().format({ name })); - typesAreConsistent = false; - return; - } + if (isClass(srcType)) { + // Look in the metaclass first if we're treating the source as an instantiable class. + if ( + treatSourceAsInstantiable && + srcType.details.effectiveMetaclass && + isInstantiableClass(srcType.details.effectiveMetaclass) + ) { + srcMemberInfo = lookUpClassMember(srcType.details.effectiveMetaclass, name); + if (srcMemberInfo) { + isMemberFromMetaclass = true; + } + } - if (symbol.isClassVar() && !srcMemberInfo.symbol.isClassVar() && !srcMemberInfo.symbol.isClassMember()) { - diag?.addMessage(Localizer.DiagnosticAddendum.protocolMemberClassVar().format({ name })); - typesAreConsistent = false; - } + if (!srcMemberInfo) { + srcMemberInfo = lookUpClassMember(srcType, name); + } - let destMemberType = evaluator.getDeclaredTypeOfSymbol(symbol)?.type; - if (!destMemberType) { - return; - } + if (!srcMemberInfo) { + diag?.addMessage(Localizer.DiagnosticAddendum.protocolMemberMissing().format({ name })); + typesAreConsistent = false; + return; + } - // Partially specialize the type of the symbol based on the MRO class. - // We can skip this if it's the dest class because it is already - // specialized. - if (!ClassType.isSameGenericClass(mroClass, destType)) { - destMemberType = partiallySpecializeType(destMemberType, mroClass, srcType); - } + srcSymbol = srcMemberInfo.symbol; - let srcMemberType: Type; - if (isInstantiableClass(srcMemberInfo.classType)) { - const symbolType = evaluator.getEffectiveTypeOfSymbol(srcMemberInfo.symbol); + if ( + destSymbol.isClassVar() && + !srcMemberInfo.symbol.isClassVar() && + !srcMemberInfo.symbol.isClassMember() + ) { + diag?.addMessage(Localizer.DiagnosticAddendum.protocolMemberClassVar().format({ name })); + typesAreConsistent = false; + } - // If this is a function, infer its return type prior to specializing it. - if (isFunction(symbolType)) { - evaluator.inferReturnTypeIfNecessary(symbolType); + // Partially specialize the type of the symbol based on the MRO class. + // We can skip this if it's the dest class because it is already + // specialized. + if (!ClassType.isSameGenericClass(mroClass, destType)) { + destMemberType = partiallySpecializeType(destMemberType, mroClass, srcType); } - srcMemberType = partiallySpecializeType(symbolType, srcMemberInfo.classType, noLiteralSrcType); - } else { - srcMemberType = UnknownType.create(); - } + if (isInstantiableClass(srcMemberInfo.classType)) { + const symbolType = evaluator.getEffectiveTypeOfSymbol(srcMemberInfo.symbol); - if (isFunction(srcMemberType) || isOverloadedFunction(srcMemberType)) { - if (isMemberFromMetaclass) { - const boundSrcFunction = evaluator.bindFunctionToClassOrObject( - ClassType.cloneAsInstance(srcType), - srcMemberType, - /* memberClass */ undefined, - /* errorNode */ undefined, - recursionCount, - /* treatConstructorAsClassMember */ false, - srcType - ); - if (boundSrcFunction) { - srcMemberType = removeParamSpecVariadicsFromSignature(boundSrcFunction); + // If this is a function, infer its return type prior to specializing it. + if (isFunction(symbolType)) { + evaluator.inferReturnTypeIfNecessary(symbolType); } - if (isFunction(destMemberType) || isOverloadedFunction(destMemberType)) { - const boundDeclaredType = evaluator.bindFunctionToClassOrObject( - ClassType.cloneAsInstance(srcType), - destMemberType, - /* memberClass */ undefined, - /* errorNode */ undefined, - recursionCount, - /* treatConstructorAsClassMember */ false, - srcType + srcMemberType = partiallySpecializeType(symbolType, srcMemberInfo.classType, noLiteralSrcType); + } else { + srcMemberType = UnknownType.create(); + } + + // If the source is a method, bind it. + if (isFunction(srcMemberType) || isOverloadedFunction(srcMemberType)) { + if (isMemberFromMetaclass || isInstantiableClass(srcMemberInfo.classType)) { + const boundSrcFunction = evaluator.bindFunctionToClassOrObject( + treatSourceAsInstantiable && !isMemberFromMetaclass + ? srcType + : ClassType.cloneAsInstance(srcType), + srcMemberType, + isMemberFromMetaclass ? undefined : (srcMemberInfo.classType as ClassType), + /* treatConstructorAsClassMember */ undefined, + isMemberFromMetaclass ? srcType : undefined, + diag?.createAddendum(), + recursionCount ); - if (boundDeclaredType) { - destMemberType = removeParamSpecVariadicsFromSignature(boundDeclaredType); + + if (boundSrcFunction) { + srcMemberType = removeParamSpecVariadicsFromSignature(boundSrcFunction); + } else { + typesAreConsistent = false; + return; } } - } else if (isInstantiableClass(srcMemberInfo.classType)) { - // Replace any "Self" TypeVar within the dest with the source type. - destMemberType = applySolvedTypeVars(destMemberType, selfTypeVarContext); + } - const boundSrcFunction = evaluator.bindFunctionToClassOrObject( - treatSourceAsInstantiable ? srcType : ClassType.cloneAsInstance(srcType), - srcMemberType, - srcMemberInfo.classType, - /* errorNode */ undefined, - recursionCount - ); - if (boundSrcFunction) { - srcMemberType = removeParamSpecVariadicsFromSignature(boundSrcFunction); - } + // Frozen dataclasses and named tuples should be treated as read-only. + if (ClassType.isFrozenDataClass(srcType) || ClassType.isReadOnlyInstanceVariables(srcType)) { + isSrcReadOnly = true; + } + } else { + srcSymbol = srcType.fields.get(name); - if (isFunction(destMemberType) || isOverloadedFunction(destMemberType)) { - const boundDeclaredType = evaluator.bindFunctionToClassOrObject( + if (!srcSymbol) { + diag?.addMessage(Localizer.DiagnosticAddendum.protocolMemberMissing().format({ name })); + typesAreConsistent = false; + return; + } + + srcMemberType = evaluator.getEffectiveTypeOfSymbol(srcSymbol); + } + + // Replace any "Self" TypeVar within the dest with the source type. + destMemberType = applySolvedTypeVars(destMemberType, selfTypeVarContext); + + // If the dest is a method, bind it. + if (isFunction(destMemberType) || isOverloadedFunction(destMemberType)) { + let boundDeclaredType: FunctionType | OverloadedFunctionType | undefined; + + if (isClass(srcType)) { + assert(srcMemberInfo); + + if (isMemberFromMetaclass || isInstantiableClass(srcMemberInfo.classType)) { + boundDeclaredType = evaluator.bindFunctionToClassOrObject( ClassType.cloneAsInstance(srcType), destMemberType, - srcMemberInfo.classType, - /* errorNode */ undefined, + isMemberFromMetaclass ? undefined : (srcMemberInfo.classType as ClassType), + /* treatConstructorAsClassMember */ undefined, + isMemberFromMetaclass ? srcType : undefined, + diag, recursionCount ); - if (boundDeclaredType) { - destMemberType = removeParamSpecVariadicsFromSignature(boundDeclaredType); - } } + } else { + boundDeclaredType = evaluator.bindFunctionToClassOrObject( + ClassType.cloneAsInstance(destType), + destMemberType, + destType, + /* treatConstructorAsClassMember */ undefined, + /* firstParamType */ undefined, + diag, + recursionCount + ); + } + + if (boundDeclaredType) { + destMemberType = removeParamSpecVariadicsFromSignature(boundDeclaredType); + } else { + typesAreConsistent = false; + return; } - } else { - // Replace any "Self" TypeVar within the dest with the source type. - destMemberType = applySolvedTypeVars(destMemberType, selfTypeVarContext); } const subDiag = diag?.createAddendum(); @@ -420,6 +467,7 @@ function assignClassToProtocolInternal( destMemberType, /* inferTypeIfNeeded */ true ); + if ( !getterType || !evaluator.assignType( @@ -437,17 +485,37 @@ function assignClassToProtocolInternal( } typesAreConsistent = false; } + + if (isSrcReadOnly) { + // The source attribute is read-only. Make sure the setter + // is not defined in the dest property. + if ( + lookUpClassMember(destMemberType, '__set__', ClassMemberLookupFlags.SkipInstanceVariables) + ) { + if (subDiag) { + subDiag.addMessage( + Localizer.DiagnosticAddendum.memberIsWritableInProtocol().format({ name }) + ); + } + typesAreConsistent = false; + } + } } } else { // Class and instance variables that are mutable need to enforce invariance. - const primaryDecl = symbol.getDeclarations()[0]; + const primaryDecl = destSymbol.getDeclarations()[0]; const isInvariant = primaryDecl?.type === DeclarationType.Variable && !primaryDecl.isFinal; + + // Temporarily add the TypeVar scope ID for this method to handle method-scoped TypeVars. + const protocolTypeVarContextClone = protocolTypeVarContext.clone(); + protocolTypeVarContextClone.addSolveForScope(getTypeVarScopeId(destMemberType)); + if ( !evaluator.assignType( destMemberType, srcMemberType, subDiag?.createAddendum(), - protocolTypeVarContext, + protocolTypeVarContextClone, /* srcTypeVarContext */ undefined, isInvariant ? assignTypeFlags | AssignTypeFlags.EnforceInvariance : assignTypeFlags, recursionCount @@ -460,13 +528,15 @@ function assignClassToProtocolInternal( subDiag.addMessage(Localizer.DiagnosticAddendum.memberTypeMismatch().format({ name })); } typesAreConsistent = false; + } else { + protocolTypeVarContext.copyFromClone(protocolTypeVarContextClone); } } - const isDestFinal = symbol + const isDestFinal = destSymbol .getTypedDeclarations() .some((decl) => decl.type === DeclarationType.Variable && !!decl.isFinal); - const isSrcFinal = srcMemberInfo.symbol + const isSrcFinal = srcSymbol .getTypedDeclarations() .some((decl) => decl.type === DeclarationType.Variable && !!decl.isFinal); @@ -483,20 +553,25 @@ function assignClassToProtocolInternal( typesAreConsistent = false; } - const destPrimaryDecl = getLastTypedDeclaredForSymbol(symbol); - const srcPrimaryDecl = getLastTypedDeclaredForSymbol(srcMemberInfo.symbol); + const destPrimaryDecl = getLastTypedDeclaredForSymbol(destSymbol); + const srcPrimaryDecl = getLastTypedDeclaredForSymbol(srcSymbol); if ( destPrimaryDecl?.type === DeclarationType.Variable && srcPrimaryDecl?.type === DeclarationType.Variable ) { - const isDestConst = !!destPrimaryDecl.isConstant; - const isSrcConst = - (isClass(srcMemberInfo.classType) && - ClassType.isReadOnlyInstanceVariables(srcMemberInfo.classType)) || - !!srcPrimaryDecl.isConstant; + const isDestReadOnly = !!destPrimaryDecl.isConstant; + let isSrcReadOnly = !!srcPrimaryDecl.isConstant; + if (srcMemberInfo && isClass(srcMemberInfo.classType)) { + if ( + ClassType.isReadOnlyInstanceVariables(srcMemberInfo.classType) || + ClassType.isFrozenDataClass(srcMemberInfo.classType) + ) { + isSrcReadOnly = true; + } + } - if (!isDestConst && isSrcConst) { + if (!isDestReadOnly && isSrcReadOnly) { if (subDiag) { subDiag.addMessage(Localizer.DiagnosticAddendum.memberIsWritableInProtocol().format({ name })); } @@ -550,120 +625,6 @@ function assignClassToProtocolInternal( return typesAreConsistent; } -export function assignModuleToProtocol( - evaluator: TypeEvaluator, - destType: ClassType, - srcType: ModuleType, - diag: DiagnosticAddendum | undefined, - destTypeVarContext: TypeVarContext | undefined, - flags: AssignTypeFlags, - recursionCount: number -): boolean { - if (recursionCount > maxTypeRecursionCount) { - return true; - } - recursionCount++; - - let typesAreConsistent = true; - const checkedSymbolSet = new Set(); - const protocolTypeVarContext = createProtocolTypeVarContext(evaluator, destType, destTypeVarContext); - - destType.details.mro.forEach((mroClass) => { - if (!isInstantiableClass(mroClass) || !ClassType.isProtocolClass(mroClass)) { - return; - } - - mroClass.details.fields.forEach((symbol, name) => { - if (!symbol.isClassMember() || symbol.isIgnoredForProtocolMatch() || checkedSymbolSet.has(name)) { - return; - } - - // Note that we've already checked this symbol. It doesn't need to - // be checked again even if it is declared by a subclass. - checkedSymbolSet.add(name); - - const memberSymbol = srcType.fields.get(name); - - if (!memberSymbol) { - diag?.addMessage(Localizer.DiagnosticAddendum.protocolMemberMissing().format({ name })); - typesAreConsistent = false; - return; - } - - let destMemberType = evaluator.getDeclaredTypeOfSymbol(symbol)?.type; - if (!destMemberType) { - return; - } - - destMemberType = partiallySpecializeType(destMemberType, destType); - - const srcMemberType = evaluator.getEffectiveTypeOfSymbol(memberSymbol); - - if (isFunction(srcMemberType) || isOverloadedFunction(srcMemberType)) { - if (isFunction(destMemberType) || isOverloadedFunction(destMemberType)) { - const boundDeclaredType = evaluator.bindFunctionToClassOrObject( - ClassType.cloneAsInstance(destType), - destMemberType, - destType, - /* errorNode */ undefined, - recursionCount - ); - if (boundDeclaredType) { - destMemberType = boundDeclaredType; - } - } - } - - const subDiag = diag?.createAddendum(); - - if ( - !evaluator.assignType( - destMemberType, - srcMemberType, - subDiag?.createAddendum(), - protocolTypeVarContext, - /* srcTypeVarContext */ undefined, - AssignTypeFlags.Default, - recursionCount - ) - ) { - if (subDiag) { - subDiag.addMessage(Localizer.DiagnosticAddendum.memberTypeMismatch().format({ name })); - } - typesAreConsistent = false; - } - }); - }); - - // If the dest protocol has type parameters, make sure the source type arguments match. - if (typesAreConsistent && destType.details.typeParameters.length > 0 && destType.typeArguments) { - // Create a specialized version of the protocol defined by the dest and - // make sure the resulting type args can be assigned. - const genericProtocolType = ClassType.cloneForSpecialization( - destType, - undefined, - /* isTypeArgumentExplicit */ false - ); - const specializedProtocolType = applySolvedTypeVars(genericProtocolType, protocolTypeVarContext) as ClassType; - - if ( - !evaluator.assignTypeArguments( - destType, - specializedProtocolType, - diag, - destTypeVarContext, - /* srcTypeVarContext */ undefined, - flags, - recursionCount - ) - ) { - typesAreConsistent = false; - } - } - - return typesAreConsistent; -} - // Given a (possibly-specialized) destType and an optional typeVarContext, creates // a new typeVarContext that combines the constraints from both the destType and // the destTypeVarContext. @@ -674,43 +635,31 @@ function createProtocolTypeVarContext( ): TypeVarContext { const protocolTypeVarContext = new TypeVarContext(getTypeVarScopeId(destType)); - let specializedDestType = destType; - if (destTypeVarContext) { - specializedDestType = applySolvedTypeVars(destType, destTypeVarContext, { - useNarrowBoundOnly: true, - }) as ClassType; - } - destType.details.typeParameters.forEach((typeParam, index) => { - if (specializedDestType.typeArguments && index < specializedDestType.typeArguments.length) { - const typeArg = specializedDestType.typeArguments[index]; - - if (!requiresSpecialization(typeArg)) { - // If the caller hasn't provided a destTypeVarContext, assume that - // the destType represents an "expected type" and populate the - // typeVarContext accordingly. For example, if the destType is - // MyProto[Literal[0]], we want to constrain the type argument to be - // no wider than Literal[0] if the type param is not contravariant. - assignTypeToTypeVar( - evaluator, - typeParam, - typeArg, - /* diag */ undefined, - protocolTypeVarContext, - destTypeVarContext ? AssignTypeFlags.Default : AssignTypeFlags.PopulatingExpectedType - ); + const entry = destTypeVarContext?.getPrimarySignature().getTypeVar(typeParam); + + if (entry) { + protocolTypeVarContext.setTypeVarType( + typeParam, + entry.narrowBound, + entry.narrowBoundNoLiterals, + entry.wideBound + ); + } else if (destType.typeArguments && index < destType.typeArguments.length) { + let typeArg = destType.typeArguments[index]; + let flags = AssignTypeFlags.PopulatingExpectedType; + let hasUnsolvedTypeVars = requiresSpecialization(typeArg); + + // If the type argument has unsolved TypeVars, see if they have + // solved values in the destTypeVarContext. + if (hasUnsolvedTypeVars && destTypeVarContext) { + typeArg = applySolvedTypeVars(typeArg, destTypeVarContext, { useNarrowBoundOnly: true }); + flags = AssignTypeFlags.Default; + hasUnsolvedTypeVars = requiresSpecialization(typeArg); } - } - if (destTypeVarContext) { - const entry = destTypeVarContext.getPrimarySignature().getTypeVar(typeParam); - if (entry) { - protocolTypeVarContext.setTypeVarType( - typeParam, - entry.narrowBound, - entry.narrowBoundNoLiterals, - entry.wideBound - ); + if (!hasUnsolvedTypeVars) { + assignTypeToTypeVar(evaluator, typeParam, typeArg, /* diag */ undefined, protocolTypeVarContext, flags); } } }); diff --git a/packages/pyright-internal/src/analyzer/scopeUtils.ts b/packages/pyright-internal/src/analyzer/scopeUtils.ts index d7d489be9..5a60b42f3 100644 --- a/packages/pyright-internal/src/analyzer/scopeUtils.ts +++ b/packages/pyright-internal/src/analyzer/scopeUtils.ts @@ -39,7 +39,8 @@ export function getScopeHierarchy(node: ParseNode, stopScope?: Scope): Scope[] | let curNode: ParseNode | undefined = node; while (curNode) { - const curScope = getScopeForNode(curNode); + const scopeNode = getEvaluationScopeNode(curNode); + const curScope = getScope(scopeNode); if (!curScope) { return undefined; @@ -53,7 +54,7 @@ export function getScopeHierarchy(node: ParseNode, stopScope?: Scope): Scope[] | return scopeHierarchy; } - curNode = curNode.parent; + curNode = scopeNode.parent; } return stopScope ? undefined : scopeHierarchy; diff --git a/packages/pyright-internal/src/analyzer/service.ts b/packages/pyright-internal/src/analyzer/service.ts index dabd5ed92..8db5c5cbf 100644 --- a/packages/pyright-internal/src/analyzer/service.ts +++ b/packages/pyright-internal/src/analyzer/service.ts @@ -19,7 +19,7 @@ import { ConfigOptions, matchFileSpecs } from '../common/configOptions'; import { ConsoleInterface, LogLevel, StandardConsole, log } from '../common/console'; import { Diagnostic } from '../common/diagnostic'; import { FileEditAction } from '../common/editAction'; -import { EditableProgram, Extensions, ProgramMutator, ProgramView } from '../common/extensibility'; +import { EditableProgram, ProgramView } from '../common/extensibility'; import { FileSystem } from '../common/fileSystem'; import { FileWatcher, FileWatcherEventType, ignoredWatchEventFunction } from '../common/fileWatcher'; import { Host, HostFactory, NoAccessHost } from '../common/host'; @@ -57,7 +57,6 @@ import { BackgroundAnalysisProgramFactory, InvalidatedReason, } from './backgroundAnalysisProgram'; -import { CacheManager } from './cacheManager'; import { ImportResolver, ImportResolverFactory, @@ -88,7 +87,6 @@ export interface AnalyzerServiceOptions { backgroundAnalysisProgramFactory?: BackgroundAnalysisProgramFactory; cancellationProvider?: CancellationProvider; libraryReanalysisTimeProvider?: () => number; - cacheManager?: CacheManager; serviceId?: string; skipScanningUserFiles?: boolean; fileSystem?: FileSystem; @@ -102,10 +100,12 @@ export function getNextServiceId(name: string) { } export class AnalyzerService { - private _instanceName: string; - private _executionRootPath: string; - private _options: AnalyzerServiceOptions; + private readonly _instanceName: string; + private readonly _options: AnalyzerServiceOptions; + private readonly _backgroundAnalysisProgram: BackgroundAnalysisProgram; + private readonly _serviceProvider: ServiceProvider; + private _executionRootPath: string; private _typeStubTargetPath: string | undefined; private _typeStubTargetIsSingleFile = false; private _sourceFileWatcher: FileWatcher | undefined; @@ -120,11 +120,10 @@ export class AnalyzerService { private _analyzeTimer: any; private _requireTrackedFileUpdate = true; private _lastUserInteractionTime = Date.now(); - private _backgroundAnalysisProgram: BackgroundAnalysisProgram; private _backgroundAnalysisCancellationSource: AbstractCancellationTokenSource | undefined; + private _disposed = false; private _pendingLibraryChanges: RefreshOptions = { changesOnly: true }; - private _serviceProvider = new ServiceProvider(); constructor(instanceName: string, serviceProvider: ServiceProvider, options: AnalyzerServiceOptions) { this._instanceName = instanceName; @@ -135,10 +134,8 @@ export class AnalyzerService { this._options.serviceId = this._options.serviceId ?? getNextServiceId(instanceName); this._options.console = options.console || new StandardConsole(); - // Add the services from the passed in service provider to the local service provider. - [...serviceProvider.items].forEach((item) => { - this._serviceProvider.add(item[0], item[1]); - }); + // Create local copy of the given service provider. + this._serviceProvider = serviceProvider.clone(); // Override the console and the file system if they were explicitly provided. if (this._options.console) { @@ -167,8 +164,7 @@ export class AnalyzerService { this._options.configOptions, importResolver, this._options.backgroundAnalysis, - this._options.maxAnalysisTime, - this._options.cacheManager + this._options.maxAnalysisTime ) : new BackgroundAnalysisProgram( this._options.serviceId, @@ -177,20 +173,8 @@ export class AnalyzerService { importResolver, this._options.backgroundAnalysis, this._options.maxAnalysisTime, - /* disableChecker */ undefined, - this._options.cacheManager + /* disableChecker */ undefined ); - - // Create the extensions tied to this program. - - // Make a wrapper around the program for mutation situations. It - // will forward the requests to the background thread too. - const mutator: ProgramMutator = { - addInterimFile: this.addInterimFile.bind(this), - updateOpenFileContents: this.updateOpenFileContents.bind(this), - setFileOpened: this.setFileOpened.bind(this), - }; - Extensions.createProgramExtensions(this._program, mutator); } get fs() { @@ -275,7 +259,6 @@ export class AnalyzerService { // Make sure we dispose program, otherwise, entire program // will leak. this._backgroundAnalysisProgram.dispose(); - Extensions.destroyProgramExtensions(this._program.id); } this._disposed = true; @@ -389,7 +372,7 @@ export class AnalyzerService { } getParseResult(path: string) { - return this._program.getBoundSourceFile(path)?.getParseResults(); + return this._program.getParseResults(path); } getSourceFile(path: string) { @@ -427,6 +410,10 @@ export class AnalyzerService { this._program.printDependencies(this._executionRootPath, verbose); } + analyzeFile(filePath: string, token: CancellationToken): Promise { + return this._backgroundAnalysisProgram.analyzeFile(filePath, token); + } + getDiagnosticsForRange(filePath: string, range: Range, token: CancellationToken): Promise { return this._backgroundAnalysisProgram.getDiagnosticsForRange(filePath, range, token); } @@ -617,9 +604,11 @@ export class AnalyzerService { ); (configOptions.pythonPath = commandLineOptions.pythonPath), this.fs; } + if (commandLineOptions.pythonEnvironmentName) { this._console.info( - `Setting pythonPath for service "${this._instanceName}": ` + `"${commandLineOptions.pythonPath}"` + `Setting environmentName for service "${this._instanceName}": ` + + `"${commandLineOptions.pythonEnvironmentName}"` ); configOptions.pythonEnvironmentName = commandLineOptions.pythonEnvironmentName; } @@ -636,19 +625,19 @@ export class AnalyzerService { if (commandLineOptions.fileSpecs.length > 0) { commandLineOptions.fileSpecs.forEach((fileSpec) => { - configOptions.include.push(getFileSpec(this.fs, projectRoot, fileSpec)); + configOptions.include.push(getFileSpec(this.serviceProvider, projectRoot, fileSpec)); }); } if (commandLineOptions.excludeFileSpecs.length > 0) { commandLineOptions.excludeFileSpecs.forEach((fileSpec) => { - configOptions.exclude.push(getFileSpec(this.fs, projectRoot, fileSpec)); + configOptions.exclude.push(getFileSpec(this.serviceProvider, projectRoot, fileSpec)); }); } if (commandLineOptions.ignoreFileSpecs.length > 0) { commandLineOptions.ignoreFileSpecs.forEach((fileSpec) => { - configOptions.ignore.push(getFileSpec(this.fs, projectRoot, fileSpec)); + configOptions.ignore.push(getFileSpec(this.serviceProvider, projectRoot, fileSpec)); }); } @@ -657,13 +646,15 @@ export class AnalyzerService { // If no config file was found and there are no explicit include // paths specified, assume the caller wants to include all source // files under the execution root path. - configOptions.include.push(getFileSpec(this.fs, commandLineOptions.executionRoot, '.')); + configOptions.include.push(getFileSpec(this.serviceProvider, commandLineOptions.executionRoot, '.')); } if (commandLineOptions.excludeFileSpecs.length === 0) { // Add a few common excludes to avoid long scan times. defaultExcludes.forEach((exclude) => { - configOptions.exclude.push(getFileSpec(this.fs, commandLineOptions.executionRoot, exclude)); + configOptions.exclude.push( + getFileSpec(this.serviceProvider, commandLineOptions.executionRoot, exclude) + ); }); } } @@ -684,11 +675,9 @@ export class AnalyzerService { configOptions.initializeFromJson( configJsonObj, this._typeCheckingMode, - this._console, - this.fs, + this.serviceProvider, host, - commandLineOptions.diagnosticSeverityOverrides, - commandLineOptions.fileSpecs.length > 0 + commandLineOptions.diagnosticSeverityOverrides ); const configFileDir = getDirectoryPath(this._configFilePath!); @@ -697,14 +686,14 @@ export class AnalyzerService { // the project should be included. if (configOptions.include.length === 0) { this._console.info(`No include entries specified; assuming ${configFileDir}`); - configOptions.include.push(getFileSpec(this.fs, configFileDir, '.')); + configOptions.include.push(getFileSpec(this.serviceProvider, configFileDir, '.')); } // If there was no explicit set of excludes, add a few common ones to avoid long scan times. if (configOptions.exclude.length === 0) { defaultExcludes.forEach((exclude) => { this._console.info(`Auto-excluding ${exclude}`); - configOptions.exclude.push(getFileSpec(this.fs, configFileDir, exclude)); + configOptions.exclude.push(getFileSpec(this.serviceProvider, configFileDir, exclude)); }); if (configOptions.autoExcludeVenv === undefined) { @@ -768,7 +757,9 @@ export class AnalyzerService { this._console.info(`Excluding typeshed stdlib stubs according to VERSIONS file:`); excludeList.forEach((exclude) => { this._console.info(` ${exclude}`); - configOptions.exclude.push(getFileSpec(this.fs, commandLineOptions.executionRoot, exclude)); + configOptions.exclude.push( + getFileSpec(this.serviceProvider, commandLineOptions.executionRoot, exclude) + ); }); } @@ -1163,7 +1154,9 @@ export class AnalyzerService { if (envMarkers.some((f) => this.fs.existsSync(combinePaths(absolutePath, ...f)))) { // Save auto exclude paths in the configOptions once we found them. if (!FileSpec.isInPath(absolutePath, exclude)) { - exclude.push(getFileSpec(this.fs, this._configOptions.projectRoot, `${absolutePath}/**`)); + exclude.push( + getFileSpec(this.serviceProvider, this._configOptions.projectRoot, `${absolutePath}/**`) + ); } this._console.info(`Auto-excluding ${absolutePath}`); @@ -1479,7 +1472,8 @@ export class AnalyzerService { // find the innermost matching search path let matchingSearchPath; - const ignoreCase = !isFileSystemCaseSensitive(this.fs); + const tempFile = this.serviceProvider.tryGet(ServiceKeys.tempFile); + const ignoreCase = !isFileSystemCaseSensitive(this.fs, tempFile); for (const libSearchPath of libSearchPaths) { if ( containsPath(libSearchPath, path, ignoreCase) && diff --git a/packages/pyright-internal/src/analyzer/sourceFile.ts b/packages/pyright-internal/src/analyzer/sourceFile.ts index ee5388269..32d006bcd 100644 --- a/packages/pyright-internal/src/analyzer/sourceFile.ts +++ b/packages/pyright-internal/src/analyzer/sourceFile.ts @@ -17,18 +17,19 @@ import { assert } from '../common/debug'; import { Diagnostic, DiagnosticCategory, TaskListToken, convertLevelToCategory } from '../common/diagnostic'; import { DiagnosticRule } from '../common/diagnosticRules'; import { DiagnosticSink, TextRangeDiagnosticSink } from '../common/diagnosticSink'; -import { Extensions } from '../common/extensibility'; +import { ServiceProvider } from '../common/extensibility'; import { FileSystem } from '../common/fileSystem'; import { LogTracker, getPathForLogging } from '../common/logTracker'; import { getFileName, normalizeSlashes, stripFileExtension } from '../common/pathUtils'; import { convertOffsetsToRange, convertTextRangeToRange } from '../common/positionUtils'; +import { ServiceKeys } from '../common/serviceProviderExtensions'; import * as StringUtils from '../common/stringUtils'; import { Range, TextRange, getEmptyRange } from '../common/textRange'; import { TextRangeCollection } from '../common/textRangeCollection'; import { Duration, timingStats } from '../common/timing'; import { Localizer } from '../localization/localize'; import { ModuleNode } from '../parser/parseNodes'; -import { IParser, ModuleImport, ParseOptions, Parser, ParseResults } from '../parser/parser'; +import { IParser, ModuleImport, ParseOptions, ParseResults, Parser } from '../parser/parser'; import { IgnoreComment } from '../parser/tokenizer'; import { Token } from '../parser/tokenizerTypes'; import { AnalyzerFileInfo, ImportLookup } from './analyzerFileInfo'; @@ -57,7 +58,6 @@ const _maxSourceFileSize = 50 * 1024 * 1024; interface ResolveImportResult { imports: ImportResult[]; builtinsImportResult?: ImportResult | undefined; - ipythonDisplayImportResult?: ImportResult | undefined; } // Indicates whether IPython syntax is supported and if so, what @@ -134,8 +134,6 @@ class WriteableData { // Information about implicit and explicit imports from this file. imports: ImportResult[] | undefined; builtinsImport: ImportResult | undefined; - ipythonDisplayImport: ImportResult | undefined; - // True if the file appears to have been deleted. isFileDeleted = false; } @@ -176,6 +174,10 @@ export class SourceFile { // special-case handling. private readonly _isTypingExtensionsStubFile: boolean; + // True if the file is the "_typeshed.pyi" file, which needs special- + // case handling. + private readonly _isTypeshedStubFile: boolean; + // True if the file one of the other built-in stub files // that require special-case handling: "collections.pyi", // "dataclasses.pyi", "abc.pyi", "asyncio/coroutines.pyi". @@ -199,7 +201,7 @@ export class SourceFile { readonly fileSystem: FileSystem; constructor( - fs: FileSystem, + readonly serviceProvider: ServiceProvider, filePath: string, moduleName: string, isThirdPartyImport: boolean, @@ -210,7 +212,7 @@ export class SourceFile { realFilePath?: string, ipythonMode?: IPythonMode ) { - this.fileSystem = fs; + this.fileSystem = serviceProvider.get(ServiceKeys.fs); this._console = console || new StandardConsole(); this._editMode = editMode; this._filePath = filePath; @@ -224,6 +226,8 @@ export class SourceFile { this._isStubFile && (this._filePath.endsWith(normalizeSlashes('stdlib/typing.pyi')) || fileName === 'typing_extensions.pyi'); this._isTypingExtensionsStubFile = this._isStubFile && fileName === 'typing_extensions.pyi'; + this._isTypeshedStubFile = + this._isStubFile && this._filePath.endsWith(normalizeSlashes('stdlib/_typeshed/__init__.pyi')); this._isBuiltInStubFile = false; if (this._isStubFile) { @@ -304,10 +308,6 @@ export class SourceFile { return this._writableData.builtinsImport; } - getIPythonDisplayImport(): ImportResult | undefined { - return this._writableData.ipythonDisplayImport; - } - getModuleSymbolTable(): SymbolTable | undefined { return this._writableData.moduleSymbolTable; } @@ -322,6 +322,7 @@ export class SourceFile { const text = this._writableData.clientDocumentContents!; this._writableData = this._preEditData; this._preEditData = undefined; + return text; } @@ -347,13 +348,18 @@ export class SourceFile { // that of the previous contents. try { // Read the file's contents. - const fileContents = this.fileSystem.readFileSync(this._filePath, 'utf8'); + if (this.fileSystem.existsSync(this._filePath)) { + const fileContents = this.fileSystem.readFileSync(this._filePath, 'utf8'); - if (fileContents.length !== this._writableData.lastFileContentLength) { - return true; - } + if (fileContents.length !== this._writableData.lastFileContentLength) { + return true; + } - if (StringUtils.hashString(fileContents) !== this._writableData.lastFileContentHash) { + if (StringUtils.hashString(fileContents) !== this._writableData.lastFileContentHash) { + return true; + } + } else { + // No longer exists, so yes it has changed. return true; } } catch (error) { @@ -367,6 +373,8 @@ export class SourceFile { // in cases where memory is low. When info is needed, the file // will be re-parsed and rebound. dropParseAndBindInfo(): void { + this._fireFileDirtyEvent(); + this._writableData.parseResults = undefined; this._writableData.moduleSymbolTable = undefined; this._writableData.isBindingNeeded = true; @@ -379,8 +387,7 @@ export class SourceFile { this._writableData.isBindingNeeded = true; this._writableData.moduleSymbolTable = undefined; - const filePath = this.getFilePath(); - Extensions.getProgramExtensions(filePath).forEach((e) => (e.fileDirty ? e.fileDirty(filePath) : null)); + this._fireFileDirtyEvent(); } markReanalysisRequired(forceRebinding: boolean): void { @@ -471,7 +478,7 @@ export class SourceFile { } prepareForClose() { - // Nothing to do currently. + this._fireFileDirtyEvent(); } isFileDeleted() { @@ -605,7 +612,6 @@ export class SourceFile { this._writableData.imports = importResult.imports; this._writableData.builtinsImport = importResult.builtinsImportResult; - this._writableData.ipythonDisplayImport = importResult.ipythonDisplayImportResult; this._writableData.parseDiagnostics = diagSink.fetchAndClear(); }); @@ -669,7 +675,6 @@ export class SourceFile { }; this._writableData.imports = undefined; this._writableData.builtinsImport = undefined; - this._writableData.ipythonDisplayImport = undefined; const diagSink = this.createDiagnosticSink(); diagSink.addError( @@ -911,7 +916,11 @@ export class SourceFile { // Filter the diagnostics based on "pyright: ignore" lines. if (this._writableData.pyrightIgnoreLines.size > 0) { diagList = diagList.filter((d) => { - if (d.category !== DiagnosticCategory.UnreachableCode && d.category !== DiagnosticCategory.Deprecated) { + if ( + d.category !== DiagnosticCategory.UnusedCode && + d.category !== DiagnosticCategory.UnreachableCode && + d.category !== DiagnosticCategory.Deprecated + ) { for (let line = d.range.start.line; line <= d.range.end.line; line++) { const pyrightIgnoreComment = this._writableData.pyrightIgnoreLines.get(line); if (pyrightIgnoreComment) { @@ -1250,6 +1259,7 @@ export class SourceFile { isStubFile: this._isStubFile, isTypingStubFile: this._isTypingStubFile, isTypingExtensionsStubFile: this._isTypingExtensionsStubFile, + isTypeshedStubFile: this._isTypeshedStubFile, isBuiltInStubFile: this._isBuiltInStubFile, isInPyTypedPackage: this._isThirdPartyPyTypedPresent, ipythonMode: this._ipythonMode, @@ -1308,10 +1318,6 @@ export class SourceFile { builtinsImportResult = resolveAndAddIfNotSelf(['builtins']); } - const ipythonDisplayImportResult = this._ipythonMode - ? resolveAndAddIfNotSelf(['IPython', 'display']) - : undefined; - for (const moduleImport of moduleImports) { const importResult = importResolver.resolveImport(this._filePath, execEnv, { leadingDots: moduleImport.leadingDots, @@ -1343,7 +1349,6 @@ export class SourceFile { return { imports, builtinsImportResult, - ipythonDisplayImportResult, }; } @@ -1374,4 +1379,17 @@ export class SourceFile { const parser = this.createParser(); return parser.parseSourceFile(fileContents, parseOptions, diagSink); } + + private _fireFileDirtyEvent() { + this.serviceProvider.tryGet(ServiceKeys.stateMutationListeners)?.forEach((l) => { + try { + l.fileDirty?.(this._filePath); + } catch (ex: any) { + const console = this.serviceProvider.tryGet(ServiceKeys.console); + if (console) { + console.error(`State mutation listener exceptoin: ${ex.message}`); + } + } + }); + } } diff --git a/packages/pyright-internal/src/analyzer/sourceFileInfo.ts b/packages/pyright-internal/src/analyzer/sourceFileInfo.ts index 7c2e6db61..a275e7d49 100644 --- a/packages/pyright-internal/src/analyzer/sourceFileInfo.ts +++ b/packages/pyright-internal/src/analyzer/sourceFileInfo.ts @@ -26,6 +26,7 @@ export class SourceFileInfo { args: OptionalArguments = {} ) { this.isCreatedInEditMode = this._editModeTracker.isEditMode; + this._writableData = this._createWriteableData(args); this._cachePreEditState(); @@ -39,10 +40,6 @@ export class SourceFileInfo { return this._writableData.builtinsImport; } - get ipythonDisplayImport() { - return this._writableData.ipythonDisplayImport; - } - // Information about the chained source file // Chained source file is not supposed to exist on file system but // must exist in the program's source file list. Module level @@ -92,17 +89,12 @@ export class SourceFileInfo { this._writableData.builtinsImport = value; } - set ipythonDisplayImport(value: SourceFileInfo | undefined) { - this._cachePreEditState(); - this._writableData.ipythonDisplayImport = value; - } - set chainedSourceFile(value: SourceFileInfo | undefined) { this._cachePreEditState(); this._writableData.chainedSourceFile = value; } - set effectiveFutureImports(value: Set | undefined) { + set effectiveFutureImports(value: ReadonlySet | undefined) { this._cachePreEditState(); this._writableData.effectiveFutureImports = value; } @@ -126,6 +118,9 @@ export class SourceFileInfo { if (this._preEditData) { this._writableData = this._preEditData; this._preEditData = undefined; + + // Some states have changed. Force some of info to be re-calcuated. + this.sourceFile.dropParseAndBindInfo(); } return this.sourceFile.restore(); @@ -150,7 +145,6 @@ export class SourceFileInfo { chainedSourceFile: args.chainedSourceFile, diagnosticsVersion: args.diagnosticsVersion, effectiveFutureImports: args.effectiveFutureImports, - ipythonDisplayImport: args.ipythonDisplayImport, imports: [], importedBy: [], shadows: [], @@ -166,7 +160,6 @@ export class SourceFileInfo { chainedSourceFile: data.chainedSourceFile, diagnosticsVersion: data.diagnosticsVersion, effectiveFutureImports: data.effectiveFutureImports, - ipythonDisplayImport: data.ipythonDisplayImport, imports: data.imports.slice(), importedBy: data.importedBy.slice(), shadows: data.shadows.slice(), @@ -185,9 +178,8 @@ interface OptionalArguments { isOpenByClient?: boolean; diagnosticsVersion?: number | undefined; builtinsImport?: SourceFileInfo | undefined; - ipythonDisplayImport?: SourceFileInfo | undefined; chainedSourceFile?: SourceFileInfo | undefined; - effectiveFutureImports?: Set; + effectiveFutureImports?: ReadonlySet; } interface WriteableData { @@ -196,7 +188,6 @@ interface WriteableData { diagnosticsVersion?: number | undefined; builtinsImport?: SourceFileInfo | undefined; - ipythonDisplayImport?: SourceFileInfo | undefined; // Information about the chained source file // Chained source file is not supposed to exist on file system but @@ -205,7 +196,7 @@ interface WriteableData { // current file's scope. chainedSourceFile?: SourceFileInfo | undefined; - effectiveFutureImports?: Set; + effectiveFutureImports?: ReadonlySet; // Information about why the file is included in the program // and its relation to other source files in the program. diff --git a/packages/pyright-internal/src/analyzer/sourceMapper.ts b/packages/pyright-internal/src/analyzer/sourceMapper.ts index a26fbc42e..091d694cb 100644 --- a/packages/pyright-internal/src/analyzer/sourceMapper.ts +++ b/packages/pyright-internal/src/analyzer/sourceMapper.ts @@ -90,9 +90,14 @@ export class SourceMapper { return []; } - findClassDeclarationsByType(originatedPath: string, type: ClassType): ClassDeclaration[] { + findDeclarationsByType(originatedPath: string, type: ClassType, useTypeAlias = false): Declaration[] { const result: ClassOrFunctionOrVariableDeclaration[] = []; - this._addClassTypeDeclarations(originatedPath, type, result, new Set()); + this._addClassTypeDeclarations(originatedPath, type, result, new Set(), useTypeAlias); + return result; + } + + findClassDeclarationsByType(originatedPath: string, type: ClassType): ClassDeclaration[] { + const result = this.findDeclarationsByType(originatedPath, type); return result.filter((r) => isClassDeclaration(r)).map((r) => r as ClassDeclaration); } @@ -587,14 +592,14 @@ export class SourceMapper { originated: string, type: ClassType, result: ClassOrFunctionOrVariableDeclaration[], - recursiveDeclCache: Set + recursiveDeclCache: Set, + useTypeAlias = false ) { const filePath = type.details.filePath; const sourceFiles = this._getSourceFiles(filePath, /* stubToShadow */ undefined, originated); - const fullClassName = type.details.fullName.substring( - type.details.moduleName.length + 1 /* +1 for trailing dot */ - ); + const fullName = useTypeAlias && type.typeAliasInfo ? type.typeAliasInfo.fullName : type.details.fullName; + const fullClassName = fullName.substring(type.details.moduleName.length + 1 /* +1 for trailing dot */); for (const sourceFile of sourceFiles) { appendArray(result, this._findClassDeclarationsByName(sourceFile, fullClassName, recursiveDeclCache)); diff --git a/packages/pyright-internal/src/analyzer/staticExpressions.ts b/packages/pyright-internal/src/analyzer/staticExpressions.ts index 9e75b18b9..349ef05c4 100644 --- a/packages/pyright-internal/src/analyzer/staticExpressions.ts +++ b/packages/pyright-internal/src/analyzer/staticExpressions.ts @@ -90,7 +90,8 @@ export function evaluateStaticBoolExpression( node.leftExpression.items[0].valueExpression.nodeType === ParseNodeType.Number && !node.leftExpression.items[0].valueExpression.isImaginary && node.leftExpression.items[0].valueExpression.value === 0 && - node.rightExpression.nodeType === ParseNodeType.Number + node.rightExpression.nodeType === ParseNodeType.Number && + node.rightExpression.isInteger ) { // Handle the special case of "sys.version_info[0] >= X" return _evaluateNumericBinaryOperation( diff --git a/packages/pyright-internal/src/analyzer/tracePrinter.ts b/packages/pyright-internal/src/analyzer/tracePrinter.ts index 71e75d1aa..979e8f344 100644 --- a/packages/pyright-internal/src/analyzer/tracePrinter.ts +++ b/packages/pyright-internal/src/analyzer/tracePrinter.ts @@ -10,7 +10,7 @@ import { isNumber, isString } from '../common/core'; import { assertNever } from '../common/debug'; import { ensureTrailingDirectorySeparator, stripFileExtension } from '../common/pathUtils'; import { convertOffsetToPosition } from '../common/positionUtils'; -import { isExpressionNode, ParseNode, ParseNodeType } from '../parser/parseNodes'; +import { ParseNode, ParseNodeType, isExpressionNode } from '../parser/parseNodes'; import { AbsoluteModuleDescriptor } from './analyzerFileInfo'; import * as AnalyzerNodeInfo from './analyzerNodeInfo'; import { Declaration, DeclarationType } from './declaration'; @@ -79,9 +79,6 @@ export function createTracePrinter(roots: string[]): TracePrinter { case TypeCategory.Never: return `Never ${wrap(type.typeAliasInfo?.fullName)}`; - case TypeCategory.None: - return `None ${wrap(type.typeAliasInfo?.fullName)}`; - case TypeCategory.OverloadedFunction: return `OverloadedFunction [${type.overloads.map((o) => wrap(printType(o), '"')).join(',')}]`; diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index 768ce3ed0..b72032f6f 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -116,7 +116,7 @@ import { addOverloadsToFunctionType, applyClassDecorator, applyFunctionDecorator, - getFunctionFlagsFromDecorators, + getFunctionInfoFromDecorators, } from './decorators'; import { createEnumType, @@ -170,6 +170,7 @@ import { ExpectedTypeResult, FunctionArgument, FunctionTypeResult, + MemberAccessDeprecationInfo, MemberAccessFlags, PrintTypeOptions, ResolveAliasOptions, @@ -191,7 +192,6 @@ import { addTypeVarsToListIfUnique, applySolvedTypeVars, applySourceContextTypeVars, - applySourceContextTypeVarsToSignature, areTypesSame, buildTypeVarContextFromSpecializedClass, combineSameSizedTuples, @@ -227,6 +227,8 @@ import { isLiteralType, isMaybeDescriptorInstance, isMetaclassInstance, + isNoneInstance, + isNoneTypeClass, isOptionalType, isPartlyUnknown, isProperty, @@ -244,10 +246,12 @@ import { mapSubtypes, partiallySpecializeType, preserveUnknown, + removeNoneFromUnion, removeParamSpecVariadicsFromFunction, removeParamSpecVariadicsFromSignature, requiresSpecialization, requiresTypeArguments, + selfSpecializeClass, setTypeArgumentsRecursive, sortTypes, specializeClassType, @@ -280,7 +284,6 @@ import { LiteralValue, ModuleType, NeverType, - NoneType, OverloadedFunctionType, SignatureWithOffsets, TupleTypeArgument, @@ -308,8 +311,6 @@ import { isInstantiableClass, isModule, isNever, - isNoneInstance, - isNoneTypeClass, isOverloadedFunction, isParamSpec, isPositionOnlySeparator, @@ -324,7 +325,6 @@ import { isVariadicTypeVar, maxTypeRecursionCount, removeFromUnion, - removeNoneFromUnion, removeUnbound, } from './types'; @@ -361,6 +361,7 @@ interface MatchArgsToParamsResult { export interface MemberAccessTypeResult { type: Type; isAsymmetricAccessor: boolean; + memberAccessDeprecationInfo?: MemberAccessDeprecationInfo; } interface ScopedTypeVarResult { @@ -563,9 +564,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let deferredClassCompletions: DeferredClassCompletion[] = []; let cancellationToken: CancellationToken | undefined; let isBasicTypesInitialized = false; + let noneClassType: Type | undefined; let noneType: Type | undefined; let objectType: Type | undefined; let typeClassType: Type | undefined; + let awaitableProtocolType: Type | undefined; let functionObj: Type | undefined; let tupleClassType: Type | undefined; let boolClassType: Type | undefined; @@ -803,6 +806,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // context, logging any errors in the process. This may require the // type of surrounding statements to be evaluated. function getType(node: ExpressionNode): Type | undefined { + initializedBasicTypes(node); + let type = evaluateTypeForSubnode(node, () => { evaluateTypesForExpressionInContext(node); })?.type; @@ -829,6 +834,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } + if (type) { + type = transformPossibleRecursiveTypeAlias(type); + } + return type; } @@ -904,7 +913,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // that occurs when resolving tuple below. getTypingType(node, 'Collection'); - noneType = getTypeshedType(node, 'NoneType') || AnyType.create(); + noneClassType = getTypeshedType(node, 'NoneType') ?? UnknownType.create(); + noneType = isInstantiableClass(noneClassType) + ? ClassType.cloneAsInstance(noneClassType) + : UnknownType.create(); + tupleClassType = getBuiltInType(node, 'tuple'); boolClassType = getBuiltInType(node, 'bool'); intClassType = getBuiltInType(node, 'int'); @@ -912,6 +925,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions dictClassType = getBuiltInType(node, 'dict'); typedDictClassType = getTypingType(node, 'TypedDict'); typedDictPrivateClassType = getTypingType(node, '_TypedDict'); + awaitableProtocolType = getTypingType(node, 'Awaitable'); mappingType = getTypeshedType(node, 'SupportsKeysAndGetItem'); if (!mappingType) { @@ -1185,6 +1199,21 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions validateTypeIsInstantiable(typeResult, flags, node); } + // Should we disable type promotions for bytes? + if ( + isInstantiableClass(typeResult.type) && + typeResult.type.includePromotions && + !typeResult.type.includeSubclasses && + ClassType.isBuiltIn(typeResult.type, 'bytes') + ) { + if (AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.disableBytesTypePromotions) { + typeResult = { + ...typeResult, + type: ClassType.cloneRemoveTypePromotions(typeResult.type), + }; + } + } + writeTypeCache(node, typeResult, flags, inferenceContext, /* allowSpeculativeCaching */ true); // If there was an expected type, make sure that the result type is compatible. @@ -1537,6 +1566,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions type: getBuiltInObject(node, isBytes ? 'bytes' : 'str'), isIncomplete, }; + + if (isClass(typeResult.type) && typeResult.type.includePromotions) { + typeResult.type = ClassType.cloneRemoveTypePromotions(typeResult.type); + } } } else { typeResult = { @@ -1698,8 +1731,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions case TypeCategory.Unbound: case TypeCategory.Unknown: case TypeCategory.Any: - case TypeCategory.Never: - case TypeCategory.None: { + case TypeCategory.Never: { return true; } @@ -1768,7 +1800,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return true; } - return false; + // If the class is not final, it's possible that it could be overridden + // such that it is falsy. To be fully correct, we'd need to do the + // following: + // return !ClassType.isFinal(type); + // However, pragmatically if the class is not an `object`, it's typically + // OK to assume that it will not be overridden in this manner. + return ClassType.isBuiltIn(type, 'object'); } } } @@ -1796,8 +1834,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return findSubtype(type, (subtype) => canBeTruthy(subtype, recursionCount)) !== undefined; } - case TypeCategory.Unbound: - case TypeCategory.None: { + case TypeCategory.Unbound: { return false; } @@ -1806,6 +1843,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return true; } + if (isNoneInstance(type)) { + return false; + } + // Check for Tuple[()] (an empty tuple). if (isTupleClass(type)) { if (type.tupleTypeArguments && type.tupleTypeArguments!.length === 0) { @@ -1914,6 +1955,24 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (ClassType.isBuiltIn(concreteSubtype, 'bool')) { return ClassType.cloneWithLiteral(concreteSubtype, /* value */ true); } + + // If the object is a "None" instance, we can eliminate it. + if (isNoneInstance(concreteSubtype)) { + return undefined; + } + + // If this is an instance of a class that cannot be subclassed, + // we cannot say definitively that it's not falsy because a subclass + // could override `__bool__`. For this reason, the code should not + // remove any classes that are not final. + // if (!ClassType.isFinal(concreteSubtype)) { + // return subtype; + // } + // However, we're going to pragmatically assume that any classes + // other than `object` will not be overridden in this manner. + if (ClassType.isBuiltIn(concreteSubtype, 'object')) { + return subtype; + } } // If it's possible for the type to be truthy, include it. @@ -1925,8 +1984,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions }); } - // Gets a member type from an object and if it's a function binds - // it to the object. If bindToClass is undefined, the binding is done + // Gets a member type from an object or class. If it's a function, binds + // it to the object or class. If selfType is undefined, the binding is done // using the objectType parameter. Callers can specify these separately // to handle the case where we're fetching the object member from a // metaclass but binding to the class. @@ -1936,164 +1995,127 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions memberName: string, usage: EvaluatorUsage = { method: 'get' }, diag: DiagnosticAddendum | undefined = undefined, - memberAccessFlags = MemberAccessFlags.None, - bindToType?: ClassType | TypeVarType + flags = MemberAccessFlags.None, + selfType?: ClassType | TypeVarType ): TypeResult | undefined { - let memberInfo = getTypeOfClassMemberName( - errorNode, - ClassType.cloneAsInstantiable(objectType), - /* isAccessedThroughObject */ true, - memberName, - usage, - diag, - memberAccessFlags | MemberAccessFlags.DisallowClassVarWrites, - bindToType - ); - - if (!memberInfo) { - const metaclass = objectType.details.effectiveMetaclass; - if ( - metaclass && - isInstantiableClass(metaclass) && - !ClassType.isBuiltIn(metaclass, 'type') && - !ClassType.isSameGenericClass(metaclass, objectType) - ) { - memberInfo = getTypeOfClassMemberName( - errorNode, - metaclass, - /* isAccessedThroughObject */ false, - memberName, - usage, - /* diag */ undefined, - memberAccessFlags | MemberAccessFlags.AccessInstanceMembersOnly, - ClassType.cloneAsInstantiable(objectType) - ); - } - } - - if (memberInfo) { - return { - type: memberInfo.type, - classType: memberInfo.classType, - isIncomplete: !!memberInfo.isTypeIncomplete, - isAsymmetricAccessor: memberInfo.isAsymmetricAccessor, - }; - } - - return undefined; - } - - // Gets a member type from a class and if it's a function binds - // it to the class. - function getTypeOfClassMember( - errorNode: ExpressionNode, - classType: ClassType, - memberName: string, - usage: EvaluatorUsage = { method: 'get' }, - diag: DiagnosticAddendum | undefined = undefined, - memberAccessFlags = MemberAccessFlags.None, - bindToType?: ClassType | TypeVarType - ): TypeResult | undefined { - let memberInfo: ClassMemberLookup | undefined; - const classDiag = diag ? new DiagnosticAddendum() : undefined; - const metaclassDiag = diag ? new DiagnosticAddendum() : undefined; - let considerMetaclassOnly = (memberAccessFlags & MemberAccessFlags.ConsiderMetaclassOnly) !== 0; - - if (ClassType.isPartiallyEvaluated(classType)) { + if (ClassType.isPartiallyEvaluated(objectType)) { addDiagnostic( AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, - Localizer.Diagnostic.classDefinitionCycle().format({ name: classType.details.name }), + Localizer.Diagnostic.classDefinitionCycle().format({ name: objectType.details.name }), errorNode ); return { type: UnknownType.create() }; } - const metaclass = classType.details.effectiveMetaclass; + // Determine the class that was used to instantiate the objectType. + // If the objectType is a class itself, then the class used to instantiate + // it is the metaclass. + const objectTypeIsInstantiable = TypeBase.isInstantiable(objectType); + const metaclass = objectType.details.effectiveMetaclass; + + let memberInfo: ClassMemberLookup | undefined; + + // If the object type is an instantiable (i.e. it derives from "type") and + // we've been asked not to consider instance members, don't look in the class. + // Consider only the metaclass class variables in this case. + let skipObjectTypeLookup = objectTypeIsInstantiable && (flags & MemberAccessFlags.AccessClassMembersOnly) !== 0; // Look up the attribute in the metaclass first. If the member is a descriptor - // (an object with a __get__ method) and the access is a 'get', the Python runtime - // uses this metaclass descriptor to satisfy the lookup. Skip this costly lookup - // in the common case where the metaclass is 'type' since we know that `type` doesn't - // have any attributes that are descriptors. + // (an object with a __get__ and __set__ method) and the access is a 'get', + // the Python runtime uses this descriptor to satisfy the lookup. Skip this + // costly lookup in the common case where the metaclass is 'type' since we know + // that `type` doesn't have any attributes that are descriptors. if ( usage.method === 'get' && + objectTypeIsInstantiable && metaclass && isInstantiableClass(metaclass) && !ClassType.isBuiltIn(metaclass, 'type') && - !ClassType.isSameGenericClass(metaclass, classType) + !ClassType.isSameGenericClass(metaclass, objectType) ) { - const metaclassMemberInfo = getTypeOfClassMemberName( + const descMemberInfo = getTypeOfClassMemberName( errorNode, metaclass, - /* isAccessedThroughObject */ false, memberName, usage, - metaclassDiag, - memberAccessFlags, - classType + /* diag */ undefined, + flags | MemberAccessFlags.SkipAttributeAccessOverride, + objectType ); - if (metaclassMemberInfo && isDescriptorInstance(metaclassMemberInfo.type)) { - considerMetaclassOnly = true; + if (descMemberInfo) { + const isProperty = + isClassInstance(descMemberInfo.type) && ClassType.isPropertyClass(descMemberInfo.type); + if (isDescriptorInstance(descMemberInfo.type, /* requireSetter */ true) || isProperty) { + skipObjectTypeLookup = true; + } } } - // Look up the attribute in the class object. - if (!memberInfo && !considerMetaclassOnly) { + if (!skipObjectTypeLookup) { + let effectiveFlags = flags; + + if (objectTypeIsInstantiable) { + effectiveFlags |= + MemberAccessFlags.AccessClassMembersOnly | MemberAccessFlags.SkipAttributeAccessOverride; + } else { + effectiveFlags |= MemberAccessFlags.DisallowClassVarWrites; + } + + // See if the member is present in the object itself. memberInfo = getTypeOfClassMemberName( errorNode, - classType, - /* isAccessedThroughObject */ false, + objectType, memberName, usage, - classDiag, - memberAccessFlags | MemberAccessFlags.AccessClassMembersOnly, - bindToType + diag, + effectiveFlags, + selfType ); } - const isMemberPresentOnClass = memberInfo?.classType !== undefined; + // If it wasn't found on the object, see if it's part of the metaclass. + if (!memberInfo && metaclass && isInstantiableClass(metaclass)) { + let effectiveFlags = flags; - // If it wasn't found on the class, see if it's part of the metaclass. - if (!memberInfo) { - const metaclass = classType.details.effectiveMetaclass; - if (metaclass && isInstantiableClass(metaclass) && !ClassType.isSameGenericClass(metaclass, classType)) { - memberInfo = getTypeOfClassMemberName( - errorNode, - metaclass, - /* isAccessedThroughObject */ true, - memberName, - usage, - metaclassDiag, - memberAccessFlags, - classType - ); + // Class members cannot be accessed on a class's metaclass through + // an instance of a class. Limit access to metaclass instance members + // in this case. + if (!objectTypeIsInstantiable) { + effectiveFlags |= + MemberAccessFlags.AccessInstanceMembersOnly | MemberAccessFlags.SkipAttributeAccessOverride; + effectiveFlags &= ~MemberAccessFlags.AccessClassMembersOnly; } + + memberInfo = getTypeOfClassMemberName( + errorNode, + ClassType.cloneAsInstance(metaclass), + memberName, + usage, + /* diag */ undefined, + effectiveFlags, + objectTypeIsInstantiable ? objectType : ClassType.cloneAsInstantiable(objectType) + ); } - if (memberInfo) { + if (memberInfo && !memberInfo.isSetTypeError) { return { type: memberInfo.type, + classType: memberInfo.classType, isIncomplete: !!memberInfo.isTypeIncomplete, isAsymmetricAccessor: memberInfo.isAsymmetricAccessor, + memberAccessDeprecationInfo: memberInfo.memberAccessDeprecationInfo, }; } - // Determine whether to use the class or metaclass diagnostic addendum. - const subDiag = isMemberPresentOnClass ? classDiag : metaclassDiag; - if (diag && subDiag) { - diag.addAddendum(subDiag); - } - return undefined; } function getBoundMethod( classType: ClassType, memberName: string, - recursionCount = 0, - treatConstructorAsClassMember = false + recursionCount = 0 ): FunctionType | OverloadedFunctionType | undefined { const memberInfo = lookUpClassMember(classType, memberName, ClassMemberLookupFlags.SkipInstanceVariables); @@ -2104,9 +2126,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions ClassType.cloneAsInstance(classType), unboundMethodType, /* memberClass */ undefined, - /* errorNode */ undefined, - recursionCount, - treatConstructorAsClassMember + /* treatConstructorAsClassMember */ true, + /* selfType */ undefined, + /* diag */ undefined, + recursionCount ); if (boundMethod) { @@ -2237,12 +2260,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // the `object` class or accepts only default parameters(* args, ** kwargs), // see if we can find a better signature from the `__new__` method. if (!methodType || isObjectInit || isDefaultParams) { - const constructorType = getBoundMethod( - subtype, - '__new__', - /* recursionCount */ undefined, - /* treatConstructorAsClassMember */ true - ); + const constructorType = getBoundMethod(subtype, '__new__'); if (constructorType) { // Is this the __new__ method provided by the object class? @@ -2392,12 +2410,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (setItemMember) { const setItemType = getTypeOfMember(setItemMember); if (isFunction(setItemType)) { - const boundFunction = bindFunctionToClassOrObject( + const boundFunction = bindFunctionToClassOrObjectWithErrors( baseType, setItemType, isInstantiableClass(setItemMember.classType) ? setItemMember.classType : undefined, expression, - /* recursionCount */ undefined, /* treatConstructorAsClassMember */ false ); if (boundFunction && isFunction(boundFunction)) { @@ -2453,10 +2470,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (isFunction(declaredType) || isOverloadedFunction(declaredType)) { if (bindFunction) { - declaredType = bindFunctionToClassOrObject( + declaredType = bindFunctionToClassOrObjectWithErrors( classOrObjectBase, declaredType, - /* memberClass */ undefined, + /* memberAccessClass */ undefined, expression ); } @@ -2475,6 +2492,16 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // (object that provides an __await__ that returns a generator object). // If errorNode is undefined, no errors are reported. function getTypeOfAwaitable(type: Type, errorNode?: ExpressionNode): Type { + if ( + !awaitableProtocolType || + !isInstantiableClass(awaitableProtocolType) || + awaitableProtocolType.details.typeParameters.length !== 1 + ) { + return UnknownType.create(); + } + + const awaitableProtocolObj = ClassType.cloneAsInstance(awaitableProtocolType); + return mapSubtypes(type, (subtype) => { subtype = makeTopLevelTypeVarsConcrete(subtype); @@ -2482,22 +2509,20 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return subtype; } + const diag = errorNode ? new DiagnosticAddendum() : undefined; + if (isClassInstance(subtype)) { - const awaitReturnType = getSpecializedReturnType(subtype, '__await__', [], errorNode); - if (awaitReturnType) { - if (isAnyOrUnknown(awaitReturnType)) { - return awaitReturnType; - } + const typeVarContext = new TypeVarContext(getTypeVarScopeId(awaitableProtocolObj)); - if (isClassInstance(awaitReturnType)) { - const iterReturnType = getSpecializedReturnType(awaitReturnType, '__iter__', [], errorNode); + if (assignType(awaitableProtocolObj, subtype, diag, typeVarContext)) { + const specializedType = applySolvedTypeVars(awaitableProtocolObj, typeVarContext); - if (iterReturnType) { - const generatorReturnType = getReturnTypeFromGenerator(awaitReturnType); - if (generatorReturnType) { - return generatorReturnType; - } - } + if ( + isClass(specializedType) && + specializedType.typeArguments && + specializedType.typeArguments.length > 0 + ) { + return specializedType.typeArguments[0]; } } } @@ -2507,7 +2532,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions addDiagnostic( fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, - Localizer.Diagnostic.typeNotAwaitable().format({ type: printType(subtype) }), + Localizer.Diagnostic.typeNotAwaitable().format({ type: printType(subtype) }) + diag?.getString(), errorNode ); } @@ -2521,7 +2546,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions function getTypeOfIterator( typeResult: TypeResult, isAsync: boolean, - errorNode: ExpressionNode | undefined + errorNode: ExpressionNode, + emitNotIterableError = true ): TypeResult | undefined { const iterMethodName = isAsync ? '__aiter__' : '__iter__'; const nextMethodName = isAsync ? '__anext__' : '__next__'; @@ -2531,7 +2557,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions type = makeTopLevelTypeVarsConcrete(type); if (isOptionalType(type)) { - if (errorNode && !typeResult.isIncomplete) { + if (!typeResult.isIncomplete && emitNotIterableError) { addDiagnostic( AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalIterable, DiagnosticRule.reportOptionalIterable, @@ -2551,49 +2577,31 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const diag = new DiagnosticAddendum(); if (isClass(subtype)) { - let iterReturnType: Type | undefined; - - if (TypeBase.isInstance(subtype)) { - // Handle an empty tuple specially. - if ( - isTupleClass(subtype) && - subtype.tupleTypeArguments && - subtype.tupleTypeArguments.length === 0 - ) { - return NeverType.createNever(); - } - - iterReturnType = getSpecializedReturnType(subtype, iterMethodName, [], errorNode); - } else if ( - TypeBase.isInstantiable(subtype) && - subtype.details.effectiveMetaclass && - isInstantiableClass(subtype.details.effectiveMetaclass) + // Handle an empty tuple specially. + if ( + TypeBase.isInstance(subtype) && + isTupleClass(subtype) && + subtype.tupleTypeArguments && + subtype.tupleTypeArguments.length === 0 ) { - iterReturnType = getSpecializedReturnType( - ClassType.cloneAsInstance(subtype.details.effectiveMetaclass), - iterMethodName, - [], - errorNode, - subtype - ); + return NeverType.createNever(); } + const iterReturnType = getTypeOfMagicMethodCall(subtype, iterMethodName, [], errorNode); + if (!iterReturnType) { // There was no __iter__. See if we can fall back to // the __getitem__ method instead. if (!isAsync && isClassInstance(subtype)) { - const getItemReturnType = getSpecializedReturnType( + const getItemReturnType = getTypeOfMagicMethodCall( subtype, '__getitem__', [ { - argumentCategory: ArgumentCategory.Simple, - typeResult: { - type: - intClassType && isInstantiableClass(intClassType) - ? ClassType.cloneAsInstance(intClassType) - : UnknownType.create(), - }, + type: + intClassType && isInstantiableClass(intClassType) + ? ClassType.cloneAsInstance(intClassType) + : UnknownType.create(), }, ], errorNode @@ -2616,7 +2624,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } if (isClassInstance(subtype)) { - let nextReturnType = getSpecializedReturnType(subtype, nextMethodName, [], errorNode); + let nextReturnType = getTypeOfMagicMethodCall(subtype, nextMethodName, [], errorNode); if (!nextReturnType) { iterReturnTypeDiag.addMessage( @@ -2662,7 +2670,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } - if (errorNode && !typeResult.isIncomplete) { + if (!typeResult.isIncomplete && emitNotIterableError) { addDiagnostic( AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, @@ -2682,7 +2690,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions function getTypeOfIterable( typeResult: TypeResult, isAsync: boolean, - errorNode: ExpressionNode | undefined + errorNode: ExpressionNode, + emitNotIterableError = true ): TypeResult | undefined { const iterMethodName = isAsync ? '__aiter__' : '__iter__'; let isValidIterable = true; @@ -2690,7 +2699,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let type = makeTopLevelTypeVarsConcrete(typeResult.type); if (isOptionalType(type)) { - if (errorNode && !typeResult.isIncomplete) { + if (!typeResult.isIncomplete && emitNotIterableError) { addDiagnostic( AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalIterable, DiagnosticRule.reportOptionalIterable, @@ -2707,30 +2716,14 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } if (isClass(subtype)) { - let iterReturnType: Type | undefined; - - if (TypeBase.isInstance(subtype)) { - iterReturnType = getSpecializedReturnType(subtype, iterMethodName, [], errorNode); - } else if ( - TypeBase.isInstantiable(subtype) && - subtype.details.effectiveMetaclass && - isInstantiableClass(subtype.details.effectiveMetaclass) - ) { - iterReturnType = getSpecializedReturnType( - ClassType.cloneAsInstance(subtype.details.effectiveMetaclass), - iterMethodName, - [], - errorNode, - subtype - ); - } + const iterReturnType = getTypeOfMagicMethodCall(subtype, iterMethodName, [], errorNode); if (iterReturnType) { return makeTopLevelTypeVarsConcrete(iterReturnType); } } - if (errorNode) { + if (emitNotIterableError) { addDiagnostic( AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, @@ -2796,16 +2789,22 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return isTypeHashable; } - function getTypedDictClassType() { - return typedDictPrivateClassType; + function getTypedDictClassType(): ClassType | undefined { + return typedDictPrivateClassType && isInstantiableClass(typedDictPrivateClassType) + ? typedDictPrivateClassType + : undefined; + } + + function getTupleClassType(): ClassType | undefined { + return tupleClassType && isInstantiableClass(tupleClassType) ? tupleClassType : undefined; } - function getTupleClassType() { - return tupleClassType; + function getObjectType(): Type { + return objectType ?? UnknownType.create(); } - function getObjectType() { - return objectType; + function getNoneType(): Type { + return noneType ?? UnknownType.create(); } function getTypingType(node: ParseNode, symbolName: string): Type | undefined { @@ -2913,10 +2912,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions flowNode, /* reference */ undefined, /* targetSymbolId */ undefined, - /* typeAtStart */ UnboundType.create(), - { - skipNoReturnCallAnalysis: true, - } + /* typeAtStart */ UnboundType.create() ); return codeFlowResult.type !== undefined && !isNever(codeFlowResult.type); @@ -3282,8 +3278,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions setAsymmetricDescriptorAssignment(target); } - writeTypeCache(target.memberName, { type, isIncomplete: isTypeIncomplete }, EvaluatorFlags.None); - writeTypeCache(target, { type, isIncomplete: isTypeIncomplete }, EvaluatorFlags.None); + const resultToCache: TypeResult = { + type, + isIncomplete: isTypeIncomplete, + memberAccessDeprecationInfo: setTypeResult.memberAccessDeprecationInfo, + }; + writeTypeCache(target.memberName, resultToCache, EvaluatorFlags.None); + writeTypeCache(target, resultToCache, EvaluatorFlags.None); } function assignTypeToMemberVariable( @@ -3546,6 +3547,42 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions writeTypeCache(target, { type, isIncomplete: isTypeIncomplete }, EvaluatorFlags.None); } + // If the type includes promotion types, expand these to their constituent types. + function expandPromotionTypes(node: ParseNode, type: Type, excludeBytes = false): Type { + return mapSubtypes(type, (subtype) => { + if (!isClass(subtype) || !subtype.includePromotions) { + return subtype; + } + + if (excludeBytes && ClassType.isBuiltIn(subtype, 'bytes')) { + return subtype; + } + + const typesToCombine: Type[] = [ClassType.cloneRemoveTypePromotions(subtype)]; + + const promotionTypeNames = typePromotions.get(subtype.details.fullName); + if (promotionTypeNames) { + for (const promotionTypeName of promotionTypeNames) { + const nameSplit = promotionTypeName.split('.'); + let promotionSubtype = getBuiltInType(node, nameSplit[nameSplit.length - 1]); + + if (promotionSubtype && isInstantiableClass(promotionSubtype)) { + promotionSubtype = ClassType.cloneRemoveTypePromotions(promotionSubtype); + + if (isClassInstance(subtype)) { + promotionSubtype = ClassType.cloneAsInstance(promotionSubtype); + } + + promotionSubtype = addConditionToType(promotionSubtype, subtype.condition); + typesToCombine.push(promotionSubtype); + } + } + } + + return combineTypes(typesToCombine); + }); + } + // Replaces all of the top-level TypeVars (as opposed to TypeVars // used as type arguments in other types) with their concrete form. // If conditionFilter is specified and the TypeVar is a constrained @@ -3640,22 +3677,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } if (isTypeVar(subtype) && !subtype.details.recursiveTypeAliasName) { - if (subtype.details.boundType) { - const boundType = TypeBase.isInstantiable(subtype) - ? convertToInstantiable(subtype.details.boundType) - : subtype.details.boundType; - - return subtype.details.isSynthesized - ? boundType - : addConditionToType(boundType, [ - { - typeVarName: TypeVarType.getNameWithScope(subtype), - constraintIndex: 0, - isConstrainedTypeVar: false, - }, - ]); - } - // If this is a recursive type alias placeholder // that hasn't yet been resolved, return it as is. if (subtype.details.recursiveTypeAliasName) { @@ -3703,32 +3724,23 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return AnyType.create(); } - // Convert to an "object" or "type" instance depending on whether - // it's instantiable. - if (TypeBase.isInstantiable(subtype)) { - if (typeClassType && isInstantiableClass(typeClassType)) { - return subtype.details.isSynthesized - ? typeClassType - : addConditionToType(ClassType.cloneAsInstance(typeClassType), [ - { - typeVarName: TypeVarType.getNameWithScope(subtype), - constraintIndex: 0, - isConstrainedTypeVar: false, - }, - ]); - } - } else if (objectType) { - return subtype.details.isSynthesized - ? objectType - : addConditionToType(objectType, [ - { - typeVarName: TypeVarType.getNameWithScope(subtype), - constraintIndex: 0, - isConstrainedTypeVar: false, - }, - ]); + // Fall back to a bound of "object" if no bound is provided. + let boundType = subtype.details.boundType ?? objectType ?? UnknownType.create(); + boundType = TypeBase.isInstantiable(subtype) ? convertToInstantiable(boundType) : boundType; + + // Handle Self and type[Self] specially. + if (subtype.details.isSynthesizedSelf && isClass(boundType)) { + return ClassType.cloneIncludeSubclasses(boundType); } + return addConditionToType(boundType, [ + { + typeVarName: TypeVarType.getNameWithScope(subtype), + constraintIndex: 0, + isConstrainedTypeVar: false, + }, + ]); + return AnyType.create(); } @@ -3836,6 +3848,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let typeWasTransformed = false; const filteredTypeArgs = type.typeArguments.map((typeArg, index) => { + if (index > type.details.typeParameters.length) { + return typeArg; + } + const variance = TypeVarType.getVariance(type.details.typeParameters[index]); if (variance !== Variance.Covariant) { return typeArg; @@ -4137,14 +4153,18 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions node.leftExpression, EvaluatorFlags.MemberAccessBaseDefaults ); - const memberType = getTypeOfMemberAccessWithBaseType( + const delAccessResult = getTypeOfMemberAccessWithBaseType( node, baseTypeResult, { method: 'del' }, EvaluatorFlags.None ); - writeTypeCache(node.memberName, { type: memberType.type }, EvaluatorFlags.None); - writeTypeCache(node, { type: memberType.type }, EvaluatorFlags.None); + const resultToCache: TypeResult = { + type: delAccessResult.type, + memberAccessDeprecationInfo: delAccessResult.memberAccessDeprecationInfo, + }; + writeTypeCache(node.memberName, resultToCache, EvaluatorFlags.None); + writeTypeCache(node, resultToCache, EvaluatorFlags.None); break; } @@ -4192,79 +4212,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } - function getReturnTypeFromGenerator(type: Type): Type | undefined { - if (isAnyOrUnknown(type)) { - return type; - } - - if (isClassInstance(type)) { - // Is this a Generator? If so, return the third - // type argument, which is the await response type. - if (ClassType.isBuiltIn(type, 'Generator')) { - const typeArgs = type.typeArguments; - if (typeArgs && typeArgs.length >= 3) { - return typeArgs[2]; - } - } - } - - return undefined; - } - - function getSpecializedReturnType( - objType: ClassType, - memberName: string, - argList: FunctionArgument[], - errorNode: ExpressionNode | undefined, - bindToClass?: ClassType - ) { - const classMember = lookUpObjectMember(objType, memberName, ClassMemberLookupFlags.SkipInstanceVariables); - if (!classMember) { - return undefined; - } - - const memberTypeResult = getTypeOfMemberInternal(classMember, objType); - if (!memberTypeResult) { - return undefined; - } - - const memberType = memberTypeResult.type; - if (isAnyOrUnknown(memberType)) { - return memberType; - } - - if (isFunction(memberType) || isOverloadedFunction(memberType)) { - const methodType = bindFunctionToClassOrObject( - bindToClass || objType, - memberType, - classMember && isInstantiableClass(classMember.classType) ? classMember.classType : undefined, - errorNode, - /* recursionCount */ undefined, - /* treatConstructorAsClassMember */ false, - /* firstParamType */ bindToClass - ); - if (methodType) { - if (isOverloadedFunction(methodType)) { - if (errorNode) { - const bestOverload = getBestOverloadForArguments( - errorNode, - { type: methodType, isIncomplete: memberTypeResult.isIncomplete }, - argList - ); - - if (bestOverload) { - return getFunctionEffectiveReturnType(bestOverload); - } - } - } else { - return getFunctionEffectiveReturnType(methodType); - } - } - } - - return undefined; - } - function getTypeOfName(node: NameNode, flags: EvaluatorFlags): TypeResult { const fileInfo = AnalyzerNodeInfo.getFileInfo(node); const name = node.value; @@ -4474,32 +4421,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } - if ( - isTypeVar(type) && - !type.details.isParamSpec && - !type.isVariadicInUnion && - (flags & EvaluatorFlags.ExpectingInstantiableType) === 0 && - type.details.name === name - ) { - // Handle the special case of a PEP 604 union. These can appear within - // an implied type alias where we are not expecting a type. - const isPep604Union = - node.parent?.nodeType === ParseNodeType.BinaryOperation && - node.parent.operator === OperatorType.BitwiseOr; - - if (!isPep604Union) { - // A TypeVar in contexts where we're not expecting a type is - // simply a TypeVar or TypeVarTuple object. - const typeVarType = type.details.isVariadic - ? getTypingType(node, 'TypeVarTuple') - : getTypingType(node, 'TypeVar'); - if (typeVarType && isInstantiableClass(typeVarType)) { - type = ClassType.cloneAsInstance(typeVarType); - } else { - type = UnknownType.create(); - } - } - } + type = convertTypeVarToRuntimeInstance(node, type, flags); if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) === 0) { reportUseOfTypeCheckOnly(type, node); @@ -4531,6 +4453,42 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return { type, isIncomplete }; } + // If the type is a TypeVar and we're not expecting a type, convert + // a TypeVar or TypeVarTuple into a runtime type. We don't currently + // do this for ParamSpec (although we arguably should) because it's + // problematic for handling P.args and P.kwargs. + function convertTypeVarToRuntimeInstance(node: ExpressionNode, type: Type, flags: EvaluatorFlags) { + if ( + node.nodeType === ParseNodeType.Name && + isTypeVar(type) && + node.value === type.details.name && + !type.isVariadicInUnion && + (flags & EvaluatorFlags.ExpectingInstantiableType) === 0 + ) { + if ((flags & EvaluatorFlags.SkipConvertParamSpecToRuntimeObject) !== 0 && type.details.isParamSpec) { + return type; + } + + // Handle the special case of a PEP 604 union. These can appear within + // an implied type alias where we are not expecting a type. + const isPep604Union = + node.parent?.nodeType === ParseNodeType.BinaryOperation && + node.parent.operator === OperatorType.BitwiseOr; + + if (!isPep604Union) { + // A TypeVar in contexts where we're not expecting a type is + // simply a runtime object. + if (type.details.runtimeClass) { + type = ClassType.cloneAsInstance(type.details.runtimeClass); + } else { + type = UnknownType.create(); + } + } + } + + return type; + } + // Handles the case where a variable or parameter is defined in an outer // scope and captured by an inner scope (either a function or a lambda). function getCodeFlowTypeForCapturedVariable( @@ -4988,16 +4946,25 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } function getTypeOfMemberAccess(node: MemberAccessNode, flags: EvaluatorFlags): TypeResult { - const baseTypeFlags = - EvaluatorFlags.MemberAccessBaseDefaults | - (flags & - (EvaluatorFlags.ExpectingTypeAnnotation | - EvaluatorFlags.VariableTypeAnnotation | - EvaluatorFlags.AllowForwardReferences | - EvaluatorFlags.NotParsedByInterpreter | - EvaluatorFlags.DisallowTypeVarsWithScopeId | - EvaluatorFlags.AssociateTypeVarsWithCurrentScope)); - const baseTypeResult = getTypeOfExpression(node.leftExpression, baseTypeFlags); + // Compute flags specifically for evaluating the left expression. + let leftExprFlags = EvaluatorFlags.MemberAccessBaseDefaults; + leftExprFlags |= + flags & + (EvaluatorFlags.ExpectingTypeAnnotation | + EvaluatorFlags.VariableTypeAnnotation | + EvaluatorFlags.AllowForwardReferences | + EvaluatorFlags.NotParsedByInterpreter | + EvaluatorFlags.DisallowTypeVarsWithScopeId | + EvaluatorFlags.AssociateTypeVarsWithCurrentScope); + + // Handle special casing for ParamSpec "args" and "kwargs" accesses. + if ((flags & EvaluatorFlags.ExpectingInstantiableType) !== 0) { + const memberName = node.memberName.value; + if (memberName === 'args' || memberName === 'kwargs') { + leftExprFlags |= EvaluatorFlags.SkipConvertParamSpecToRuntimeObject; + } + } + const baseTypeResult = getTypeOfExpression(node.leftExpression, leftExprFlags); if (isTypeAliasPlaceholder(baseTypeResult.type)) { return { @@ -5095,10 +5062,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let isAsymmetricAccessor: boolean | undefined; const isRequired = false; const isNotRequired = false; + let memberAccessDeprecationInfo: MemberAccessDeprecationInfo | undefined; // If the base type was incomplete and unbound, don't proceed // because false positive errors will be generated. - if (baseTypeResult.isIncomplete && isUnbound(baseTypeResult.type)) { + if (baseTypeResult.isIncomplete && isUnbound(baseType)) { return { type: UnknownType.create(/* isIncomplete */ true), isIncomplete: true }; } @@ -5110,23 +5078,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } - function getTypeOfNoneBase(subtype: NoneType) { - if (noneType && isInstantiableClass(noneType)) { - if (TypeBase.isInstance(subtype)) { - return getTypeOfObjectMember( - node.memberName, - ClassType.cloneAsInstance(noneType), - memberName, - usage, - diag - ); - } else { - return getTypeOfClassMember(node.memberName, noneType, memberName, usage, diag); - } - } - return undefined; - } - if (isParamSpec(baseType) && baseType.paramSpecAccess) { baseType = makeTopLevelTypeVarsConcrete(baseType); } @@ -5195,7 +5146,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions node, { type: makeTopLevelTypeVarsConcrete(baseType), - bindToType: baseType, + bindToSelfType: TypeBase.isInstantiable(baseType) ? convertToInstance(baseType) : baseType, isIncomplete, }, usage, @@ -5207,59 +5158,32 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } case TypeCategory.Class: { - if (TypeBase.isInstantiable(baseType)) { - const typeResult = getTypeOfClassMember( - node.memberName, - baseType, - memberName, - usage, - diag, - MemberAccessFlags.None, - baseTypeResult.bindToType - ); - - type = typeResult?.type; - if (typeResult?.isIncomplete) { - isIncomplete = true; - } - - if (typeResult?.isAsymmetricAccessor) { - isAsymmetricAccessor = true; - } - } else { - // Handle the special case of 'name' and 'value' members within an enum. - const enumMemberResult = getTypeOfEnumMember( - evaluatorInterface, - node, - baseType, - memberName, - isIncomplete - ); - if (enumMemberResult) { - return enumMemberResult; - } - - const typeResult = getTypeOfObjectMember( + const typeResult = + getTypeOfEnumMember(evaluatorInterface, node, baseType, memberName, isIncomplete) ?? + getTypeOfObjectMember( node.memberName, baseType, memberName, usage, diag, /* memberAccessFlags */ undefined, - baseTypeResult.bindToType + baseTypeResult.bindToSelfType ); - if (typeResult) { - type = addConditionToType(typeResult.type, getTypeCondition(baseType)); - } + if (typeResult) { + type = addConditionToType(typeResult.type, getTypeCondition(baseType)); + } - if (typeResult?.isIncomplete) { - isIncomplete = true; - } + if (typeResult?.isIncomplete) { + isIncomplete = true; + } - if (typeResult?.isAsymmetricAccessor) { - isAsymmetricAccessor = true; - } + if (typeResult?.isAsymmetricAccessor) { + isAsymmetricAccessor = true; + } + + if (typeResult?.memberAccessDeprecationInfo) { + memberAccessDeprecationInfo = typeResult.memberAccessDeprecationInfo; } break; } @@ -5360,44 +5284,55 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions case TypeCategory.Union: { type = mapSubtypes(baseType, (subtype) => { - if (isNoneInstance(subtype)) { - const typeResult = getTypeOfNoneBase(subtype); + if (isUnbound(subtype)) { + // Don't do anything if it's unbound. The error will already + // be reported elsewhere. + return undefined; + } + + if (isNoneInstance(subtype) && noneType && isClassInstance(noneType)) { + const typeResult = getTypeOfObjectMember(node.memberName, noneType, memberName, usage, diag); + if (typeResult) { type = addConditionToType(typeResult.type, getTypeCondition(baseType)); if (typeResult.isIncomplete) { isIncomplete = true; } + return type; - } else { - if (!isIncomplete) { - addDiagnostic( - AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalMemberAccess, - DiagnosticRule.reportOptionalMemberAccess, - Localizer.Diagnostic.noneUnknownMember().format({ name: memberName }), - node.memberName - ); - } - return undefined; } - } else if (isUnbound(subtype)) { - // Don't do anything if it's unbound. The error will already - // be reported elsewhere. - return undefined; - } else { - const typeResult = getTypeOfMemberAccessWithBaseType( - node, - { - type: subtype, - isIncomplete: baseTypeResult.isIncomplete, - }, - usage, - EvaluatorFlags.None - ); - if (typeResult.isIncomplete) { - isIncomplete = true; + + if (!isIncomplete) { + addDiagnostic( + AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalMemberAccess, + DiagnosticRule.reportOptionalMemberAccess, + Localizer.Diagnostic.noneUnknownMember().format({ name: memberName }), + node.memberName + ); } - return typeResult.type; + + return undefined; + } + + const typeResult = getTypeOfMemberAccessWithBaseType( + node, + { + type: subtype, + isIncomplete: baseTypeResult.isIncomplete, + }, + usage, + EvaluatorFlags.None + ); + + if (typeResult.isIncomplete) { + isIncomplete = true; } + + if (typeResult?.memberAccessDeprecationInfo) { + memberAccessDeprecationInfo = typeResult.memberAccessDeprecationInfo; + } + + return typeResult.type; }); break; } @@ -5428,17 +5363,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions break; } - case TypeCategory.None: { - const typeResult = getTypeOfNoneBase(baseType); - if (typeResult) { - type = addConditionToType(typeResult.type, getTypeCondition(baseType)); - if (typeResult.isIncomplete) { - isIncomplete = true; - } - } - break; - } - default: diag.addMessage(Localizer.DiagnosticAddendum.typeUnsupported().format({ type: printType(baseType) })); break; @@ -5521,18 +5445,17 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } - return { type, isIncomplete, isAsymmetricAccessor, isRequired, isNotRequired }; + return { type, isIncomplete, isAsymmetricAccessor, isRequired, isNotRequired, memberAccessDeprecationInfo }; } function getTypeOfClassMemberName( errorNode: ExpressionNode, classType: ClassType, - isAccessedThroughObject: boolean, memberName: string, usage: EvaluatorUsage, diag: DiagnosticAddendum | undefined, flags: MemberAccessFlags, - bindToType?: ClassType | TypeVarType + selfType?: ClassType | TypeVarType ): ClassMemberLookup | undefined { let classLookupFlags = ClassMemberLookupFlags.Default; if (flags & MemberAccessFlags.AccessClassMembersOnly) { @@ -5554,6 +5477,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions classLookupFlags |= ClassMemberLookupFlags.SkipOriginalClass; } + const isAccessedThroughObject = TypeBase.isInstance(classType); + // Always look for a member with a declared type first. let memberInfo = lookUpClassMember( classType, @@ -5598,7 +5523,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // if the class variable is a descriptor object. In this case, we will // clear the flag that causes an error to be generated. if (usage.method === 'set' && memberInfo.symbol.isClassVar() && isAccessedThroughObject) { - const selfClass = bindToType || memberName === '__new__' ? undefined : classType; + const selfClass = selfType ?? memberName === '__new__' ? undefined : classType; const typeResult = getTypeOfMemberInternal(memberInfo, selfClass); if (typeResult) { @@ -5625,9 +5550,9 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // to leave the Self type generic (not specialized). We'll also // skip this for __new__ methods because they are not bound // to the class but rather assume the type of the cls argument. - if (bindToType) { - if (isTypeVar(bindToType) && bindToType.details.isSynthesizedSelf) { - selfClass = bindToType; + if (selfType) { + if (isTypeVar(selfType) && selfType.details.isSynthesizedSelf) { + selfClass = selfType; } else { selfClass = undefined; } @@ -5679,8 +5604,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions type, memberInfo, classType, - bindToType, - isAccessedThroughObject, + selfType, flags, errorNode, memberName, @@ -5692,6 +5616,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return undefined; } type = descriptorResult.type; + let isSetTypeError = false; if (usage.method === 'set' && usage.setType) { // Verify that the assigned type is compatible. @@ -5705,7 +5630,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions }) ); } - return undefined; + isSetTypeError = true; } if ( @@ -5718,7 +5643,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions name: printType(ClassType.cloneAsInstance(memberInfo.classType)), }) ); - return undefined; + isSetTypeError = true; } } @@ -5726,10 +5651,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions symbol: memberInfo.symbol, type, isTypeIncomplete, + isSetTypeError, isClassMember: !memberInfo.isInstanceMember, isClassVar: memberInfo.isClassVar, classType: memberInfo.classType, isAsymmetricAccessor: descriptorResult.isAsymmetricAccessor, + memberAccessDeprecationInfo: descriptorResult?.memberAccessDeprecationInfo, }; } @@ -5740,12 +5667,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions (flags & (MemberAccessFlags.AccessClassMembersOnly | MemberAccessFlags.SkipAttributeAccessOverride)) === 0 ) { - const generalAttrType = applyAttributeAccessOverride(classType, errorNode, usage, memberName); + const generalAttrType = applyAttributeAccessOverride(classType, errorNode, usage, memberName, selfType); if (generalAttrType) { return { symbol: undefined, type: generalAttrType.type, isTypeIncomplete: false, + isSetTypeError: false, isClassMember: false, isClassVar: false, isAsymmetricAccessor: generalAttrType.isAsymmetricAccessor, @@ -5764,9 +5692,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions function applyDescriptorAccessMethod( type: Type, memberInfo: ClassMember | undefined, - baseTypeClass: ClassType, - bindToType: ClassType | TypeVarType | undefined, - isAccessedThroughObject: boolean, + classType: ClassType, + selfType: ClassType | TypeVarType | undefined, flags: MemberAccessFlags, errorNode: ExpressionNode, memberName: string, @@ -5774,8 +5701,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions diag: DiagnosticAddendum | undefined ): MemberAccessTypeResult | undefined { const treatConstructorAsClassMember = (flags & MemberAccessFlags.TreatConstructorAsClassMethod) !== 0; + const isAccessedThroughObject = TypeBase.isInstance(classType); let isTypeValid = true; let isAsymmetricAccessor = false; + let memberAccessDeprecationInfo: MemberAccessDeprecationInfo | undefined; type = mapSubtypes(type, (subtype) => { const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype); @@ -5855,10 +5784,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argumentCategory: ArgumentCategory.Simple, typeResult: { type: ClassType.isClassProperty(lookupClass) - ? baseTypeClass + ? classType : isAccessedThroughObject - ? bindToType ?? ClassType.cloneAsInstance(baseTypeClass) - : NoneType.createInstance(), + ? selfType ?? ClassType.cloneAsInstance(classType) + : getNoneType(), }, }, ]; @@ -5868,7 +5797,9 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argList.push({ argumentCategory: ArgumentCategory.Simple, typeResult: { - type: baseTypeClass, + type: isAccessedThroughObject + ? ClassType.cloneAsInstantiable(classType) + : classType, }, }); } else if (usage.method === 'set') { @@ -5904,7 +5835,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // it directly from the class has an ambiguous meaning. if ( (flags & MemberAccessFlags.AccessClassMembersOnly) !== 0 && - ClassType.isProtocolClass(baseTypeClass) + ClassType.isProtocolClass(classType) ) { diag?.addMessage(Localizer.DiagnosticAddendum.propertyAccessFromProtocolClass()); isTypeValid = false; @@ -5928,20 +5859,15 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // because of the way we model the __get__ logic in the property class. if (ClassType.isPropertyClass(concreteSubtype) && !isAccessedThroughMetaclass) { if (memberInfo && isInstantiableClass(memberInfo.classType)) { - bindToClass = memberInfo.classType; - } - } else { - if (isInstantiableClass(accessMethod.classType)) { - bindToClass = accessMethod.classType; + bindToClass = ClassType.cloneAsInstance(memberInfo.classType); } } - let boundMethodType = bindFunctionToClassOrObject( + let boundMethodType = bindFunctionToClassOrObjectWithErrors( lookupClass, methodType, bindToClass, errorNode, - /* recursionCount */ undefined, /* treatConstructorAsClassMember */ undefined, isAccessedThroughMetaclass ? concreteSubtype : undefined ); @@ -5958,7 +5884,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const specializedBoundType = partiallySpecializeType( boundMethodType, bindToClass, - baseTypeClass + classType ); if (specializedBoundType) { if ( @@ -5978,6 +5904,23 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions /* skipUnknownArgCheck */ true ); + if ( + callResult.overloadsUsedForCall && + callResult.overloadsUsedForCall.length >= 1 + ) { + const overloadUsed = callResult.overloadsUsedForCall[0]; + if (overloadUsed.details.deprecatedMessage) { + memberAccessDeprecationInfo = { + deprecationMessage: overloadUsed.details.deprecatedMessage, + accessType: + lookupClass && ClassType.isPropertyClass(lookupClass) + ? 'property' + : 'descriptor', + accessMethod: usage.method, + }; + } + } + if (callResult.argumentErrors) { if (usage.method === 'set') { if ( @@ -6058,28 +6001,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // If this function is an instance member (e.g. a lambda that was // assigned to an instance variable), don't perform any binding. if (!isAccessedThroughObject || (memberInfo && !memberInfo.isInstanceMember)) { - let effectiveBindToType = bindToType; - - if (bindToType && !isInstantiableMetaclass(baseTypeClass)) { - // If bindToType is an instantiable class or TypeVar but we're targeting - // an instance method (in a non-metaclass), we need to convert - // the bindToType to an instance. - const targetMethod = isFunction(concreteSubtype) - ? concreteSubtype - : concreteSubtype.overloads[0]; - if (FunctionType.isInstanceMethod(targetMethod) && !TypeBase.isInstance(bindToType)) { - effectiveBindToType = convertToInstance(bindToType) as ClassType | TypeVarType; - } - } - - return bindFunctionToClassOrObject( - isAccessedThroughObject ? ClassType.cloneAsInstance(baseTypeClass) : baseTypeClass, + return bindFunctionToClassOrObjectWithErrors( + classType, concreteSubtype, memberInfo && isInstantiableClass(memberInfo.classType) ? memberInfo.classType : undefined, errorNode, - /* recursionCount */ undefined, treatConstructorAsClassMember, - effectiveBindToType + selfType && isClass(selfType) ? ClassType.cloneIncludeSubclasses(selfType) : selfType ); } } @@ -6165,7 +6093,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return undefined; } - return { type, isAsymmetricAccessor }; + return { type, isAsymmetricAccessor, memberAccessDeprecationInfo }; } function isAsymmetricDescriptorClass(classType: ClassType): boolean { @@ -6247,18 +6175,22 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions classType: ClassType, errorNode: ExpressionNode, usage: EvaluatorUsage, - memberName: string + memberName: string, + selfType?: ClassType | TypeVarType ): MemberAccessTypeResult | undefined { const getAttributeAccessMember = (name: string) => { // See if the class has a "__getattribute__" or "__getattr__" method. // If so, arbitrary members are supported. - return getTypeOfClassMember( + return getTypeOfObjectMember( errorNode, classType, name, { method: 'get' }, /* diag */ undefined, - MemberAccessFlags.SkipObjectBaseClass | MemberAccessFlags.SkipAttributeAccessOverride + MemberAccessFlags.AccessClassMembersOnly | + MemberAccessFlags.SkipObjectBaseClass | + MemberAccessFlags.SkipAttributeAccessOverride, + selfType )?.type; }; @@ -6279,11 +6211,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } const argList: FunctionArgument[] = [ - { - // Provide "self" argument. - argumentCategory: ArgumentCategory.Simple, - typeResult: { type: ClassType.cloneAsInstance(classType) }, - }, { // Provide "name" argument. argumentCategory: ArgumentCategory.Simple, @@ -6303,28 +6230,24 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } if (isFunction(accessMemberType) || isOverloadedFunction(accessMemberType)) { - const boundMethodType = bindFunctionToClassOrObject(classType, accessMemberType, classType, errorNode); - - if (boundMethodType && (isFunction(boundMethodType) || isOverloadedFunction(boundMethodType))) { - const typeVarContext = new TypeVarContext(getTypeVarScopeId(boundMethodType)); - const callResult = validateCallArguments( - errorNode, - argList, - { type: boundMethodType }, - typeVarContext, - /* skipUnknownArgCheck */ true - ); - - let isAsymmetricAccessor = false; - if (usage.method === 'set') { - isAsymmetricAccessor = isClassWithAsymmetricAttributeAccessor(classType); - } + const typeVarContext = new TypeVarContext(getTypeVarScopeId(accessMemberType)); + const callResult = validateCallArguments( + errorNode, + argList, + { type: accessMemberType }, + typeVarContext, + /* skipUnknownArgCheck */ true + ); - return { - type: callResult.returnType ?? UnknownType.create(), - isAsymmetricAccessor, - }; + let isAsymmetricAccessor = false; + if (usage.method === 'set') { + isAsymmetricAccessor = isClassWithAsymmetricAttributeAccessor(classType); } + + return { + type: callResult.returnType ?? UnknownType.create(), + isAsymmetricAccessor, + }; } } @@ -6380,7 +6303,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } - const indexTypeResult = getTypeOfIndexWithBaseType(node, baseTypeResult, { method: 'get' }, flags); + const indexTypeResult = getTypeOfIndexWithBaseType( + node, + baseTypeResult, + { method: 'get' }, + flags & ~EvaluatorFlags.DisallowPep695TypeAlias + ); if (isCodeFlowSupportedForReference(node)) { // We limit type narrowing for index expressions to built-in types that are @@ -6845,13 +6773,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions !ClassType.isBuiltIn(concreteSubtype.details.effectiveMetaclass, ['type', '_InitVarMeta']) && (flags & EvaluatorFlags.ExpectingInstantiableType) === 0 ) { - const itemMethodType = getTypeOfClassMember( + const itemMethodType = getTypeOfObjectMember( node, concreteSubtype, getIndexAccessMagicMethodName(usage), /* usage */ undefined, /* diag */ undefined, - MemberAccessFlags.SkipAttributeAccessOverride | MemberAccessFlags.ConsiderMetaclassOnly + MemberAccessFlags.SkipAttributeAccessOverride ); if ((flags & EvaluatorFlags.ExpectingTypeAnnotation) !== 0) { @@ -6986,6 +6914,19 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return result.type; } + if (isNoneInstance(concreteSubtype)) { + if (!isIncomplete) { + addDiagnostic( + AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalSubscript, + DiagnosticRule.reportOptionalSubscript, + Localizer.Diagnostic.noneNotSubscriptable(), + node.baseExpression + ); + } + + return UnknownType.create(); + } + if (isClassInstance(concreteSubtype)) { const typeResult = getTypeOfIndexedObjectOrClass(node, concreteSubtype, usage); if (typeResult.isIncomplete) { @@ -6998,17 +6939,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return NeverType.createNever(); } - if (isNoneInstance(concreteSubtype) && !isIncomplete) { - addDiagnostic( - AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalSubscript, - DiagnosticRule.reportOptionalSubscript, - Localizer.Diagnostic.noneNotSubscriptable(), - node.baseExpression - ); - - return UnknownType.create(); - } - if (!isIncomplete) { const fileInfo = AnalyzerNodeInfo.getFileInfo(node); addDiagnostic( @@ -7172,23 +7102,14 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } const magicMethodName = getIndexAccessMagicMethodName(usage); - const itemMethodType = isClassInstance(baseType) - ? getTypeOfObjectMember( - node, - baseType, - magicMethodName, - /* usage */ undefined, - /* diag */ undefined, - MemberAccessFlags.SkipAttributeAccessOverride - )?.type - : getTypeOfClassMember( - node, - baseType, - magicMethodName, - /* usage */ undefined, - /* diag */ undefined, - MemberAccessFlags.SkipAttributeAccessOverride | MemberAccessFlags.ConsiderMetaclassOnly - )?.type; + const itemMethodType = getTypeOfObjectMember( + node, + baseType, + magicMethodName, + /* usage */ undefined, + /* diag */ undefined, + MemberAccessFlags.SkipAttributeAccessOverride + )?.type; if (!itemMethodType) { const fileInfo = AnalyzerNodeInfo.getFileInfo(node); @@ -7879,7 +7800,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions ); } - const argList = node.arguments.map((arg) => { + const argList = ParseTreeUtils.getArgumentsByRuntimeOrder(node).map((arg) => { const functionArg: FunctionArgument = { valueExpression: arg.valueExpression, argumentCategory: arg.argumentCategory, @@ -8222,7 +8143,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions addInformation(Localizer.Diagnostic.revealLocalsNone(), node); } - return NoneType.createInstance(); + return getNoneType(); } function getTypeOfSuperCall(node: CallNode): TypeResult { @@ -8230,7 +8151,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions addError(Localizer.Diagnostic.superCallArgCount(), node.arguments[2]); } - const enclosingFunction = ParseTreeUtils.getEnclosingFunction(node); + const enclosingFunction = ParseTreeUtils.getEnclosingFunctionEvaluationScope(node); const enclosingClass = enclosingFunction ? ParseTreeUtils.getEnclosingClass(enclosingFunction, /* stopAtFunction */ true) : undefined; @@ -8374,9 +8295,9 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions type: resultIsInstance ? ClassType.cloneAsInstance(lookupResults.classType) : lookupResults.classType, - bindToType: bindToType + bindToSelfType: bindToType ? TypeBase.cloneForCondition( - synthesizeTypeVarForSelfCls(bindToType, !resultIsInstance), + synthesizeTypeVarForSelfCls(bindToType, /* isClsParam */ false), bindToType.condition ) : undefined, @@ -8765,6 +8686,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions { type: overload, isIncomplete: typeResult.isIncomplete }, overloadIndex ); + if (!matchResults.argumentErrors) { filteredMatchResults.push(matchResults); } @@ -8813,7 +8735,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // Create a helper function that evaluates the overload that best // matches the arg/param lists. - function evaluateUsingBestMatchingOverload(skipUnknownArgCheck: boolean) { + function evaluateUsingBestMatchingOverload(skipUnknownArgCheck: boolean, emitNoOverloadFoundError: boolean) { // Find the match with the smallest argument match score. If there // are more than one with the same score, use the one with the // largest index. Later overloads tend to be more general. @@ -8824,6 +8746,27 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return current.argumentMatchScore < previous.argumentMatchScore ? current : previous; }); + // If there is more than one filtered match, report that no match + // was possible and emit a diagnostic that provides the most likely. + if (emitNoOverloadFoundError) { + const functionName = bestMatch.overload.details.name || ''; + const diagnostic = addDiagnostic( + AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, + DiagnosticRule.reportGeneralTypeIssues, + Localizer.Diagnostic.noOverload().format({ name: functionName }), + errorNode + ); + + const overrideDecl = bestMatch.overload.details.declaration; + if (diagnostic && overrideDecl) { + diagnostic.addRelatedInfo( + Localizer.DiagnosticAddendum.overloadIndex().format({ index: bestMatch.overloadIndex + 1 }), + overrideDecl.path, + overrideDecl.range + ); + } + } + const effectiveTypeVarContext = typeVarContext ?? new TypeVarContext(); effectiveTypeVarContext.addSolveForScope(getTypeVarScopeIds(bestMatch.overload)); effectiveTypeVarContext.unlock(); @@ -8841,7 +8784,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // use the normal type matching mechanism because it is faster and // will provide a clearer error message. if (filteredMatchResults.length === 1) { - return evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ false); + return evaluateUsingBestMatchingOverload( + /* skipUnknownArgCheck */ false, + /* emitNoOverloadFoundError */ false + ); } let expandedArgTypes: (Type | undefined)[][] | undefined = [argList.map((arg) => undefined)]; @@ -8900,7 +8846,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // in speculative mode because it's very expensive, and we're going to // suppress the diagnostic anyway. if (!isDiagnosticSuppressedForNode(errorNode) && !isTypeIncomplete) { - const result = evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ true); + const result = evaluateUsingBestMatchingOverload( + /* skipUnknownArgCheck */ true, + /* emitNoOverloadFoundError */ true + ); // Replace the result with an unknown type since we don't know // what overload should have been used. @@ -9116,6 +9065,17 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } case TypeCategory.Class: { + if (isNoneInstance(expandedCallType)) { + addDiagnostic( + AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, + DiagnosticRule.reportOptionalCall, + Localizer.Diagnostic.noneNotCallable(), + errorNode + ); + + return { argumentErrors: true }; + } + if (TypeBase.isInstantiable(expandedCallType)) { return validateCallForInstantiableClass( errorNode, @@ -9139,34 +9099,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions ); } - case TypeCategory.None: { - if (TypeBase.isInstantiable(expandedCallType)) { - if (noneType && isInstantiableClass(noneType)) { - const callResult = validateCallForInstantiableClass( - errorNode, - argList, - noneType, - noneType, - skipUnknownArgCheck, - inferenceContext - ); - - return { ...callResult, returnType: NoneType.createInstance() }; - } - - return { returnType: NoneType.createInstance() }; - } - - addDiagnostic( - AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, - DiagnosticRule.reportOptionalCall, - Localizer.Diagnostic.noneNotCallable(), - errorNode - ); - - return { argumentErrors: true }; - } - // TypeVars should have been expanded in most cases, // but we still need to handle the case of Type[T] where // T is a constrained type that contains a union. We also @@ -9943,7 +9875,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const remainingParamCount = positionParamLimitIndex - paramIndex - 1; if (paramIndex >= positionParamLimitIndex) { - if (!typeResult.type.details.paramSpec) { + if (paramSpecArgList) { + // Push the remaining positional args onto the param spec arg list. + while (argIndex < positionalArgCount) { + paramSpecArgList.push(argList[argIndex]); + argIndex++; + } + } else { let tooManyPositionals = false; if (foundUnpackedListArg && argList[argIndex].argumentCategory === ArgumentCategory.UnpackedList) { @@ -10006,8 +9944,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // with a ParamSpec and a Concatenate operator. PEP 612 indicates that // all positional parameters specified in the Concatenate must be // filled explicitly. - if (typeResult.type.details.paramSpec && paramIndex < positionParamLimitIndex) { - if (isTypeVar(argTypeResult.type) && argTypeResult.type.paramSpecAccess === 'args') { + if (paramIndex < positionParamLimitIndex) { + if ( + isTypeVar(argTypeResult.type) && + argTypeResult.type.paramSpecAccess === 'args' && + paramDetails.params[paramIndex].param.category !== ParameterCategory.ArgsList + ) { if (!isDiagnosticSuppressedForNode(errorNode)) { addDiagnostic( AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, @@ -10375,14 +10317,17 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions isParamSpecKwargsArgument(typeResult.type.details.paramSpec, argType) ) { unpackedDictionaryArgType = AnyType.create(); - validateArgTypeParams.push({ - paramCategory: ParameterCategory.KwargsDict, - paramType: typeResult.type.details.paramSpec, - requiresTypeVarMatching: false, - argument: argList[argIndex], - argType: isParamSpec(argType) ? undefined : AnyType.create(), - errorNode: argList[argIndex].valueExpression || errorNode, - }); + + if (!paramSpecArgList) { + validateArgTypeParams.push({ + paramCategory: ParameterCategory.KwargsDict, + paramType: typeResult.type.details.paramSpec, + requiresTypeVarMatching: false, + argument: argList[argIndex], + argType: isParamSpec(argType) ? undefined : AnyType.create(), + errorNode: argList[argIndex].valueExpression || errorNode, + }); + } } else { const strObjType = getBuiltInObject(errorNode, 'str'); @@ -11162,7 +11107,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions matchResults.paramSpecArgList, matchResults.paramSpecTarget, typeVarContext, - typeCondition + signatureTracker ); if (paramSpecArgResult.argumentErrors) { @@ -11454,7 +11399,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argList: FunctionArgument[], paramSpec: TypeVarType, destTypeVarContext: TypeVarContext, - conditionFilter: TypeCondition[] | undefined + signatureTracker: UniqueSignatureTracker ): ParamSpecArgResult { const signatureContexts = destTypeVarContext.getSignatureContexts(); @@ -11465,7 +11410,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argList, paramSpec, signatureContexts[0], - conditionFilter + signatureTracker ); } @@ -11480,7 +11425,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argList, paramSpec, context, - conditionFilter + signatureTracker ); if (!paramSpecArgResult.argumentErrors) { @@ -11502,7 +11447,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argList, paramSpec, filteredSignatureContexts.length > 0 ? filteredSignatureContexts[0] : signatureContexts[0], - conditionFilter + signatureTracker ); return { argumentErrors: paramSpecArgResult.argumentErrors, typeVarContexts }; @@ -11513,218 +11458,81 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argList: FunctionArgument[], paramSpec: TypeVarType, typeVarContext: TypeVarSignatureContext, - conditionFilter: TypeCondition[] | undefined + signatureTracker: UniqueSignatureTracker ): ParamSpecArgResult { - const paramSpecType = typeVarContext.getParamSpecType(paramSpec); + let paramSpecType = typeVarContext.getParamSpecType(paramSpec); if (!paramSpecType) { - addDiagnostic( - AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, - DiagnosticRule.reportGeneralTypeIssues, - Localizer.Diagnostic.paramSpecNotBound().format({ type: printType(paramSpec) }), - argList[0]?.valueExpression || errorNode - ); - return { argumentErrors: true, typeVarContexts: [undefined] }; + paramSpecType = convertTypeToParamSpecValue(paramSpec); } - const liveTypeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(errorNode); - + const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, { type: paramSpecType }, 0); + const functionType = matchResults.overload; const srcTypeVarContext = new TypeVarContext(getTypeVarScopeIds(paramSpecType)); - let reportedArgError = false; - - let sawUnpackedListArgument = false; - let sawUnpackedDictArgument = false; - let paramMap = new Map(); - - // We'll use two passes in case there are type variables that depend - // on later arguments. - const passCount = 2; - for (let i = 0; i < passCount; i++) { - // Unless we're on the last pass, use speculative mode to suppress - // any diagnostics. - useSpeculativeMode(i < passCount - 1 ? errorNode : undefined, () => { - // Build a map of all named parameters. - paramMap = new Map(); - const paramSpecParams = paramSpecType.details.parameters; - paramSpecParams.forEach((param) => { - if (param.name) { - paramMap.set(param.name, param); - } - }); - - let positionalIndex = 0; - let positionalIndexLimit = paramSpecParams.findIndex( - (paramInfo) => paramInfo.category !== ParameterCategory.Simple - ); - if (positionalIndexLimit < 0) { - positionalIndexLimit = paramSpecParams.length; - } - const argsParam = paramSpecParams.find( - (paramInfo) => paramInfo.category === ParameterCategory.ArgsList - ); - const kwargsParam = paramSpecParams.find( - (paramInfo) => paramInfo.category === ParameterCategory.KwargsDict - ); - - const signatureTracker = new UniqueSignatureTracker(); - const nestedArgList: FunctionArgument[] = []; - - argList.forEach((arg) => { - if (arg.argumentCategory === ArgumentCategory.Simple) { - let paramType: Type | undefined; - - if (arg.name) { - const paramInfo = paramMap.get(arg.name.value); - if (paramInfo) { - paramType = paramInfo.type; - paramMap.delete(arg.name.value); - } else if (kwargsParam) { - paramType = kwargsParam.type; - } else { - addDiagnostic( - AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, - DiagnosticRule.reportGeneralTypeIssues, - Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), - arg.name || errorNode - ); - reportedArgError = true; - } - } else { - if (positionalIndex < positionalIndexLimit) { - const paramInfo = paramSpecParams[positionalIndex]; - paramType = paramInfo.type; - if (paramInfo.name) { - paramMap.delete(paramInfo.name); - } - } else if (argsParam) { - paramType = argsParam.type; - } else if (paramSpecType.details.paramSpec) { - nestedArgList.push(arg); - } else { - addDiagnostic( - AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, - DiagnosticRule.reportGeneralTypeIssues, - paramSpecParams.length === 1 - ? Localizer.Diagnostic.argPositionalExpectedOne() - : Localizer.Diagnostic.argPositionalExpectedCount().format({ - expected: paramSpecParams.length, - }), - arg.valueExpression ?? errorNode - ); - reportedArgError = true; - } - - positionalIndex++; - } - - if (paramType) { - const argResult = validateArgType( - { - paramCategory: ParameterCategory.Simple, - paramType: transformExpectedType( - paramType, - liveTypeVarScopes, - /* usageOffset */ undefined - ), - requiresTypeVarMatching: false, - argument: arg, - errorNode: arg.valueExpression || errorNode, - }, - srcTypeVarContext, - signatureTracker, - /* functionType */ undefined, - { conditionFilter } - ); - - if (!argResult.isCompatible) { - reportedArgError = true; - } - } - } else if (arg.argumentCategory === ArgumentCategory.UnpackedList) { - sawUnpackedListArgument = true; - - // See if there is an *args parameter. - const argsParam = paramSpecParams.find( - (param) => param.category === ParameterCategory.ArgsList && param.name - ); - if (argsParam && paramMap.has(argsParam.name!)) { - // TODO - validate args type - paramMap.delete(argsParam.name!); - } - } else { - sawUnpackedDictArgument = true; - assert(arg.argumentCategory === ArgumentCategory.UnpackedDictionary); - - // See if there is an *kwargs parameter. - const kwargsParam = paramSpecParams.find( - (param) => param.category === ParameterCategory.KwargsDict - ); - if (kwargsParam && paramMap.has(kwargsParam.name!)) { - // TODO - validate kwargs type - paramMap.delete(kwargsParam.name!); - } - } - }); - - // Handle recursive ParamSpecs. - if (paramSpecType.details.paramSpec) { - const boundTypeForParamSpec = srcTypeVarContext - .getPrimarySignature() - .getParamSpecType(paramSpecType.details.paramSpec); - - if (boundTypeForParamSpec) { - const paramSpecArgResult = validateFunctionArgumentsForParamSpec( - errorNode, - nestedArgList, - paramSpecType.details.paramSpec, - srcTypeVarContext, - conditionFilter - ); - if (paramSpecArgResult.argumentErrors) { - reportedArgError = true; - } - } + if (matchResults.argumentErrors) { + // Evaluate types of all args. This will ensure that referenced symbols are + // not reported as unaccessed. + argList.forEach((arg) => { + if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) { + getTypeOfExpression(arg.valueExpression); } }); + + return { argumentErrors: true, typeVarContexts: [srcTypeVarContext] }; } - // Report any missing parameters. - if (!reportedArgError) { - let unassignedParams = Array.from(paramMap.keys()); + // Handle the recursive case where we're passing (*args: P.args, **kwargs: P.args) + // a remaining function of type (*P). + if ( + functionType.details.paramSpec && + functionType.details.parameters.length === 0 && + isTypeSame(functionType.details.paramSpec, paramSpec) + ) { + // If there are any arguments other than *args: P.args or **kwargs: P.kwargs, + // report an error. + let sawArgs = false; + let sawKwargs = false; + let argumentErrors = false; + let argErrorNode: ExpressionNode | undefined; + + for (const arg of argList) { + const argType = getTypeOfArgument(arg)?.type; + const isArgTypeCompatible = argType && (isTypeSame(argType, paramSpec) || isAnyOrUnknown(argType)); + + if (arg.argumentCategory === ArgumentCategory.UnpackedList && !sawArgs && isArgTypeCompatible) { + sawArgs = true; + } else if ( + arg.argumentCategory === ArgumentCategory.UnpackedDictionary && + !sawKwargs && + isArgTypeCompatible + ) { + sawKwargs = true; + } else { + argErrorNode = argErrorNode ?? arg.valueExpression; + argumentErrors = true; + } + } - // Parameters that have defaults can be left unspecified. - unassignedParams = unassignedParams.filter((name) => { - const paramInfo = paramMap.get(name)!; - return paramInfo.category === ParameterCategory.Simple && !paramInfo.hasDefault; - }); + if (!sawArgs || !sawKwargs) { + argumentErrors = true; + } - if ( - unassignedParams.length > 0 && - !paramSpecType.details.paramSpec && - !sawUnpackedListArgument && - !sawUnpackedDictArgument - ) { - const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', '); + if (argumentErrors) { addDiagnostic( AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, - unassignedParams.length === 1 - ? Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames }) - : Localizer.Diagnostic.argMissingForParams().format({ names: missingParamNames }), - errorNode + Localizer.Diagnostic.paramSpecArgsMissing().format({ + type: printType(functionType.details.paramSpec), + }), + argErrorNode ?? errorNode ); - reportedArgError = true; } - } - if (!reportedArgError) { - applySourceContextTypeVarsToSignature(typeVarContext, srcTypeVarContext); + return { argumentErrors, typeVarContexts: [srcTypeVarContext] }; } - return { - argumentErrors: reportedArgError, - typeVarContexts: [reportedArgError ? srcTypeVarContext : undefined], - }; + const result = validateFunctionArgumentTypes(errorNode, matchResults, srcTypeVarContext, signatureTracker); + return { argumentErrors: !!result.argumentErrors, typeVarContexts: [srcTypeVarContext] }; } function validateArgType( @@ -12115,7 +11923,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions addError(Localizer.Diagnostic.typeVarFirstArg(), firstArg.valueExpression || errorNode); } - const typeVar = TypeVarType.createInstantiable(typeVarName, /* isParamSpec */ false); + const typeVar = TypeVarType.createInstantiable(typeVarName, /* isParamSpec */ false, classType); // Parse the remaining parameters. const paramNameMap = new Map(); @@ -12141,7 +11949,9 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const argType = argList[i].typeResult?.type ?? getTypeOfExpressionExpectingType(argList[i].valueExpression!).type; - if (requiresSpecialization(argType, /* ignorePseudoGeneric */ true)) { + if ( + requiresSpecialization(argType, { ignorePseudoGeneric: true, ignoreImplicitTypeArgs: true }) + ) { addError( Localizer.Diagnostic.typeVarBoundGeneric(), argList[i].valueExpression || errorNode @@ -12218,7 +12028,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argList[i].typeResult?.type ?? getTypeOfExpressionExpectingType(argList[i].valueExpression!).type; - if (requiresSpecialization(argType, /* ignorePseudoGeneric */ true)) { + if (requiresSpecialization(argType, { ignorePseudoGeneric: true })) { addError( Localizer.Diagnostic.typeVarConstraintGeneric(), argList[i].valueExpression || errorNode @@ -12294,7 +12104,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions addError(Localizer.Diagnostic.typeVarFirstArg(), firstArg.valueExpression || errorNode); } - const typeVar = TypeVarType.createInstantiable(typeVarName, /* isParamSpec */ false); + const typeVar = TypeVarType.createInstantiable(typeVarName, /* isParamSpec */ false, classType); typeVar.details.isVariadic = true; // Parse the remaining parameters. @@ -12368,7 +12178,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions addError(Localizer.Diagnostic.paramSpecFirstArg(), firstArg.valueExpression || errorNode); } - const paramSpec = TypeVarType.createInstantiable(paramSpecName, /* isParamSpec */ true); + const paramSpec = TypeVarType.createInstantiable(paramSpecName, /* isParamSpec */ true, classType); // Parse the remaining parameters. for (let i = 1; i < argList.length; i++) { @@ -12692,7 +12502,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions type: ClassType.cloneAsInstance(baseClass), hasDeclaredType: true, }); - initType.details.declaredReturnType = NoneType.createInstance(); + initType.details.declaredReturnType = getNoneType(); classType.details.fields.set('__init__', Symbol.createWithType(SymbolFlags.ClassMember, initType)); // Synthesize a trivial __new__ method. @@ -12752,14 +12562,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return classType; } - function getTypeOfConstant(node: ConstantNode, flags: EvaluatorFlags): TypeResult | undefined { + function getTypeOfConstant(node: ConstantNode, flags: EvaluatorFlags): TypeResult { let type: Type | undefined; if (node.constType === KeywordType.None) { - type = - (flags & EvaluatorFlags.ExpectingInstantiableType) !== 0 - ? NoneType.createType() - : NoneType.createInstance(); + type = (flags & EvaluatorFlags.ExpectingInstantiableType) !== 0 ? noneClassType : noneType; } else if ( node.constType === KeywordType.True || node.constType === KeywordType.False || @@ -12778,19 +12585,15 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } - if (!type) { - return undefined; - } - - return { type }; + return { type: type ?? UnknownType.create() }; } - function getTypeOfMagicMethodReturn( + function getTypeOfMagicMethodCall( objType: Type, - args: TypeResult[], - magicMethodName: string, + methodName: string, + argList: TypeResult[], errorNode: ExpressionNode, - inferenceContext: InferenceContext | undefined + inferenceContext?: InferenceContext ): Type | undefined { let magicMethodSupported = true; @@ -12799,28 +12602,19 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let magicMethodType: Type | undefined; const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype); - if (isClassInstance(concreteSubtype)) { + if (isClass(concreteSubtype)) { magicMethodType = getTypeOfObjectMember( errorNode, concreteSubtype, - magicMethodName, + methodName, /* usage */ undefined, /* diag */ undefined, - MemberAccessFlags.SkipAttributeAccessOverride | MemberAccessFlags.AccessClassMembersOnly - )?.type; - } else if (isInstantiableClass(concreteSubtype)) { - magicMethodType = getTypeOfClassMember( - errorNode, - concreteSubtype, - magicMethodName, - /* usage */ undefined, - /* diag */ undefined, - MemberAccessFlags.SkipAttributeAccessOverride | MemberAccessFlags.ConsiderMetaclassOnly + MemberAccessFlags.AccessClassMembersOnly | MemberAccessFlags.SkipAttributeAccessOverride )?.type; } if (magicMethodType) { - const functionArgs: FunctionArgument[] = args.map((arg) => { + const functionArgs: FunctionArgument[] = argList.map((arg) => { return { argumentCategory: ArgumentCategory.Simple, typeResult: arg, @@ -13030,35 +12824,43 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return undefined; } - const builtInDict = getBuiltInObject(node, 'dict'); - if (!isClassInstance(builtInDict)) { - return undefined; - } + let expectedKeyType: Type; + let expectedValueType: Type; - const dictTypeVarContext = new TypeVarContext(getTypeVarScopeId(builtInDict)); - if ( - !populateTypeVarContextBasedOnExpectedType( - evaluatorInterface, - builtInDict, - inferenceContext.expectedType, - dictTypeVarContext, - ParseTreeUtils.getTypeVarScopesForNode(node), - node.start - ) - ) { - return undefined; - } + if (isAnyOrUnknown(inferenceContext.expectedType)) { + expectedKeyType = inferenceContext.expectedType; + expectedValueType = inferenceContext.expectedType; + } else { + const builtInDict = getBuiltInObject(node, 'dict'); + if (!isClassInstance(builtInDict)) { + return undefined; + } - const specializedDict = applySolvedTypeVars( - ClassType.cloneAsInstantiable(builtInDict), - dictTypeVarContext - ) as ClassType; - if (!specializedDict.typeArguments || specializedDict.typeArguments.length !== 2) { - return undefined; - } + const dictTypeVarContext = new TypeVarContext(getTypeVarScopeId(builtInDict)); + if ( + !populateTypeVarContextBasedOnExpectedType( + evaluatorInterface, + builtInDict, + inferenceContext.expectedType, + dictTypeVarContext, + ParseTreeUtils.getTypeVarScopesForNode(node), + node.start + ) + ) { + return undefined; + } - const expectedKeyType = specializedDict.typeArguments[0]; - const expectedValueType = specializedDict.typeArguments[1]; + const specializedDict = applySolvedTypeVars( + ClassType.cloneAsInstantiable(builtInDict), + dictTypeVarContext + ) as ClassType; + if (!specializedDict.typeArguments || specializedDict.typeArguments.length !== 2) { + return undefined; + } + + expectedKeyType = specializedDict.typeArguments[0]; + expectedValueType = specializedDict.typeArguments[1]; + } // Dict and MutableMapping types have invariant value types, so they // cannot be narrowed further. Other super-types like Mapping, Collection, @@ -13336,12 +13138,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } else if (mappingType && isInstantiableClass(mappingType)) { const mappingTypeVarContext = new TypeVarContext(getTypeVarScopeId(mappingType)); - // Self-specialize the class. - mappingType = ClassType.cloneForSpecialization( - mappingType, - mappingType.details.typeParameters, - /* isTypeArgumentExplicit */ true - ); + mappingType = selfSpecializeClass(mappingType); if ( assignType( @@ -13488,40 +13285,45 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let isIncomplete = false; let typeErrors = false; const verifyHashable = node.nodeType === ParseNodeType.Set; + let expectedEntryType: Type; - if (!isClassInstance(inferenceContext.expectedType)) { - return undefined; - } + if (isAnyOrUnknown(inferenceContext.expectedType)) { + expectedEntryType = inferenceContext.expectedType; + } else { + if (!isClassInstance(inferenceContext.expectedType)) { + return undefined; + } - const builtInListOrSet = getBuiltInObject(node, builtInClassName); - if (!isClassInstance(builtInListOrSet)) { - return undefined; - } + const builtInListOrSet = getBuiltInObject(node, builtInClassName); + if (!isClassInstance(builtInListOrSet)) { + return undefined; + } - const typeVarContext = new TypeVarContext(getTypeVarScopeId(builtInListOrSet)); - if ( - !populateTypeVarContextBasedOnExpectedType( - evaluatorInterface, - builtInListOrSet, - inferenceContext.expectedType, - typeVarContext, - ParseTreeUtils.getTypeVarScopesForNode(node), - node.start - ) - ) { - return undefined; - } + const typeVarContext = new TypeVarContext(getTypeVarScopeId(builtInListOrSet)); + if ( + !populateTypeVarContextBasedOnExpectedType( + evaluatorInterface, + builtInListOrSet, + inferenceContext.expectedType, + typeVarContext, + ParseTreeUtils.getTypeVarScopesForNode(node), + node.start + ) + ) { + return undefined; + } + + const specializedListOrSet = applySolvedTypeVars( + ClassType.cloneAsInstantiable(builtInListOrSet), + typeVarContext + ) as ClassType; + if (!specializedListOrSet.typeArguments || specializedListOrSet.typeArguments.length !== 1) { + return undefined; + } - const specializedListOrSet = applySolvedTypeVars( - ClassType.cloneAsInstantiable(builtInListOrSet), - typeVarContext - ) as ClassType; - if (!specializedListOrSet.typeArguments || specializedListOrSet.typeArguments.length !== 1) { - return undefined; + expectedEntryType = specializedListOrSet.typeArguments[0]; } - const expectedEntryType = specializedListOrSet.typeArguments[0]; - const entryTypes: Type[] = []; const expectedTypeDiagAddendum = new DiagnosticAddendum(); node.entries.forEach((entry) => { @@ -13791,14 +13593,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } function getTypeOfLambda(node: LambdaNode, inferenceContext: InferenceContext | undefined): TypeResult { - let isIncomplete = !!inferenceContext?.isTypeIncomplete; - const functionType = FunctionType.createInstance('', '', '', FunctionTypeFlags.PartiallyEvaluated); - functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node); - - // Pre-cache the incomplete function type in case the evaluation of the - // lambda depends on itself. - writeTypeCache(node, { type: functionType, isIncomplete: true }, EvaluatorFlags.None); - let expectedFunctionTypes: FunctionType[] = []; if (inferenceContext) { mapSubtypes(inferenceContext.expectedType, (subtype) => { @@ -13815,40 +13609,62 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return undefined; }); + } - // Determine the minimum number of parameters that are required to - // satisfy the lambda. - const minLambdaParamCount = node.parameters.filter( - (param) => - param.category === ParameterCategory.Simple && !!param.name && param.defaultValue === undefined - ).length; - const maxLambdaParamCount = node.parameters.filter( - (param) => param.category === ParameterCategory.Simple && !!param.name - ).length; - - // Remove any expected subtypes that don't satisfy the minimum - // parameter count requirement. - expectedFunctionTypes = expectedFunctionTypes.filter((functionType) => { - const functionParamCount = functionType.details.parameters.filter( - (param) => !!param.name && !param.hasDefault - ).length; - const hasVarArgs = functionType.details.parameters.some( - (param) => !!param.name && param.category !== ParameterCategory.Simple - ); - const hasParamSpec = !!functionType.details.paramSpec; + if (expectedFunctionTypes.length <= 1) { + return getTypeOfLambdaWithExpectedType( + node, + expectedFunctionTypes.length > 0 ? expectedFunctionTypes[0] : undefined, + inferenceContext, + /* forceSpeculative */ false + ); + } + + // Sort the expected types for deterministic results. + expectedFunctionTypes = sortTypes(expectedFunctionTypes) as FunctionType[]; - return ( - hasVarArgs || - hasParamSpec || - (functionParamCount >= minLambdaParamCount && functionParamCount <= maxLambdaParamCount) + // If there's more than one type, try each in turn until we find one that works. + for (const expectedFunctionType of expectedFunctionTypes) { + const result = getTypeOfLambdaWithExpectedType( + node, + expectedFunctionType, + inferenceContext, + /* forceSpeculative */ true + ); + if (!result.typeErrors) { + return getTypeOfLambdaWithExpectedType( + node, + expectedFunctionType, + inferenceContext, + /* forceSpeculative */ false ); - }); + } } - // For now, use only the first expected type. - const expectedFunctionType = expectedFunctionTypes.length > 0 ? expectedFunctionTypes[0] : undefined; + return getTypeOfLambdaWithExpectedType( + node, + expectedFunctionTypes[0], + inferenceContext, + /* forceSpeculative */ true + ); + } + + function getTypeOfLambdaWithExpectedType( + node: LambdaNode, + expectedType: FunctionType | undefined, + inferenceContext: InferenceContext | undefined, + forceSpeculative: boolean + ): TypeResult { + let isIncomplete = !!inferenceContext?.isTypeIncomplete; let paramsArePositionOnly = true; - const expectedParamDetails = expectedFunctionType ? getParameterListDetails(expectedFunctionType) : undefined; + const expectedParamDetails = expectedType ? getParameterListDetails(expectedType) : undefined; + + const functionType = FunctionType.createInstance('', '', '', FunctionTypeFlags.PartiallyEvaluated); + functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node); + + // Pre-cache the incomplete function type in case the evaluation of the + // lambda depends on itself. + writeTypeCache(node, { type: functionType, isIncomplete: true }, EvaluatorFlags.None); node.parameters.forEach((param, index) => { let paramType: Type | undefined; @@ -13928,9 +13744,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions }); } - const expectedReturnType = expectedFunctionType - ? getFunctionEffectiveReturnType(expectedFunctionType) - : undefined; + const expectedReturnType = expectedType ? getFunctionEffectiveReturnType(expectedType) : undefined; + let typeErrors = false; // If we're speculatively evaluating the lambda, create another speculative // evaluation scope for the return expression and do not allow retention @@ -13940,7 +13755,9 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // the parameter types that we set above, and the speculative type cache // doesn't know about that context. useSpeculativeMode( - isSpeculativeModeInUse(node) || inferenceContext?.isTypeIncomplete ? node.expression : undefined, + forceSpeculative || isSpeculativeModeInUse(node) || inferenceContext?.isTypeIncomplete + ? node.expression + : undefined, () => { const returnTypeResult = getTypeOfExpression( node.expression, @@ -13952,16 +13769,25 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (returnTypeResult.isIncomplete) { isIncomplete = true; } + + if (returnTypeResult.typeErrors) { + typeErrors = true; + } }, { - dependentType: inferenceContext?.expectedType, + dependentType: expectedType, } ); // Mark the function type as no longer being evaluated. functionType.details.flags &= ~FunctionTypeFlags.PartiallyEvaluated; - return { type: functionType, isIncomplete }; + // Is the resulting function compatible with the expected type? + if (expectedType && !assignType(expectedType, functionType)) { + typeErrors = true; + } + + return { type: functionType, isIncomplete, typeErrors }; } function getTypeOfListComprehension(node: ListComprehensionNode, inferenceContext?: InferenceContext): TypeResult { @@ -13989,7 +13815,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions expectedElementType = getTypeOfIterator( { type: inferenceContext.expectedType }, isAsync, - /* errorNode */ undefined + node, + /* emitNotIterableError */ false )?.type; } @@ -14018,9 +13845,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions type = ClassType.cloneAsInstance( ClassType.cloneForSpecialization( builtInIteratorType, - isAsync - ? [elementType, NoneType.createInstance()] - : [elementType, NoneType.createInstance(), NoneType.createInstance()], + isAsync ? [elementType, getNoneType()] : [elementType, getNoneType(), getNoneType()], /* isTypeArgumentExplicit */ true ) ); @@ -14274,6 +14099,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(errorNode); if (typeArgs && typeArgs.length > 0) { + functionType.isCallableWithTypeArgs = true; + if (typeArgs[0].typeList) { const typeList = typeArgs[0].typeList; let sawUnpacked = false; @@ -14425,7 +14252,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions typeArg0Type = UnknownType.create(); } - const optionalType = combineTypes([typeArg0Type, NoneType.createType()]); + const optionalType = combineTypes([typeArg0Type, noneClassType ?? UnknownType.create()]); if (isUnion(optionalType)) { TypeBase.setSpecialForm(optionalType); @@ -14437,7 +14264,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions function cloneBuiltinObjectWithLiteral(node: ParseNode, builtInName: string, value: LiteralValue): Type { const type = getBuiltInObject(node, builtInName); if (isClassInstance(type)) { - return ClassType.cloneWithLiteral(type, value); + return ClassType.cloneWithLiteral(ClassType.cloneRemoveTypePromotions(type), value); } return UnknownType.create(); @@ -14491,7 +14318,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } else if (itemExpr.constType === KeywordType.False) { type = cloneBuiltinClassWithLiteral(node, 'bool', false); } else if (itemExpr.constType === KeywordType.None) { - type = NoneType.createType(); + type = noneClassType ?? UnknownType.create(); } } else if ( itemExpr.nodeType === ParseNodeType.UnaryOperation && @@ -14569,7 +14396,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // A ClassVar should not allow TypeVars or generic types parameterized // by TypeVars. - if (requiresSpecialization(type, /* ignorePseudoGeneric */ true, /* ignoreSelf */ true)) { + if (requiresSpecialization(type, { ignorePseudoGeneric: true, ignoreSelf: true })) { const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode); addDiagnostic( @@ -14644,7 +14471,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const enclosingFunction = ParseTreeUtils.getEnclosingFunction(errorNode); if (enclosingFunction) { - const functionFlags = getFunctionFlagsFromDecorators( + const functionInfo = getFunctionInfoFromDecorators( evaluatorInterface, enclosingFunction, /* isInClass */ true @@ -14653,7 +14480,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const isInnerFunction = !!ParseTreeUtils.getEnclosingFunction(enclosingFunction); if (!isInnerFunction) { // Check for static methods. - if (functionFlags & FunctionTypeFlags.StaticMethod) { + if (functionInfo.flags & FunctionTypeFlags.StaticMethod) { addDiagnostic( fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, @@ -14758,9 +14585,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions isNotRequired = classType.details.name === 'NotRequired'; } - isRequired = classType.details.name === 'Required'; - isNotRequired = classType.details.name === 'NotRequired'; - if (!isUsageLegal) { addError( classType.details.name === 'ReadOnly' @@ -15172,7 +14996,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (TypeBase.isInstance(typeVar)) { return typeVar; } - return convertToInstance(typeVar) as TypeVarType; + return convertToInstance(typeVar); }); const typeAliasScopeId = ParseTreeUtils.getScopeIdForNode(name); @@ -15329,15 +15153,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions ['ReadOnly', { alias: '', module: 'builtins' }], ]); - let aliasMapEntry = specialTypes.get(assignedName); - - // Support ReadOnly only as an experimental feature. - if ( - assignedName === 'ReadOnly' && - !AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures - ) { - aliasMapEntry = undefined; - } + const aliasMapEntry = specialTypes.get(assignedName); if (aliasMapEntry) { const cachedType = readTypeCache(node, EvaluatorFlags.None); @@ -15373,7 +15189,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const assignedName = nameNode.value; if (assignedName === 'Any') { - return AnyType.create(); + return AnyType.createSpecialForm(); } const specialTypes: Map = new Map([ @@ -15553,10 +15369,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (typeAliasNameNode) { // If this was a speculative type alias, it becomes a real type alias // only if the evaluated type is an instantiable type. - if ( - !isSpeculativeTypeAlias || - (TypeBase.isInstantiable(rightHandType) && !isUnknown(rightHandType)) - ) { + if (!isSpeculativeTypeAlias || isLegalImplicitTypeAliasType(rightHandType)) { // If this is a type alias, record its name based on the assignment target. rightHandType = transformTypeForTypeAlias( rightHandType, @@ -15759,6 +15572,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } function getTypeOfClass(node: ClassNode): ClassTypeResult | undefined { + initializedBasicTypes(node); + // Is this type already cached? const cachedClassType = readTypeCache(node.name, EvaluatorFlags.None); @@ -15783,7 +15598,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions scope?.type === ScopeType.Builtin || fileInfo.isTypingStubFile || fileInfo.isTypingExtensionsStubFile || - fileInfo.isBuiltInStubFile + fileInfo.isBuiltInStubFile || + fileInfo.isTypeshedStubFile ) { classFlags |= ClassTypeFlags.BuiltInClass; @@ -15818,6 +15634,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions classType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node); + // Is this a special type that supports type promotions according to PEP 484? + if (typePromotions.has(classType.details.fullName)) { + classType.includePromotions = true; + } + // Some classes refer to themselves within type arguments used within // base classes. We'll register the partially-constructed class type // to allow these to be resolved. @@ -15893,6 +15714,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions argType = removeUnbound(argType); } + // Any is allowed as a base class. Remove its "special form" flag to avoid + // false positive errors. + if (isAny(argType) && TypeBase.isSpecialForm(argType)) { + argType = AnyType.create(); + } + if (!isAnyOrUnknown(argType) && !isUnbound(argType)) { if (isMetaclassInstance(argType)) { assert(isClassInstance(argType)); @@ -16084,10 +15911,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } else { metaclassNode = arg.valueExpression; } - } else if ( - ClassType.isTypedDictClass(classType) && - (arg.name.value === 'total' || arg.name.value === 'readonly') - ) { + } else if (ClassType.isTypedDictClass(classType) && arg.name.value === 'total') { // The "total" and "readonly" parameters apply only for TypedDict classes. // PEP 589 specifies that the parameter must be either True or False. const constArgValue = evaluateStaticBoolExpression( @@ -16102,8 +15926,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions ); } else if (arg.name.value === 'total' && !constArgValue) { classType.details.flags |= ClassTypeFlags.CanOmitDictValues; - } else if (arg.name.value === 'readonly' && constArgValue) { - classType.details.flags |= ClassTypeFlags.DictValuesReadOnly; } } else { // Collect arguments that will be passed to the `__init_subclass__` @@ -16216,7 +16038,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions SymbolFlags.ClassVar | SymbolFlags.IgnoredForProtocolMatch | SymbolFlags.IgnoredForOverrideChecks, - NoneType.createInstance() + getNoneType() ) ); } @@ -16299,7 +16121,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (metaclassNode) { const metaclassType = getTypeOfExpression(metaclassNode, exprFlags).type; if (isInstantiableClass(metaclassType) || isUnknown(metaclassType)) { - if (requiresSpecialization(metaclassType, /* ignorePseudoGeneric */ true)) { + if (requiresSpecialization(metaclassType, { ignorePseudoGeneric: true })) { addDiagnostic( fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, @@ -16647,7 +16469,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions node.parameters.forEach((param) => { const paramSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(param.name); - assert(paramSymbol); + if (!paramSymbol) { + // This can happen if the code is unreachable. + return; + } const typeOfParam = getDeclaredTypeOfSymbol(paramSymbol, param.name)?.type; if (!typeOfParam || !isTypeVar(typeOfParam)) { @@ -16681,12 +16506,21 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions !derivesFromClassRecursive(effectiveMetaclass, baseClassMeta, /* ignoreUnknown */ false) ) { if (!reportedMetaclassConflict) { + const diag = new DiagnosticAddendum(); + + diag.addMessage( + Localizer.DiagnosticAddendum.metaclassConflict().format({ + metaclass1: printType(convertToInstance(effectiveMetaclass)), + metaclass2: printType(convertToInstance(baseClassMeta)), + }) + ); addDiagnostic( AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, DiagnosticRule.reportGeneralTypeIssues, - Localizer.Diagnostic.metaclassConflict(), + Localizer.Diagnostic.metaclassConflict() + diag.getString(), errorNode ); + // Don't report more than once. reportedMetaclassConflict = true; } @@ -16825,14 +16659,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const initSubclassMethodInfo = getTypeOfClassMemberName( errorNode, classType, - /* isAccessedThroughObject */ false, '__init_subclass__', { method: 'get' }, /* diag */ undefined, MemberAccessFlags.AccessClassMembersOnly | MemberAccessFlags.SkipObjectBaseClass | - MemberAccessFlags.SkipOriginalClass, - classType + MemberAccessFlags.SkipOriginalClass ); if (initSubclassMethodInfo) { @@ -16845,7 +16677,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions { type: initSubclassMethodType }, /* typeVarContext */ undefined, /* skipUnknownArgCheck */ false, - makeInferenceContext(NoneType.createInstance()) + makeInferenceContext(getNoneType()) ); } } else if (classType.details.effectiveMetaclass && isClass(classType.details.effectiveMetaclass)) { @@ -16944,6 +16776,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } function getTypeOfFunction(node: FunctionNode): FunctionTypeResult | undefined { + initializedBasicTypes(node); + // Is this predecorated function type cached? let functionType = readTypeCache(node.name, EvaluatorFlags.None); @@ -17010,6 +16844,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // See if there are any overloads provided by previous function declarations. if (isFunction(decoratedType)) { + decoratedType.details.deprecatedMessage = functionType.details.deprecatedMessage; + if (FunctionType.isOverloaded(decoratedType)) { // Mark all the parameters as accessed. node.parameters.forEach((param) => { @@ -17051,7 +16887,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions containingClassType = getTypeOfClass(containingClassNode)?.classType; } - let functionFlags = getFunctionFlagsFromDecorators(evaluatorInterface, node, !!containingClassNode); + const functionInfo = getFunctionInfoFromDecorators(evaluatorInterface, node, !!containingClassNode); + let functionFlags = functionInfo.flags; if (functionDecl?.isGenerator) { functionFlags |= FunctionTypeFlags.Generator; } @@ -17075,6 +16912,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions ); functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node); + functionType.details.deprecatedMessage = functionInfo.deprecationMessage; if (node.name.value === '__init__' || node.name.value === '__new__') { if (containingClassNode) { @@ -17218,9 +17056,20 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let defaultValueType: Type | undefined; if (param.defaultValue) { + // If this is a stub file, a protocol, an overload, or a class + // whose body is a placeholder implementation, treat a "...", as + // an "Any" value. + let treatEllipsisAsAny = fileInfo.isStubFile || ParseTreeUtils.isSuiteEmpty(node.suite); + if (containingClassType && ClassType.isProtocolClass(containingClassType)) { + treatEllipsisAsAny = true; + } + if (FunctionType.isOverloaded(functionType) || FunctionType.isAbstractMethod(functionType)) { + treatEllipsisAsAny = true; + } + defaultValueType = getTypeOfExpression( param.defaultValue, - EvaluatorFlags.ConvertEllipsisToAny, + treatEllipsisAsAny ? EvaluatorFlags.ConvertEllipsisToAny : EvaluatorFlags.None, makeInferenceContext(annotatedType) ).type; } @@ -17383,7 +17232,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // Special-case the __init__ method, which is commonly left without // an annotated return type, but we can assume it returns None. if (node.name.value === '__init__') { - functionType.details.declaredReturnType = NoneType.createInstance(); + functionType.details.declaredReturnType = getNoneType(); } else { functionType.details.declaredReturnType = UnknownType.create(); } @@ -17506,7 +17355,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions !isOptionalType(type) && !AnalyzerNodeInfo.getFileInfo(param).diagnosticRuleSet.strictParameterNoneValue ) { - return combineTypes([type, NoneType.createInstance()]); + return combineTypes([type, getNoneType()]); } return type; @@ -17859,14 +17708,14 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions inferredReturnTypes.push(returnType); } else { - inferredReturnTypes.push(NoneType.createInstance()); + inferredReturnTypes.push(getNoneType()); } } }); } if (!functionNeverReturns && implicitlyReturnsNone) { - inferredReturnTypes.push(NoneType.createInstance()); + inferredReturnTypes.push(getNoneType()); } inferredReturnType = combineTypes(inferredReturnTypes); @@ -17914,7 +17763,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const yieldType = getTypeOfExpression(yieldNode.expression).type; inferredYieldTypes.push(yieldType ?? UnknownType.create()); } else { - inferredYieldTypes.push(NoneType.createInstance()); + inferredYieldTypes.push(getNoneType()); } } } @@ -17922,7 +17771,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } if (inferredYieldTypes.length === 0) { - inferredYieldTypes.push(NoneType.createInstance()); + inferredYieldTypes.push(getNoneType()); } const inferredYieldType = combineTypes(inferredYieldTypes); @@ -17946,7 +17795,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions typeArgs.push( inferredYieldType, sendType, - isNever(inferredReturnType) ? NoneType.createInstance() : inferredReturnType + isNever(inferredReturnType) ? getNoneType() : inferredReturnType ); if (useAwaitableGenerator) { @@ -18131,10 +17980,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const additionalHelp = new DiagnosticAddendum(); if (isClass(subtype)) { - let enterType = getTypeOfMagicMethodReturn( + let enterType = getTypeOfMagicMethodCall( subtype, - [], enterMethodName, + [], node.expression, /* inferenceContext */ undefined ); @@ -18150,10 +17999,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (!isAsync) { if ( - getTypeOfMagicMethodReturn( + getTypeOfMagicMethodCall( subtype, - [], '__aenter__', + [], node.expression, /* inferenceContext */ undefined ) @@ -18185,10 +18034,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (isClass(subtype)) { const anyArg: TypeResult = { type: AnyType.create() }; - const exitType = getTypeOfMagicMethodReturn( + const exitType = getTypeOfMagicMethodCall( subtype, - [anyArg, anyArg, anyArg], exitMethodName, + [anyArg, anyArg, anyArg], node.expression, /* inferenceContext */ undefined ); @@ -18956,7 +18805,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // See if the function is a method in a child class. We may be able to // infer the type of the parameter from a method of the same name in // a parent class if it has an annotated type. - const functionFlags = getFunctionFlagsFromDecorators(evaluatorInterface, functionNode, /* isInClass */ true); + const functionFlags = getFunctionInfoFromDecorators( + evaluatorInterface, + functionNode, + /* isInClass */ true + ).flags; const inferredParamType = inferParameterType(functionNode, functionFlags, paramIndex, classInfo?.classType); writeTypeCache( @@ -19935,6 +19788,19 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions .getDeclarations() .find((decl) => decl.type === DeclarationType.Parameter); } + + const parameterDetails = getParameterListDetails(type); + if (parameterDetails.unpackedKwargsTypedDictType) { + const lookupResults = lookUpClassMember( + parameterDetails.unpackedKwargsTypedDictType, + paramName + ); + if (lookupResults) { + return lookupResults.symbol + .getDeclarations() + .find((decl) => decl.type === DeclarationType.Variable); + } + } } } } @@ -20194,7 +20060,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } if (declaration.intrinsicType === 'str | None') { - return { type: combineTypes([strType, NoneType.createInstance()]) }; + return { type: combineTypes([strType, getNoneType()]) }; } if (declaration.intrinsicType === 'int') { @@ -20353,13 +20219,24 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return cachedTypeVarType; } - let typeVar = TypeVarType.createInstantiable(node.name.value); + let runtimeClassName = 'TypeVar'; + if (node.typeParamCategory === TypeParameterCategory.TypeVarTuple) { + runtimeClassName = 'TypeVarTuple'; + } else if (node.typeParamCategory === TypeParameterCategory.ParamSpec) { + runtimeClassName = 'ParamSpec'; + } + const runtimeType = getTypingType(node, runtimeClassName); + const runtimeClass = runtimeType && isInstantiableClass(runtimeType) ? runtimeType : undefined; + + let typeVar = TypeVarType.createInstantiable( + node.name.value, + node.typeParamCategory === TypeParameterCategory.ParamSpec, + runtimeClass + ); typeVar.details.isTypeParamSyntax = true; if (node.typeParamCategory === TypeParameterCategory.TypeVarTuple) { typeVar.details.isVariadic = true; - } else if (node.typeParamCategory === TypeParameterCategory.ParamSpec) { - typeVar.details.isParamSpec = true; } // Cache the value before we evaluate the bound or the default type in @@ -20372,7 +20249,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const constraints = node.boundExpression.expressions.map((constraint) => { const constraintType = getTypeOfExpressionExpectingType(constraint).type; - if (requiresSpecialization(constraintType, /* ignorePseudoGeneric */ true)) { + if ( + requiresSpecialization(constraintType, { + ignorePseudoGeneric: true, + ignoreImplicitTypeArgs: true, + }) + ) { addError(Localizer.Diagnostic.typeVarBoundGeneric(), constraint); } @@ -20392,7 +20274,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } else { const boundType = getTypeOfExpressionExpectingType(node.boundExpression).type; - if (requiresSpecialization(boundType, /* ignorePseudoGeneric */ true)) { + if (requiresSpecialization(boundType, { ignorePseudoGeneric: true })) { addError(Localizer.Diagnostic.typeVarConstraintGeneric(), node.boundExpression); } @@ -20637,11 +20519,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // If this was a speculative type alias, it becomes a real type alias only // in the event that its inferred type is instantiable or explicitly Any // (but not an ellipsis). - if ( - TypeBase.isInstantiable(inferredType) && - !isUnknown(inferredType) && - !isEllipsisType(inferredType) - ) { + if (isLegalImplicitTypeAliasType(inferredType)) { inferredType = transformTypeForTypeAlias( inferredType, resolvedDecl.typeAliasName, @@ -20820,14 +20698,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const effectiveTypeCacheKey = `${usageNodeId === undefined ? '.' : usageNodeId.toString()}${ useLastDecl ? '*' : '' }`; + const cacheEntry = cacheEntries?.get(effectiveTypeCacheKey); - if (cacheEntries) { - const result = cacheEntries.get(effectiveTypeCacheKey); - if (result) { - if (!result.isIncomplete) { - return result; - } - } + if (cacheEntry && !cacheEntry.isIncomplete) { + return cacheEntry; } // Infer the type. @@ -20935,8 +20809,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions declsToConsider.push(resolvedDecl); }); - const evaluationAttempts = (cacheEntries?.get(effectiveTypeCacheKey)?.evaluationAttempts ?? 0) + 1; - const result = getTypeOfSymbolForDecls(symbol, declsToConsider, evaluationAttempts); + const result = getTypeOfSymbolForDecls(symbol, declsToConsider, effectiveTypeCacheKey); // Add the result to the effective type cache if it doesn't include speculative results. if (!result.includesSpeculativeResult) { @@ -20957,11 +20830,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } // Returns the type of a symbol based on a subset of its declarations. - function getTypeOfSymbolForDecls( - symbol: Symbol, - decls: Declaration[], - evaluationAttempts: number - ): EffectiveTypeResult { + function getTypeOfSymbolForDecls(symbol: Symbol, decls: Declaration[], typeCacheKey: string): EffectiveTypeResult { const typesToCombine: Type[] = []; let isIncomplete = false; let sawPendingEvaluation = false; @@ -21039,6 +20908,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } }); + // How many times have we already attempted to evaluate this declaration already? + const cacheEntries = effectiveTypeCache.get(symbol.id); + const evaluationAttempts = (cacheEntries?.get(typeCacheKey)?.evaluationAttempts ?? 0) + 1; + let type: Type; if (typesToCombine.length > 0) { @@ -21217,7 +21090,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // Don't bother inferring the return type of __init__ because it's // always None. if (FunctionType.isInstanceMethod(type) && type.details.name === '__init__') { - returnType = NoneType.createInstance(); + returnType = getNoneType(); } else if (type.details.declaration) { const functionNode = type.details.declaration.node; analyzeUnannotatedFunctions = @@ -21506,6 +21379,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions isIncomplete: !!typeResult.isIncomplete, }; } + } else if (isAnyOrUnknown(member.classType)) { + return { + type: member.classType, + isIncomplete: false, + }; } return undefined; @@ -21576,15 +21454,17 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } // Handle special-case type promotions. - const promotionList = typePromotions.get(destType.details.fullName); - if ( - promotionList && - promotionList.some((srcName) => - srcType.details.mro.some((mroClass) => isClass(mroClass) && srcName === mroClass.details.fullName) - ) - ) { - if ((flags & AssignTypeFlags.EnforceInvariance) === 0) { - return true; + if (destType.includePromotions) { + const promotionList = typePromotions.get(destType.details.fullName); + if ( + promotionList && + promotionList.some((srcName) => + srcType.details.mro.some((mroClass) => isClass(mroClass) && srcName === mroClass.details.fullName) + ) + ) { + if ((flags & AssignTypeFlags.EnforceInvariance) === 0) { + return true; + } } } @@ -21668,6 +21548,15 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions destType: destErrorTypeText, }) ); + + // Tell the user about the disableBytesTypePromotions if that is involved. + if (ClassType.isBuiltIn(destType, 'bytes')) { + const promotions = typePromotions.get(destType.details.fullName); + if (promotions && promotions.some((name) => name === srcType.details.fullName)) { + diag?.addMessage(Localizer.DiagnosticAddendum.bytesTypePromotions()); + } + } + return false; } @@ -22187,6 +22076,15 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (includeDiagAddendum) { childDiag.addAddendum(assignmentDiag); } + + if (isCompatible && ClassType.isSameGenericClass(destType, srcType)) { + // Add additional notes to help the user if this is a common type mismatch. + if (ClassType.isBuiltIn(destType, 'dict') && srcArgIndex === 1) { + childDiag.addMessage(Localizer.DiagnosticAddendum.invariantSuggestionDict()); + } else if (ClassType.isBuiltIn(destType, 'list')) { + childDiag.addMessage(Localizer.DiagnosticAddendum.invariantSuggestionList()); + } + } } else { diag.addAddendum(assignmentDiag); } @@ -22527,7 +22425,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return true; } - if (isAnyOrUnknown(srcType)) { + if (isAnyOrUnknown(srcType) && !TypeBase.isSpecialForm(srcType)) { const targetTypeVarContext = (flags & AssignTypeFlags.ReverseTypeVarMatching) === 0 ? destTypeVarContext : srcTypeVarContext; if (targetTypeVarContext) { @@ -22639,7 +22537,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } - // Is the src a specialized "Type" object? + // Is the src a specialized "type" object? if (isClassInstance(expandedSrcType) && ClassType.isBuiltIn(expandedSrcType, 'type')) { const srcTypeArgs = expandedSrcType.typeArguments; let typeTypeArg: Type | undefined; @@ -22727,6 +22625,34 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)) ); return false; + } else if (isClassInstance(expandedSrcType) && isMetaclassInstance(expandedSrcType)) { + // If the source is a metaclass instance, verify that it's compatible with + // the metaclass of the instantiable dest type. + const destMetaclass = destType.details.effectiveMetaclass; + + if (destMetaclass && isInstantiableClass(destMetaclass)) { + if ( + assignClass( + ClassType.cloneAsInstance(destMetaclass), + expandedSrcType, + diag, + destTypeVarContext, + srcTypeVarContext, + flags, + recursionCount, + /* reportErrorsUsingObjType */ false + ) + ) { + return true; + } + + diag?.addMessage( + Localizer.DiagnosticAddendum.typeAssignmentMismatch().format( + printSrcDestTypes(srcType, destType) + ) + ); + return false; + } } } @@ -22786,14 +22712,15 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // Handle LiteralString special form. if (ClassType.isBuiltIn(destType, 'LiteralString')) { if (ClassType.isBuiltIn(concreteSrcType, 'str') && concreteSrcType.literalValue !== undefined) { - return true; + return (flags & AssignTypeFlags.EnforceInvariance) === 0; } else if (ClassType.isBuiltIn(concreteSrcType, 'LiteralString')) { return true; } } else if ( ClassType.isBuiltIn(concreteSrcType, 'LiteralString') && strClassType && - isInstantiableClass(strClassType) + isInstantiableClass(strClassType) && + (flags & AssignTypeFlags.EnforceInvariance) === 0 ) { concreteSrcType = ClassType.cloneAsInstance(strClassType); } @@ -22908,7 +22835,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions ); } } - } else if (isAnyOrUnknown(concreteSrcType)) { + } else if (isAnyOrUnknown(concreteSrcType) && !TypeBase.isSpecialForm(concreteSrcType)) { return (flags & AssignTypeFlags.OverloadOverlapCheck) === 0; } else if (isUnion(concreteSrcType)) { return assignType( @@ -23088,11 +23015,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // Are we trying to assign None to a protocol? if (isNoneInstance(srcType) && isClassInstance(destType) && ClassType.isProtocolClass(destType)) { - if (noneType && isInstantiableClass(noneType)) { + if (noneClassType && isInstantiableClass(noneClassType)) { return assignClassToProtocol( evaluatorInterface, ClassType.cloneAsInstantiable(destType), - noneType, + noneClassType, diag, destTypeVarContext, srcTypeVarContext, @@ -23766,54 +23693,33 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions let specializedSrcType = srcType; let specializedDestType = destType; - let reverseMatchingFailed = false; + let doSpecializationStep = false; if ((flags & AssignTypeFlags.ReverseTypeVarMatching) === 0) { specializedDestType = applySolvedTypeVars(destType, destTypeVarContext, { useNarrowBoundOnly: true }); - - if (requiresSpecialization(specializedDestType)) { - reverseMatchingFailed = !assignType( - specializedSrcType, - specializedDestType, - /* diag */ undefined, - srcTypeVarContext, - destTypeVarContext, - (flags ^ AssignTypeFlags.ReverseTypeVarMatching) | AssignTypeFlags.RetainLiteralsForTypeVar, - recursionCount - ); - - specializedDestType = applySolvedTypeVars(destType, destTypeVarContext); - } + doSpecializationStep = requiresSpecialization(specializedDestType); } else { specializedSrcType = applySolvedTypeVars(srcType, srcTypeVarContext, { useNarrowBoundOnly: true }); + doSpecializationStep = requiresSpecialization(specializedSrcType); + } - if (requiresSpecialization(specializedSrcType)) { - reverseMatchingFailed = !assignType( - specializedSrcType, - specializedDestType, - /* diag */ undefined, - srcTypeVarContext, - destTypeVarContext, - (flags ^ AssignTypeFlags.ReverseTypeVarMatching) | AssignTypeFlags.RetainLiteralsForTypeVar, - recursionCount - ); + // Is an additional specialization step required? + if (doSpecializationStep) { + assignType( + specializedSrcType, + specializedDestType, + /* diag */ undefined, + srcTypeVarContext, + destTypeVarContext, + (flags ^ AssignTypeFlags.ReverseTypeVarMatching) | AssignTypeFlags.RetainLiteralsForTypeVar, + recursionCount + ); + if ((flags & AssignTypeFlags.ReverseTypeVarMatching) === 0) { + specializedDestType = applySolvedTypeVars(destType, destTypeVarContext); + } else { specializedSrcType = applySolvedTypeVars(srcType, srcTypeVarContext); } - - if (reverseMatchingFailed) { - if (diag && paramIndex !== undefined) { - diag.addMessage( - Localizer.DiagnosticAddendum.paramAssignment().format({ - index: paramIndex + 1, - sourceType: printType(destType), - destType: printType(srcType), - }) - ); - } - - return false; - } } // Handle the special case where the source is a Self type and the @@ -24499,7 +24405,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions category: p.category, name: p.name, isNameSynthesized: p.isNameSynthesized, - hasDefault: !!p.hasDefault, + hasDefault: p.hasDefault, + hasDeclaredType: p.hasDeclaredType, defaultValueExpression: p.defaultValueExpression, type: FunctionType.getEffectiveParameterType(effectiveSrcType, index), }); @@ -24530,9 +24437,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions remainingParams.forEach((param) => { FunctionType.addParameter(remainingFunction, param); }); - remainingFunction.details.paramSpec = srcParamSpec - ? (convertToInstance(srcParamSpec) as TypeVarType) - : undefined; + remainingFunction.details.paramSpec = srcParamSpec ? convertToInstance(srcParamSpec) : undefined; if ( !assignType( @@ -24551,8 +24456,8 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions remainingParams.length > 0 || !srcParamSpec || !assignType( - convertToInstance(destParamSpec) as TypeVarType, - convertToInstance(srcParamSpec) as TypeVarType, + convertToInstance(destParamSpec), + convertToInstance(srcParamSpec), /* diag */ undefined, destTypeVarContext, srcTypeVarContext, @@ -24665,15 +24570,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } recursionCount++; - // If this is a tuple with defined tuple type arguments, don't overwrite them. - if (assignedType.tupleTypeArguments) { - return undefined; - } - if ( assignedType.details.typeParameters.length > 0 && assignedType.typeArguments && - assignedType.typeArguments.length <= assignedType.details.typeParameters.length + assignedType.typeArguments.length <= assignedType.details.typeParameters.length && + !assignedType.tupleTypeArguments ) { const typeVarContext = new TypeVarContext(getTypeVarScopeId(assignedType)); populateTypeVarContextBasedOnExpectedType( @@ -25503,7 +25404,11 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const decl = getLastTypedDeclaredForSymbol(symbol); if (decl && decl.type === DeclarationType.Function) { - const functionFlags = getFunctionFlagsFromDecorators(evaluatorInterface, decl.node, true); + const functionFlags = getFunctionInfoFromDecorators( + evaluatorInterface, + decl.node, + true + ).flags; isAbstract = !!(functionFlags & FunctionTypeFlags.AbstractMethod); } else { // If a symbol is overridden by a non-function, it is no longer @@ -25536,20 +25441,51 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return methodList; } + function bindFunctionToClassOrObjectWithErrors( + baseType: ClassType | undefined, + memberType: FunctionType | OverloadedFunctionType, + memberClass?: ClassType, + errorNode?: ParseNode, + treatConstructorAsClassMember = false, + selfType?: ClassType | TypeVarType + ): FunctionType | OverloadedFunctionType | undefined { + const diag = errorNode ? new DiagnosticAddendum() : undefined; + + const result = bindFunctionToClassOrObject( + baseType, + memberType, + memberClass, + treatConstructorAsClassMember, + selfType, + diag + ); + + if (!result && errorNode && diag) { + addDiagnostic( + AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, + DiagnosticRule.reportGeneralTypeIssues, + diag.getString(), + errorNode + ); + } + + return result; + } + // If the memberType is an instance or class method, creates a new // version of the function that has the "self" or "cls" parameter bound - // to it. If treatAsClassMethod is true, the function is treated like a - // class method even if it's not marked as such. That's needed to - // special-case the __new__ magic method when it's invoked as a - // constructor (as opposed to by name). + // to it. If treatConstructorAsClassMember is true, the function is + // treated like a class method even if it's not marked as such. That's + // needed to special-case the __new__ magic method when it's invoked as + // a constructor (as opposed to by name). function bindFunctionToClassOrObject( baseType: ClassType | undefined, memberType: FunctionType | OverloadedFunctionType, memberClass?: ClassType, - errorNode?: ParseNode, - recursionCount = 0, treatConstructorAsClassMember = false, - firstParamType?: ClassType | TypeVarType + selfType?: ClassType | TypeVarType, + diag?: DiagnosticAddendum, + recursionCount = 0 ): FunctionType | OverloadedFunctionType | undefined { if (isFunction(memberType)) { // If the caller specified no base type, always strip the @@ -25564,16 +25500,17 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return memberType; } - const baseObj = isClassInstance(baseType) - ? baseType - : ClassType.cloneAsInstance(specializeClassType(baseType)); + const baseObj: ClassType = isInstantiableClass(baseType) + ? ClassType.cloneAsInstance(specializeClassType(baseType)) + : baseType; + return partiallySpecializeFunctionForBoundClassOrObject( baseType, memberType, - memberClass || ClassType.cloneAsInstantiable(baseObj), - errorNode, + memberClass ?? ClassType.cloneAsInstantiable(baseObj), + diag, recursionCount, - firstParamType || baseObj, + selfType ?? baseObj, /* stripFirstParam */ isClassInstance(baseType) ); } @@ -25583,22 +25520,15 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions (treatConstructorAsClassMember && FunctionType.isConstructorMethod(memberType)) ) { const baseClass = isInstantiableClass(baseType) ? baseType : ClassType.cloneAsInstantiable(baseType); - - // If the caller passed an object as the base type, we need to also - // convert the firstParamType to an instantiable. - const effectiveFirstParamType = firstParamType - ? isInstantiableClass(baseType) - ? firstParamType - : (convertToInstantiable(firstParamType) as ClassType | TypeVarType) - : baseClass; + const clsType = selfType ? (convertToInstantiable(selfType) as ClassType | TypeVarType) : undefined; return partiallySpecializeFunctionForBoundClassOrObject( - TypeBase.isInstance(baseType) ? ClassType.cloneAsInstantiable(baseType) : baseType, + baseClass, memberType, - memberClass || baseClass, - errorNode, + memberClass ?? baseClass, + diag, recursionCount, - effectiveFirstParamType, + clsType ?? baseClass, /* stripFirstParam */ true ); } @@ -25607,12 +25537,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions const baseClass = isInstantiableClass(baseType) ? baseType : ClassType.cloneAsInstantiable(baseType); return partiallySpecializeFunctionForBoundClassOrObject( - TypeBase.isInstance(baseType) ? ClassType.cloneAsInstantiable(baseType) : baseType, + baseClass, memberType, - memberClass || baseClass, - errorNode, + memberClass ?? baseClass, + diag, recursionCount, - /* effectiveFirstParamType */ undefined, + /* firstParamType */ undefined, /* stripFirstParam */ false ); } @@ -25625,10 +25555,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions baseType, overload, memberClass, - /* errorNode */ undefined, - recursionCount, treatConstructorAsClassMember, - firstParamType + selfType, + /* diag */ undefined, + recursionCount ); if (boundMethod) { @@ -25636,25 +25566,29 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } }); - if (OverloadedFunctionType.getOverloads(newOverloadType).length === 0) { - // No overloads matched, so rebind with the errorNode + const newOverloads = OverloadedFunctionType.getOverloads(newOverloadType); + if (newOverloads.length === 0) { + // No overloads matched, so rebind with the diag // to report the error(s) to the user. - if (errorNode) { + if (diag) { memberType.overloads.forEach((overload) => { bindFunctionToClassOrObject( baseType, overload, memberClass, - errorNode, - recursionCount, treatConstructorAsClassMember, - firstParamType + selfType, + diag, + recursionCount ); }); } + return undefined; - } else if (newOverloadType.overloads.length === 1) { - return newOverloadType.overloads[0]; + } + + if (newOverloads.length === 1) { + return newOverloads[0]; } return newOverloadType; @@ -25673,7 +25607,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions baseType: ClassType, memberType: FunctionType, memberClass: ClassType, - errorNode: ParseNode | undefined, + diag: DiagnosticAddendum | undefined, recursionCount: number, firstParamType: ClassType | TypeVarType | undefined, stripFirstParam = true @@ -25686,7 +25620,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions // Fill out the typeVarContext for the "self" or "cls" parameter. typeVarContext.addSolveForScope(getTypeVarScopeId(memberType)); - const diag = errorNode ? new DiagnosticAddendum() : undefined; if ( isTypeVar(memberTypeFirstParamType) && @@ -25710,7 +25643,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions !assignType( memberTypeFirstParamType, firstParamType, - diag, + diag?.createAddendum(), typeVarContext, /* srcTypeVarContext */ undefined, AssignTypeFlags.AllowUnspecifiedTypeArguments, @@ -25722,24 +25655,16 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions !memberTypeFirstParam.isNameSynthesized && memberTypeFirstParam.hasDeclaredType ) { - if (errorNode) { - const methodName = memberType.details.name || '(unnamed)'; - addDiagnostic( - AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, - DiagnosticRule.reportGeneralTypeIssues, + if (diag) { + diag.addMessage( Localizer.Diagnostic.bindTypeMismatch().format({ type: printType(baseType), - methodName: methodName, + methodName: memberType.details.name || '', paramName: memberTypeFirstParam.name, - }) + diag?.getString(), - errorNode + }) ); - } else { - // If there was no errorNode, we couldn't report the error, - // so we will instead return undefined and let the caller - // deal with the error. - return undefined; } + return undefined; } } } @@ -25818,6 +25743,25 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions return true; } + function isLegalImplicitTypeAliasType(type: Type) { + // We explicitly exclude "Unknown" and "...". + if (isUnknown(type) || isEllipsisType(type)) { + return false; + } + + // Look at the subtypes within the union. If any of them are not + // instantiable (other than "None" which is special-cased), it is + // not a legal type alias type. + let isLegal = true; + doForEachSubtype(type, (subtype) => { + if (!TypeBase.isInstantiable(subtype) && !isNoneInstance(subtype)) { + isLegal = false; + } + }); + + return isLegal; + } + function printObjectTypeForClass(type: ClassType): string { return TypePrinter.printObjectTypeForClass( type, @@ -26011,6 +25955,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions getGetterTypeFromProperty, getTypeOfArgument, markNamesAccessed, + expandPromotionTypes, makeTopLevelTypeVarsConcrete, mapSubtypesExpandTypeVars, isTypeSubsumedByOtherType, @@ -26028,7 +25973,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions getTypeOfObjectMember, getTypeOfClassMemberName, getBoundMethod, - getTypeOfMagicMethodReturn, + getTypeOfMagicMethodCall, bindFunctionToClassOrObject, getCallSignatureInfo, getAbstractMethods, @@ -26042,6 +25987,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions getTypedDictClassType, getTupleClassType, getObjectType, + getNoneType, getBuiltInObject, getTypingType, assignTypeArguments, diff --git a/packages/pyright-internal/src/analyzer/typeEvaluatorTypes.ts b/packages/pyright-internal/src/analyzer/typeEvaluatorTypes.ts index b3fb60427..d87b1d721 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluatorTypes.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluatorTypes.ts @@ -145,6 +145,10 @@ export const enum EvaluatorFlags { // Disallow a type alias defined with a "type" statement. DisallowPep695TypeAlias = 1 << 24, + // If evaluation is a TypeVarType that is a ParamSpec, do + // not convert it to its corresponding ParamSpec runtime object. + SkipConvertParamSpecToRuntimeObject = 1 << 25, + // Defaults used for evaluating the LHS of a call expression. CallBaseDefaults = DoNotSpecialize | DisallowPep695TypeAlias, @@ -167,7 +171,7 @@ export interface TypeResult { // as the class or object used to bind the member, but the // "super" call can specify a different class or object to // bind. - bindToType?: ClassType | TypeVarType | undefined; + bindToSelfType?: ClassType | TypeVarType | undefined; unpackedType?: Type | undefined; typeList?: TypeResultWithNode[] | undefined; @@ -180,12 +184,14 @@ export interface TypeResult { // Used for getTypeOfObjectMember to indicate that class // that declares the member. - classType?: ClassType | UnknownType; + classType?: ClassType | UnknownType | AnyType; // Variadic type arguments allow the shorthand "()" to // represent an empty tuple (i.e. Tuple[()]). isEmptyTupleShorthand?: boolean | undefined; + // Additional diagnostic information that explains why the expression + // type is incompatible with the expected type. expectedTypeDiagAddendum?: DiagnosticAddendum | undefined; // Is member a descriptor object that is asymmetric with respect @@ -201,12 +207,25 @@ export interface TypeResult { // If a call expression, which overloads were used to satisfy it? overloadsUsedForCall?: FunctionType[]; + + // For member access expressions, deprecation messages related to + // magic methods invoked via the member access + memberAccessDeprecationInfo?: MemberAccessDeprecationInfo; } export interface TypeResultWithNode extends TypeResult { node: ParseNode; } +// Describes deprecation details about a symbol accessed via a member +// access expression, perhaps through a property or descriptor accessor +// method. +export interface MemberAccessDeprecationInfo { + accessType: 'property' | 'descriptor'; + accessMethod: 'get' | 'set' | 'del'; + deprecationMessage: string; +} + export interface EvaluatorUsage { method: 'get' | 'set' | 'del'; @@ -368,11 +387,14 @@ export interface ClassMemberLookup { type: Type; isTypeIncomplete: boolean; + // True if access violates the type (used only for 'set' usage). + isSetTypeError: boolean; + // True if class member, false otherwise. isClassMember: boolean; // The class that declares the accessed member. - classType?: ClassType | UnknownType; + classType?: ClassType | UnknownType | AnyType; // True if the member is explicitly declared as ClassVar // within a Protocol. @@ -381,6 +403,9 @@ export interface ClassMemberLookup { // Is member a descriptor object that is asymmetric with respect // to __get__ and __set__ types? isAsymmetricAccessor: boolean; + + // Deprecation messages related to magic methods invoked via the member access. + memberAccessDeprecationInfo?: MemberAccessDeprecationInfo; } export interface PrintTypeOptions { @@ -430,11 +455,6 @@ export const enum MemberAccessFlags { // acts like a class method instead. TreatConstructorAsClassMethod = 1 << 5, - // By default, class member lookups start with the class itself - // and fall back on the metaclass if it's not found. This option - // skips the first check. - ConsiderMetaclassOnly = 1 << 6, - // If an attribute cannot be found when looking for instance // members, normally an attribute access override method // (__getattr__, etc.) may provide the missing attribute type. @@ -514,16 +534,19 @@ export interface TypeEvaluator { getTypeOfIterable: ( typeResult: TypeResult, isAsync: boolean, - errorNode: ExpressionNode | undefined + errorNode: ExpressionNode, + emitNotIterableError?: boolean ) => TypeResult | undefined; getTypeOfIterator: ( typeResult: TypeResult, isAsync: boolean, - errorNode: ExpressionNode | undefined + errorNode: ExpressionNode, + emitNotIterableError?: boolean ) => TypeResult | undefined; getGetterTypeFromProperty: (propertyClass: ClassType, inferTypeIfNeeded: boolean) => Type | undefined; getTypeOfArgument: (arg: FunctionArgument) => TypeResult; markNamesAccessed: (node: ParseNode, names: string[]) => void; + expandPromotionTypes: (node: ParseNode, type: Type) => Type; makeTopLevelTypeVarsConcrete: (type: Type, makeParamSpecsConcrete?: boolean) => Type; mapSubtypesExpandTypeVars: ( type: Type, @@ -556,18 +579,17 @@ export interface TypeEvaluator { memberName: string, usage?: EvaluatorUsage, diag?: DiagnosticAddendum | undefined, - memberAccessFlags?: MemberAccessFlags, - bindToType?: ClassType | TypeVarType + flags?: MemberAccessFlags, + selfType?: ClassType | TypeVarType ): TypeResult | undefined; getTypeOfClassMemberName: ( errorNode: ExpressionNode, classType: ClassType, - isAccessedThroughObject: boolean, memberName: string, usage: EvaluatorUsage, diag: DiagnosticAddendum | undefined, flags: MemberAccessFlags, - bindToType?: ClassType | TypeVarType + selfType?: ClassType | TypeVarType ) => ClassMemberLookup | undefined; getBoundMethod: ( classType: ClassType, @@ -575,10 +597,10 @@ export interface TypeEvaluator { recursionCount?: number, treatConstructorAsClassMember?: boolean ) => FunctionType | OverloadedFunctionType | undefined; - getTypeOfMagicMethodReturn: ( + getTypeOfMagicMethodCall: ( objType: Type, - args: TypeResult[], - magicMethodName: string, + methodName: string, + argList: TypeResult[], errorNode: ExpressionNode, inferenceContext: InferenceContext | undefined ) => Type | undefined; @@ -586,10 +608,10 @@ export interface TypeEvaluator { baseType: ClassType | undefined, memberType: FunctionType | OverloadedFunctionType, memberClass?: ClassType, - errorNode?: ParseNode, - recursionCount?: number, treatConstructorAsClassMember?: boolean, - firstParamType?: ClassType | TypeVarType + selfType?: ClassType | TypeVarType, + diag?: DiagnosticAddendum, + recursionCount?: number ) => FunctionType | OverloadedFunctionType | undefined; getCallSignatureInfo: (node: CallNode, activeIndex: number, activeOrFake: boolean) => CallSignatureInfo | undefined; getAbstractMethods: (classType: ClassType) => AbstractMethod[]; @@ -628,9 +650,10 @@ export interface TypeEvaluator { ) => void; assignClassToSelf: (destType: ClassType, srcType: ClassType) => boolean; getBuiltInObject: (node: ParseNode, name: string, typeArguments?: Type[]) => Type; - getTypedDictClassType: () => Type | undefined; - getTupleClassType: () => Type | undefined; - getObjectType: () => Type | undefined; + getTypedDictClassType: () => ClassType | undefined; + getTupleClassType: () => ClassType | undefined; + getObjectType: () => Type; + getNoneType: () => Type; getTypingType: (node: ParseNode, symbolName: string) => Type | undefined; inferReturnTypeIfNecessary: (type: Type) => void; inferTypeParameterVarianceForClass: (type: ClassType) => void; diff --git a/packages/pyright-internal/src/analyzer/typeGuards.ts b/packages/pyright-internal/src/analyzer/typeGuards.ts index 0b2ac4749..72d3d0203 100644 --- a/packages/pyright-internal/src/analyzer/typeGuards.ts +++ b/packages/pyright-internal/src/analyzer/typeGuards.ts @@ -9,6 +9,7 @@ * negative ("else") narrowing cases. */ +import { assert } from '../common/debug'; import { ArgumentCategory, AssignmentExpressionNode, @@ -43,15 +44,12 @@ import { isInstantiableClass, isModule, isNever, - isNoneInstance, - isNoneTypeClass, isOverloadedFunction, isSameWithoutLiteralValue, isTypeSame, isTypeVar, isUnpackedVariadicTypeVar, maxTypeRecursionCount, - NoneType, OverloadedFunctionType, TupleTypeArgument, Type, @@ -76,9 +74,13 @@ import { getSpecializedTupleType, getTypeCondition, getTypeVarScopeId, + isInstantiableMetaclass, isLiteralType, isLiteralTypeOrUnion, isMaybeDescriptorInstance, + isMetaclassInstance, + isNoneInstance, + isNoneTypeClass, isProperty, isTupleClass, isUnboundedTupleClass, @@ -86,6 +88,7 @@ import { lookUpObjectMember, mapSubtypes, specializeTupleClass, + specializeWithUnknown, transformPossibleRecursiveTypeAlias, } from './typeUtils'; import { TypeVarContext } from './typeVarContext'; @@ -407,9 +410,7 @@ export function getTypeNarrowingCallback( if ( equalsOrNotEqualsOperator && testExpression.leftExpression.nodeType === ParseNodeType.Call && - testExpression.leftExpression.arguments.length === 1 && - testExpression.rightExpression.nodeType === ParseNodeType.Number && - testExpression.rightExpression.isInteger + testExpression.leftExpression.arguments.length === 1 ) { const arg0Expr = testExpression.leftExpression.arguments[0].valueExpression; @@ -421,13 +422,20 @@ export function getTypeNarrowingCallback( const callType = callTypeResult.type; if (isFunction(callType) && callType.details.fullName === 'builtins.len') { - const tupleLength = testExpression.rightExpression.value; + const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression); + const rightType = rightTypeResult.type; + + if ( + isClassInstance(rightType) && + typeof rightType.literalValue === 'number' && + rightType.literalValue >= 0 + ) { + const tupleLength = rightType.literalValue; - if (typeof tupleLength === 'number') { return (type: Type) => { return { type: narrowTypeForTupleLength(evaluator, type, tupleLength, adjIsPositiveTest), - isIncomplete: !!callTypeResult.isIncomplete, + isIncomplete: !!callTypeResult.isIncomplete || !!rightTypeResult.isIncomplete, }; }; } @@ -1068,7 +1076,7 @@ function narrowTupleTypeForIsNone(evaluator: TypeEvaluator, type: Type, isPositi const typeOfEntry = evaluator.makeTopLevelTypeVarsConcrete(tupleType.tupleTypeArguments[indexValue].type); if (isPositiveTest) { - if (!evaluator.assignType(typeOfEntry, NoneType.createInstance())) { + if (!evaluator.assignType(typeOfEntry, evaluator.getNoneType())) { return undefined; } } else { @@ -1111,7 +1119,7 @@ function narrowTypeForIsNone(evaluator: TypeEvaluator, type: Type, isPositiveTes if (isClassInstance(subtype) && ClassType.isBuiltIn(subtype, 'object')) { resultIncludesNoneSubtype = true; return isPositiveTest - ? addConditionToType(NoneType.createInstance(), subtype.condition) + ? addConditionToType(evaluator.getNoneType(), subtype.condition) : adjustedSubtype; } @@ -1164,7 +1172,7 @@ function narrowTypeForIsEllipsis(evaluator: TypeEvaluator, type: Type, isPositiv // See if it's a match for object. if (isClassInstance(subtype) && ClassType.isBuiltIn(subtype, 'object')) { return isPositiveTest - ? addConditionToType(NoneType.createInstance(), subtype.condition) + ? addConditionToType(evaluator.getNoneType(), subtype.condition) : adjustedSubtype; } @@ -1184,9 +1192,9 @@ function narrowTypeForIsEllipsis(evaluator: TypeEvaluator, type: Type, isPositiv // that accepts a single class, and a more complex form that accepts a tuple // of classes (including arbitrarily-nested tuples). This method determines // which form and returns a list of classes or undefined. -function getIsInstanceClassTypes(argType: Type): (ClassType | TypeVarType | NoneType | FunctionType)[] | undefined { +function getIsInstanceClassTypes(argType: Type): (ClassType | TypeVarType | FunctionType)[] | undefined { let foundNonClassType = false; - const classTypeList: (ClassType | TypeVarType | NoneType | FunctionType)[] = []; + const classTypeList: (ClassType | TypeVarType | FunctionType)[] = []; // Create a helper function that returns a list of class types or // undefined if any of the types are not valid. @@ -1195,6 +1203,7 @@ function getIsInstanceClassTypes(argType: Type): (ClassType | TypeVarType | None if (isInstantiableClass(subtype) || (isTypeVar(subtype) && TypeBase.isInstantiable(subtype))) { classTypeList.push(subtype); } else if (isNoneTypeClass(subtype)) { + assert(isInstantiableClass(subtype)); classTypeList.push(subtype); } else if ( isFunction(subtype) && @@ -1234,28 +1243,32 @@ function getIsInstanceClassTypes(argType: Type): (ClassType | TypeVarType | None export function isIsinstanceFilterSuperclass( evaluator: TypeEvaluator, - varType: ClassType, + varType: Type, + concreteVarType: ClassType, filterType: Type, concreteFilterType: ClassType, isInstanceCheck: boolean ) { + if (isTypeVar(filterType)) { + return isTypeSame(convertToInstance(filterType), varType); + } + // If the filter type represents all possible subclasses // of a type, we can't make any statements about its superclass - // relationship with varType. + // relationship with concreteVarType. if (concreteFilterType.includeSubclasses) { return false; } - if (isTypeVar(filterType)) { - return false; - } - - if (ClassType.isDerivedFrom(varType, concreteFilterType)) { + if (ClassType.isDerivedFrom(concreteVarType, concreteFilterType)) { return true; } if (isInstanceCheck) { - if (ClassType.isProtocolClass(concreteFilterType) && evaluator.assignType(concreteFilterType, varType)) { + if ( + ClassType.isProtocolClass(concreteFilterType) && + evaluator.assignType(concreteFilterType, concreteVarType) + ) { return true; } } @@ -1263,7 +1276,7 @@ export function isIsinstanceFilterSuperclass( // Handle the special case where the variable type is a TypedDict and // we're filtering against 'dict'. TypedDict isn't derived from dict, // but at runtime, isinstance returns True. - if (ClassType.isBuiltIn(concreteFilterType, 'dict') && ClassType.isTypedDictClass(varType)) { + if (ClassType.isBuiltIn(concreteFilterType, 'dict') && ClassType.isTypedDictClass(concreteVarType)) { return true; } @@ -1273,7 +1286,6 @@ export function isIsinstanceFilterSuperclass( export function isIsinstanceFilterSubclass( evaluator: TypeEvaluator, varType: ClassType, - filterType: Type, concreteFilterType: ClassType, isInstanceCheck: boolean ) { @@ -1298,23 +1310,25 @@ export function isIsinstanceFilterSubclass( function narrowTypeForIsInstance( evaluator: TypeEvaluator, type: Type, - classTypeList: (ClassType | TypeVarType | NoneType | FunctionType)[], + classTypeList: (ClassType | TypeVarType | FunctionType)[], isInstanceCheck: boolean, isPositiveTest: boolean, allowIntersections: boolean, errorNode: ExpressionNode ): Type { - const expandedTypes = mapSubtypes(type, (subtype) => { + let expandedTypes = mapSubtypes(type, (subtype) => { return transformPossibleRecursiveTypeAlias(subtype); }); + expandedTypes = evaluator.expandPromotionTypes(errorNode, type); + // Filters the varType by the parameters of the isinstance // and returns the list of types the varType could be after // applying the filter. const filterClassType = ( - varType: ClassType, - unexpandedType: Type, - constraints: TypeCondition[] | undefined, + varType: Type, + concreteVarType: ClassType, + conditions: TypeCondition[] | undefined, negativeFallbackType: Type ): Type[] => { const filteredTypes: Type[] = []; @@ -1323,20 +1337,33 @@ function narrowTypeForIsInstance( let isClassRelationshipIndeterminate = false; for (const filterType of classTypeList) { - const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType); + let concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType); if (isInstantiableClass(concreteFilterType)) { + // If the class was implicitly specialized (e.g. because its type + // parameters have default values), replace the default type arguments + // with Unknown. + if (concreteFilterType.typeArguments && !concreteFilterType.isTypeArgumentExplicit) { + concreteFilterType = specializeWithUnknown( + ClassType.cloneForSpecialization( + concreteFilterType, + /* typeArguments */ undefined, + /* isTypeArgumentExplicit */ false + ) + ); + } + const filterIsSuperclass = isIsinstanceFilterSuperclass( evaluator, varType, + concreteVarType, filterType, concreteFilterType, isInstanceCheck ); const filterIsSubclass = isIsinstanceFilterSubclass( evaluator, - varType, - filterType, + concreteVarType, concreteFilterType, isInstanceCheck ); @@ -1353,7 +1380,7 @@ function narrowTypeForIsInstance( if ( filterIsSubclass && filterIsSuperclass && - !ClassType.isSameGenericClass(varType, concreteFilterType) + !ClassType.isSameGenericClass(concreteVarType, concreteFilterType) ) { isClassRelationshipIndeterminate = true; } @@ -1362,12 +1389,12 @@ function narrowTypeForIsInstance( if (filterIsSuperclass) { // If the variable type is a subclass of the isinstance filter, // we haven't learned anything new about the variable type. - filteredTypes.push(addConditionToType(varType, constraints)); + filteredTypes.push(addConditionToType(concreteVarType, conditions)); } else if (filterIsSubclass) { if ( evaluator.assignType( - varType, - filterType, + concreteVarType, + concreteFilterType, /* diag */ undefined, /* destTypeVarContext */ undefined, /* srcTypeVarContext */ undefined, @@ -1397,7 +1424,7 @@ function narrowTypeForIsInstance( populateTypeVarContextBasedOnExpectedType( evaluator, unspecializedFilterType, - varType, + concreteVarType, typeVarContext, /* liveTypeVarScopes */ undefined, errorNode.start @@ -1412,11 +1439,11 @@ function narrowTypeForIsInstance( } } - filteredTypes.push(addConditionToType(specializedFilterType, constraints)); + filteredTypes.push(addConditionToType(specializedFilterType, conditions)); } } else if ( allowIntersections && - !ClassType.isFinal(varType) && + !ClassType.isFinal(concreteVarType) && !ClassType.isFinal(concreteFilterType) ) { // The two types appear to have no relation. It's possible that the @@ -1424,11 +1451,11 @@ function narrowTypeForIsInstance( // be a mix-in class used with the other. In this case, we'll // synthesize a new class type that represents an intersection of // the two types. - const className = ``; + const className = ``; const fileInfo = getFileInfo(errorNode); // The effective metaclass of the intersection is the narrower of the two metaclasses. - let effectiveMetaclass = varType.details.effectiveMetaclass; + let effectiveMetaclass = concreteVarType.details.effectiveMetaclass; if (concreteFilterType.details.effectiveMetaclass) { if ( !effectiveMetaclass || @@ -1447,21 +1474,24 @@ function narrowTypeForIsInstance( ParseTreeUtils.getTypeSourceId(errorNode), /* declaredMetaclass */ undefined, effectiveMetaclass, - varType.details.docString + concreteVarType.details.docString ); - newClassType.details.baseClasses = [ClassType.cloneAsInstantiable(varType), concreteFilterType]; + newClassType.details.baseClasses = [ + ClassType.cloneAsInstantiable(concreteVarType), + concreteFilterType, + ]; computeMroLinearization(newClassType); newClassType = addConditionToType(newClassType, concreteFilterType.condition) as ClassType; if ( - isTypeVar(unexpandedType) && - !unexpandedType.details.isParamSpec && - unexpandedType.details.constraints.length === 0 + isTypeVar(varType) && + !varType.details.isParamSpec && + varType.details.constraints.length === 0 ) { newClassType = addConditionToType(newClassType, [ { - typeVarName: TypeVarType.getNameWithScope(unexpandedType), + typeVarName: TypeVarType.getNameWithScope(varType), constraintIndex: 0, isConstrainedTypeVar: false, }, @@ -1470,10 +1500,10 @@ function narrowTypeForIsInstance( let newClassInstanceType = ClassType.cloneAsInstance(newClassType); - if (varType.condition) { + if (concreteVarType.condition) { newClassInstanceType = addConditionToType( newClassInstanceType, - varType.condition + concreteVarType.condition ) as ClassType; } @@ -1488,12 +1518,14 @@ function narrowTypeForIsInstance( } else if (isTypeVar(filterType) && TypeBase.isInstantiable(filterType)) { // Handle the case where the filter type is Type[T] and the unexpanded // subtype is some instance type, possibly T. - if (isInstanceCheck && TypeBase.isInstance(unexpandedType)) { - if (isTypeVar(unexpandedType) && isTypeSame(convertToInstance(filterType), unexpandedType)) { + if (isInstanceCheck && TypeBase.isInstance(varType)) { + if (isTypeVar(varType) && isTypeSame(convertToInstance(filterType), varType)) { // If the unexpanded subtype is T, we can definitively filter // in both the positive and negative cases. if (isPositiveTest) { - filteredTypes.push(unexpandedType); + filteredTypes.push(varType); + } else { + foundSuperclass = true; } } else { if (isPositiveTest) { @@ -1501,20 +1533,20 @@ function narrowTypeForIsInstance( } else { // If the unexpanded subtype is some other instance, we can't // filter anything because it might be an instance. - filteredTypes.push(unexpandedType); + filteredTypes.push(varType); isClassRelationshipIndeterminate = true; } } - } else if (!isInstanceCheck && TypeBase.isInstantiable(unexpandedType)) { - if (isTypeVar(unexpandedType) && isTypeSame(filterType, unexpandedType)) { + } else if (!isInstanceCheck && TypeBase.isInstantiable(varType)) { + if (isTypeVar(varType) && isTypeSame(filterType, varType)) { if (isPositiveTest) { - filteredTypes.push(unexpandedType); + filteredTypes.push(varType); } } else { if (isPositiveTest) { filteredTypes.push(filterType); } else { - filteredTypes.push(unexpandedType); + filteredTypes.push(varType); isClassRelationshipIndeterminate = true; } } @@ -1524,12 +1556,12 @@ function narrowTypeForIsInstance( if (isInstanceCheck) { let isCallable = false; - if (isClass(varType)) { - if (TypeBase.isInstantiable(unexpandedType)) { + if (isClass(concreteVarType)) { + if (TypeBase.isInstantiable(varType)) { isCallable = true; } else { isCallable = !!lookUpClassMember( - varType, + concreteVarType, '__call__', ClassMemberLookupFlags.SkipInstanceVariables ); @@ -1538,10 +1570,14 @@ function narrowTypeForIsInstance( if (isCallable) { if (isPositiveTest) { - filteredTypes.push(unexpandedType); + filteredTypes.push(varType); } else { foundSuperclass = true; } + } else if (evaluator.assignType(concreteVarType, filterType)) { + if (isPositiveTest) { + filteredTypes.push(filterType); + } } } } @@ -1568,6 +1604,61 @@ function narrowTypeForIsInstance( return filteredTypes.map((t) => convertToInstance(t)); }; + // Filters the metaclassType (which is assumed to be a metaclass instance) + // by the classTypeList and returns the list of types the varType could be + // after applying the filter. + const filterMetaclassType = (metaclassType: ClassType, negativeFallbackType: Type): Type[] => { + const filteredTypes: Type[] = []; + + let foundPositiveMatch = false; + let isMatchIndeterminate = false; + + for (const filterType of classTypeList) { + const concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType); + + if (isInstantiableClass(concreteFilterType)) { + const filterMetaclass = concreteFilterType.details.effectiveMetaclass; + + if (filterMetaclass && isInstantiableClass(filterMetaclass)) { + const isMetaclassOverlap = evaluator.assignType( + metaclassType, + ClassType.cloneAsInstance(filterMetaclass) + ); + + if (isMetaclassOverlap) { + if (isPositiveTest) { + filteredTypes.push(filterType); + foundPositiveMatch = true; + } else if (!isTypeSame(metaclassType, filterMetaclass) || filterMetaclass.includeSubclasses) { + filteredTypes.push(metaclassType); + isMatchIndeterminate = true; + } + } + } else { + filteredTypes.push(metaclassType); + isMatchIndeterminate = true; + } + } else { + filteredTypes.push(metaclassType); + isMatchIndeterminate = true; + } + } + + // In the negative case, if one or more of the filters + // always match the type in the positive case, then there's nothing + // left after the filter is applied. + if (!isPositiveTest) { + if (!foundPositiveMatch || isMatchIndeterminate) { + filteredTypes.push(negativeFallbackType); + } + } + + // We perform a double conversion from instance to instantiable + // here to make sure that the includeSubclasses flag is cleared + // if it's a class. + return filteredTypes.map((t) => (isInstantiableClass(t) ? convertToInstantiable(convertToInstance(t)) : t)); + }; + const filterFunctionType = (varType: FunctionType | OverloadedFunctionType, unexpandedType: Type): Type[] => { const filteredTypes: Type[] = []; @@ -1612,6 +1703,14 @@ function narrowTypeForIsInstance( return filteredTypes; }; + const classListContainsNoneType = () => + classTypeList.some((t) => { + if (isNoneTypeClass(t)) { + return true; + } + return isInstantiableClass(t) && ClassType.isBuiltIn(t, 'NoneType'); + }); + const anyOrUnknownSubstitutions: Type[] = []; const anyOrUnknown: Type[] = []; @@ -1625,7 +1724,7 @@ function narrowTypeForIsInstance( // on a constrained TypeVar that they want to filter based on its constrained // parts. const negativeFallback = getTypeCondition(subtype) ? subtype : unexpandedSubtype; - const isSubtypeTypeObject = isClassInstance(subtype) && ClassType.isBuiltIn(subtype, 'type'); + const isSubtypeMetaclass = isMetaclassInstance(subtype); if (isPositiveTest && isAnyOrUnknown(subtype)) { // If this is a positive test and the effective type is Any or @@ -1652,18 +1751,7 @@ function narrowTypeForIsInstance( if (isInstanceCheck) { if (isNoneInstance(subtype)) { - const containsNoneType = classTypeList.some((t) => { - if (isNoneTypeClass(t)) { - return true; - } - return isInstantiableClass(t) && ClassType.isBuiltIn(t, 'NoneType'); - }); - - if (isPositiveTest) { - return containsNoneType ? subtype : undefined; - } else { - return containsNoneType ? undefined : subtype; - } + return classListContainsNoneType() === isPositiveTest ? subtype : undefined; } if (isModule(subtype) || (isClassInstance(subtype) && ClassType.isBuiltIn(subtype, 'ModuleType'))) { @@ -1683,11 +1771,11 @@ function narrowTypeForIsInstance( } } - if (isClassInstance(subtype) && !isSubtypeTypeObject) { + if (isClassInstance(subtype) && !isSubtypeMetaclass) { return combineTypes( filterClassType( - ClassType.cloneAsInstantiable(subtype), convertToInstance(unexpandedSubtype), + ClassType.cloneAsInstantiable(subtype), getTypeCondition(subtype), negativeFallback ) @@ -1698,31 +1786,37 @@ function narrowTypeForIsInstance( return combineTypes(filterFunctionType(subtype, convertToInstance(unexpandedSubtype))); } - if (isInstantiableClass(subtype) || isSubtypeTypeObject) { - // Handle the special case of isinstance(x, type). - const includesTypeType = classTypeList.some( - (classType) => isInstantiableClass(classType) && ClassType.isBuiltIn(classType, 'type') - ); + if (isInstantiableClass(subtype) || isSubtypeMetaclass) { + // Handle the special case of isinstance(x, metaclass). + const includesMetaclassType = classTypeList.some((classType) => isInstantiableMetaclass(classType)); if (isPositiveTest) { - return includesTypeType ? negativeFallback : undefined; + return includesMetaclassType ? negativeFallback : undefined; } else { - return includesTypeType ? undefined : negativeFallback; + return includesMetaclassType ? undefined : negativeFallback; } } } else { - if (isInstantiableClass(subtype)) { - return combineTypes( - filterClassType(subtype, unexpandedSubtype, getTypeCondition(subtype), negativeFallback) - ); + if (isNoneTypeClass(subtype)) { + return classListContainsNoneType() === isPositiveTest ? subtype : undefined; + } + + if (isClass(subtype)) { + if (isInstantiableClass(subtype)) { + return combineTypes( + filterClassType(unexpandedSubtype, subtype, getTypeCondition(subtype), negativeFallback) + ); + } else if (isMetaclassInstance(subtype)) { + return combineTypes(filterMetaclassType(subtype, negativeFallback)); + } } - if (isSubtypeTypeObject) { + if (isSubtypeMetaclass) { const objectType = evaluator.getBuiltInObject(errorNode, 'object'); if (objectType && isClassInstance(objectType)) { return combineTypes( filterClassType( - ClassType.cloneAsInstantiable(objectType), convertToInstantiable(unexpandedSubtype), + ClassType.cloneAsInstantiable(objectType), getTypeCondition(subtype), negativeFallback ) @@ -2210,10 +2304,14 @@ function narrowTypeForTypeIs(evaluator: TypeEvaluator, type: Type, classType: Cl if (ClassType.isSameGenericClass(subtype, classType)) { return subtype; } + return addConditionToType(ClassType.cloneAsInstance(classType), subtype.condition); } - return undefined; - } else { + + if (!classType.includeSubclasses) { + return undefined; + } + } else if (!classType.includeSubclasses) { // If the class if marked final and it matches, then // we can eliminate it in the negative case. if (matches && ClassType.isFinal(subtype)) { @@ -2265,6 +2363,7 @@ function narrowTypeForClassComparison( !ClassType.isSameGenericClass(concreteSubtype, classType) && !isIsinstanceFilterSuperclass( evaluator, + subtype, concreteSubtype, classType, classType, @@ -2300,7 +2399,14 @@ function narrowTypeForLiteralComparison( ): Type { return mapSubtypes(referenceType, (subtype) => { subtype = evaluator.makeTopLevelTypeVarsConcrete(subtype); - if (isClassInstance(subtype) && ClassType.isSameGenericClass(literalType, subtype)) { + + if (isAnyOrUnknown(subtype)) { + if (isPositiveTest) { + return literalType; + } + + return subtype; + } else if (isClassInstance(subtype) && ClassType.isSameGenericClass(literalType, subtype)) { if (subtype.literalValue !== undefined) { const literalValueMatches = ClassType.isLiteralValueSame(subtype, literalType); if ((literalValueMatches && !isPositiveTest) || (!literalValueMatches && isPositiveTest)) { @@ -2379,12 +2485,15 @@ function narrowTypeForCallable( return isPositiveTest ? subtype : undefined; } - case TypeCategory.None: case TypeCategory.Module: { return isPositiveTest ? undefined : subtype; } case TypeCategory.Class: { + if (isNoneInstance(subtype)) { + return isPositiveTest ? undefined : subtype; + } + if (TypeBase.isInstantiable(subtype)) { return isPositiveTest ? subtype : undefined; } diff --git a/packages/pyright-internal/src/analyzer/typePrinter.ts b/packages/pyright-internal/src/analyzer/typePrinter.ts index 8e159ed2c..5579cdc75 100644 --- a/packages/pyright-internal/src/analyzer/typePrinter.ts +++ b/packages/pyright-internal/src/analyzer/typePrinter.ts @@ -20,7 +20,6 @@ import { isClassInstance, isInstantiableClass, isNever, - isNoneInstance, isParamSpec, isTypeSame, isTypeVar, @@ -28,15 +27,15 @@ import { isUnpacked, isVariadicTypeVar, maxTypeRecursionCount, - removeNoneFromUnion, TupleTypeArgument, Type, TypeBase, TypeCategory, + TypeFlags, TypeVarType, Variance, } from './types'; -import { convertToInstance, doForEachSubtype, isTupleClass } from './typeUtils'; +import { convertToInstance, doForEachSubtype, isNoneInstance, isTupleClass, removeNoneFromUnion } from './typeUtils'; const singleTickRegEx = /'/g; const escapedDoubleQuoteRegEx = /\\"/g; @@ -501,9 +500,14 @@ function printTypeInternal( for (const sourceSubtype of typeAliasSource.subtypes) { let unionSubtypeIndex = 0; let foundMatch = false; + const sourceSubtypeInstance = convertToInstance(sourceSubtype); for (const unionSubtype of type.subtypes) { - if (isTypeSame(sourceSubtype, unionSubtype, { ignoreTypeFlags: true })) { + if ( + isTypeSame(sourceSubtypeInstance, unionSubtype, { + typeFlagsToHonor: TypeFlags.Instance | TypeFlags.Instantiable, + }) + ) { if (!subtypeHandledSet.has(unionSubtypeIndex)) { allSubtypesPreviouslyHandled = false; } @@ -709,12 +713,6 @@ function printTypeInternal( return typeVarName; } - case TypeCategory.None: { - return `${ - TypeBase.isInstantiable(type) ? `${_printNestedInstantiable(type, 'None')}` : 'None' - }${getConditionalIndicator(type)}`; - } - case TypeCategory.Never: { return type.isNoReturn ? 'NoReturn' : 'Never'; } @@ -848,6 +846,11 @@ function printObjectTypeForClassInternal( (printTypeFlags & PrintTypeFlags.UseFullyQualifiedNames) !== 0 ? type.details.fullName : type.details.name; } + // Special-case NoneType to convert it to None. + if (ClassType.isBuiltIn(type, 'NoneType')) { + objName = 'None'; + } + // Use the fully-qualified name if the name isn't unique. if (!uniqueNameMap.isUnique(objName)) { objName = type.details.fullName; diff --git a/packages/pyright-internal/src/analyzer/typeUtils.ts b/packages/pyright-internal/src/analyzer/typeUtils.ts index 47c6ffe30..94ba81412 100644 --- a/packages/pyright-internal/src/analyzer/typeUtils.ts +++ b/packages/pyright-internal/src/analyzer/typeUtils.ts @@ -30,7 +30,6 @@ import { isInstantiableClass, isKeywordOnlySeparator, isNever, - isNoneInstance, isOverloadedFunction, isParamSpec, isPositionOnlySeparator, @@ -44,8 +43,8 @@ import { maxTypeRecursionCount, ModuleType, NeverType, - NoneType, OverloadedFunctionType, + removeFromUnion, SignatureWithOffsets, SpecializedFunctionTypes, TupleTypeArgument, @@ -71,7 +70,7 @@ export interface ClassMember { symbol: Symbol; // Partially-specialized class that contains the class member - classType: ClassType | UnknownType; + classType: ClassType | UnknownType | AnyType; // True if it is an instance or class member; it can be both a class and // an instance member in cases where a class variable is overridden @@ -221,6 +220,18 @@ export interface InferenceContext { signatureTracker?: UniqueSignatureTracker; } +export interface RequiresSpecializationOptions { + // Ignore pseudo-generic classes (those with PseudoGenericClass flag set) + // when determining whether the type requires specialization? + ignorePseudoGeneric?: boolean; + + // Ignore Self type? + ignoreSelf?: boolean; + + // Ignore classes whose isTypeArgumentExplicit flag is false? + ignoreImplicitTypeArgs?: boolean; +} + // Tracks whether a function signature has been seen before within // an expression. For example, in the expression "foo(foo, foo)", the // signature for "foo" will be seen three times at three different @@ -281,6 +292,20 @@ export function isOptionalType(type: Type): boolean { return false; } +export function isNoneInstance(type: Type): boolean { + return isClassInstance(type) && ClassType.isBuiltIn(type, 'NoneType'); +} + +export function isNoneTypeClass(type: Type): boolean { + return isInstantiableClass(type) && ClassType.isBuiltIn(type, 'NoneType'); +} + +// If the type is a union, remove an "None" type from the union, +// returning only the known types. +export function removeNoneFromUnion(type: Type): Type { + return removeFromUnion(type, (t: Type) => isNoneInstance(t)); +} + export function isIncompleteUnknown(type: Type): boolean { return isUnknown(type) && type.isIncomplete; } @@ -398,6 +423,68 @@ export function mapSubtypes(type: Type, callback: (type: Type) => Type | undefin return transformedSubtype; } +// The code flow engine uses a special form of the UnknownType (with the +// isIncomplete flag set) to distinguish between an unknown that was generated +// in a loop because it was temporarily incomplete versus an unknown that is +// permanently incomplete. Once an unknown appears within a loop, it is often +// propagated to other types during code flow analysis. We want to remove these +// incomplete unknowns if we find that they are union'ed with other types. +export function cleanIncompleteUnknown(type: Type, recursionCount = 0): Type { + if (recursionCount >= maxTypeRecursionCount) { + return type; + } + recursionCount++; + + const result = mapSubtypes(type, (subtype) => { + // If it's an incomplete unknown, eliminate it. + if (isUnknown(subtype) && subtype.isIncomplete) { + return undefined; + } + + if (isClass(subtype) && subtype.typeArguments) { + let typeChanged = false; + + if (subtype.tupleTypeArguments) { + const updatedTupleTypeArgs = subtype.tupleTypeArguments.map((tupleTypeArg) => { + const newTypeArg = cleanIncompleteUnknown(tupleTypeArg.type, recursionCount); + if (newTypeArg !== tupleTypeArg.type) { + typeChanged = true; + } + return { type: newTypeArg, isUnbounded: tupleTypeArg.isUnbounded }; + }); + + if (typeChanged) { + return specializeTupleClass( + subtype, + updatedTupleTypeArgs, + !!subtype.isTypeArgumentExplicit, + !!subtype.isUnpacked + ); + } + } else { + const updatedTypeArgs = subtype.typeArguments.map((typeArg) => { + const newTypeArg = cleanIncompleteUnknown(typeArg, recursionCount); + if (newTypeArg !== typeArg) { + typeChanged = true; + } + return newTypeArg; + }); + + if (typeChanged) { + return ClassType.cloneForSpecialization(subtype, updatedTypeArgs, !!subtype.isTypeArgumentExplicit); + } + } + } + + // TODO - this doesn't currently handle function types. + + return subtype; + }); + + // If we eliminated everything, don't return a Never. + return isNever(result) ? type : result; +} + // Sorts types into a deterministic order. export function sortTypes(types: Type[]): Type[] { return types.slice(0).sort((a, b) => { @@ -419,7 +506,6 @@ function compareTypes(a: Type, b: Type, recursionCount = 0): number { case TypeCategory.Unbound: case TypeCategory.Unknown: case TypeCategory.Any: - case TypeCategory.None: case TypeCategory.Never: case TypeCategory.Union: { return 0; @@ -506,6 +592,13 @@ function compareTypes(a: Type, b: Type, recursionCount = 0): number { return 1; } + // Always sort NoneType at the end. + if (ClassType.isBuiltIn(a, 'NoneType')) { + return 1; + } else if (ClassType.isBuiltIn(bClass, 'NoneType')) { + return -1; + } + // Sort non-generics before generics. if (a.details.typeParameters.length > 0 || isTupleClass(a)) { if (bClass.details.typeParameters.length === 0) { @@ -577,6 +670,19 @@ export function doForEachSubtype( } } +export function doForEachSignature( + type: FunctionType | OverloadedFunctionType, + callback: (type: FunctionType, index: number) => void +) { + if (isFunction(type)) { + callback(type, 0); + } else { + OverloadedFunctionType.getOverloads(type).forEach((overload, index) => { + callback(overload, index); + }); + } +} + // Determines if all of the types in the array are the same. export function areTypesSame(types: Type[], options: TypeSameOptions): boolean { if (types.length < 2) { @@ -653,9 +759,6 @@ export function getFullNameOfType(type: Type): string | undefined { case TypeCategory.Unknown: return 'typing.Any'; - case TypeCategory.None: - return 'builtins.None'; - case TypeCategory.Class: return type.details.fullName; @@ -686,7 +789,6 @@ export function addConditionToType(type: Type, condition: TypeCondition[] | unde case TypeCategory.TypeVar: return type; - case TypeCategory.None: case TypeCategory.Function: return TypeBase.cloneForCondition(type, TypeCondition.combine(type.condition, condition)); @@ -715,7 +817,6 @@ export function getTypeCondition(type: Type): TypeCondition[] | undefined { case TypeCategory.Union: return undefined; - case TypeCategory.None: case TypeCategory.Class: case TypeCategory.Function: return type.condition; @@ -845,12 +946,59 @@ export function specializeWithDefaultTypeArgs(type: ClassType): ClassType { return ClassType.cloneForSpecialization( type, - type.details.typeParameters.map((param) => param.details.defaultType ?? UnknownType.create()), + type.details.typeParameters.map((param) => param.details.defaultType ?? getUnknownTypeForTypeVar(param)), /* isTypeArgumentExplicit */ false, - /* includeSubclasses */ true + /* includeSubclasses */ type.includeSubclasses ); } +// Specializes the class with "Unknown" type args (or the equivalent for ParamSpecs +// or TypeVarTuples). +export function specializeWithUnknown(type: ClassType): ClassType { + if (type.details.typeParameters.length === 0) { + return type; + } + + return ClassType.cloneForSpecialization( + type, + type.details.typeParameters.map((param) => getUnknownTypeForTypeVar(param)), + /* isTypeArgumentExplicit */ false, + /* includeSubclasses */ type.includeSubclasses + ); +} + +// Returns "Unknown" for simple TypeVars or the equivalent for a ParamSpec. +export function getUnknownTypeForTypeVar(typeVar: TypeVarType): Type { + if (typeVar.details.isParamSpec) { + return getUnknownTypeForParamSpec(); + } + + return UnknownType.create(); +} + +// Returns the "Unknown" equivalent for a ParamSpec. +export function getUnknownTypeForParamSpec(): FunctionType { + const newFunction = FunctionType.createInstance( + '', + '', + '', + FunctionTypeFlags.ParamSpecValue | FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck + ); + FunctionType.addDefaultParameters(newFunction); + return newFunction; +} + +// If the class is generic and not already specialized, this function +// "self specializes" the class, filling in its own type parameters +// as type arguments. +export function selfSpecializeClass(type: ClassType): ClassType { + if (type.details.typeParameters.length === 0 || type.typeArguments) { + return type; + } + + return ClassType.cloneForSpecialization(type, type.details.typeParameters, /* isTypeArgumentExplicit */ true); +} + // Determines whether the type derives from tuple. If so, it returns // the specialized tuple type. export function getSpecializedTupleType(type: Type): ClassType | undefined { @@ -1238,6 +1386,11 @@ export function validateTypeVarDefault( } } +export function replaceTypeVarsWithAny(type: Type): Type { + const transformer = new TypeVarAnyReplacer(); + return transformer.apply(type, 0); +} + // During bidirectional type inference for constructors, an "expected type" // is used to prepopulate the type var map. This is problematic when the // expected type uses TypeVars that are not part of the context of the @@ -1403,11 +1556,11 @@ export function* getClassMemberIterator( // The class derives from an unknown type, so all bets are off // when trying to find a member. Return an unknown symbol. const cm: ClassMember = { - symbol: Symbol.createWithType(SymbolFlags.None, UnknownType.create()), + symbol: Symbol.createWithType(SymbolFlags.None, mroClass), isInstanceMember: false, isClassMember: true, isClassVar: false, - classType: UnknownType.create(), + classType: isAnyOrUnknown(mroClass) ? mroClass : UnknownType.create(), isTypeDeclared: false, skippedUndeclaredType: false, }; @@ -1486,13 +1639,13 @@ export function* getClassMemberIterator( } } else if (isAnyOrUnknown(classType)) { // The class derives from an unknown type, so all bets are off - // when trying to find a member. Return an unknown symbol. + // when trying to find a member. Return an Any or Unknown symbol. const cm: ClassMember = { - symbol: Symbol.createWithType(SymbolFlags.None, UnknownType.create()), + symbol: Symbol.createWithType(SymbolFlags.None, classType), isInstanceMember: false, isClassMember: true, isClassVar: false, - classType: UnknownType.create(), + classType, isTypeDeclared: false, skippedUndeclaredType: false, }; @@ -1846,14 +1999,10 @@ export function setTypeArgumentsRecursive( if (destType.details.paramSpec) { // Fill in an empty signature for a ParamSpec. if (!typeVarContext.getPrimarySignature().getTypeVar(destType.details.paramSpec)) { - const newFunction = FunctionType.createInstance( - '', - '', - '', - FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck | FunctionTypeFlags.ParamSpecValue + typeVarContext.setTypeVarType( + destType.details.paramSpec, + getUnknownTypeForTypeVar(destType.details.paramSpec) ); - FunctionType.addDefaultParameters(newFunction); - typeVarContext.setTypeVarType(destType.details.paramSpec, newFunction); } } break; @@ -2082,6 +2231,9 @@ export function isEffectivelyInstantiable(type: Type): boolean { return false; } +export function convertToInstance(type: ClassType, includeSubclasses?: boolean): ClassType; +export function convertToInstance(type: TypeVarType, includeSubclasses?: boolean): TypeVarType; +export function convertToInstance(type: Type, includeSubclasses?: boolean): Type; export function convertToInstance(type: Type, includeSubclasses = true): Type { // See if we've already performed this conversion and cached it. if (type.cached?.instanceType && includeSubclasses) { @@ -2106,18 +2258,9 @@ export function convertToInstance(type: Type, includeSubclasses = true): Type { } } - // Handle NoneType as a special case. - if (TypeBase.isInstantiable(subtype) && ClassType.isBuiltIn(subtype, 'NoneType')) { - return NoneType.createInstance(); - } - return ClassType.cloneAsInstance(subtype, includeSubclasses); } - case TypeCategory.None: { - return NoneType.createInstance(); - } - case TypeCategory.Function: { if (TypeBase.isInstantiable(subtype)) { return FunctionType.cloneAsInstance(subtype); @@ -2131,6 +2274,10 @@ export function convertToInstance(type: Type, includeSubclasses = true): Type { } break; } + + case TypeCategory.Any: { + return AnyType.convertToInstance(subtype); + } } return subtype; @@ -2172,10 +2319,6 @@ export function convertToInstantiable(type: Type, includeSubclasses = true): Typ return ClassType.cloneAsInstantiable(subtype, includeSubclasses); } - case TypeCategory.None: { - return NoneType.createType(); - } - case TypeCategory.Function: { return FunctionType.cloneAsInstantiable(subtype); } @@ -2579,7 +2722,10 @@ export function removeParamSpecVariadicsFromFunction(type: FunctionType): Functi return type; } - return FunctionType.cloneRemoveParamSpecVariadics(type, argsParam.type); + return FunctionType.cloneRemoveParamSpecVariadics( + type, + TypeVarType.cloneForParamSpecAccess(argsParam.type, /* access */ undefined) + ); } function _expandVariadicUnpackedUnion(type: Type) { @@ -2651,8 +2797,7 @@ export function requiresTypeArguments(classType: ClassType) { export function requiresSpecialization( type: Type, - ignorePseudoGeneric = false, - ignoreSelf = false, + options?: RequiresSpecializationOptions, recursionCount = 0 ): boolean { if (recursionCount > maxTypeRecursionCount) { @@ -2661,12 +2806,12 @@ export function requiresSpecialization( recursionCount++; // Is the answer cached? - const canUseCache = !ignorePseudoGeneric && !ignoreSelf; + const canUseCache = !options?.ignorePseudoGeneric && !options?.ignoreSelf; if (canUseCache && type.cached?.requiresSpecialization !== undefined) { return type.cached.requiresSpecialization; } - const result = _requiresSpecialization(type, ignorePseudoGeneric, ignoreSelf, recursionCount); + const result = _requiresSpecialization(type, options, recursionCount); if (canUseCache) { if (type.cached === undefined) { @@ -2678,22 +2823,19 @@ export function requiresSpecialization( return result; } -function _requiresSpecialization( - type: Type, - ignorePseudoGeneric = false, - ignoreSelf = false, - recursionCount = 0 -): boolean { +function _requiresSpecialization(type: Type, options?: RequiresSpecializationOptions, recursionCount = 0): boolean { switch (type.category) { case TypeCategory.Class: { - if (ClassType.isPseudoGenericClass(type) && ignorePseudoGeneric) { + if (ClassType.isPseudoGenericClass(type) && options?.ignorePseudoGeneric) { + return false; + } + + if (!type.isTypeArgumentExplicit && options?.ignoreImplicitTypeArgs) { return false; } if (type.typeArguments) { - return type.typeArguments.some((typeArg) => - requiresSpecialization(typeArg, ignorePseudoGeneric, ignoreSelf, recursionCount) - ); + return type.typeArguments.some((typeArg) => requiresSpecialization(typeArg, options, recursionCount)); } return ClassType.getTypeParameters(type).length > 0; @@ -2705,14 +2847,7 @@ function _requiresSpecialization( } for (let i = 0; i < type.details.parameters.length; i++) { - if ( - requiresSpecialization( - FunctionType.getEffectiveParameterType(type, i), - ignorePseudoGeneric, - ignoreSelf, - recursionCount - ) - ) { + if (requiresSpecialization(FunctionType.getEffectiveParameterType(type, i), options, recursionCount)) { return true; } } @@ -2722,11 +2857,11 @@ function _requiresSpecialization( ? type.specializedTypes.returnType : type.details.declaredReturnType; if (declaredReturnType) { - if (requiresSpecialization(declaredReturnType, ignorePseudoGeneric, ignoreSelf, recursionCount)) { + if (requiresSpecialization(declaredReturnType, options, recursionCount)) { return true; } } else if (type.inferredReturnType) { - if (requiresSpecialization(type.inferredReturnType, ignorePseudoGeneric, ignoreSelf, recursionCount)) { + if (requiresSpecialization(type.inferredReturnType, options, recursionCount)) { return true; } } @@ -2735,21 +2870,17 @@ function _requiresSpecialization( } case TypeCategory.OverloadedFunction: { - return type.overloads.some((overload) => - requiresSpecialization(overload, ignorePseudoGeneric, ignoreSelf, recursionCount) - ); + return type.overloads.some((overload) => requiresSpecialization(overload, options, recursionCount)); } case TypeCategory.Union: { - return type.subtypes.some((subtype) => - requiresSpecialization(subtype, ignorePseudoGeneric, ignoreSelf, recursionCount) - ); + return type.subtypes.some((subtype) => requiresSpecialization(subtype, options, recursionCount)); } case TypeCategory.TypeVar: { // Most TypeVar types need to be specialized. if (!type.details.recursiveTypeAliasName) { - if (type.details.isSynthesizedSelf && ignoreSelf) { + if (type.details.isSynthesizedSelf && options?.ignoreSelf) { return false; } @@ -2760,7 +2891,7 @@ function _requiresSpecialization( // if it has generic type arguments. if (type.typeAliasInfo?.typeArguments) { return type.typeAliasInfo.typeArguments.some((typeArg) => - requiresSpecialization(typeArg, ignorePseudoGeneric, ignoreSelf, recursionCount) + requiresSpecialization(typeArg, options, recursionCount) ); } } @@ -3070,14 +3201,7 @@ export function convertTypeToParamSpecValue(type: Type): FunctionType { return newFunction; } - const newFunction = FunctionType.createInstance( - '', - '', - '', - FunctionTypeFlags.ParamSpecValue | FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck - ); - FunctionType.addDefaultParameters(newFunction); - return newFunction; + return getUnknownTypeForParamSpec(); } export function convertParamSpecValueToType(paramSpecValue: FunctionType, omitParamSpec = false): Type { @@ -3716,6 +3840,21 @@ class TypeVarTransformer { } } +// Converts all type variables to Any. +class TypeVarAnyReplacer extends TypeVarTransformer { + constructor() { + super(); + } + + override transformTypeVar(typeVar: TypeVarType) { + return AnyType.create(); + } + + override transformParamSpec(paramSpec: TypeVarType) { + return getUnknownTypeForParamSpec(); + } +} + // For a TypeVar with a default type, validates whether the default type is using // any other TypeVars that are not currently in scope. class TypeVarDefaultValidator extends TypeVarTransformer { @@ -3927,23 +4066,6 @@ class ApplySolvedTypeVarsTransformer extends TypeVarTransformer { return UnknownType.create(); } - // If we're solving a default type, handle type variables with no scope ID. - if (this._isSolvingDefaultType && !typeVar.scopeId) { - const replacementEntry = signatureContext - .getTypeVars() - .find((entry) => entry.typeVar.details.name === typeVar.details.name); - - if (replacementEntry) { - return signatureContext.getTypeVarType(replacementEntry.typeVar); - } - - if (typeVar.details.defaultType) { - return this.apply(typeVar.details.defaultType, recursionCount); - } - - return UnknownType.create(); - } - return undefined; } @@ -4021,7 +4143,7 @@ class ApplySolvedTypeVarsTransformer extends TypeVarTransformer { return convertTypeToParamSpecValue(this.apply(paramSpec.details.defaultType, recursionCount)); } - return this._getUnknownParamSpec(); + return getUnknownTypeForParamSpec(); } if (!paramSpec.scopeId || !this._typeVarContext.hasSolveForScope(paramSpec.scopeId)) { @@ -4052,7 +4174,7 @@ class ApplySolvedTypeVarsTransformer extends TypeVarTransformer { } // Convert to the ParamSpec equivalent of "Unknown". - return this._getUnknownParamSpec(); + return getUnknownTypeForParamSpec(); } return undefined; @@ -4095,18 +4217,6 @@ class ApplySolvedTypeVarsTransformer extends TypeVarTransformer { this._isSolvingDefaultType = wasSolvingDefaultType; return result; } - - private _getUnknownParamSpec() { - const paramSpecValue = FunctionType.createInstance( - '', - '', - '', - FunctionTypeFlags.ParamSpecValue | FunctionTypeFlags.SkipArgsKwargsCompatibilityCheck - ); - FunctionType.addDefaultParameters(paramSpecValue); - - return paramSpecValue; - } } class ExpectedTypeTransformer extends TypeVarTransformer { diff --git a/packages/pyright-internal/src/analyzer/typeVarContext.ts b/packages/pyright-internal/src/analyzer/typeVarContext.ts index 309e9ae72..9848b0ab6 100644 --- a/packages/pyright-internal/src/analyzer/typeVarContext.ts +++ b/packages/pyright-internal/src/analyzer/typeVarContext.ts @@ -206,7 +206,6 @@ export class TypeVarSignatureContext { switch (type.category) { case TypeCategory.Unknown: case TypeCategory.Any: - case TypeCategory.None: case TypeCategory.TypeVar: { return 0.5; } @@ -275,11 +274,15 @@ export class TypeVarSignatureContext { } export class TypeVarContext { + static nextTypeVarContextId = 1; + private _id; private _solveForScopes: TypeVarScopeId[] | undefined; private _isLocked = false; private _signatureContexts: TypeVarSignatureContext[]; constructor(solveForScopes?: TypeVarScopeId[] | TypeVarScopeId) { + this._id = TypeVarContext.nextTypeVarContextId++; + if (Array.isArray(solveForScopes)) { this._solveForScopes = solveForScopes; } else if (solveForScopes !== undefined) { @@ -340,6 +343,10 @@ export class TypeVarContext { } } + getId() { + return this._id; + } + // Returns the list of scopes this type var map is "solving". getSolveForScopes() { return this._solveForScopes; @@ -440,12 +447,12 @@ export class TypeVarContext { return this._signatureContexts; } - doForEachSignatureContext(callback: (signature: TypeVarSignatureContext) => void) { + doForEachSignatureContext(callback: (signature: TypeVarSignatureContext, signatureIndex: number) => void) { const wasLocked = this.isLocked(); this.unlock(); - this.getSignatureContexts().forEach((signature) => { - callback(signature); + this.getSignatureContexts().forEach((signature, signatureIndex) => { + callback(signature, signatureIndex); }); if (wasLocked) { diff --git a/packages/pyright-internal/src/analyzer/typeWalker.ts b/packages/pyright-internal/src/analyzer/typeWalker.ts index 982db8486..f421d6e6c 100644 --- a/packages/pyright-internal/src/analyzer/typeWalker.ts +++ b/packages/pyright-internal/src/analyzer/typeWalker.ts @@ -15,7 +15,6 @@ import { FunctionType, ModuleType, NeverType, - NoneType, OverloadedFunctionType, Type, TypeCategory, @@ -68,10 +67,6 @@ export class TypeWalker { this.visitUnknown(type); break; - case TypeCategory.None: - this.visitNone(type); - break; - case TypeCategory.Never: this.visitNever(type); break; @@ -136,10 +131,6 @@ export class TypeWalker { // Nothing to do. } - visitNone(type: NoneType): void { - // Nothing to do. - } - visitNever(type: NeverType): void { // Nothing to do. } diff --git a/packages/pyright-internal/src/analyzer/typedDicts.ts b/packages/pyright-internal/src/analyzer/typedDicts.ts index 475137035..93e2943f5 100644 --- a/packages/pyright-internal/src/analyzer/typedDicts.ts +++ b/packages/pyright-internal/src/analyzer/typedDicts.ts @@ -46,7 +46,6 @@ import { isTypeSame, maxTypeRecursionCount, NeverType, - NoneType, OverloadedFunctionType, Type, TypedDictEntry, @@ -171,7 +170,7 @@ export function createTypedDictType( if (usingDictSyntax) { for (const arg of argList.slice(2)) { - if (arg.name?.value === 'total' || arg.name?.value === 'readonly') { + if (arg.name?.value === 'total') { if ( !arg.valueExpression || arg.valueExpression.nodeType !== ParseNodeType.Constant || @@ -186,8 +185,6 @@ export function createTypedDictType( ); } else if (arg.name.value === 'total' && arg.valueExpression.constType === KeywordType.False) { classType.details.flags |= ClassTypeFlags.CanOmitDictValues; - } else if (arg.name.value === 'readonly' && arg.valueExpression.constType === KeywordType.True) { - classType.details.flags |= ClassTypeFlags.DictValuesReadOnly; } } else { evaluator.addError(Localizer.Diagnostic.typedDictExtraArgs(), arg.valueExpression || errorNode); @@ -255,7 +252,7 @@ export function synthesizeTypedDictClassMethods( type: ClassType.cloneAsInstance(classType), hasDeclaredType: true, }); - initOverride1.details.declaredReturnType = NoneType.createInstance(); + initOverride1.details.declaredReturnType = evaluator.getNoneType(); // The first parameter must be positional-only. FunctionType.addParameter(initOverride1, { @@ -285,7 +282,7 @@ export function synthesizeTypedDictClassMethods( type: ClassType.cloneAsInstance(classType), hasDeclaredType: true, }); - initOverride2.details.declaredReturnType = NoneType.createInstance(); + initOverride2.details.declaredReturnType = evaluator.getNoneType(); // All parameters must be named, so insert an empty "*". FunctionType.addParameter(initOverride2, { @@ -297,7 +294,6 @@ export function synthesizeTypedDictClassMethods( const entries = getTypedDictMembersForClass(evaluator, classType); let allEntriesAreNotRequired = true; let allEntriesAreReadOnly = true; - let allEntriesAreWritable = true; entries.forEach((entry, name) => { FunctionType.addParameter(initOverride1, { category: ParameterCategory.Simple, @@ -319,9 +315,7 @@ export function synthesizeTypedDictClassMethods( allEntriesAreNotRequired = false; } - if (entry.isReadOnly) { - allEntriesAreWritable = false; - } else { + if (!entry.isReadOnly) { allEntriesAreReadOnly = false; } }); @@ -400,7 +394,7 @@ export function synthesizeTypedDictClassMethods( } else { getOverload.details.declaredReturnType = isEntryRequired ? valueType - : combineTypes([valueType, NoneType.createInstance()]); + : combineTypes([valueType, evaluator.getNoneType()]); } return getOverload; } @@ -479,35 +473,106 @@ export function synthesizeTypedDictClassMethods( hasDeclaredType: true, type: keyType, }); - delItemOverload.details.declaredReturnType = NoneType.createInstance(); + delItemOverload.details.declaredReturnType = evaluator.getNoneType(); return delItemOverload; } function createUpdateMethod() { - const updateMethod = FunctionType.createSynthesizedInstance('update'); - FunctionType.addParameter(updateMethod, selfParam); - - // If at least one entry is read-only, don't allow updates. We need to override - // the update method provided by the _TypedDict base class, so we'll use - // a Never parameter to generate an error if someone attempts to call it - // in this case. - FunctionType.addParameter(updateMethod, { + // Overload 1: update(__m: Partial[], /) + const updateMethod1 = FunctionType.createSynthesizedInstance('update', FunctionTypeFlags.Overloaded); + FunctionType.addParameter(updateMethod1, selfParam); + + // Overload 2: update(__m: Iterable[tuple[, ]], /) + const updateMethod2 = FunctionType.createSynthesizedInstance('update', FunctionTypeFlags.Overloaded); + FunctionType.addParameter(updateMethod2, selfParam); + + // Overload 3: update(*, : , ...) + const updateMethod3 = FunctionType.createSynthesizedInstance('update', FunctionTypeFlags.Overloaded); + FunctionType.addParameter(updateMethod3, selfParam); + + // If all entries are read-only, don't allow updates. + FunctionType.addParameter(updateMethod1, { category: ParameterCategory.Simple, name: '__m', hasDeclaredType: true, - type: !allEntriesAreWritable + type: allEntriesAreReadOnly ? NeverType.createNever() : ClassType.cloneAsInstance(ClassType.cloneForPartialTypedDict(classType)), }); - FunctionType.addParameter(updateMethod, { + FunctionType.addParameter(updateMethod1, { category: ParameterCategory.Simple, name: '', type: AnyType.create(), }); - updateMethod.details.declaredReturnType = NoneType.createInstance(); - return updateMethod; + FunctionType.addParameter(updateMethod3, { + category: ParameterCategory.ArgsList, + name: '', + hasDeclaredType: false, + type: UnknownType.create(), + }); + + updateMethod1.details.declaredReturnType = evaluator.getNoneType(); + updateMethod2.details.declaredReturnType = evaluator.getNoneType(); + updateMethod3.details.declaredReturnType = evaluator.getNoneType(); + + const tuplesToCombine: Type[] = []; + const tupleClass = evaluator.getBuiltInType(node, 'tuple'); + + entries.forEach((entry, name) => { + if (!entry.isReadOnly) { + // For writable entries, add a tuple entry. + if (tupleClass && isInstantiableClass(tupleClass) && strClass && isInstantiableClass(strClass)) { + const tupleType = specializeTupleClass(ClassType.cloneAsInstance(tupleClass), [ + { + type: ClassType.cloneWithLiteral(ClassType.cloneAsInstance(strClass), name), + isUnbounded: false, + }, + { type: entry.valueType, isUnbounded: false }, + ]); + + tuplesToCombine.push(tupleType); + } + + // For writable entries, add a keyword argument. + FunctionType.addParameter(updateMethod3, { + category: ParameterCategory.Simple, + name, + hasDeclaredType: true, + hasDefault: true, + defaultType: AnyType.create(/* isEllipsis */ true), + type: entry.valueType, + }); + } + }); + + const iterableClass = evaluator.getTypingType(node, 'Iterable'); + if (iterableClass && isInstantiableClass(iterableClass)) { + const iterableType = ClassType.cloneAsInstance(iterableClass); + + FunctionType.addParameter(updateMethod2, { + category: ParameterCategory.Simple, + name: '__m', + hasDeclaredType: true, + type: ClassType.cloneForSpecialization( + iterableType, + [combineTypes(tuplesToCombine)], + /* isTypeArgumentExplicit */ true + ), + }); + } + + FunctionType.addParameter(updateMethod2, { + category: ParameterCategory.Simple, + name: '', + type: AnyType.create(), + }); + + // Note that the order of method1 and method2 is swapped. This is done so + // the method1 signature is used in the error message when neither method2 + // or method1 match. + return OverloadedFunctionType.create([updateMethod2, updateMethod1, updateMethod3]); } const getOverloads: FunctionType[] = []; @@ -550,7 +615,7 @@ export function synthesizeTypedDictClassMethods( getOverloads.push( createGetMethod( literalStringInstance, - NoneType.createInstance(), + evaluator.getNoneType(), /* includeDefault */ false, /* isEntryRequired */ true ) @@ -600,12 +665,13 @@ export function synthesizeTypedDictClassMethods( if (isClassFinal && allEntriesAreNotRequired && !allEntriesAreReadOnly) { const clearMethod = FunctionType.createSynthesizedInstance('clear'); FunctionType.addParameter(clearMethod, selfParam); - clearMethod.details.declaredReturnType = NoneType.createInstance(); + clearMethod.details.declaredReturnType = evaluator.getNoneType(); symbolTable.set('clear', Symbol.createWithType(SymbolFlags.ClassMember, clearMethod)); const popItemMethod = FunctionType.createSynthesizedInstance('popitem'); FunctionType.addParameter(popItemMethod, selfParam); - let tupleType = evaluator.getTupleClassType(); + let tupleType: Type | undefined = evaluator.getTupleClassType(); + if (tupleType && isInstantiableClass(tupleType)) { tupleType = specializeTupleClass( ClassType.cloneAsInstance(tupleType), @@ -618,6 +684,7 @@ export function synthesizeTypedDictClassMethods( } else { tupleType = UnknownType.create(); } + popItemMethod.details.declaredReturnType = tupleType; symbolTable.set('popitem', Symbol.createWithType(SymbolFlags.ClassMember, popItemMethod)); } @@ -641,6 +708,19 @@ export function getTypedDictMembersForClass(evaluator: TypeEvaluator, classType: classType.details.typedDictEntries!.forEach((value, key) => { const tdEntry = { ...value }; tdEntry.valueType = applySolvedTypeVars(tdEntry.valueType, typeVarContext); + + // If the class is "Partial", make all entries optional and convert all + // read-only entries to Never. + if (classType.isTypedDictPartial) { + tdEntry.isRequired = false; + + if (tdEntry.isReadOnly) { + tdEntry.valueType = NeverType.createNever(); + } else { + tdEntry.isReadOnly = true; + } + } + entries.set(key, tdEntry); }); @@ -653,13 +733,6 @@ export function getTypedDictMembersForClass(evaluator: TypeEvaluator, classType: }); } - // If the class is "Partial", make all entries optional. - if (classType.isTypedDictPartial) { - entries.forEach((entry) => { - entry.isRequired = false; - }); - } - return entries; } @@ -754,7 +827,7 @@ function getTypedDictMembersForClassRecursive( valueType = applySolvedTypeVars(valueType, typeVarContext); let isRequired = !ClassType.isCanOmitDictValues(classType); - let isReadOnly = ClassType.isDictValuesReadOnly(classType); + let isReadOnly = false; if (isRequiredTypedDictVariable(evaluator, symbol)) { isRequired = true; @@ -838,14 +911,13 @@ export function assignTypedDictToTypedDict( recursionCount = 0 ) { let typesAreConsistent = true; - const isDestPartial = !!destType.isTypedDictPartial; const destEntries = getTypedDictMembersForClass(evaluator, destType); const srcEntries = getTypedDictMembersForClass(evaluator, srcType, /* allowNarrowed */ true); destEntries.forEach((destEntry, name) => { const srcEntry = srcEntries.get(name); if (!srcEntry) { - if (!isDestPartial) { + if (destEntry.isRequired || !destEntry.isReadOnly) { diag?.createAddendum().addMessage( Localizer.DiagnosticAddendum.typedDictFieldMissing().format({ name, @@ -853,9 +925,31 @@ export function assignTypedDictToTypedDict( }) ); typesAreConsistent = false; + } else { + // Missing entries are implicitly typed as ReadOnly[NotRequired[object]], + // so we need to make sure the dest entry is compatible with that. + const objType = evaluator.getObjectType(); + + if (isClassInstance(objType)) { + const subDiag = diag?.createAddendum(); + if ( + !evaluator.assignType( + destEntry.valueType, + objType, + subDiag?.createAddendum(), + typeVarContext, + /* srcTypeVarContext */ undefined, + flags, + recursionCount + ) + ) { + subDiag?.addMessage(Localizer.DiagnosticAddendum.memberTypeMismatch().format({ name })); + typesAreConsistent = false; + } + } } } else { - if (destEntry.isRequired !== srcEntry.isRequired && !destEntry.isReadOnly && !isDestPartial) { + if (destEntry.isRequired !== srcEntry.isRequired && !destEntry.isReadOnly) { const message = destEntry.isRequired ? Localizer.DiagnosticAddendum.typedDictFieldRequired() : Localizer.DiagnosticAddendum.typedDictFieldNotRequired(); @@ -868,7 +962,7 @@ export function assignTypedDictToTypedDict( typesAreConsistent = false; } - if (!destEntry.isReadOnly && srcEntry.isReadOnly && !isDestPartial) { + if (!destEntry.isReadOnly && srcEntry.isReadOnly) { diag?.createAddendum().addMessage( Localizer.DiagnosticAddendum.typedDictFieldNotReadOnly().format({ name, @@ -879,6 +973,13 @@ export function assignTypedDictToTypedDict( } const subDiag = diag?.createAddendum(); + let adjustedFlags = flags; + + // If the dest field is not read-only, we need to enforce invariance. + if (!destEntry.isReadOnly) { + adjustedFlags |= AssignTypeFlags.EnforceInvariance; + } + if ( !evaluator.assignType( destEntry.valueType, @@ -886,7 +987,7 @@ export function assignTypedDictToTypedDict( subDiag?.createAddendum(), typeVarContext, /* srcTypeVarContext */ undefined, - flags, + adjustedFlags, recursionCount ) ) { diff --git a/packages/pyright-internal/src/analyzer/types.ts b/packages/pyright-internal/src/analyzer/types.ts index 239d1f28d..0e3c6f897 100644 --- a/packages/pyright-internal/src/analyzer/types.ts +++ b/packages/pyright-internal/src/analyzer/types.ts @@ -24,9 +24,6 @@ export const enum TypeCategory { // Type can be anything. Any, - // Special "None" type defined in Python. - None, - // Used in type narrowing to indicate that all possible // subtypes in a union have been eliminated, and execution // should never get to this point. @@ -46,7 +43,7 @@ export const enum TypeCategory { // Module instance. Module, - // Composite type (e.g. Number OR String OR None). + // Composite type (e.g. Number OR String). Union, // Type variable (defined with TypeVar) @@ -74,7 +71,6 @@ export type UnionableType = | UnboundType | UnknownType | AnyType - | NoneType | FunctionType | OverloadedFunctionType | ClassType @@ -115,6 +111,7 @@ export type InheritanceChain = (ClassType | UnknownType)[]; export interface TypeSameOptions { ignorePseudoGeneric?: boolean; ignoreTypeFlags?: boolean; + typeFlagsToHonor?: TypeFlags; ignoreTypedDictNarrowEntries?: boolean; treatAnySameAsUnknown?: boolean; } @@ -477,10 +474,6 @@ export const enum ClassTypeFlags { // the dictionary values can be omitted. CanOmitDictValues = 1 << 8, - // Used in conjunction with TypedDictClass, indicates that - // the dictionary values are all readonly. - DictValuesReadOnly = 1 << 9, - // The class derives from a class that has the ABCMeta // metaclass. Such classes are allowed to contain // @abstractmethod decorators. @@ -662,6 +655,11 @@ export interface ClassType extends TypeBase { // of abstract or protocol classes. includeSubclasses?: boolean; + // This class type represents the class and any auto-promotion + // types that PEP 484 indicates should be treated as subclasses + // when the type appears within a type annotation. + includePromotions?: boolean; + // Some types can be further constrained to have // literal types (e.g. true or 'string' or 3). literalValue?: LiteralValue | undefined; @@ -677,7 +675,9 @@ export interface ClassType extends TypeBase { typedDictNarrowedEntries?: Map | undefined; // Indicates that the typed dict class should be considered "partial", - // i.e. all of its entries are effectively NotRequired. + // i.e. all of its entries are effectively NotRequired and only + // writable entries are considered present, and they are marked read-only. + // This is used for the TypedDict "update" method. isTypedDictPartial?: boolean; // Indicates whether the class is an asymmetric descriptor @@ -767,7 +767,7 @@ export namespace ClassType { ): ClassType { const newClassType = TypeBase.cloneType(classType); - newClassType.typeArguments = typeArguments; + newClassType.typeArguments = typeArguments?.length === 0 ? undefined : typeArguments; newClassType.isTypeArgumentExplicit = isTypeArgumentExplicit; if (includeSubclasses) { @@ -787,6 +787,16 @@ export namespace ClassType { return newClassType; } + export function cloneIncludeSubclasses(classType: ClassType) { + if (classType.includeSubclasses) { + return classType; + } + + const newClassType = TypeBase.cloneType(classType); + newClassType.includeSubclasses = true; + return newClassType; + } + export function cloneWithLiteral(classType: ClassType, value: LiteralValue | undefined): ClassType { const newClassType = TypeBase.cloneType(classType); newClassType.literalValue = value; @@ -822,6 +832,16 @@ export namespace ClassType { return newClassType; } + export function cloneRemoveTypePromotions(classType: ClassType): ClassType { + if (!classType.includePromotions) { + return classType; + } + + const newClassType = TypeBase.cloneType(classType); + delete newClassType.includePromotions; + return newClassType; + } + export function cloneForTypeGuard( classType: ClassType, typeGuardType: Type, @@ -1016,10 +1036,6 @@ export namespace ClassType { return !!(classType.details.flags & ClassTypeFlags.CanOmitDictValues); } - export function isDictValuesReadOnly(classType: ClassType) { - return !!(classType.details.flags & ClassTypeFlags.DictValuesReadOnly); - } - export function isEnumClass(classType: ClassType) { return !!(classType.details.flags & ClassTypeFlags.EnumClass); } @@ -1101,6 +1117,10 @@ export namespace ClassType { } recursionCount++; + if (!classType.isTypedDictPartial !== !type2.isTypedDictPartial) { + return false; + } + // If the class details match, it's definitely the same class. if (classType.details === type2.details) { return true; @@ -1439,6 +1459,11 @@ export interface FunctionType extends TypeBase { // for that call and any other signatures that were passed as // arguments to it. trackedSignatures?: SignatureWithOffsets[]; + + // If this function is created with a "Callable" annotation with + // type arguments? This allows us to detect and report an error + // when this is used in an isinstance call. + isCallableWithTypeArgs?: boolean; } export namespace FunctionType { @@ -1833,6 +1858,10 @@ export namespace FunctionType { newFunction.details.paramSpec = paramSpec; } + if (type.inferredReturnType) { + newFunction.inferredReturnType = type.inferredReturnType; + } + return newFunction; } @@ -2039,30 +2068,6 @@ export namespace OverloadedFunctionType { } } -export interface NoneType extends TypeBase { - category: TypeCategory.None; -} - -export namespace NoneType { - const _noneInstance: NoneType = { - category: TypeCategory.None, - flags: TypeFlags.Instance, - }; - - const _noneType: NoneType = { - category: TypeCategory.None, - flags: TypeFlags.Instantiable, - }; - - export function createInstance() { - return _noneInstance; - } - - export function createType() { - return _noneType; - } -} - export interface NeverType extends TypeBase { category: TypeCategory.Never; isNoReturn: boolean; @@ -2096,6 +2101,12 @@ export interface AnyType extends TypeBase { } export namespace AnyType { + const _anyInstanceSpecialForm: AnyType = { + category: TypeCategory.Any, + isEllipsis: false, + flags: TypeFlags.Instance | TypeFlags.Instantiable | TypeFlags.SpecialForm, + }; + const _anyInstance: AnyType = { category: TypeCategory.Any, isEllipsis: false, @@ -2111,6 +2122,22 @@ export namespace AnyType { export function create(isEllipsis = false) { return isEllipsis ? _ellipsisInstance : _anyInstance; } + + export function createSpecialForm() { + return _anyInstanceSpecialForm; + } +} + +export namespace AnyType { + export function convertToInstance(type: AnyType): AnyType { + // Remove the "special form" flag if it's set. Otherwise + // simply return the existing type. + if (TypeBase.isSpecialForm(type)) { + return AnyType.create(); + } + + return type; + } } // References a single condition associated with a constrained TypeVar. @@ -2334,6 +2361,7 @@ export interface TypeVarDetails { constraints: Type[]; boundType?: Type | undefined; defaultType?: Type | undefined; + runtimeClass?: ClassType | undefined; isParamSpec: boolean; isVariadic: boolean; @@ -2410,8 +2438,8 @@ export namespace TypeVarType { return create(name, /* isParamSpec */ false, TypeFlags.Instance); } - export function createInstantiable(name: string, isParamSpec = false) { - return create(name, isParamSpec, TypeFlags.Instantiable); + export function createInstantiable(name: string, isParamSpec = false, runtimeClass?: ClassType) { + return create(name, isParamSpec, TypeFlags.Instantiable, runtimeClass); } export function cloneAsInstance(type: TypeVarType): TypeVarType { @@ -2543,7 +2571,7 @@ export namespace TypeVarType { return `${name}.${scopeId}`; } - function create(name: string, isParamSpec: boolean, typeFlags: TypeFlags): TypeVarType { + function create(name: string, isParamSpec: boolean, typeFlags: TypeFlags, runtimeClass?: ClassType): TypeVarType { const newTypeVarType: TypeVarType = { category: TypeCategory.TypeVar, details: { @@ -2553,6 +2581,7 @@ export namespace TypeVarType { isParamSpec, isVariadic: false, isSynthesized: false, + runtimeClass, }, flags: typeFlags, }; @@ -2602,14 +2631,6 @@ export function isNever(type: Type): type is NeverType { return type.category === TypeCategory.Never; } -export function isNoneInstance(type: Type): type is NoneType { - return type.category === TypeCategory.None && TypeBase.isInstance(type); -} - -export function isNoneTypeClass(type: Type): type is NoneType { - return type.category === TypeCategory.None && TypeBase.isInstantiable(type); -} - export function isAny(type: Type): type is AnyType { return type.category === TypeCategory.Any; } @@ -2746,9 +2767,18 @@ export function isTypeSame(type1: Type, type2: Type, options: TypeSameOptions = } if (!options.ignoreTypeFlags) { - // The Annotated flag should never be considered for type compatibility. - const type1Flags = type1.flags & ~TypeFlags.Annotated; - const type2Flags = type2.flags & ~TypeFlags.Annotated; + let type1Flags = type1.flags; + let type2Flags = type2.flags; + + // Mask out the flags that we don't care about. + if (options.typeFlagsToHonor !== undefined) { + type1Flags &= options.typeFlagsToHonor; + type2Flags &= options.typeFlagsToHonor; + } else { + // By default, we don't care about the Annotated flag. + type1Flags &= ~TypeFlags.Annotated; + type2Flags &= ~TypeFlags.Annotated; + } if (type1Flags !== type2Flags) { return false; @@ -2819,6 +2849,10 @@ export function isTypeSame(type1: Type, type2: Type, options: TypeSameOptions = return false; } + if (!type1.isTypedDictPartial !== !classType2.isTypedDictPartial) { + return false; + } + if (!options.ignoreTypedDictNarrowEntries && !ClassType.isTypedDictNarrowedEntriesSame(type1, classType2)) { return false; } @@ -3067,19 +3101,6 @@ export function removeUnknownFromUnion(type: Type): Type { return removeFromUnion(type, (t: Type) => isUnknown(t)); } -export function removeIncompleteUnknownFromUnion(type: Type): Type { - return removeFromUnion(type, (t: Type) => isUnknown(t) && t.isIncomplete); -} - -export function cleanIncompleteUnknown(type: Type): Type { - const typeWithoutUnknown = removeIncompleteUnknownFromUnion(type); - if (!isNever(typeWithoutUnknown)) { - return typeWithoutUnknown; - } - - return type; -} - // If the type is a union, remove an "unbound" type from the union, // returning only the known types. export function removeUnbound(type: Type): Type { @@ -3094,12 +3115,6 @@ export function removeUnbound(type: Type): Type { return type; } -// If the type is a union, remove an "None" type from the union, -// returning only the known types. -export function removeNoneFromUnion(type: Type): Type { - return removeFromUnion(type, (t: Type) => isNoneInstance(t)); -} - export function removeFromUnion(type: Type, removeFilter: (type: Type) => boolean) { if (isUnion(type)) { const remainingTypes = type.subtypes.filter((t) => !removeFilter(t)); diff --git a/packages/pyright-internal/src/backgroundAnalysisBase.ts b/packages/pyright-internal/src/backgroundAnalysisBase.ts index fcc1b8323..a2fcc9151 100644 --- a/packages/pyright-internal/src/backgroundAnalysisBase.ts +++ b/packages/pyright-internal/src/backgroundAnalysisBase.ts @@ -30,7 +30,6 @@ import { ConsoleInterface, LogLevel, log } from './common/console'; import * as debug from './common/debug'; import { Diagnostic } from './common/diagnostic'; import { FileDiagnostics } from './common/diagnosticSink'; -import { Extensions } from './common/extensibility'; import { disposeCancellationToken, getCancellationTokenFromId } from './common/fileBasedCancellationUtils'; import { Host, HostKind } from './common/host'; import { LogTracker } from './common/logTracker'; @@ -107,6 +106,27 @@ export class BackgroundAnalysisBase { this._startOrResumeAnalysis('analyze', program, token); } + async analyzeFile(filePath: string, token: CancellationToken): Promise { + throwIfCancellationRequested(token); + + const { port1, port2 } = new MessageChannel(); + const waiter = getBackgroundWaiter(port1); + + const cancellationId = getCancellationTokenId(token); + this.enqueueRequest({ + requestType: 'analyzeFile', + data: { filePath, cancellationId }, + port: port2, + }); + + const result = await waiter; + + port2.close(); + port1.close(); + + return result; + } + async getDiagnosticsForRange(filePath: string, range: Range, token: CancellationToken): Promise { throwIfCancellationRequested(token); @@ -238,7 +258,7 @@ export class BackgroundAnalysisBase { } default: - debug.fail(`${msg.requestType} is not expected`); + debug.fail(`${msg.requestType} is not expected. Message structure: ${JSON.stringify(msg)}`); } } @@ -278,27 +298,6 @@ export abstract class BackgroundAnalysisRunnerBase extends BackgroundThreadBase this.logTracker = new LogTracker(console, `BG(${threadId})`); this._program = new Program(this.importResolver, this._configOptions, serviceProvider, this.logTracker); - - // Create the extensions bound to the program for this background thread - Extensions.createProgramExtensions(this._program, { - addInterimFile: (filePath: string) => this._program.addInterimFile(filePath), - setFileOpened: (filePath, version, contents, ipythonMode, chainedFilePath, realFilePath) => { - this._program.setFileOpened(filePath, version, contents, { - isTracked: this._program.owns(filePath), - ipythonMode, - chainedFilePath, - realFilePath, - }); - }, - updateOpenFileContents: (filePath, version, contents, ipythonMode, realFilePath) => { - this._program.setFileOpened(filePath, version, contents, { - isTracked: this._program.owns(filePath), - ipythonMode, - chainedFilePath: undefined, - realFilePath, - }); - }, - }); } get program(): Program { @@ -338,6 +337,16 @@ export abstract class BackgroundAnalysisRunnerBase extends BackgroundThreadBase break; } + case 'analyzeFile': { + run(() => { + const { filePath, cancellationId } = msg.data; + const token = getCancellationTokenFromId(cancellationId); + + return this.handleAnalyzeFile(filePath, token); + }, msg.port!); + break; + } + case 'getDiagnosticsForRange': { run(() => { const { filePath, range, cancellationId } = msg.data; @@ -490,6 +499,11 @@ export abstract class BackgroundAnalysisRunnerBase extends BackgroundThreadBase } } + protected handleAnalyzeFile(filePath: string, token: CancellationToken) { + throwIfCancellationRequested(token); + return this.program.analyzeFile(filePath, token); + } + protected handleGetDiagnosticsForRange(filePath: string, range: Range, token: CancellationToken) { throwIfCancellationRequested(token); return this.program.getDiagnosticsForRange(filePath, range); @@ -600,7 +614,6 @@ export abstract class BackgroundAnalysisRunnerBase extends BackgroundThreadBase protected override handleShutdown() { this._program.dispose(); - Extensions.destroyProgramExtensions(this._program.id); super.handleShutdown(); } @@ -705,7 +718,8 @@ export type AnalysisRequestKind = | 'writeTypeStub' | 'setImportResolver' | 'shutdown' - | 'addInterimFile'; + | 'addInterimFile' + | 'analyzeFile'; export interface AnalysisRequest { requestType: AnalysisRequestKind; diff --git a/packages/pyright-internal/src/backgroundThreadBase.ts b/packages/pyright-internal/src/backgroundThreadBase.ts index 592f0e78f..425507f0d 100644 --- a/packages/pyright-internal/src/backgroundThreadBase.ts +++ b/packages/pyright-internal/src/backgroundThreadBase.ts @@ -13,7 +13,7 @@ import { ConfigOptions } from './common/configOptions'; import { ConsoleInterface, LogLevel } from './common/console'; import * as debug from './common/debug'; import { FileSpec } from './common/pathUtils'; -import { createFromRealFileSystem } from './common/realFileSystem'; +import { createFromRealFileSystem, RealTempFile } from './common/realFileSystem'; import { ServiceProvider } from './common/serviceProvider'; import './common/serviceProviderExtensions'; import { ServiceKeys } from './common/serviceProviderExtensions'; @@ -59,6 +59,9 @@ export class BackgroundThreadBase { if (!this._serviceProvider.tryGet(ServiceKeys.fs)) { this._serviceProvider.add(ServiceKeys.fs, createFromRealFileSystem(this.getConsole())); } + if (!this._serviceProvider.tryGet(ServiceKeys.tempFile)) { + this._serviceProvider.add(ServiceKeys.tempFile, new RealTempFile()); + } } protected get fs() { @@ -78,7 +81,7 @@ export class BackgroundThreadBase { } protected handleShutdown() { - this.fs.dispose(); + this._serviceProvider.tryGet(ServiceKeys.tempFile)?.dispose(); parentPort?.close(); } } diff --git a/packages/pyright-internal/src/commands/dumpFileDebugInfoCommand.ts b/packages/pyright-internal/src/commands/dumpFileDebugInfoCommand.ts index 3c417dc7a..c400648d7 100644 --- a/packages/pyright-internal/src/commands/dumpFileDebugInfoCommand.ts +++ b/packages/pyright-internal/src/commands/dumpFileDebugInfoCommand.ts @@ -136,7 +136,7 @@ export class DumpFileDebugInfoCommand implements ServerCommand { const kind = params.arguments[1]; const workspace = await this._ls.getWorkspaceForFile(filePath); - const parseResults = workspace.service.getParseResult(filePath); + const parseResults = workspace.service.getParseResult(workspace.service.fs.realCasePath(filePath)); if (!parseResults) { return []; } @@ -522,8 +522,6 @@ function getTypeCategoryString(typeCategory: TypeCategory, type: any) { return 'Unknown'; case TypeCategory.Any: return 'Any'; - case TypeCategory.None: - return 'None'; case TypeCategory.Never: return 'Never'; case TypeCategory.Function: diff --git a/packages/pyright-internal/src/common/configOptions.ts b/packages/pyright-internal/src/common/configOptions.ts index 0fb791c19..4c7950f7f 100644 --- a/packages/pyright-internal/src/common/configOptions.ts +++ b/packages/pyright-internal/src/common/configOptions.ts @@ -13,22 +13,24 @@ import { getPathsFromPthFiles } from '../analyzer/pythonPathUtils'; import * as pathConsts from '../common/pathConsts'; import { appendArray } from './collectionUtils'; import { DiagnosticSeverityOverridesMap } from './commandLineOptions'; -import { ConsoleInterface } from './console'; +import { ConsoleInterface, NullConsole } from './console'; import { TaskListToken } from './diagnostic'; import { DiagnosticRule } from './diagnosticRules'; import { FileSystem } from './fileSystem'; import { Host } from './host'; import { + FileSpec, combinePaths, ensureTrailingDirectorySeparator, - FileSpec, getFileSpec, isDirectory, normalizePath, realCasePath, resolvePaths, } from './pathUtils'; -import { latestStablePythonVersion, PythonVersion, versionFromString, versionToString } from './pythonVersion'; +import { PythonVersion, latestStablePythonVersion, versionFromString, versionToString } from './pythonVersion'; +import { ServiceProvider } from './serviceProvider'; +import { ServiceKeys } from './serviceProviderExtensions'; export enum PythonPlatform { Darwin = 'Darwin', @@ -118,6 +120,9 @@ export interface DiagnosticRuleSet { // Enable support for type: ignore comments? enableTypeIgnoreComments: boolean; + // No longer treat bytearray and memoryview as subclasses of bytes? + disableBytesTypePromotions: boolean; + // Treat old typing aliases as deprecated if pythonVersion >= 3.9? deprecateTypingAliases: boolean; @@ -345,6 +350,7 @@ export function getBooleanDiagnosticRules(includeNonOverridable = false) { DiagnosticRule.strictParameterNoneValue, DiagnosticRule.enableExperimentalFeatures, DiagnosticRule.deprecateTypingAliases, + DiagnosticRule.disableBytesTypePromotions, ]; if (includeNonOverridable) { @@ -449,6 +455,7 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet { enableExperimentalFeatures: false, enableTypeIgnoreComments: true, deprecateTypingAliases: false, + disableBytesTypePromotions: false, reportGeneralTypeIssues: 'none', reportPropertyTypeMismatch: 'none', reportFunctionMemberAccess: 'none', @@ -533,6 +540,7 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet { enableExperimentalFeatures: false, enableTypeIgnoreComments: true, deprecateTypingAliases: false, + disableBytesTypePromotions: false, reportGeneralTypeIssues: 'error', reportPropertyTypeMismatch: 'none', reportFunctionMemberAccess: 'none', @@ -617,6 +625,7 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet { enableExperimentalFeatures: false, enableTypeIgnoreComments: true, // Not overridden by strict mode deprecateTypingAliases: false, + disableBytesTypePromotions: true, reportGeneralTypeIssues: 'error', reportPropertyTypeMismatch: 'none', reportFunctionMemberAccess: 'error', @@ -880,41 +889,38 @@ export class ConfigOptions { initializeFromJson( configObj: any, typeCheckingMode: string | undefined, - console: ConsoleInterface, - fs: FileSystem, + serviceProvider: ServiceProvider, host: Host, - diagnosticOverrides?: DiagnosticSeverityOverridesMap, - skipIncludeSection = false + diagnosticOverrides?: DiagnosticSeverityOverridesMap ) { this.initializedFromJson = true; + const console = serviceProvider.tryGet(ServiceKeys.console) ?? new NullConsole(); // Read the "include" entry. - if (!skipIncludeSection) { - this.include = []; - if (configObj.include !== undefined) { - if (!Array.isArray(configObj.include)) { - console.error(`Config "include" entry must must contain an array.`); - } else { - const filesList = configObj.include as string[]; - filesList.forEach((fileSpec, index) => { - if (typeof fileSpec !== 'string') { - console.error(`Index ${index} of "include" array should be a string.`); - } else if (isAbsolute(fileSpec)) { - console.error(`Ignoring path "${fileSpec}" in "include" array because it is not relative.`); - } else { - this.include.push(getFileSpec(fs, this.projectRoot, fileSpec)); - } - }); - } + if (configObj.include !== undefined) { + if (!Array.isArray(configObj.include)) { + console.error(`Config "include" entry must must contain an array.`); + } else { + this.include = []; + const filesList = configObj.include as string[]; + filesList.forEach((fileSpec, index) => { + if (typeof fileSpec !== 'string') { + console.error(`Index ${index} of "include" array should be a string.`); + } else if (isAbsolute(fileSpec)) { + console.error(`Ignoring path "${fileSpec}" in "include" array because it is not relative.`); + } else { + this.include.push(getFileSpec(serviceProvider, this.projectRoot, fileSpec)); + } + }); } } // Read the "exclude" entry. - this.exclude = []; if (configObj.exclude !== undefined) { if (!Array.isArray(configObj.exclude)) { console.error(`Config "exclude" entry must contain an array.`); } else { + this.exclude = []; const filesList = configObj.exclude as string[]; filesList.forEach((fileSpec, index) => { if (typeof fileSpec !== 'string') { @@ -922,18 +928,18 @@ export class ConfigOptions { } else if (isAbsolute(fileSpec)) { console.error(`Ignoring path "${fileSpec}" in "exclude" array because it is not relative.`); } else { - this.exclude.push(getFileSpec(fs, this.projectRoot, fileSpec)); + this.exclude.push(getFileSpec(serviceProvider, this.projectRoot, fileSpec)); } }); } } // Read the "ignore" entry. - this.ignore = []; if (configObj.ignore !== undefined) { if (!Array.isArray(configObj.ignore)) { console.error(`Config "ignore" entry must contain an array.`); } else { + this.ignore = []; const filesList = configObj.ignore as string[]; filesList.forEach((fileSpec, index) => { if (typeof fileSpec !== 'string') { @@ -941,18 +947,18 @@ export class ConfigOptions { } else if (isAbsolute(fileSpec)) { console.error(`Ignoring path "${fileSpec}" in "ignore" array because it is not relative.`); } else { - this.ignore.push(getFileSpec(fs, this.projectRoot, fileSpec)); + this.ignore.push(getFileSpec(serviceProvider, this.projectRoot, fileSpec)); } }); } } // Read the "strict" entry. - this.strict = []; if (configObj.strict !== undefined) { if (!Array.isArray(configObj.strict)) { console.error(`Config "strict" entry must contain an array.`); } else { + this.strict = []; const filesList = configObj.strict as string[]; filesList.forEach((fileSpec, index) => { if (typeof fileSpec !== 'string') { @@ -960,7 +966,7 @@ export class ConfigOptions { } else if (isAbsolute(fileSpec)) { console.error(`Ignoring path "${fileSpec}" in "strict" array because it is not relative.`); } else { - this.strict.push(getFileSpec(fs, this.projectRoot, fileSpec)); + this.strict.push(getFileSpec(serviceProvider, this.projectRoot, fileSpec)); } }); } diff --git a/packages/pyright-internal/src/common/diagnosticRules.ts b/packages/pyright-internal/src/common/diagnosticRules.ts index 043d4e7be..d2799099c 100644 --- a/packages/pyright-internal/src/common/diagnosticRules.ts +++ b/packages/pyright-internal/src/common/diagnosticRules.ts @@ -19,6 +19,7 @@ export enum DiagnosticRule { enableExperimentalFeatures = 'enableExperimentalFeatures', enableTypeIgnoreComments = 'enableTypeIgnoreComments', deprecateTypingAliases = 'deprecateTypingAliases', + disableBytesTypePromotions = 'disableBytesTypePromotions', reportGeneralTypeIssues = 'reportGeneralTypeIssues', reportPropertyTypeMismatch = 'reportPropertyTypeMismatch', diff --git a/packages/pyright-internal/src/common/extensibility.ts b/packages/pyright-internal/src/common/extensibility.ts index 9e82cd26b..81d469445 100644 --- a/packages/pyright-internal/src/common/extensibility.ts +++ b/packages/pyright-internal/src/common/extensibility.ts @@ -8,14 +8,12 @@ import { CancellationToken } from 'vscode-languageserver'; -import { getFileInfo } from '../analyzer/analyzerNodeInfo'; import { Declaration } from '../analyzer/declaration'; import { ImportResolver } from '../analyzer/importResolver'; import * as prog from '../analyzer/program'; -import * as src from '../analyzer/sourceFileInfo'; import { SourceMapper } from '../analyzer/sourceMapper'; import { TypeEvaluator } from '../analyzer/typeEvaluatorTypes'; -import { LanguageServerBase, LanguageServerInterface } from '../languageServerBase'; +import { ServerSettings } from '../languageServerBase'; import { ParseNode } from '../parser/parseNodes'; import { ParseResults } from '../parser/parser'; import { ConfigOptions } from './configOptions'; @@ -25,18 +23,7 @@ import { Range } from './textRange'; import { SymbolTable } from '../analyzer/symbol'; import { Diagnostic } from '../common/diagnostic'; import { IPythonMode } from '../analyzer/sourceFile'; -import { ServiceKey } from './serviceProvider'; - -export interface LanguageServiceExtension { - // empty -} - -export interface ProgramExtension { - readonly declarationProviderExtension?: DeclarationProviderExtension; - - fileDirty?: (filePath: string) => void; - clearCache?: () => void; -} +import { GroupServiceKey, ServiceKey } from './serviceProvider'; export interface SourceFile { // See whether we can convert these to regular properties. @@ -77,7 +64,10 @@ export interface SourceFileInfo { export interface ServiceProvider { tryGet(key: ServiceKey): T | undefined; + tryGet(key: GroupServiceKey): readonly T[] | undefined; + get(key: ServiceKey): T; + get(key: GroupServiceKey): readonly T[]; } // Readonly wrapper around a Program. Makes sure it doesn't mutate the program. @@ -108,7 +98,6 @@ export interface ProgramView { getDiagnosticsForRange(filePath: string, range: Range): Diagnostic[]; // See whether we can get rid of these methods - getBoundSourceFileInfo(file: string, content?: string, force?: boolean): src.SourceFileInfo | undefined; handleMemoryHighUsage(): void; clone(): prog.Program; } @@ -143,126 +132,37 @@ export interface ProgramMutator { ): void; } -export interface ExtensionFactory { - createProgramExtension?: (view: ProgramView, mutator: ProgramMutator) => ProgramExtension; - createLanguageServiceExtension?: (languageserver: LanguageServerInterface) => LanguageServiceExtension; -} - -export enum DeclarationUseCase { - Definition, +export enum ReferenceUseCase { Rename, References, } -export interface DeclarationProviderExtension { - tryGetDeclarations( - evaluator: TypeEvaluator, - node: ParseNode, - offset: number, - useCase: DeclarationUseCase, - token: CancellationToken - ): Declaration[]; +export interface SymbolDefinitionProvider { + tryGetDeclarations(node: ParseNode, offset: number, token: CancellationToken): Declaration[]; } -interface OwnedProgramExtension extends ProgramExtension { - readonly view: ProgramView; +export interface SymbolUsageProviderFactory { + tryCreateProvider( + useCase: ReferenceUseCase, + declarations: readonly Declaration[], + token: CancellationToken + ): SymbolUsageProvider | undefined; } -interface OwnedLanguageServiceExtension extends LanguageServiceExtension { - readonly owner: LanguageServerBase; +/** + * All Apis are supposed to be `idempotent` and `deterministic` + * + * All Apis should return the same results regardless how often there are called + * in whatever orders for the same inputs. + */ +export interface SymbolUsageProvider { + appendSymbolNamesTo(symbolNames: Set): void; + appendDeclarationsTo(to: Declaration[]): void; + appendDeclarationsAt(context: ParseNode, from: readonly Declaration[], to: Declaration[]): void; } -export namespace Extensions { - const factories: ExtensionFactory[] = []; - let programExtensions: OwnedProgramExtension[] = []; - let languageServiceExtensions: OwnedLanguageServiceExtension[] = []; - - export function register(entries: ExtensionFactory[]) { - factories.push(...entries); - } - export function createProgramExtensions(view: ProgramView, mutator: ProgramMutator) { - programExtensions.push( - ...(factories - .map((s) => { - let result = s.createProgramExtension ? s.createProgramExtension(view, mutator) : undefined; - if (result) { - // Add the extra parameter that we use for finding later. - result = Object.defineProperty(result, 'view', { value: view }); - } - return result; - }) - .filter((s) => !!s) as OwnedProgramExtension[]) - ); - } - - export function destroyProgramExtensions(viewId: string) { - programExtensions = programExtensions.filter((s) => s.view.id !== viewId); - } - - export function createLanguageServiceExtensions(languageServer: LanguageServerInterface) { - languageServiceExtensions.push( - ...(factories - .map((s) => { - let result = s.createLanguageServiceExtension - ? s.createLanguageServiceExtension(languageServer) - : undefined; - if (result && !(result as any).owner) { - // Add the extra parameter that we use for finding later. - result = Object.defineProperty(result, 'owner', { value: languageServer }); - } - return result; - }) - .filter((s) => !!s) as OwnedLanguageServiceExtension[]) - ); - } - - export function destroyLanguageServiceExtensions(languageServer: LanguageServerBase) { - languageServiceExtensions = languageServiceExtensions.filter((s) => s.owner !== languageServer); - } - - function getBestProgram(filePath: string): ProgramView { - // Find the best program to use for this file. - const programs = [...new Set(programExtensions.map((s) => s.view))]; - let bestProgram: ProgramView | undefined; - programs.forEach((program) => { - // If the file is tracked by this program, use it. - if (program.owns(filePath)) { - if (!bestProgram || filePath.startsWith(program.rootPath)) { - bestProgram = program; - } - } - }); - - // If we didn't find a program that tracks the file, use the first one that claims ownership. - if (bestProgram === undefined) { - if (programs.length === 1) { - bestProgram = programs[0]; - } else { - bestProgram = programs.find((p) => p.getBoundSourceFileInfo(filePath)) || programs[0]; - } - } - return bestProgram; - } - - export function getProgramExtensions(nodeOrFilePath: ParseNode | string) { - const filePath = - typeof nodeOrFilePath === 'string' ? nodeOrFilePath.toString() : getFileInfo(nodeOrFilePath).filePath; - const bestProgram = getBestProgram(filePath); - - return getProgramExtensionsForView(bestProgram); - } - - export function getLanguageServiceExtensions() { - return languageServiceExtensions as LanguageServiceExtension[]; - } - - export function getProgramExtensionsForView(view: ProgramView) { - return programExtensions.filter((s) => s.view === view) as ProgramExtension[]; - } - - export function unregister() { - programExtensions.splice(0, programExtensions.length); - languageServiceExtensions.splice(0, languageServiceExtensions.length); - factories.splice(0, factories.length); - } +export interface StatusMutationListener { + fileDirty?: (filePath: string) => void; + clearCache?: () => void; + updateSettings?: (settings: T) => void; } diff --git a/packages/pyright-internal/src/common/fileSystem.ts b/packages/pyright-internal/src/common/fileSystem.ts index 1df9458b7..8ffa3ef9f 100644 --- a/packages/pyright-internal/src/common/fileSystem.ts +++ b/packages/pyright-internal/src/common/fileSystem.ts @@ -32,11 +32,6 @@ export interface MkDirOptions { // mode: string | number; } -export interface TmpfileOptions { - postfix?: string; - prefix?: string; -} - export interface ReadOnlyFileSystem { existsSync(path: string): boolean; chdir(path: string): void; @@ -80,7 +75,14 @@ export interface FileSystem extends ReadOnlyFileSystem { createReadStream(path: string): fs.ReadStream; createWriteStream(path: string): fs.WriteStream; copyFileSync(src: string, dst: string): void; +} + +export interface TmpfileOptions { + postfix?: string; + prefix?: string; +} +export interface TempFile { // The directory returned by tmpdir must exist and be the same each time tmpdir is called. tmpdir(): string; tmpfile(options?: TmpfileOptions): string; @@ -93,6 +95,12 @@ export namespace FileSystem { } } +export namespace TempFile { + export function is(value: any): value is TempFile { + return value.tmpdir && value.tmpfile && value.dispose; + } +} + export class VirtualDirent implements fs.Dirent { constructor(public name: string, private _file: boolean) {} diff --git a/packages/pyright-internal/src/common/fullAccessHost.ts b/packages/pyright-internal/src/common/fullAccessHost.ts index a92939592..0429e3f63 100644 --- a/packages/pyright-internal/src/common/fullAccessHost.ts +++ b/packages/pyright-internal/src/common/fullAccessHost.ts @@ -10,7 +10,7 @@ import * as child_process from 'child_process'; import { CancellationToken } from 'vscode-languageserver'; import { PythonPathResult } from '../analyzer/pythonPathUtils'; -import { OperationCanceledException } from './cancellationUtils'; +import { OperationCanceledException, throwIfCancellationRequested } from './cancellationUtils'; import { PythonPlatform } from './configOptions'; import { assertNever } from './debug'; import { FileSystem } from './fileSystem'; @@ -134,6 +134,9 @@ export class FullAccessHost extends LimitedAccessHost { cwd: string, token: CancellationToken ): Promise { + // If it is already cancelled, don't bother to run script. + throwIfCancellationRequested(token); + // What to do about conda here? return new Promise<{ stdout: string; stderr: string }>((resolve, reject) => { let stdout = ''; @@ -145,7 +148,18 @@ export class FullAccessHost extends LimitedAccessHost { ); const tokenWatch = token.onCancellationRequested(() => { if (child) { - child.kill(); + try { + if (child.pid && child.exitCode === null) { + if (process.platform === 'win32') { + // Windows doesn't support SIGTERM, so execute taskkill to kill the process + child_process.execSync(`taskkill /pid ${child.pid} /T /F`); + } else { + process.kill(child.pid); + } + } + } catch { + // Ignore. + } } reject(new OperationCanceledException()); }); diff --git a/packages/pyright-internal/src/common/pathUtils.ts b/packages/pyright-internal/src/common/pathUtils.ts index 58b0beb0e..5b78735e1 100644 --- a/packages/pyright-internal/src/common/pathUtils.ts +++ b/packages/pyright-internal/src/common/pathUtils.ts @@ -9,18 +9,21 @@ import type { Dirent } from 'fs'; import * as path from 'path'; -import { URI } from 'vscode-uri'; +import { URI, Utils } from 'vscode-uri'; import { Char } from './charCodes'; import { some } from './collectionUtils'; import { GetCanonicalFileName, identity } from './core'; import { randomBytesHex } from './crypto'; import * as debug from './debug'; -import { FileSystem, ReadOnlyFileSystem, Stats } from './fileSystem'; +import { ServiceProvider } from './extensibility'; +import { FileSystem, ReadOnlyFileSystem, Stats, TempFile } from './fileSystem'; +import { ServiceKeys } from './serviceProviderExtensions'; import { equateStringsCaseInsensitive, equateStringsCaseSensitive } from './stringUtils'; let _fsCaseSensitivity: boolean | undefined = undefined; let _underTest: boolean = false; +const _uriSchemePattern = /^\w[\w\d+.-]*$/; export interface FileSpec { // File specs can contain wildcard characters (**, *, ?). This @@ -89,37 +92,61 @@ export function forEachAncestorDirectory( } export function getDirectoryPath(pathString: string): string { + if (isUri(pathString)) { + return Utils.dirname(URI.parse(pathString).with({ fragment: '', query: '' })).toString(); + } return pathString.substr(0, Math.max(getRootLength(pathString), pathString.lastIndexOf(path.sep))); } -export function getRootLength(pathString: string): number { +export function isUri(pathString: string) { + return pathString.indexOf(':') > 1 && _uriSchemePattern.test(pathString.split(':')[0]); +} + +/** + * Returns length of the root part of a path or URL (i.e. length of "/", "x:/", "//server/"). + */ +export function getRootLength(pathString: string, checkUri = true): number { if (pathString.charAt(0) === path.sep) { if (pathString.charAt(1) !== path.sep) { - return 1; + return 1; // POSIX: "/" (or non-normalized "\") } const p1 = pathString.indexOf(path.sep, 2); if (p1 < 0) { - return 2; - } - const p2 = pathString.indexOf(path.sep, p1 + 1); - if (p2 < 0) { - return p1 + 1; + return pathString.length; // UNC: "//server" or "\\server" } - return p2 + 1; + return p1 + 1; // UNC: "//server/" or "\\server\" } if (pathString.charAt(1) === ':') { if (pathString.charAt(2) === path.sep) { - return 3; + return 3; // DOS: "c:/" or "c:\" + } + if (pathString.length === 2) { + return 2; // DOS: "c:" (but not "c:d") } } + + if (checkUri && isUri(pathString)) { + const uri = URI.parse(pathString); + if (uri.authority) { + return uri.scheme.length + 3; // URI: "file://" + } else { + return uri.scheme.length + 1; // URI: "untitled:" + } + } + return 0; } +export function getPathSeparator(pathString: string) { + return isUri(pathString) ? '/' : path.sep; +} + export function getPathComponents(pathString: string) { const normalizedPath = normalizeSlashes(pathString); - const rootLength = getRootLength(normalizedPath); + const rootLength = getRootLength(normalizedPath, /* checkUri */ isUri(normalizedPath)); const root = normalizedPath.substring(0, rootLength); - const rest = normalizedPath.substring(rootLength).split(path.sep); + const sep = getPathSeparator(pathString); + const rest = normalizedPath.substring(rootLength).split(sep); if (rest.length > 0 && !rest[rest.length - 1]) { rest.pop(); } @@ -163,7 +190,8 @@ export function combinePathComponents(components: string[]): string { } const root = components[0] && ensureTrailingDirectorySeparator(components[0]); - return normalizeSlashes(root + components.slice(1).join(path.sep)); + const sep = getPathSeparator(root); + return normalizeSlashes(root + components.slice(1).join(sep)); } export function getRelativePath(dirPath: string, relativeTo: string) { @@ -173,10 +201,11 @@ export function getRelativePath(dirPath: string, relativeTo: string) { const pathComponents = getPathComponents(dirPath); const relativeToComponents = getPathComponents(relativeTo); + const sep = getPathSeparator(dirPath); let relativePath = '.'; for (let i = relativeToComponents.length; i < pathComponents.length; i++) { - relativePath += path.sep + pathComponents[i]; + relativePath += sep + pathComponents[i]; } return relativePath; @@ -218,9 +247,11 @@ export function directoryExists(fs: ReadOnlyFileSystem, path: string): boolean { const getInvalidSeparator = (sep: string) => (sep === '/' ? '\\' : '/'); export function normalizeSlashes(pathString: string, sep = path.sep): string { - if (pathString.includes(getInvalidSeparator(sep))) { - const separatorRegExp = /[\\/]/g; - return pathString.replace(separatorRegExp, sep); + if (!isUri(pathString)) { + if (pathString.includes(getInvalidSeparator(sep))) { + const separatorRegExp = /[\\/]/g; + return pathString.replace(separatorRegExp, sep); + } } return pathString; @@ -240,7 +271,7 @@ export function resolvePaths(path: string, ...paths: (string | undefined)[]): st return normalizePath(some(paths) ? combinePaths(path, ...paths) : normalizeSlashes(path)); } -export function combinePaths(pathString: string, ...paths: (string | undefined)[]): string { +function combineFilePaths(pathString: string, ...paths: (string | undefined)[]): string { if (pathString) { pathString = normalizeSlashes(pathString); } @@ -252,7 +283,7 @@ export function combinePaths(pathString: string, ...paths: (string | undefined)[ relativePath = normalizeSlashes(relativePath); - if (!pathString || getRootLength(relativePath) !== 0) { + if (!pathString || getRootLength(relativePath, /* checkUri */ false) !== 0) { pathString = relativePath; } else { pathString = ensureTrailingDirectorySeparator(pathString) + relativePath; @@ -262,6 +293,29 @@ export function combinePaths(pathString: string, ...paths: (string | undefined)[ return pathString; } +export function combinePaths(pathString: string, ...paths: (string | undefined)[]): string { + if (!isUri(pathString)) { + // Not a URI, or a URI with a single letter scheme. + return combineFilePaths(pathString, ...paths); + } + + // Go through the paths to see if any are rooted. If so, treat as + // a file path. On linux this might be wrong if a path starts with '/'. + if (some(paths, (p) => !!p && getRootLength(p, /* checkUri */ false) !== 0)) { + return combineFilePaths(pathString, ...paths); + } + + // Otherwise this is a URI + const nonEmptyPaths = paths.filter((p) => !!p) as string[]; + const uri = URI.parse(pathString); + + // Make sure we have a path to append to. + if (uri.path === '' || uri.path === undefined) { + nonEmptyPaths.unshift('/'); + } + return Utils.joinPath(uri.with({ fragment: '', query: '' }), ...nonEmptyPaths).toString(); +} + /** * Determines whether a `parent` path contains a `child` path using the provide case sensitivity. */ @@ -431,7 +485,9 @@ export function getBaseFileName(pathString: string, extensions?: string | readon // return the trailing portion of the path starting after the last (non-terminal) directory // separator but not including any trailing directory separator. pathString = stripTrailingDirectorySeparator(pathString); - const name = pathString.slice(Math.max(getRootLength(pathString), pathString.lastIndexOf(path.sep) + 1)); + const name = isUri(pathString) + ? Utils.basename(URI.parse(pathString).with({ fragment: '', query: '' })) + : pathString.slice(Math.max(getRootLength(pathString), pathString.lastIndexOf(path.sep) + 1)); const extension = extensions !== undefined && ignoreCase !== undefined ? getAnyExtensionFromPath(name, extensions, ignoreCase) @@ -484,8 +540,9 @@ export function getRelativePathComponentsFromDirectory( } export function ensureTrailingDirectorySeparator(pathString: string): string { + const sep = getPathSeparator(pathString); if (!hasTrailingDirectorySeparator(pathString)) { - return pathString + path.sep; + return pathString + sep; } return pathString; @@ -536,11 +593,16 @@ export function stripFileExtension(fileName: string, multiDotExtension = false) } export function realCasePath(pathString: string, fileSystem: ReadOnlyFileSystem): string { - return normalizePath(fileSystem.realCasePath(pathString)); + return isUri(pathString) ? pathString : fileSystem.realCasePath(pathString); } export function normalizePath(pathString: string): string { - return normalizeSlashes(path.normalize(pathString)); + if (!isUri(pathString)) { + return normalizeSlashes(path.normalize(pathString)); + } + + // Must be a URI, already normalized. + return pathString; } export function isDirectory(fs: ReadOnlyFileSystem, path: string): boolean { @@ -639,13 +701,17 @@ export function getWildcardRegexPattern(rootPath: string, fileSpec: string): str const pathComponents = getPathComponents(absolutePath); - const escapedSeparator = getRegexEscapedSeparator(); + const escapedSeparator = getRegexEscapedSeparator(getPathSeparator(rootPath)); const doubleAsteriskRegexFragment = `(${escapedSeparator}[^${escapedSeparator}][^${escapedSeparator}]*)*?`; const reservedCharacterPattern = new RegExp(`[^\\w\\s${escapedSeparator}]`, 'g'); // Strip the directory separator from the root component. if (pathComponents.length > 0) { pathComponents[0] = stripTrailingDirectorySeparator(pathComponents[0]); + + if (pathComponents[0].startsWith('\\\\')) { + pathComponents[0] = '\\\\' + pathComponents[0]; + } } let regExPattern = ''; @@ -699,6 +765,7 @@ export function getWildcardRoot(rootPath: string, fileSpec: string): string { } const pathComponents = getPathComponents(absolutePath); + const sep = getPathSeparator(absolutePath); // Strip the directory separator from the root component. if (pathComponents.length > 0) { @@ -706,7 +773,7 @@ export function getWildcardRoot(rootPath: string, fileSpec: string): string { } if (pathComponents.length === 1 && !pathComponents[0]) { - return path.sep; + return sep; } let wildcardRoot = ''; @@ -721,7 +788,7 @@ export function getWildcardRoot(rootPath: string, fileSpec: string): string { } if (!firstComponent) { - component = path.sep + component; + component = sep + component; } wildcardRoot += component; @@ -736,12 +803,15 @@ export function hasPythonExtension(path: string) { return path.endsWith('.py') || path.endsWith('.pyi'); } -export function getFileSpec(fs: FileSystem, rootPath: string, fileSpec: string): FileSpec { +export function getFileSpec(sp: ServiceProvider, rootPath: string, fileSpec: string): FileSpec { let regExPattern = getWildcardRegexPattern(rootPath, fileSpec); - const escapedSeparator = getRegexEscapedSeparator(); + const escapedSeparator = getRegexEscapedSeparator(getPathSeparator(rootPath)); regExPattern = `^(${regExPattern})($|${escapedSeparator})`; - const regExp = new RegExp(regExPattern, isFileSystemCaseSensitive(fs) ? undefined : 'i'); + const fs = sp.get(ServiceKeys.fs); + const tmp = sp.tryGet(ServiceKeys.tempFile); + + const regExp = new RegExp(regExPattern, isFileSystemCaseSensitive(fs, tmp) ? undefined : 'i'); const wildcardRoot = getWildcardRoot(rootPath, fileSpec); const hasDirectoryWildcard = isDirectoryWildcardPatternPresent(fileSpec); @@ -752,9 +822,9 @@ export function getFileSpec(fs: FileSystem, rootPath: string, fileSpec: string): }; } -export function getRegexEscapedSeparator() { +export function getRegexEscapedSeparator(pathSep: string = path.sep) { // we don't need to escape "/" in typescript regular expression - return path.sep === '/' ? '/' : '\\\\'; + return pathSep === '/' ? '/' : '\\\\'; } /** @@ -867,16 +937,22 @@ export function convertUriToPath(fs: ReadOnlyFileSystem, uriString: string): str export function extractPathFromUri(uriString: string) { const uri = URI.parse(uriString); - // When schema is "file", we use fsPath so that we can handle things like UNC paths. - let convertedPath = normalizePath(uri.scheme === 'file' ? uri.fsPath : uri.path); + // Only for file scheme do we actually modify anything. All other uri strings + // maintain the same value they started with. + if (uri.scheme === 'file' && !uri.fragment) { + // When schema is "file", we use fsPath so that we can handle things like UNC paths. + let convertedPath = normalizePath(uri.fsPath); - // If this is a DOS-style path with a drive letter, remove - // the leading slash. - if (convertedPath.match(/^\\[a-zA-Z]:\\/)) { - convertedPath = convertedPath.slice(1); + // If this is a DOS-style path with a drive letter, remove + // the leading slash. + if (convertedPath.match(/^\\[a-zA-Z]:\\/)) { + convertedPath = convertedPath.slice(1); + } + + return convertedPath; } - return convertedPath; + return uriString; } export function convertPathToUri(fs: ReadOnlyFileSystem, path: string): string { @@ -889,19 +965,23 @@ export function setTestingMode(underTest: boolean) { const isFileSystemCaseSensitiveMap = new WeakMap(); -export function isFileSystemCaseSensitive(fs: FileSystem) { +export function isFileSystemCaseSensitive(fs: FileSystem, tmp?: TempFile) { + if (!tmp) { + return false; + } + if (!_underTest && _fsCaseSensitivity !== undefined) { return _fsCaseSensitivity; } if (!isFileSystemCaseSensitiveMap.has(fs)) { - _fsCaseSensitivity = isFileSystemCaseSensitiveInternal(fs); + _fsCaseSensitivity = isFileSystemCaseSensitiveInternal(fs, tmp); isFileSystemCaseSensitiveMap.set(fs, _fsCaseSensitivity); } return !!isFileSystemCaseSensitiveMap.get(fs); } -export function isFileSystemCaseSensitiveInternal(fs: FileSystem) { +export function isFileSystemCaseSensitiveInternal(fs: FileSystem, tmp: TempFile) { let filePath: string | undefined = undefined; try { // Make unique file name. @@ -909,8 +989,8 @@ export function isFileSystemCaseSensitiveInternal(fs: FileSystem) { let mangledFilePath: string; do { name = `${randomBytesHex(21)}-a`; - filePath = path.join(fs.tmpdir(), name); - mangledFilePath = path.join(fs.tmpdir(), name.toUpperCase()); + filePath = path.join(tmp.tmpdir(), name); + mangledFilePath = path.join(tmp.tmpdir(), name.toUpperCase()); } while (fs.existsSync(filePath) || fs.existsSync(mangledFilePath)); fs.writeFileSync(filePath, '', 'utf8'); diff --git a/packages/pyright-internal/src/common/pythonVersion.ts b/packages/pyright-internal/src/common/pythonVersion.ts index be1c94066..fd01679e6 100644 --- a/packages/pyright-internal/src/common/pythonVersion.ts +++ b/packages/pyright-internal/src/common/pythonVersion.ts @@ -27,7 +27,7 @@ export enum PythonVersion { V3_13 = 0x030d, } -export const latestStablePythonVersion = PythonVersion.V3_11; +export const latestStablePythonVersion = PythonVersion.V3_12; export function versionToString(version: PythonVersion): string { const majorVersion = (version >> 8) & 0xff; diff --git a/packages/pyright-internal/src/common/realFileSystem.ts b/packages/pyright-internal/src/common/realFileSystem.ts index bdc6d6b30..151361ac5 100644 --- a/packages/pyright-internal/src/common/realFileSystem.ts +++ b/packages/pyright-internal/src/common/realFileSystem.ts @@ -13,7 +13,7 @@ import { isMainThread } from 'worker_threads'; import { ChokidarFileWatcherProvider } from './chokidarFileWatcherProvider'; import { ConsoleInterface, NullConsole } from './console'; -import { FileSystem, MkDirOptions, TmpfileOptions } from './fileSystem'; +import { FileSystem, MkDirOptions, TempFile, TmpfileOptions } from './fileSystem'; import { FileWatcher, FileWatcherEventHandler, @@ -22,7 +22,7 @@ import { FileWatcherProvider, nullFileWatcherProvider, } from './fileWatcher'; -import { combinePaths, getDirectoryPath, getFileName, getRootLength } from './pathUtils'; +import { combinePaths, getRootLength, isUri } from './pathUtils'; // Automatically remove files created by tmp at process exit. tmp.setGracefulCleanup(); @@ -209,8 +209,6 @@ class YarnFS extends PosixFS { const yarnFS = new YarnFS(); class RealFileSystem implements FileSystem { - private _tmpdir?: tmp.DirResult; - constructor(private _fileWatcherProvider: FileWatcherProvider, private _console: ConsoleInterface) {} existsSync(path: string) { @@ -235,21 +233,11 @@ class RealFileSystem implements FileSystem { } readdirSync(path: string): string[] { - return yarnFS.readdirSync(path).map((entry) => { - // Make sure the entry name is the real case. - const fullPath = combinePaths(path, entry); - const realPath = this.realCasePath(fullPath); - return getFileName(realPath); - }); + return yarnFS.readdirSync(path); } readdirEntriesSync(path: string): fs.Dirent[] { return yarnFS.readdirSync(path, { withFileTypes: true }).map((entry): fs.Dirent => { - // Make sure the entry name is the real case. - const fullPath = combinePaths(path, entry.name); - const realPath = this.realCasePath(fullPath); - (entry.name as any) = getFileName(realPath); - // Treat zip/egg files as directories. // See: https://github.com/yarnpkg/berry/blob/master/packages/vscode-zipfs/sources/ZipFSProvider.ts if (hasZipExtension(entry.name)) { @@ -290,12 +278,10 @@ class RealFileSystem implements FileSystem { // See: https://github.com/yarnpkg/berry/blob/master/packages/vscode-zipfs/sources/ZipFSProvider.ts if (hasZipExtension(path)) { if (stat.isFile() && yarnFS.isZip(path)) { - return { - ...stat, - isFile: () => false, - isDirectory: () => true, - isZipDirectory: () => true, - }; + stat.isFile = () => false; + stat.isDirectory = () => true; + (stat as any).isZipDirectory = () => true; + return stat; } } return stat; @@ -355,38 +341,29 @@ class RealFileSystem implements FileSystem { return buffer.toString(encoding); } - tmpdir() { - if (!this._tmpdir) { - this._tmpdir = tmp.dirSync({ prefix: 'pyright' }); - } - - return this._tmpdir.name; - } - - tmpfile(options?: TmpfileOptions): string { - const f = tmp.fileSync({ dir: this.tmpdir(), discardDescriptor: true, ...options }); - return f.name; - } - realCasePath(path: string): string { try { - // If it doesn't exist in the real FS, try going up a level and combining it. - if (!fs.existsSync(path)) { - if (getRootLength(path) <= 0) { - return path; - } - return combinePaths(this.realCasePath(getDirectoryPath(path)), getFileName(path)); + // If it doesn't exist in the real FS, then just use this path. + if (!this.existsSync(path)) { + return this._getNormalizedPath(path); } // If it does exist, skip this for symlinks. - const stat = fs.statSync(path); + const stat = fs.lstatSync(path); if (stat.isSymbolicLink()) { - return path; + return this._getNormalizedPath(path); } // realpathSync.native will return casing as in OS rather than // trying to preserve casing given. - return fs.realpathSync.native(path); + const realCase = fs.realpathSync.native(path); + + // On UNC mapped drives we want to keep the original drive letter. + if (getRootLength(realCase) !== getRootLength(path)) { + return path; + } + + return realCase; } catch (e: any) { // Return as it is, if anything failed. this._console.log(`Failed to get real file system casing for ${path}: ${e}`); @@ -408,6 +385,10 @@ class RealFileSystem implements FileSystem { } getUri(path: string): string { + // If this is not a file path, just return the original path. + if (isUri(path)) { + return path; + } return URI.file(path).toString(); } @@ -415,13 +396,16 @@ class RealFileSystem implements FileSystem { return /[^\\/]\.(?:egg|zip|jar)[\\/]/.test(path) && yarnFS.isZip(path); } - dispose(): void { - try { - this._tmpdir?.removeCallback(); - this._tmpdir = undefined; - } catch { - // ignore + private _getNormalizedPath(path: string) { + const driveLength = getRootLength(path); + + if (driveLength === 0) { + return path; } + + // `vscode` sometimes uses different casing for drive letter. + // Make sure we normalize at least drive letter. + return combinePaths(fs.realpathSync.native(path.substring(0, driveLength)), path.substring(driveLength)); } } @@ -473,3 +457,29 @@ export class WorkspaceFileWatcherProvider implements FileWatcherProvider, FileWa }); } } + +export class RealTempFile implements TempFile { + private _tmpdir?: tmp.DirResult; + + tmpdir() { + if (!this._tmpdir) { + this._tmpdir = tmp.dirSync({ prefix: 'pyright' }); + } + + return this._tmpdir.name; + } + + tmpfile(options?: TmpfileOptions): string { + const f = tmp.fileSync({ dir: this.tmpdir(), discardDescriptor: true, ...options }); + return f.name; + } + + dispose(): void { + try { + this._tmpdir?.removeCallback(); + this._tmpdir = undefined; + } catch { + // ignore + } + } +} diff --git a/packages/pyright-internal/src/common/serviceProvider.ts b/packages/pyright-internal/src/common/serviceProvider.ts index 5ce4ced66..a5db329cc 100644 --- a/packages/pyright-internal/src/common/serviceProvider.ts +++ b/packages/pyright-internal/src/common/serviceProvider.ts @@ -6,31 +6,113 @@ * Container for different services used within the application. */ -interface InternalKey {} +import { addIfUnique, removeArrayElements } from './collectionUtils'; +import * as debug from './debug'; +abstract class InternalKey { + abstract readonly kind: 'singleton' | 'group'; +} + +/** + * Key for singleton service T. + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export class ServiceKey extends InternalKey { + readonly kind = 'singleton'; +} + +/** + * Key for group of service T. + */ // eslint-disable-next-line @typescript-eslint/no-unused-vars -export class ServiceKey implements InternalKey {} +export class GroupServiceKey extends InternalKey { + readonly kind = 'group'; +} + +export type AllServiceKeys = ServiceKey | GroupServiceKey; export class ServiceProvider { - private _container: Map = new Map(); + private _container = new Map(); + + add(key: ServiceKey, value: T | undefined): void; + add(key: GroupServiceKey, value: T): void; + add(key: AllServiceKeys, value: T | undefined): void { + if (key.kind === 'group') { + this._addGroupService(key, value); + return; + } - get items() { - return this._container.entries(); + if (key.kind === 'singleton') { + if (value !== undefined) { + this._container.set(key, value); + } else { + this.remove(key); + } + return; + } + + debug.assertNever(key, `Unknown key type ${typeof key}`); } - add(key: ServiceKey, value: T) { - this._container.set(key, value); + remove(key: ServiceKey): void; + remove(key: GroupServiceKey, value: T): void; + remove(key: AllServiceKeys, value?: T): void { + if (key.kind === 'group') { + this._removeGroupService(key, value); + return; + } + + if (key.kind === 'singleton') { + this._container.delete(key); + return; + } + + debug.assertNever(key, `Unknown key type ${typeof key}`); } - tryGet(key: ServiceKey): T | undefined { + tryGet(key: ServiceKey): T | undefined; + tryGet(key: GroupServiceKey): readonly T[] | undefined; + tryGet(key: AllServiceKeys): T | readonly T[] | undefined { return this._container.get(key); } - get(key: ServiceKey): T { - const value = this.tryGet(key); + get(key: ServiceKey): T; + get(key: GroupServiceKey): readonly T[]; + get(key: AllServiceKeys): T | readonly T[] { + const value = key.kind === 'group' ? this.tryGet(key) : this.tryGet(key); if (value === undefined) { throw new Error(`Global service provider not initialized for ${key.toString()}`); } + return value; } + + clone() { + const serviceProvider = new ServiceProvider(); + this._container.forEach((value, key) => serviceProvider._container.set(key, value)); + + return serviceProvider; + } + + private _addGroupService(key: GroupServiceKey, newValue: T | undefined) { + // Explicitly cast to remove `readonly` + const services = this.tryGet(key) as T[] | undefined; + if (services === undefined) { + this._container.set(key, [newValue]); + return; + } + + if (newValue !== undefined) { + addIfUnique(services, newValue); + } + } + + private _removeGroupService(key: GroupServiceKey, oldValue: T) { + const services = this.tryGet(key) as T[]; + if (services === undefined) { + return; + } + + removeArrayElements(services, (s) => s === oldValue); + } } diff --git a/packages/pyright-internal/src/common/serviceProviderExtensions.ts b/packages/pyright-internal/src/common/serviceProviderExtensions.ts index 27ae04c3a..be280a305 100644 --- a/packages/pyright-internal/src/common/serviceProviderExtensions.ts +++ b/packages/pyright-internal/src/common/serviceProviderExtensions.ts @@ -5,20 +5,26 @@ * * Shortcuts to common services. */ +import { CacheManager } from '../analyzer/cacheManager'; import { ISourceFileFactory } from '../analyzer/program'; import { IPythonMode, SourceFile, SourceFileEditMode } from '../analyzer/sourceFile'; -import { SupportPartialStubs, SupportUriToPathMapping } from '../pyrightFileSystem'; +import { SupportPartialStubs } from '../pyrightFileSystem'; import { ConsoleInterface } from './console'; -import { FileSystem } from './fileSystem'; +import { + StatusMutationListener, + ServiceProvider as ReadOnlyServiceProvider, + SymbolDefinitionProvider, + SymbolUsageProviderFactory, +} from './extensibility'; +import { FileSystem, TempFile } from './fileSystem'; import { LogTracker } from './logTracker'; -import { ServiceKey, ServiceProvider } from './serviceProvider'; +import { GroupServiceKey, ServiceKey, ServiceProvider } from './serviceProvider'; declare module './serviceProvider' { interface ServiceProvider { fs(): FileSystem; console(): ConsoleInterface; sourceFileFactory(): ISourceFileFactory; - uriMapper(): SupportUriToPathMapping; partialStubs(): SupportPartialStubs; } } @@ -28,7 +34,11 @@ export namespace ServiceKeys { export const console = new ServiceKey(); export const sourceFileFactory = new ServiceKey(); export const partialStubs = new ServiceKey(); - export const uriMapper = new ServiceKey(); + export const symbolDefinitionProvider = new GroupServiceKey(); + export const symbolUsageProviderFactory = new GroupServiceKey(); + export const stateMutationListeners = new GroupServiceKey(); + export const tempFile = new ServiceKey(); + export const cacheManager = new ServiceKey(); } export function createServiceProvider(...services: any): ServiceProvider { @@ -48,8 +58,11 @@ export function createServiceProvider(...services: any): ServiceProvider { if (SupportPartialStubs.is(service)) { sp.add(ServiceKeys.partialStubs, service); } - if (SupportUriToPathMapping.is(service)) { - sp.add(ServiceKeys.uriMapper, service); + if (TempFile.is(service)) { + sp.add(ServiceKeys.tempFile, service); + } + if (CacheManager.is(service)) { + sp.add(ServiceKeys.cacheManager, service); } }); return sp; @@ -61,9 +74,6 @@ ServiceProvider.prototype.fs = function () { ServiceProvider.prototype.console = function () { return this.get(ServiceKeys.console); }; -ServiceProvider.prototype.uriMapper = function () { - return this.get(ServiceKeys.uriMapper); -}; ServiceProvider.prototype.partialStubs = function () { return this.get(ServiceKeys.partialStubs); }; @@ -74,7 +84,7 @@ ServiceProvider.prototype.sourceFileFactory = function () { const DefaultSourceFileFactory: ISourceFileFactory = { createSourceFile( - fs: FileSystem, + serviceProvider: ReadOnlyServiceProvider, filePath: string, moduleName: string, isThirdPartyImport: boolean, @@ -86,7 +96,7 @@ const DefaultSourceFileFactory: ISourceFileFactory = { ipythonMode?: IPythonMode ) { return new SourceFile( - fs, + serviceProvider, filePath, moduleName, isThirdPartyImport, diff --git a/packages/pyright-internal/src/common/uriParser.ts b/packages/pyright-internal/src/common/uriParser.ts index dc7dd7a29..33c3f3f12 100644 --- a/packages/pyright-internal/src/common/uriParser.ts +++ b/packages/pyright-internal/src/common/uriParser.ts @@ -14,7 +14,17 @@ import { isString } from './core'; import { FileSystem } from './fileSystem'; import { convertUriToPath } from './pathUtils'; -export class UriParser { +export interface IUriParser { + decodeTextDocumentPosition( + textDocument: TextDocumentIdentifier, + position: Position + ): { filePath: string; position: Position }; + decodeTextDocumentUri(uriString: string): string; + isUntitled(uri: URI | string | undefined): boolean; + isLocal(uri: URI | string | undefined): boolean; +} + +export class UriParser implements IUriParser { constructor(protected readonly fs: FileSystem) {} decodeTextDocumentPosition(textDocument: TextDocumentIdentifier, position: Position) { diff --git a/packages/pyright-internal/src/languageServerBase.ts b/packages/pyright-internal/src/languageServerBase.ts index 0567b35ef..2b6a80cbb 100644 --- a/packages/pyright-internal/src/languageServerBase.ts +++ b/packages/pyright-internal/src/languageServerBase.ts @@ -79,7 +79,6 @@ import { TextDocument } from 'vscode-languageserver-textdocument'; import { formatBufferWithYapf } from '../../pyright-yapf'; import { AnalysisResults } from './analyzer/analysis'; import { BackgroundAnalysisProgram, InvalidatedReason } from './analyzer/backgroundAnalysisProgram'; -import { CacheManager } from './analyzer/cacheManager'; import { ImportResolver } from './analyzer/importResolver'; import { MaxAnalysisTime } from './analyzer/program'; import { AnalyzerService, configFileNames, getNextServiceId } from './analyzer/service'; @@ -103,12 +102,18 @@ import { } from './common/diagnostic'; import { DiagnosticRule } from './common/diagnosticRules'; import { FileDiagnostics } from './common/diagnosticSink'; -import { Extensions } from './common/extensibility'; -import { FileSystem } from './common/fileSystem'; import { FileWatcherEventType, FileWatcherHandler, FileWatcherProvider } from './common/fileWatcher'; +import { FileSystem, ReadOnlyFileSystem } from './common/fileSystem'; import { Host } from './common/host'; import { fromLSPAny } from './common/lspUtils'; -import { convertPathToUri, deduplicateFolders, getDirectoryPath, getFileName, isFile } from './common/pathUtils'; +import { + convertPathToUri, + convertUriToPath, + deduplicateFolders, + getDirectoryPath, + getFileName, + isFile, +} from './common/pathUtils'; import { ProgressReportTracker, ProgressReporter } from './common/progressReporter'; import { ServiceProvider } from './common/serviceProvider'; import { DocumentRange, Position, Range } from './common/textRange'; @@ -118,6 +123,7 @@ import { CallHierarchyProvider } from './languageService/callHierarchyProvider'; import { CompletionItemData, CompletionProvider } from './languageService/completionProvider'; import { DefinitionFilter, DefinitionProvider, TypeDefinitionProvider } from './languageService/definitionProvider'; import { DocumentHighlightProvider } from './languageService/documentHighlightProvider'; +import { CollectionResult } from './languageService/documentSymbolCollector'; import { DocumentSymbolProvider } from './languageService/documentSymbolProvider'; import { HoverProvider } from './languageService/hoverProvider'; import { canNavigateToFile } from './languageService/navigationUtils'; @@ -126,7 +132,7 @@ import { RenameProvider } from './languageService/renameProvider'; import { SignatureHelpProvider } from './languageService/signatureHelpProvider'; import { WorkspaceSymbolProvider } from './languageService/workspaceSymbolProvider'; import { Localizer, setLocaleOverride } from './localization/localize'; -import { SupportUriToPathMapping } from './pyrightFileSystem'; +import { ParseResults } from './parser/parser'; import { InitStatus, WellKnownWorkspaceKinds, Workspace, WorkspaceFactory } from './workspaceFactory'; export interface ServerSettings { @@ -347,11 +353,11 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis protected readonly workspaceFactory: WorkspaceFactory; protected readonly openFileMap = new Map(); - protected readonly cacheManager: CacheManager; - - protected readonly uriMapper: SupportUriToPathMapping; protected readonly fs: FileSystem; + // The URIs for which diagnostics are reported + protected readonly documentsWithDiagnostics = new Set(); + readonly uriParser: UriParser; constructor( @@ -371,9 +377,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis this.console.info(`Server root directory: ${serverOptions.rootDirectory}`); - this.cacheManager = new CacheManager(); - - this.uriMapper = this.serverOptions.serviceProvider.uriMapper(); this.fs = this.serverOptions.serviceProvider.fs(); this.uriParser = uriParserFactory(this.fs); @@ -384,7 +387,8 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis /* isWeb */ false, this.createAnalyzerServiceForWorkspace.bind(this), this.isPythonPathImmutable.bind(this), - this.onWorkspaceCreated.bind(this) + this.onWorkspaceCreated.bind(this), + this.onWorkspaceRemoved.bind(this) ); // Set the working directory to a known location within @@ -402,9 +406,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis // Listen on the connection. this.connection.listen(); - - // Setup extensions - Extensions.createLanguageServiceExtensions(this); } get console(): ConsoleInterface { @@ -454,7 +455,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis backgroundAnalysisProgramFactory: this.createBackgroundAnalysisProgram.bind(this), cancellationProvider: this.serverOptions.cancellationProvider, libraryReanalysisTimeProvider, - cacheManager: this.cacheManager, serviceId, fileSystem: services?.fs ?? this.serverOptions.serviceProvider.fs(), }); @@ -614,8 +614,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis configOptions: ConfigOptions, importResolver: ImportResolver, backgroundAnalysis?: BackgroundAnalysisBase, - maxAnalysisTime?: MaxAnalysisTime, - cacheManager?: CacheManager + maxAnalysisTime?: MaxAnalysisTime ): BackgroundAnalysisProgram { return new BackgroundAnalysisProgram( serviceId, @@ -624,8 +623,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis importResolver, backgroundAnalysis, maxAnalysisTime, - /* disableChecker */ undefined, - cacheManager + /* disableChecker */ undefined ); } @@ -913,14 +911,16 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis params: ReferenceParams, token: CancellationToken, workDoneReporter: WorkDoneProgressReporter, - resultReporter: ResultProgressReporter | undefined + resultReporter: ResultProgressReporter | undefined, + createDocumentRange?: (filePath: string, result: CollectionResult, parseResults: ParseResults) => DocumentRange, + convertToLocation?: (fs: ReadOnlyFileSystem, ranges: DocumentRange) => Location | undefined ): Promise { if (this._pendingFindAllRefsCancellationSource) { this._pendingFindAllRefsCancellationSource.cancel(); this._pendingFindAllRefsCancellationSource = undefined; } - // VS Code doesn't support cancellation of "final all references". + // VS Code doesn't support cancellation of "find all references". // We provide a progress bar a cancellation button so the user can cancel // any long-running actions. const progress = await this.getProgressReporter( @@ -944,12 +944,12 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis } return workspace.service.run((program) => { - return new ReferencesProvider(program, source.token).reportReferences( - filePath, - position, - params.context.includeDeclaration, - resultReporter - ); + return new ReferencesProvider( + program, + source.token, + createDocumentRange, + convertToLocation + ).reportReferences(filePath, position, params.context.includeDeclaration, resultReporter); }, token); } finally { progress.reporter.done(); @@ -1204,11 +1204,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis protected async onDidOpenTextDocument(params: DidOpenTextDocumentParams, ipythonMode = IPythonMode.None) { const filePath = this.uriParser.decodeTextDocumentUri(params.textDocument.uri); - if (!this.uriMapper.addUriMap(params.textDocument.uri, filePath)) { - // We do not support opening 1 file with 2 different uri. - return; - } - let doc = this.openFileMap.get(filePath); if (doc) { // We shouldn't get an open text document request for an already-opened doc. @@ -1230,11 +1225,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis this.recordUserInteractionTime(); const filePath = this.uriParser.decodeTextDocumentUri(params.textDocument.uri); - if (!this.uriMapper.hasUriMapEntry(params.textDocument.uri, filePath)) { - // We do not support opening 1 file with 2 different uri. - return; - } - const doc = this.openFileMap.get(filePath); if (!doc) { // We shouldn't get a change text request for a closed doc. @@ -1254,10 +1244,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis protected async onDidCloseTextDocument(params: DidCloseTextDocumentParams) { const filePath = this.uriParser.decodeTextDocumentUri(params.textDocument.uri); - if (!this.uriMapper.removeUriMap(params.textDocument.uri, filePath)) { - // We do not support opening 1 file with 2 different uri. - return; - } // Send this close to all the workspaces that might contain this file. const workspaces = await this.getContainingWorkspacesForFile(filePath); @@ -1355,8 +1341,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis return; } - this._sendDiagnostics(this.convertDiagnostics(fs, fileDiag)); - this.uriMapper.pendingRequest(fileDiag.filePath, fileDiag.diagnostics.length > 0); + this.sendDiagnostics(this.convertDiagnostics(fs, fileDiag)); }); if (!this._progressReporter.isEnabled(results)) { @@ -1392,6 +1377,27 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis // Otherwise the initialize completion should cause settings to be updated on all workspaces. } + protected onWorkspaceRemoved(workspace: Workspace) { + const documentsWithDiagnosticsList = [...this.documentsWithDiagnostics]; + const otherWorkspaces = this.workspaceFactory.items().filter((w) => w !== workspace); + + for (const uri of documentsWithDiagnosticsList) { + const filePath = convertUriToPath(workspace.service.fs, uri); + + if (workspace.service.isTracked(filePath)) { + // Do not clean up diagnostics for files tracked by multiple workspaces + if (otherWorkspaces.some((w) => w.service.isTracked(filePath))) { + continue; + } + this.sendDiagnostics([ + { + uri: uri, + diagnostics: [], + }, + ]); + } + } + } protected createAnalyzerServiceForWorkspace( name: string, @@ -1464,6 +1470,17 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis }; } + protected sendDiagnostics(params: PublishDiagnosticsParams[]) { + for (const param of params) { + if (param.diagnostics.length === 0) { + this.documentsWithDiagnostics.delete(param.uri); + } else { + this.documentsWithDiagnostics.add(param.uri); + } + this.connection.sendDiagnostics(param); + } + } + private _setupFileWatcher() { if (!this.client.hasWatchFileCapability) { // we won't get notifs from client for changes, let's spawn a watcher to track our own @@ -1499,7 +1516,7 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis }); } - // File watcher is pylance wide service. Dispose all existing file watchers and create new ones. + // Dispose all existing file watchers and create new ones. this.connection.client.register(DidChangeWatchedFilesNotification.type, { watchers }).then((d) => { if (this._lastFileWatcherRegistration) { this._lastFileWatcherRegistration.dispose(); @@ -1509,12 +1526,6 @@ export abstract class LanguageServerBase implements LanguageServerInterface, Dis }); } - private _sendDiagnostics(params: PublishDiagnosticsParams[]) { - for (const param of params) { - this.connection.sendDiagnostics(param); - } - } - private _getCompatibleMarkupKind(clientSupportedFormats: MarkupKind[] | undefined) { const serverSupportedFormats = [MarkupKind.PlainText, MarkupKind.Markdown]; diff --git a/packages/pyright-internal/src/languageService/autoImporter.ts b/packages/pyright-internal/src/languageService/autoImporter.ts index 4d98883f8..0fc2701c7 100644 --- a/packages/pyright-internal/src/languageService/autoImporter.ts +++ b/packages/pyright-internal/src/languageService/autoImporter.ts @@ -54,9 +54,11 @@ export type ModuleSymbolMap = Map; export interface AutoImportResult { readonly name: string; + readonly declPath: string; + readonly originalDeclPath: string; + readonly insertionText: string; readonly symbol?: Symbol; readonly source?: string; - readonly insertionText: string; readonly edits?: TextEditAction[]; readonly alias?: string; readonly kind?: CompletionItemKind; @@ -83,6 +85,7 @@ export interface ImportAliasData { readonly symbol?: Symbol; readonly kind?: SymbolKind; readonly itemKind?: CompletionItemKind; + readonly filePath: string; } export type AutoImportResultMap = Map; @@ -289,6 +292,8 @@ export class AutoImporter { source: importAliasData.importParts.importFrom, insertionText: autoImportTextEdits.insertionText, edits: autoImportTextEdits.edits, + declPath: importAliasData.importParts.filePath, + originalDeclPath: importAliasData.filePath, }); }); }); @@ -348,6 +353,7 @@ export class AutoImporter { symbol: autoImportSymbol.symbol, kind: autoImportSymbol.importAlias.kind, itemKind: autoImportSymbol.importAlias.itemKind, + filePath: autoImportSymbol.importAlias.modulePath, }, importAliasMap ); @@ -371,6 +377,8 @@ export class AutoImporter { kind: autoImportSymbol.itemKind ?? convertSymbolKindToCompletionItemKind(autoImportSymbol.kind), insertionText: autoImportTextEdits.insertionText, edits: autoImportTextEdits.edits, + declPath: moduleFilePath, + originalDeclPath: moduleFilePath, }); }); @@ -403,7 +411,13 @@ export class AutoImporter { kind: SymbolKind.Module, itemKind: CompletionItemKind.Module, }, - { importParts, importGroup, kind: SymbolKind.Module, itemKind: CompletionItemKind.Module }, + { + importParts, + importGroup, + kind: SymbolKind.Module, + itemKind: CompletionItemKind.Module, + filePath: moduleFilePath, + }, importAliasMap ); } diff --git a/packages/pyright-internal/src/languageService/callHierarchyProvider.ts b/packages/pyright-internal/src/languageService/callHierarchyProvider.ts index f1857cd62..2e60e8290 100644 --- a/packages/pyright-internal/src/languageService/callHierarchyProvider.ts +++ b/packages/pyright-internal/src/languageService/callHierarchyProvider.ts @@ -21,13 +21,12 @@ import * as DeclarationUtils from '../analyzer/declarationUtils'; import * as ParseTreeUtils from '../analyzer/parseTreeUtils'; import { ParseTreeWalker } from '../analyzer/parseTreeWalker'; import { isUserCode } from '../analyzer/sourceFileInfoUtils'; -import { SourceMapper } from '../analyzer/sourceMapper'; import { TypeEvaluator } from '../analyzer/typeEvaluatorTypes'; import { ClassMemberLookupFlags, doForEachSubtype, lookUpClassMember, lookUpObjectMember } from '../analyzer/typeUtils'; import { ClassType, isClassInstance, isFunction, isInstantiableClass } from '../analyzer/types'; import { throwIfCancellationRequested } from '../common/cancellationUtils'; import { appendArray } from '../common/collectionUtils'; -import { ProgramView } from '../common/extensibility'; +import { ProgramView, ReferenceUseCase, SymbolUsageProvider } from '../common/extensibility'; import { getSymbolKind } from '../common/lspUtils'; import { convertPathToUri, getFileName } from '../common/pathUtils'; import { convertOffsetsToRange } from '../common/positionUtils'; @@ -35,12 +34,13 @@ import { Position, rangesAreEqual } from '../common/textRange'; import { ReferencesProvider, ReferencesResult } from '../languageService/referencesProvider'; import { CallNode, MemberAccessNode, NameNode, ParseNode, ParseNodeType } from '../parser/parseNodes'; import { ParseResults } from '../parser/parser'; -import { DocumentSymbolCollector, DocumentSymbolCollectorUseCase } from './documentSymbolCollector'; +import { DocumentSymbolCollector } from './documentSymbolCollector'; import { canNavigateToFile } from './navigationUtils'; +import { ServiceKeys } from '../common/serviceProviderExtensions'; +import { isDefined } from '../common/core'; export class CallHierarchyProvider { private readonly _parseResults: ParseResults | undefined; - private readonly _sourceMapper: SourceMapper; constructor( private _program: ProgramView, @@ -49,7 +49,6 @@ export class CallHierarchyProvider { private _token: CancellationToken ) { this._parseResults = this._program.getParseResults(this._filePath); - this._sourceMapper = this._program.getSourceMapper(this._filePath, this._token); } onPrepare(): CallHierarchyItem[] | null { @@ -123,12 +122,7 @@ export class CallHierarchyProvider { for (const curSourceFileInfo of sourceFiles) { if (isUserCode(curSourceFileInfo) || curSourceFileInfo.isOpenByClient) { const filePath = curSourceFileInfo.sourceFile.getFilePath(); - const itemsToAdd = this._getIncomingCallsForDeclaration( - this._program.getParseResults(filePath)!, - filePath, - symbolName, - targetDecl - ); + const itemsToAdd = this._getIncomingCallsForDeclaration(filePath, symbolName, targetDecl); if (itemsToAdd) { appendArray(items, itemsToAdd); @@ -272,7 +266,6 @@ export class CallHierarchyProvider { } private _getIncomingCallsForDeclaration( - parseResults: ParseResults, filePath: string, symbolName: string, declaration: Declaration @@ -280,13 +273,11 @@ export class CallHierarchyProvider { throwIfCancellationRequested(this._token); const callFinder = new FindIncomingCallTreeWalker( + this._program, filePath, symbolName, declaration, - parseResults, - this._evaluator, - this._token, - this._program + this._token ); const incomingCalls = callFinder.findCalls(); @@ -299,7 +290,7 @@ export class CallHierarchyProvider { this._filePath, this._position, /* reporter */ undefined, - DocumentSymbolCollectorUseCase.Reference, + ReferenceUseCase.References, this._token ); } @@ -438,18 +429,30 @@ class FindOutgoingCallTreeWalker extends ParseTreeWalker { } class FindIncomingCallTreeWalker extends ParseTreeWalker { - private _incomingCalls: CallHierarchyIncomingCall[] = []; + private readonly _incomingCalls: CallHierarchyIncomingCall[] = []; + private readonly _declarations: Declaration[] = []; + + private readonly _usageProviders: SymbolUsageProvider[]; + private readonly _parseResults: ParseResults; constructor( - private _filePath: string, - private _symbolName: string, - private _declaration: Declaration, - private _parseResults: ParseResults, - private _evaluator: TypeEvaluator, - private _cancellationToken: CancellationToken, - private _program: ProgramView + private readonly _program: ProgramView, + private readonly _filePath: string, + private readonly _symbolName: string, + private readonly _targetDeclaration: Declaration, + private readonly _cancellationToken: CancellationToken ) { super(); + + this._parseResults = this._program.getParseResults(this._filePath)!; + this._usageProviders = (this._program.serviceProvider.tryGet(ServiceKeys.symbolUsageProviderFactory) ?? []) + .map((f) => + f.tryCreateProvider(ReferenceUseCase.References, [this._targetDeclaration], this._cancellationToken) + ) + .filter(isDefined); + + this._declarations.push(this._targetDeclaration); + this._usageProviders.forEach((p) => p.appendDeclarationsTo(this._declarations)); } findCalls(): CallHierarchyIncomingCall[] { @@ -461,7 +464,6 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker { throwIfCancellationRequested(this._cancellationToken); let nameNode: NameNode | undefined; - if (node.leftExpression.nodeType === ParseNodeType.Name) { nameNode = node.leftExpression; } else if (node.leftExpression.nodeType === ParseNodeType.MemberAccess) { @@ -470,18 +472,11 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker { // Don't bother doing any more work if the name doesn't match. if (nameNode && nameNode.value === this._symbolName) { - const declarations = DocumentSymbolCollector.getDeclarationsForNode( - this._program, - nameNode, - /* resolveLocalName */ true, - DocumentSymbolCollectorUseCase.Reference, - this._cancellationToken - ); - + const declarations = this._getDeclarations(nameNode); if (declarations) { - if (this._declaration.type === DeclarationType.Alias) { + if (this._targetDeclaration.type === DeclarationType.Alias) { const resolvedCurDecls = this._evaluator.resolveAliasDeclaration( - this._declaration, + this._targetDeclaration, /* resolveLocalNames */ true ); if ( @@ -491,7 +486,9 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker { this._addIncomingCallForDeclaration(nameNode!); } } else if ( - declarations.some((decl) => DeclarationUtils.areDeclarationsSame(decl!, this._declaration)) + declarations.some((decl) => + this._declarations.some((t) => DeclarationUtils.areDeclarationsSame(decl, t)) + ) ) { this._addIncomingCallForDeclaration(nameNode!); } @@ -532,7 +529,11 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker { return; } - if (propertyDecls.some((decl) => DeclarationUtils.areDeclarationsSame(decl!, this._declaration))) { + if ( + propertyDecls.some((decl) => + DeclarationUtils.areDeclarationsSame(decl!, this._targetDeclaration) + ) + ) { this._addIncomingCallForDeclaration(node.memberName); } }); @@ -542,6 +543,24 @@ class FindIncomingCallTreeWalker extends ParseTreeWalker { return true; } + private get _evaluator(): TypeEvaluator { + return this._program.evaluator!; + } + + private _getDeclarations(node: NameNode) { + const declarations = DocumentSymbolCollector.getDeclarationsForNode( + this._program, + node, + /* resolveLocalName */ true, + this._cancellationToken + ); + + const results = [...declarations]; + this._usageProviders.forEach((p) => p.appendDeclarationsAt(node, declarations, results)); + + return results; + } + private _addIncomingCallForDeclaration(nameNode: NameNode) { const executionNode = ParseTreeUtils.getExecutionScopeNode(nameNode); if (!executionNode) { diff --git a/packages/pyright-internal/src/languageService/completionProvider.ts b/packages/pyright-internal/src/languageService/completionProvider.ts index dbf7d6e05..b1be52523 100644 --- a/packages/pyright-internal/src/languageService/completionProvider.ts +++ b/packages/pyright-internal/src/languageService/completionProvider.ts @@ -24,7 +24,6 @@ import { Declaration, DeclarationType, FunctionDeclaration, - isFunctionDeclaration, isIntrinsicDeclaration, isVariableDeclaration, VariableDeclaration, @@ -32,6 +31,7 @@ import { import { isDefinedInFile } from '../analyzer/declarationUtils'; import { convertDocStringToMarkdown, convertDocStringToPlainText } from '../analyzer/docStringConversion'; import { ImportedModuleDescriptor } from '../analyzer/importResolver'; +import { ImportResult } from '../analyzer/importResult'; import { isTypedKwargs } from '../analyzer/parameterUtils'; import * as ParseTreeUtils from '../analyzer/parseTreeUtils'; import { getCallNodeAndActiveParameterIndex } from '../analyzer/parseTreeUtils'; @@ -46,13 +46,13 @@ import { CallSignatureInfo, TypeEvaluator } from '../analyzer/typeEvaluatorTypes import { printLiteralValue } from '../analyzer/typePrinter'; import { ClassType, + combineTypes, FunctionType, isClass, isClassInstance, isFunction, isInstantiableClass, isModule, - isNoneInstance, isOverloadedFunction, isUnknown, Type, @@ -62,13 +62,14 @@ import { import { ClassMemberLookupFlags, containsLiteralType, + doForEachSignature, doForEachSubtype, getMembersForClass, getMembersForModule, isLiteralType, isMaybeDescriptorInstance, + isNoneInstance, lookUpClassMember, - lookUpObjectMember, } from '../analyzer/typeUtils'; import { throwIfCancellationRequested } from '../common/cancellationUtils'; import { appendArray } from '../common/collectionUtils'; @@ -83,6 +84,7 @@ import * as StringUtils from '../common/stringUtils'; import { comparePositions, Position, TextRange } from '../common/textRange'; import { TextRangeCollection } from '../common/textRangeCollection'; import { convertToTextEdits } from '../common/workspaceEditUtils'; +import { Localizer } from '../localization/localize'; import { ArgumentCategory, DecoratorNode, @@ -124,8 +126,6 @@ import { } from './completionProviderUtils'; import { DocumentSymbolCollector } from './documentSymbolCollector'; import { getAutoImportText, getDocumentationPartsForTypeAndDecl } from './tooltipUtils'; -import { ImportResult } from '../analyzer/importResult'; -import { Localizer } from '../localization/localize'; namespace Keywords { const base: string[] = [ @@ -2118,41 +2118,42 @@ export class CompletionProvider { return values; } - private _getIndexerKeyType(baseType: ClassType) { - // Handle dict type - if (ClassType.isBuiltIn(baseType, 'dict') || ClassType.isBuiltIn(baseType, 'Mapping')) { - if (baseType.typeArguments?.length === 2) { - return baseType.typeArguments[0]; - } - } + private _getIndexKeyType(baseType: ClassType) { + // Handle __getitem__. + const getItemType = this.evaluator.getBoundMethod(baseType, '__getitem__'); + if (getItemType) { + const typesToCombine: Type[] = []; - // Handle simple __getitem__ - const member = lookUpObjectMember(baseType, '__getitem__'); - if (member?.symbol.hasDeclarations()) { - const declaration = member.symbol.getDeclarations()[0]; - if (isFunctionDeclaration(declaration) && declaration.isMethod) { - const getItemType = this.evaluator.getTypeForDeclaration(declaration)?.type; - if (getItemType && isFunction(getItemType) && getItemType.details.parameters.length === 2) { - return getItemType.details.parameters[1].type; + // Handle both overloaded and non-overloaded functions. + doForEachSignature(getItemType, (signature) => { + if ( + signature.details.parameters.length >= 1 && + signature.details.parameters[0].category === ParameterCategory.Simple + ) { + typesToCombine.push(FunctionType.getEffectiveParameterType(signature, 0)); } + }); + + if (typesToCombine.length > 0) { + return combineTypes(typesToCombine); } } return undefined; } - private _getIndexerKeys(indexNode: IndexNode, invocationNode: ParseNode) { + private _getIndexKeys(indexNode: IndexNode, invocationNode: ParseNode) { const baseType = this.evaluator.getType(indexNode.baseExpression); if (!baseType || !isClassInstance(baseType)) { return []; } - // See whether indexer key is typed using Literal types. If it is, return those literal keys. - const keyType = this._getIndexerKeyType(baseType); - if (keyType) { + // See whether subscript is typed using Literal types. If it is, return those literal keys. + const subscriptType = this._getIndexKeyType(baseType); + if (subscriptType) { const keys: string[] = []; - this._getSubTypesWithLiteralValues(keyType).forEach((v) => { + this._getSubTypesWithLiteralValues(subscriptType).forEach((v) => { if ( !ClassType.isBuiltIn(v, 'str') && !ClassType.isBuiltIn(v, 'int') && @@ -2376,7 +2377,7 @@ export class CompletionProvider { } const quoteInfo = this._getQuoteInfo(priorWord, priorTextInString); - const keys = this._getIndexerKeys(argument.parent, parseNode); + const keys = this._getIndexKeys(argument.parent, parseNode); let keyFound = false; for (const key of keys) { diff --git a/packages/pyright-internal/src/languageService/definitionProvider.ts b/packages/pyright-internal/src/languageService/definitionProvider.ts index 2f3d846fe..32ae95762 100644 --- a/packages/pyright-internal/src/languageService/definitionProvider.ts +++ b/packages/pyright-internal/src/languageService/definitionProvider.ts @@ -22,11 +22,12 @@ import { TypeCategory, isOverloadedFunction } from '../analyzer/types'; import { throwIfCancellationRequested } from '../common/cancellationUtils'; import { appendArray } from '../common/collectionUtils'; import { isDefined } from '../common/core'; -import { DeclarationUseCase, Extensions, ProgramView } from '../common/extensibility'; +import { ProgramView, ServiceProvider } from '../common/extensibility'; import { convertPositionToOffset } from '../common/positionUtils'; import { DocumentRange, Position, rangesAreEqual } from '../common/textRange'; import { ParseNode, ParseNodeType } from '../parser/parseNodes'; import { ParseResults } from '../parser/parser'; +import { ServiceKeys } from '../common/serviceProviderExtensions'; export enum DefinitionFilter { All = 'all', @@ -134,6 +135,7 @@ class DefinitionProviderBase { protected constructor( protected readonly sourceMapper: SourceMapper, protected readonly evaluator: TypeEvaluator, + private readonly _serviceProvider: ServiceProvider | undefined, protected readonly node: ParseNode | undefined, protected readonly offset: number, private readonly _filter: DefinitionFilter, @@ -145,19 +147,13 @@ class DefinitionProviderBase { const definitions: DocumentRange[] = []; - // Let extensions have a try first. - Extensions.getProgramExtensions(node).forEach((e) => { - if (e.declarationProviderExtension) { - const declarations = e.declarationProviderExtension.tryGetDeclarations( - this.evaluator, - node, - offset, - DeclarationUseCase.Definition, - this.token - ); + const factories = this._serviceProvider?.tryGet(ServiceKeys.symbolDefinitionProvider); + if (factories) { + factories.forEach((f) => { + const declarations = f.tryGetDeclarations(node, offset, this.token); this.resolveDeclarations(declarations, definitions); - } - }); + }); + } // There should be only one 'definition', so only if extensions failed should we try again. if (definitions.length === 0) { @@ -194,7 +190,7 @@ export class DefinitionProvider extends DefinitionProviderBase { const parseResults = program.getParseResults(filePath); const { node, offset } = _tryGetNode(parseResults, position); - super(sourceMapper, program.evaluator!, node, offset, filter, token); + super(sourceMapper, program.evaluator!, program.serviceProvider, node, offset, filter, token); } static getDefinitionsForNode( @@ -204,7 +200,15 @@ export class DefinitionProvider extends DefinitionProviderBase { offset: number, token: CancellationToken ) { - const provider = new DefinitionProviderBase(sourceMapper, evaluator, node, offset, DefinitionFilter.All, token); + const provider = new DefinitionProviderBase( + sourceMapper, + evaluator, + undefined, + node, + offset, + DefinitionFilter.All, + token + ); return provider.getDefinitionsForNode(node, offset); } @@ -225,7 +229,7 @@ export class TypeDefinitionProvider extends DefinitionProviderBase { const parseResults = program.getParseResults(filePath); const { node, offset } = _tryGetNode(parseResults, position); - super(sourceMapper, program.evaluator!, node, offset, DefinitionFilter.All, token); + super(sourceMapper, program.evaluator!, program.serviceProvider, node, offset, DefinitionFilter.All, token); this._filePath = filePath; } diff --git a/packages/pyright-internal/src/languageService/documentHighlightProvider.ts b/packages/pyright-internal/src/languageService/documentHighlightProvider.ts index 1e8860f6d..77c187ef0 100644 --- a/packages/pyright-internal/src/languageService/documentHighlightProvider.ts +++ b/packages/pyright-internal/src/languageService/documentHighlightProvider.ts @@ -12,7 +12,7 @@ import { CancellationToken, DocumentHighlight, DocumentHighlightKind } from 'vsc import * as ParseTreeUtils from '../analyzer/parseTreeUtils'; import { throwIfCancellationRequested } from '../common/cancellationUtils'; -import { ProgramView } from '../common/extensibility'; +import { ProgramView, ReferenceUseCase } from '../common/extensibility'; import { convertOffsetsToRange, convertPositionToOffset } from '../common/positionUtils'; import { Position, TextRange } from '../common/textRange'; import { ParseNodeType } from '../parser/parseNodes'; @@ -56,7 +56,10 @@ export class DocumentHighlightProvider { node, this._token, this._parseResults.parseTree, - /* treatModuleInImportAndFromImportSame */ true + { + treatModuleInImportAndFromImportSame: true, + useCase: ReferenceUseCase.References, + } ); const lines = this._parseResults.tokenizerOutput.lines; diff --git a/packages/pyright-internal/src/languageService/documentSymbolCollector.ts b/packages/pyright-internal/src/languageService/documentSymbolCollector.ts index bc46152f7..dd3543415 100644 --- a/packages/pyright-internal/src/languageService/documentSymbolCollector.ts +++ b/packages/pyright-internal/src/languageService/documentSymbolCollector.ts @@ -11,20 +11,12 @@ import { CancellationToken } from 'vscode-languageserver'; import * as AnalyzerNodeInfo from '../analyzer/analyzerNodeInfo'; -import { - AliasDeclaration, - Declaration, - DeclarationType, - FunctionDeclaration, - isAliasDeclaration, - isFunctionDeclaration, -} from '../analyzer/declaration'; +import { AliasDeclaration, Declaration, DeclarationType, isAliasDeclaration } from '../analyzer/declaration'; import { areDeclarationsSame, createSynthesizedAliasDeclaration, getDeclarationsWithUsesLocalNameRemoved, } from '../analyzer/declarationUtils'; -import * as ParseTreeUtils from '../analyzer/parseTreeUtils'; import { getModuleNode, getStringNodeValueRange } from '../analyzer/parseTreeUtils'; import { ParseTreeWalker } from '../analyzer/parseTreeWalker'; import { ScopeType } from '../analyzer/scope'; @@ -34,74 +26,121 @@ import { collectImportedByCells } from '../analyzer/sourceFileInfoUtils'; import { isStubFile } from '../analyzer/sourceMapper'; import { Symbol } from '../analyzer/symbol'; import { TypeEvaluator } from '../analyzer/typeEvaluatorTypes'; -import { ClassMemberLookupFlags, lookUpClassMember } from '../analyzer/typeUtils'; -import { TypeCategory, isInstantiableClass } from '../analyzer/types'; +import { TypeCategory } from '../analyzer/types'; import { throwIfCancellationRequested } from '../common/cancellationUtils'; import { appendArray } from '../common/collectionUtils'; import { assert } from '../common/debug'; -import { DeclarationUseCase, Extensions, ProgramView } from '../common/extensibility'; +import { ProgramView, ReferenceUseCase, SymbolUsageProvider } from '../common/extensibility'; import { TextRange } from '../common/textRange'; -import { - ClassNode, - FunctionNode, - ImportAsNode, - NameNode, - ParseNode, - ParseNodeType, - StringListNode, - StringNode, -} from '../parser/parseNodes'; +import { ImportAsNode, NameNode, ParseNode, ParseNodeType, StringListNode, StringNode } from '../parser/parseNodes'; +import { ServiceKeys } from '../common/serviceProviderExtensions'; +import { isDefined } from '../common/core'; export type CollectionResult = { node: NameNode | StringNode; range: TextRange; }; -export enum DocumentSymbolCollectorUseCase { - Rename, - Reference, +export interface DocumentSymbolCollectorOptions { + readonly treatModuleInImportAndFromImportSame?: boolean; + readonly skipUnreachableCode?: boolean; + readonly useCase?: ReferenceUseCase; + + /** + * If `providers` are set, `collector` will assume + * `appendSymbolNamesTo` and `appendDeclarationsTo` have already + * been handled and will not call them again. + * + * If `collector` will result in the same `providers`, `symbolNames`, and `decls` for + * all files, set `providers` so that `collector` doesn't need to perform the same work + * repeatedly for all files. + */ + readonly providers?: readonly SymbolUsageProvider[]; +} + +// 99% of time, `find all references` is looking for a symbol imported from the other file to this file. +// By caching the result of `resolveAlias` we only need to resolve it once per a file. +const withLocalNamesCacheIndex = 0; +const withoutLocalNamesCacheIndex = 1; + +type CacheEntry = { original: Declaration; resolved: Declaration | undefined } | undefined; + +export class AliasResolver { + private readonly _caches: CacheEntry[] = [undefined, undefined]; + + constructor(private readonly _evaluator: TypeEvaluator) { + // Empty + } + + resolve(declaration: Declaration, resolveLocalNames: boolean): Declaration | undefined { + const index = resolveLocalNames ? withLocalNamesCacheIndex : withoutLocalNamesCacheIndex; + + if (this._caches[index] && this._caches[index]!.original === declaration) { + return this._caches[index]!.resolved; + } + + const resolved = this._evaluator.resolveAliasDeclaration(declaration, resolveLocalNames, { + allowExternallyHiddenAccess: true, + skipFileNeededCheck: true, + }); + + this._caches[index] = { original: declaration, resolved }; + return resolved; + } } // This walker looks for symbols that are semantically equivalent // to the requested symbol. export class DocumentSymbolCollector extends ParseTreeWalker { - private _results: CollectionResult[] = []; - private _dunderAllNameNodes = new Set(); - private _initFunction: FunctionNode | undefined; - private _symbolNames: Set = new Set(); + private readonly _results: CollectionResult[] = []; + private readonly _dunderAllNameNodes = new Set(); + private readonly _symbolNames: Set = new Set(); + private readonly _declarations: Declaration[] = []; + + private readonly _usageProviders: readonly SymbolUsageProvider[]; + private readonly _treatModuleInImportAndFromImportSame: boolean; + private readonly _skipUnreachableCode: boolean; + private readonly _useCase: ReferenceUseCase; + + private _aliasResolver: AliasResolver; constructor( - private _program: ProgramView, + private readonly _program: ProgramView, symbolNames: string[], - private _declarations: Declaration[], - private _cancellationToken: CancellationToken, - private _startingNode: ParseNode, - private _treatModuleInImportAndFromImportSame = false, - private _skipUnreachableCode = true, - private _useCase = DocumentSymbolCollectorUseCase.Reference + declarations: Declaration[], + private readonly _startingNode: ParseNode, + private readonly _cancellationToken: CancellationToken, + options?: DocumentSymbolCollectorOptions ) { super(); + this._aliasResolver = new AliasResolver(this._program.evaluator!); + // Start with the symbols passed in symbolNames.forEach((s) => this._symbolNames.add(s)); + this._declarations.push(...declarations); + + this._treatModuleInImportAndFromImportSame = options?.treatModuleInImportAndFromImportSame ?? false; + this._skipUnreachableCode = options?.skipUnreachableCode ?? true; + this._useCase = options?.useCase ?? ReferenceUseCase.References; + + this._usageProviders = + options?.providers ?? + (this._program.serviceProvider.tryGet(ServiceKeys.symbolUsageProviderFactory) ?? []) + .map((f) => f.tryCreateProvider(this._useCase, declarations, this._cancellationToken)) + .filter(isDefined); + + if (options?.providers === undefined) { + // Check whether we need to add new symbol names and declarations. + this._usageProviders.forEach((p) => { + p.appendSymbolNamesTo(this._symbolNames); + p.appendDeclarationsTo(this._declarations); + }); + } // Don't report strings in __all__ right away, that will // break the assumption on the result ordering. this._setDunderAllNodes(this._startingNode); - - // Check if one of our symbols is __init__ and we - // have a class declaration in the list and we are - // computing symbols for references and not rename. - const initDeclaration = _declarations.find( - (d) => d.type === DeclarationType.Function && d.node.name.value === '__init__' - ); - if (initDeclaration && _useCase === DocumentSymbolCollectorUseCase.Reference) { - const classDeclaration = _declarations.find((d) => d.type === DeclarationType.Class); - if (classDeclaration) { - this._initFunction = initDeclaration.node as FunctionNode; - this._symbolNames.add((classDeclaration.node as ClassNode).name.value); - } - } } static collectFromNode( @@ -109,17 +148,9 @@ export class DocumentSymbolCollector extends ParseTreeWalker { node: NameNode, cancellationToken: CancellationToken, startingNode?: ParseNode, - treatModuleInImportAndFromImportSame = false, - skipUnreachableCode = true, - useCase = DocumentSymbolCollectorUseCase.Reference + options?: DocumentSymbolCollectorOptions ): CollectionResult[] { - const declarations = this.getDeclarationsForNode( - program, - node, - /* resolveLocalName */ true, - useCase, - cancellationToken - ); + const declarations = this.getDeclarationsForNode(program, node, /* resolveLocalName */ true, cancellationToken); startingNode = startingNode ?? getModuleNode(node); if (!startingNode) { @@ -130,11 +161,9 @@ export class DocumentSymbolCollector extends ParseTreeWalker { program, [node.value], declarations, - cancellationToken, startingNode, - treatModuleInImportAndFromImportSame, - skipUnreachableCode, - useCase + cancellationToken, + options ); return collector.collect(); @@ -144,7 +173,6 @@ export class DocumentSymbolCollector extends ParseTreeWalker { program: ProgramView, node: NameNode, resolveLocalName: boolean, - useCase: DocumentSymbolCollectorUseCase, token: CancellationToken ): Declaration[] { throwIfCancellationRequested(token); @@ -154,14 +182,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker { return []; } - const declarations = this._getDeclarationsForNode( - node, - useCase, - evaluator, - token, - /* skipUnreachableCode */ false - ); - + const declarations = getDeclarationsForNameNode(evaluator, node, /* skipUnreachableCode */ false); const fileInfo = AnalyzerNodeInfo.getFileInfo(node); const resolvedDeclarations: Declaration[] = []; @@ -169,12 +190,12 @@ export class DocumentSymbolCollector extends ParseTreeWalker { declarations.forEach((decl) => { const resolvedDecl = evaluator.resolveAliasDeclaration(decl, resolveLocalName); if (resolvedDecl) { - this._addIfUnique(resolvedDeclarations, resolvedDecl); + addDeclarationIfUnique(resolvedDeclarations, resolvedDecl); if (sourceMapper && isStubFile(resolvedDecl.path)) { const implDecls = sourceMapper.findDeclarations(resolvedDecl); for (const implDecl of implDecls) { if (implDecl && implDecl.path) { - this._addIfUnique(resolvedDeclarations, implDecl); + addDeclarationIfUnique(resolvedDeclarations, implDecl); } } } @@ -212,7 +233,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker { .forEach((decl) => { const resolvedDecl = evaluator!.resolveAliasDeclaration(decl, resolveLocalName); if (resolvedDecl) { - DocumentSymbolCollector._addIfUnique(declarations, resolvedDecl); + addDeclarationIfUnique(declarations, resolvedDecl); } }); } @@ -238,17 +259,10 @@ export class DocumentSymbolCollector extends ParseTreeWalker { } if (this._declarations.length > 0) { - const declarations = DocumentSymbolCollector._getDeclarationsForNode( - node, - this._useCase, - this._evaluator, - this._cancellationToken, - this._skipUnreachableCode - ); - + const declarations = getDeclarationsForNameNode(this._evaluator, node, this._skipUnreachableCode); if (declarations && declarations.length > 0) { // Does this name share a declaration with the symbol of interest? - if (declarations.some((decl) => this._resultsContainsDeclaration(decl, node))) { + if (this._resultsContainsDeclaration(node, declarations)) { this._addResult(node); } } @@ -269,6 +283,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker { this._addResult(matching); } } + return super.visitStringList(node); } @@ -291,12 +306,8 @@ export class DocumentSymbolCollector extends ParseTreeWalker { this._results.push({ node, range }); } - private _isDeclarationAllowed(resolvedDecl: Declaration, referenceNode: ParseNode) { - // Declaration is allowed if: - // Matches one of our declarations. - // and -- - // That match is the right kind. - const match = this._declarations.find((decl) => + private _isDeclarationAllowed(resolvedDecl: Declaration) { + return this._declarations.some((decl) => areDeclarationsSame( decl, resolvedDecl, @@ -304,47 +315,34 @@ export class DocumentSymbolCollector extends ParseTreeWalker { /* skipRangeForAliases */ true ) ); - if (match) { - // Special case for __init__ being one of our symbol names and we - // have a class name as the other. - if (this._initFunction) { - // If this is a method, must be an __init__ reference. - if (match.type === DeclarationType.Function) { - return true; - } else if (match.type === DeclarationType.Class) { - // If this is a class type match, only match on class calls. - // Meaning something like so: - // a = ClassA() - return referenceNode.parent?.nodeType === ParseNodeType.Call; - } - return false; - } - return true; - } - return false; } - private _resultsContainsDeclaration(declaration: Declaration, referenceNode: ParseNode) { - // Resolve the declaration. - const resolvedDecl = this._evaluator.resolveAliasDeclaration(declaration, /* resolveLocalNames */ false); - if (!resolvedDecl) { - return false; - } + private _resultsContainsDeclaration(usage: ParseNode, declarations: readonly Declaration[]) { + const results = [...declarations]; + this._usageProviders.forEach((p) => p.appendDeclarationsAt(usage, declarations, results)); - // The reference results declarations are already resolved, so we don't - // need to call resolveAliasDeclaration on them. - if (this._isDeclarationAllowed(resolvedDecl, referenceNode)) { - return true; - } + return results.some((declaration) => { + // Resolve the declaration. + const resolvedDecl = this._aliasResolver.resolve(declaration, /* resolveLocalNames */ false); + if (!resolvedDecl) { + return false; + } - // We didn't find the declaration using local-only alias resolution. Attempt - // it again by fully resolving the alias. - const resolvedDeclNonlocal = this._getResolveAliasDeclaration(resolvedDecl); - if (!resolvedDeclNonlocal || resolvedDeclNonlocal === resolvedDecl) { - return false; - } + // The reference results declarations are already resolved, so we don't + // need to call resolveAliasDeclaration on them. + if (this._isDeclarationAllowed(resolvedDecl)) { + return true; + } + + // We didn't find the declaration using local-only alias resolution. Attempt + // it again by fully resolving the alias. + const resolvedDeclNonlocal = this._getResolveAliasDeclaration(resolvedDecl); + if (!resolvedDeclNonlocal || resolvedDeclNonlocal === resolvedDecl) { + return false; + } - return this._isDeclarationAllowed(resolvedDeclNonlocal, referenceNode); + return this._isDeclarationAllowed(resolvedDeclNonlocal); + }); } private _getResolveAliasDeclaration(declaration: Declaration) { @@ -355,7 +353,7 @@ export class DocumentSymbolCollector extends ParseTreeWalker { return getDeclarationsWithUsesLocalNameRemoved([declaration])[0]; } - const resolvedDecl = this._evaluator.resolveAliasDeclaration(declaration, /* resolveLocalNames */ true); + const resolvedDecl = this._aliasResolver.resolve(declaration, /* resolveLocalNames */ true); return isAliasDeclFromImportAsWithAlias(resolvedDecl) ? getDeclarationsWithUsesLocalNameRemoved([resolvedDecl])[0] : resolvedDecl; @@ -396,280 +394,180 @@ export class DocumentSymbolCollector extends ParseTreeWalker { return; } - if (!symbolInScope.symbol.getDeclarations().some((d) => this._resultsContainsDeclaration(d, stringNode))) { + if (!this._resultsContainsDeclaration(stringNode, symbolInScope.symbol.getDeclarations())) { return; } this._dunderAllNameNodes.add(stringNode); }); } +} - private static _addIfUnique(declarations: Declaration[], itemToAdd: Declaration) { - for (const def of declarations) { - if ( - areDeclarationsSame( - def, - itemToAdd, - /* treatModuleInImportAndFromImportSame */ false, - /* skipRangeForAliases */ true - ) - ) { - return; - } - } - - declarations.push(itemToAdd); +export function getDeclarationsForNameNode(evaluator: TypeEvaluator, node: NameNode, skipUnreachableCode = true) { + // This can handle symbols brought in by wildcard (import *) as long as the declarations that the symbol collector + // compares against point to the actual alias declaration, not one that uses local name (ex, import alias) + if (node.parent?.nodeType !== ParseNodeType.ModuleName) { + return _getDeclarationsForNonModuleNameNode(evaluator, node, skipUnreachableCode); } - private static _getDeclarationsForInitNode(node: NameNode, evaluator: TypeEvaluator): Declaration[] { - const parent = ParseTreeUtils.getEnclosingClassOrFunction(node.parent!); - // See what type of __init__ we're at. - if (parent?.nodeType === ParseNodeType.Class) { - // This is a def for '__init__'. We should include the class name too. - return this._getDeclarationsForNonModuleNameNode(parent.name, evaluator); - } else if ( - node.parent?.nodeType === ParseNodeType.MemberAccess && - ((node.parent.leftExpression.nodeType === ParseNodeType.Call && - node.parent.leftExpression.leftExpression.nodeType === ParseNodeType.Name && - node.parent.leftExpression.leftExpression.value === 'super') || - (node.parent.leftExpression.nodeType === ParseNodeType.Name && - node.parent.leftExpression.value === 'super')) + return _getDeclarationsForModuleNameNode(evaluator, node); +} + +export function addDeclarationIfUnique(declarations: Declaration[], itemToAdd: Declaration) { + for (const def of declarations) { + if ( + areDeclarationsSame( + def, + itemToAdd, + /* treatModuleInImportAndFromImportSame */ false, + /* skipRangeForAliases */ true + ) ) { - // We're on the 'super().__init__' call. - const decls = evaluator.getDeclarationsForNameNode(node, /* skipUnreachableCode */ true); - if (decls && decls.length > 0 && decls[0].node.parent) { - // Parent node of the decl should be the class - const classNode = ParseTreeUtils.getEnclosingClass(decls[0].node.parent); - if (classNode) { - return this._getDeclarationsForNonModuleNameNode(classNode.name, evaluator); - } - } + return; } - - return []; } - private static _getDeclarationsForNode( - node: NameNode, - useCase: DocumentSymbolCollectorUseCase, - evaluator: TypeEvaluator, - token: CancellationToken, - skipUnreachableCode = true - ): Declaration[] { - let result: Declaration[] = []; + declarations.push(itemToAdd); +} - // This can handle symbols brought in by wildcard (import *) as long as the declarations that the symbol collector - // compares against point to the actual alias declaration, not one that uses local name (ex, import alias) - if (node.parent?.nodeType !== ParseNodeType.ModuleName) { - result = this._getDeclarationsForNonModuleNameNode(node, evaluator, skipUnreachableCode); +function _getDeclarationsForNonModuleNameNode( + evaluator: TypeEvaluator, + node: NameNode, + skipUnreachableCode = true +): Declaration[] { + assert(node.parent?.nodeType !== ParseNodeType.ModuleName); + + let decls = evaluator.getDeclarationsForNameNode(node, skipUnreachableCode) || []; + if (node.parent?.nodeType === ParseNodeType.ImportFromAs) { + // Make sure we get the decl for this specific "from import" statement + decls = decls.filter((d) => d.node === node.parent); + } - // Special case for __init__. Might be __init__ on a class. - if (node.value === '__init__' && useCase === DocumentSymbolCollectorUseCase.Reference && node.parent) { - appendArray(result, this._getDeclarationsForInitNode(node, evaluator)); - } - } else { - result = this._getDeclarationsForModuleNameNode(node, evaluator); + // If we can't get decl, see whether we can get type from the node. + // Some might have synthesized type for the node such as subModule in import X.Y statement. + if (decls.length === 0) { + const type = evaluator.getType(node); + if (type?.category === TypeCategory.Module) { + // Synthesize decl for the module. + return [createSynthesizedAliasDeclaration(type.filePath)]; } + } - // Let extensions also add declarations. - Extensions.getProgramExtensions(node).forEach((e) => { - const declUseCase = - useCase === DocumentSymbolCollectorUseCase.Rename - ? DeclarationUseCase.Rename - : DeclarationUseCase.References; - const extras = e.declarationProviderExtension?.tryGetDeclarations( - evaluator, - node, - node.start, - declUseCase, - token - ); - if (extras && extras.length > 0) { - appendArray(result, extras); - } - }); + // We would like to make X in import X and import X.Y as Y to match, but path for + // X in import X and one in import X.Y as Y might not match since path in X.Y will point + // to X.Y rather than X if import statement has an alias. + // so, for such case, we put synthesized one so we can treat X in both statement same. + for (const aliasDecl of decls.filter((d) => isAliasDeclaration(d) && !d.loadSymbolsFromPath)) { + const node = (aliasDecl as AliasDeclaration).node; + if (node.nodeType === ParseNodeType.ImportFromAs) { + // from ... import X case, decl in the submodule fallback has the path. + continue; + } - return result; + appendArray(decls, evaluator.getDeclarationsForNameNode(node.module.nameParts[0], skipUnreachableCode) || []); } - private static _getDeclarationsForNonModuleNameNode( - node: NameNode, - evaluator: TypeEvaluator, - skipUnreachableCode = true - ): Declaration[] { - assert(node.parent?.nodeType !== ParseNodeType.ModuleName); - - let decls = evaluator.getDeclarationsForNameNode(node, skipUnreachableCode) || []; - if (node.parent?.nodeType === ParseNodeType.ImportFromAs) { - // Make sure we get the decl for this specific "from import" statement - decls = decls.filter((d) => d.node === node.parent); - } + return decls; +} - // If we can't get decl, see whether we can get type from the node. - // Some might have synthesized type for the node such as subModule in import X.Y statement. - if (decls.length === 0) { - const type = evaluator.getType(node); - if (type?.category === TypeCategory.Module) { - // Synthesize decl for the module. - return [createSynthesizedAliasDeclaration(type.filePath)]; - } - } +function _getDeclarationsForModuleNameNode(evaluator: TypeEvaluator, node: NameNode): Declaration[] { + assert(node.parent?.nodeType === ParseNodeType.ModuleName); + + // We don't have symbols corresponding to ModuleName in our system since those + // are not referenceable. but in "find all reference", we want to match those + // if it refers to the same module file. Code below handles different kind of + // ModuleName cases. + const moduleName = node.parent; + if ( + moduleName.parent?.nodeType === ParseNodeType.ImportAs || + moduleName.parent?.nodeType === ParseNodeType.ImportFrom + ) { + const index = moduleName.nameParts.findIndex((n) => n === node); - // We would like to make X in import X and import X.Y as Y to match, but path for - // X in import X and one in import X.Y as Y might not match since path in X.Y will point - // to X.Y rather than X if import statement has an alias. - // so, for such case, we put synthesized one so we can treat X in both statement same. - for (const aliasDecl of decls.filter((d) => isAliasDeclaration(d) && !d.loadSymbolsFromPath)) { - const node = (aliasDecl as AliasDeclaration).node; - if (node.nodeType === ParseNodeType.ImportFromAs) { - // from ... import X case, decl in the submodule fallback has the path. - continue; - } + // Special case, first module name part. + if (index === 0) { + // 1. import X or from X import ... + const decls: Declaration[] = []; + // First, we need to put decls for module names type evaluator synthesized so that + // we can match both "import X" and "from X import ..." appendArray( decls, - evaluator.getDeclarationsForNameNode(node.module.nameParts[0], skipUnreachableCode) || [] + evaluator.getDeclarationsForNameNode(moduleName.nameParts[0])?.filter((d) => isAliasDeclaration(d)) || + [] ); - } - - // For now, we only support function overriding. - for (const decl of decls.filter( - (d) => isFunctionDeclaration(d) && d.isMethod && d.node.name.value.length > 0 - )) { - const methodDecl = decl as FunctionDeclaration; - const enclosingClass = ParseTreeUtils.getEnclosingClass(methodDecl.node); - const classResults = enclosingClass ? evaluator.getTypeOfClass(enclosingClass) : undefined; - if (!classResults) { - continue; - } - - // Skip init and new as being overloads. They're not really overloads. - if (methodDecl.node.name.value === '__init__' || methodDecl.node.name.value === '__new__') { - continue; - } - for (const mroClass of classResults.classType.details.mro) { - if (isInstantiableClass(mroClass)) { - const currentMember = lookUpClassMember(mroClass, methodDecl.node.name.value); - const baseMember = lookUpClassMember( - mroClass, - methodDecl.node.name.value, - ClassMemberLookupFlags.SkipOriginalClass - ); - if (currentMember && !baseMember) { - // Found base decl of the overridden method. Hold onto the decls. - currentMember.symbol - .getDeclarations() - .filter((d) => isFunctionDeclaration(d) && d.isMethod) - .forEach((d) => this._addIfUnique(decls, d)); - } - } + if (decls.length === 0 || moduleName.parent.nodeType !== ParseNodeType.ImportAs) { + return decls; } - } - - return decls; - } - - private static _getDeclarationsForModuleNameNode(node: NameNode, evaluator: TypeEvaluator): Declaration[] { - assert(node.parent?.nodeType === ParseNodeType.ModuleName); - // We don't have symbols corresponding to ModuleName in our system since those - // are not referenceable. but in "find all reference", we want to match those - // if it refers to the same module file. Code below handles different kind of - // ModuleName cases. - const moduleName = node.parent; - if ( - moduleName.parent?.nodeType === ParseNodeType.ImportAs || - moduleName.parent?.nodeType === ParseNodeType.ImportFrom - ) { - const index = moduleName.nameParts.findIndex((n) => n === node); + // If module name belong to "import xxx" not "from xxx", then see whether + // we can get regular decls (decls created from binder, not synthesized from type eval) + // from symbol as well. + // ex, import X as x + const isImportAsWithAlias = + moduleName.nameParts.length === 1 && + moduleName.parent.nodeType === ParseNodeType.ImportAs && + !!moduleName.parent.alias; + + // if "import" has alias, symbol is assigned to alias, not the module. + const importName = isImportAsWithAlias + ? (moduleName.parent as ImportAsNode).alias!.value + : moduleName.nameParts[0].value; + + // And we also need to re-use "decls for X" binder has created + // so that it matches with decls type evaluator returns for "references for X". + // ex) import X or from .X import ... in init file and etc. + const symbolWithScope = ScopeUtils.getScopeForNode(node)?.lookUpSymbolRecursive(importName); + if (symbolWithScope && moduleName.nameParts.length === 1) { + let declsFromSymbol: Declaration[] = []; - // Special case, first module name part. - if (index === 0) { - // 1. import X or from X import ... - const decls: Declaration[] = []; - - // First, we need to put decls for module names type evaluator synthesized so that - // we can match both "import X" and "from X import ..." appendArray( - decls, - evaluator - .getDeclarationsForNameNode(moduleName.nameParts[0]) - ?.filter((d) => isAliasDeclaration(d)) || [] + declsFromSymbol, + symbolWithScope.symbol.getDeclarations().filter((d) => isAliasDeclaration(d)) ); - if (decls.length === 0 || moduleName.parent.nodeType !== ParseNodeType.ImportAs) { - return decls; + // If symbols are re-used, then find one that belong to this import statement. + if (declsFromSymbol.length > 1) { + declsFromSymbol = declsFromSymbol.filter((d) => { + d = d as AliasDeclaration; + + if (d.firstNamePart !== undefined) { + // For multiple import statements with sub modules, decl can be re-used. + // ex) import X.Y and import X.Z or from .X import ... in init file. + // Decls for X will be reused for both import statements, and node will point + // to first import statement. For those case, use firstNamePart instead to check. + return d.firstNamePart === moduleName.nameParts[0].value; + } + + return d.node === moduleName.parent; + }); } - // If module name belong to "import xxx" not "from xxx", then see whether - // we can get regular decls (decls created from binder, not synthesized from type eval) - // from symbol as well. // ex, import X as x - const isImportAsWithAlias = - moduleName.nameParts.length === 1 && - moduleName.parent.nodeType === ParseNodeType.ImportAs && - !!moduleName.parent.alias; - - // if "import" has alias, symbol is assigned to alias, not the module. - const importName = isImportAsWithAlias - ? (moduleName.parent as ImportAsNode).alias!.value - : moduleName.nameParts[0].value; - - // And we also need to re-use "decls for X" binder has created - // so that it matches with decls type evaluator returns for "references for X". - // ex) import X or from .X import ... in init file and etc. - const symbolWithScope = ScopeUtils.getScopeForNode(node)?.lookUpSymbolRecursive(importName); - if (symbolWithScope && moduleName.nameParts.length === 1) { - let declsFromSymbol: Declaration[] = []; - - appendArray( - declsFromSymbol, - symbolWithScope.symbol.getDeclarations().filter((d) => isAliasDeclaration(d)) - ); - - // If symbols are re-used, then find one that belong to this import statement. - if (declsFromSymbol.length > 1) { - declsFromSymbol = declsFromSymbol.filter((d) => { - d = d as AliasDeclaration; - - if (d.firstNamePart !== undefined) { - // For multiple import statements with sub modules, decl can be re-used. - // ex) import X.Y and import X.Z or from .X import ... in init file. - // Decls for X will be reused for both import statements, and node will point - // to first import statement. For those case, use firstNamePart instead to check. - return d.firstNamePart === moduleName.nameParts[0].value; - } - - return d.node === moduleName.parent; - }); - } - - // ex, import X as x - // We have decls for the alias "x" not the module name "X". Convert decls for the "X" - if (isImportAsWithAlias) { - declsFromSymbol = getDeclarationsWithUsesLocalNameRemoved(declsFromSymbol); - } - - appendArray(decls, declsFromSymbol); + // We have decls for the alias "x" not the module name "X". Convert decls for the "X" + if (isImportAsWithAlias) { + declsFromSymbol = getDeclarationsWithUsesLocalNameRemoved(declsFromSymbol); } - return decls; + appendArray(decls, declsFromSymbol); } - if (index > 0) { - // 2. import X.Y or from X.Y import .... - // For submodule "Y", we just use synthesized decls from type evaluator. - // Decls for these sub module don't actually exist in the system. Instead, symbol for Y in - // "import X.Y" hold onto synthesized module type (without any decl). - // And "from X.Y import ..." doesn't have any symbol associated module names. - // they can't be referenced in the module. - return evaluator.getDeclarationsForNameNode(moduleName.nameParts[index]) || []; - } + return decls; + } - return []; + if (index > 0) { + // 2. import X.Y or from X.Y import .... + // For submodule "Y", we just use synthesized decls from type evaluator. + // Decls for these sub module don't actually exist in the system. Instead, symbol for Y in + // "import X.Y" hold onto synthesized module type (without any decl). + // And "from X.Y import ..." doesn't have any symbol associated module names. + // they can't be referenced in the module. + return evaluator.getDeclarationsForNameNode(moduleName.nameParts[index]) || []; } return []; } + + return []; } diff --git a/packages/pyright-internal/src/languageService/hoverProvider.ts b/packages/pyright-internal/src/languageService/hoverProvider.ts index cf0264e55..e116bd740 100644 --- a/packages/pyright-internal/src/languageService/hoverProvider.ts +++ b/packages/pyright-internal/src/languageService/hoverProvider.ts @@ -11,7 +11,7 @@ import { CancellationToken, Hover, MarkupKind } from 'vscode-languageserver'; -import { Declaration, DeclarationType } from '../analyzer/declaration'; +import { Declaration, DeclarationType, VariableDeclaration } from '../analyzer/declaration'; import { convertDocStringToMarkdown, convertDocStringToPlainText } from '../analyzer/docStringConversion'; import * as ParseTreeUtils from '../analyzer/parseTreeUtils'; import { SourceMapper } from '../analyzer/sourceMapper'; @@ -28,23 +28,22 @@ import { isModule, isOverloadedFunction, isTypeVar, - isUnknown, } from '../analyzer/types'; import { throwIfCancellationRequested } from '../common/cancellationUtils'; import { assertNever, fail } from '../common/debug'; -import { DeclarationUseCase, Extensions, ProgramView } from '../common/extensibility'; +import { ProgramView } from '../common/extensibility'; import { convertOffsetToPosition, convertPositionToOffset } from '../common/positionUtils'; import { Position, Range, TextRange } from '../common/textRange'; -import { ExpressionNode, NameNode, ParseNode, ParseNodeType, StringNode, isExpressionNode } from '../parser/parseNodes'; +import { ExpressionNode, NameNode, ParseNode, ParseNodeType, StringNode } from '../parser/parseNodes'; import { ParseResults } from '../parser/parser'; import { - combineExpressionTypes, getClassAndConstructorTypes, getConstructorTooltip, getDocumentationPartsForTypeAndDecl, getToolTipForType, getTypeForToolTip, } from './tooltipUtils'; +import { SignatureDisplayType } from '../common/configOptions'; export interface HoverTextPart { python?: boolean; @@ -110,6 +109,42 @@ export function addDocumentationResultsPart(docString: string | undefined, forma fail(`Unsupported markup type: ${format}`); } +export function getVariableTypeText( + evaluator: TypeEvaluator, + declaration: VariableDeclaration, + name: string, + type: Type, + typeNode: ExpressionNode, + functionSignatureDisplay: SignatureDisplayType +) { + let label = declaration.isConstant || evaluator.isFinalVariableDeclaration(declaration) ? 'constant' : 'variable'; + + let expandTypeAlias = false; + let typeVarName: string | undefined; + if (type.typeAliasInfo && typeNode.nodeType === ParseNodeType.Name) { + const typeAliasInfo = getTypeAliasInfo(type); + if (typeAliasInfo?.name === typeNode.value) { + if (isTypeVar(type)) { + label = type.details.isParamSpec ? 'param spec' : 'type variable'; + typeVarName = type.details.name; + } else { + expandTypeAlias = true; + label = 'type alias'; + } + } + } + + // Handle the case where type is a function and was assigned to a variable. + if (type.category === TypeCategory.Function || type.category === TypeCategory.OverloadedFunction) { + return getToolTipForType(type, label, name, evaluator, /* isProperty */ false, functionSignatureDisplay); + } + + const typeText = + typeVarName || name + ': ' + evaluator.printType(getTypeForToolTip(evaluator, typeNode), { expandTypeAlias }); + + return `(${label}) ` + typeText; +} + export class HoverProvider { private readonly _parseResults: ParseResults | undefined; private readonly _sourceMapper: SourceMapper; @@ -187,23 +222,7 @@ export class HoverProvider { }; if (node.nodeType === ParseNodeType.Name) { - // First give extensions a crack at getting a declaration. - let declarations: Declaration[] | undefined = Extensions.getProgramExtensions(node) - .map( - (e) => - e.declarationProviderExtension?.tryGetDeclarations( - this._evaluator, - node, - offset, - DeclarationUseCase.Definition, - this._token - ) || [] - ) - .flat(); - if (declarations.length === 0) { - declarations = this._evaluator.getDeclarationsForNameNode(node); - } - + const declarations = this._evaluator.getDeclarationsForNameNode(node); if (declarations && declarations.length > 0) { const primaryDeclaration = HoverProvider.getPrimaryDeclaration(declarations); this._addResultsForDeclaration(results.parts, primaryDeclaration, node); @@ -268,11 +287,6 @@ export class HoverProvider { } case DeclarationType.Variable: { - let label = - resolvedDecl.isConstant || this._evaluator.isFinalVariableDeclaration(resolvedDecl) - ? 'constant' - : 'variable'; - // If the named node is an aliased import symbol, we can't call // getType on the original name because it's not in the symbol // table. Instead, use the node from the resolved alias. @@ -297,74 +311,24 @@ export class HoverProvider { // Determine if this identifier is a type alias. If so, expand // the type alias when printing the type information. - let type = this._getType(typeNode); - - // We may have more type information in the alternativeTypeNode. Use that if it's better. - if ( - isUnknown(type) && - resolvedDecl.alternativeTypeNode && - isExpressionNode(resolvedDecl.alternativeTypeNode) - ) { - const inferredType = this._getType(resolvedDecl.alternativeTypeNode); - if (!isUnknown(inferredType)) { - type = inferredType; - typeNode = resolvedDecl.alternativeTypeNode; - } - } - - let expandTypeAlias = false; - let typeVarName: string | undefined; - if (type.typeAliasInfo && typeNode.nodeType === ParseNodeType.Name) { - const typeAliasInfo = getTypeAliasInfo(type); - if (typeAliasInfo?.name === typeNode.value) { - if (isTypeVar(type)) { - label = type.details.isParamSpec ? 'param spec' : 'type variable'; - typeVarName = type.details.name; - } else { - expandTypeAlias = true; - label = 'type alias'; - } - } - } + const type = this._getType(typeNode); + const typeText = getVariableTypeText( + this._evaluator, + resolvedDecl, + node.value, + type, + typeNode, + this._functionSignatureDisplay + ); - let typeText: string; - const varType = this._getType(typeNode); - // Handle the case where type is a function and was assigned to a variable. - if ( - varType.category === TypeCategory.Function || - varType.category === TypeCategory.OverloadedFunction - ) { - typeText = getToolTipForType( - type, - label, - node.value, - this._evaluator, - /* isProperty */ false, - this._functionSignatureDisplay - ); - } else { - typeText = typeVarName || node.value + this._getTypeText(typeNode, { expandTypeAlias }); - typeText = `(${label}) ` + typeText; - } this._addResultsPart(parts, typeText, /* python */ true); this._addDocumentationPart(parts, node, resolvedDecl); break; } case DeclarationType.Parameter: { - if (resolvedDecl.inferredName && resolvedDecl.inferredTypeNodes) { - this._addResultsPart( - parts, - '(parameter) ' + resolvedDecl.inferredName + this._getTypesText(resolvedDecl.inferredTypeNodes), - /* python */ true - ); - } else { - this._addResultsPart( - parts, - '(parameter) ' + node.value + this._getTypeText(node), - /* python */ true - ); - } + this._addResultsPart(parts, '(parameter) ' + node.value + this._getTypeText(node), /* python */ true); + if (resolvedDecl.docString) { this._addResultsPart(parts, resolvedDecl.docString); } @@ -389,11 +353,11 @@ export class HoverProvider { case DeclarationType.Class: case DeclarationType.SpecialBuiltInClass: { - const nameNode = resolvedDecl.type === DeclarationType.Class ? resolvedDecl.node.name : node; if (this._addInitOrNewMethodInsteadIfCallNode(node, parts, resolvedDecl)) { return; } + const nameNode = resolvedDecl.type === DeclarationType.Class ? resolvedDecl.node.name : node; this._addResultsPart(parts, '(class) ' + nameNode.value, /* python */ true); this._addDocumentationPart(parts, node, resolvedDecl); break; @@ -510,11 +474,6 @@ export class HoverProvider { return ': ' + this._evaluator.printType(type, options); } - private _getTypesText(nodes: ExpressionNode[], options?: PrintTypeOptions): string { - const type = combineExpressionTypes(nodes, this._evaluator); - return ': ' + this._evaluator.printType(type, options); - } - private _addDocumentationPart(parts: HoverTextPart[], node: NameNode, resolvedDecl: Declaration | undefined) { const type = this._getType(node); this._addDocumentationPartForType(parts, type, resolvedDecl, node.value); diff --git a/packages/pyright-internal/src/languageService/navigationUtils.ts b/packages/pyright-internal/src/languageService/navigationUtils.ts index bb76eb830..a7a266fb8 100644 --- a/packages/pyright-internal/src/languageService/navigationUtils.ts +++ b/packages/pyright-internal/src/languageService/navigationUtils.ts @@ -14,8 +14,12 @@ export function canNavigateToFile(fs: ReadOnlyFileSystem, path: string): boolean return !fs.isInZip(path); } -export function convertDocumentRangesToLocation(fs: ReadOnlyFileSystem, ranges: DocumentRange[]): Location[] { - return ranges.map((range) => convertDocumentRangeToLocation(fs, range)).filter((loc) => !!loc) as Location[]; +export function convertDocumentRangesToLocation( + fs: ReadOnlyFileSystem, + ranges: DocumentRange[], + converter: (fs: ReadOnlyFileSystem, range: DocumentRange) => Location | undefined = convertDocumentRangeToLocation +): Location[] { + return ranges.map((range) => converter(fs, range)).filter((loc) => !!loc) as Location[]; } export function convertDocumentRangeToLocation(fs: ReadOnlyFileSystem, range: DocumentRange): Location | undefined { diff --git a/packages/pyright-internal/src/languageService/referencesProvider.ts b/packages/pyright-internal/src/languageService/referencesProvider.ts index f1b4f4e1a..c486910f0 100644 --- a/packages/pyright-internal/src/languageService/referencesProvider.ts +++ b/packages/pyright-internal/src/languageService/referencesProvider.ts @@ -19,15 +19,18 @@ import { isVisibleExternally } from '../analyzer/symbolUtils'; import { TypeEvaluator } from '../analyzer/typeEvaluatorTypes'; import { maxTypeRecursionCount } from '../analyzer/types'; import { throwIfCancellationRequested } from '../common/cancellationUtils'; +import { isDefined } from '../common/core'; import { appendArray } from '../common/collectionUtils'; import { assertNever } from '../common/debug'; -import { ProgramView } from '../common/extensibility'; +import { ProgramView, ReferenceUseCase, SymbolUsageProvider } from '../common/extensibility'; import { convertOffsetToPosition, convertPositionToOffset } from '../common/positionUtils'; import { DocumentRange, Position, TextRange, doesRangeContain } from '../common/textRange'; import { NameNode, ParseNode, ParseNodeType } from '../parser/parseNodes'; import { ParseResults } from '../parser/parser'; -import { DocumentSymbolCollector, DocumentSymbolCollectorUseCase } from './documentSymbolCollector'; +import { CollectionResult, DocumentSymbolCollector } from './documentSymbolCollector'; +import { ReadOnlyFileSystem } from '../common/fileSystem'; import { convertDocumentRangesToLocation } from './navigationUtils'; +import { ServiceKeys } from '../common/serviceProviderExtensions'; export type ReferenceCallback = (locations: DocumentRange[]) => void; @@ -41,7 +44,8 @@ export class ReferencesResult { readonly nodeAtOffset: ParseNode, readonly symbolNames: string[], readonly declarations: Declaration[], - readonly useCase: DocumentSymbolCollectorUseCase, + readonly useCase: ReferenceUseCase, + readonly providers: readonly SymbolUsageProvider[], private readonly _reporter?: ReferenceCallback ) { // Filter out any import decls. but leave one with alias. @@ -102,7 +106,12 @@ export class FindReferencesTreeWalker { private _filePath: string, private _referencesResult: ReferencesResult, private _includeDeclaration: boolean, - private _cancellationToken: CancellationToken + private _cancellationToken: CancellationToken, + private readonly _createDocumentRange: ( + filePath: string, + result: CollectionResult, + parseResults: ParseResults + ) => DocumentRange = FindReferencesTreeWalker.createDocumentRange ) { this._parseResults = this._program.getParseResults(this._filePath); } @@ -117,35 +126,48 @@ export class FindReferencesTreeWalker { this._program, this._referencesResult.symbolNames, this._referencesResult.declarations, - this._cancellationToken, rootNode!, - /* treatModuleInImportAndFromImportSame */ true, - /* skipUnreachableCode */ false, - this._referencesResult.useCase + this._cancellationToken, + { + treatModuleInImportAndFromImportSame: true, + skipUnreachableCode: false, + useCase: this._referencesResult.useCase, + providers: this._referencesResult.providers, + } ); for (const result of collector.collect()) { // Is it the same symbol? if (this._includeDeclaration || result.node !== this._referencesResult.nodeAtOffset) { - results.push({ - path: this._filePath, - range: { - start: convertOffsetToPosition(result.range.start, this._parseResults.tokenizerOutput.lines), - end: convertOffsetToPosition( - TextRange.getEnd(result.range), - this._parseResults.tokenizerOutput.lines - ), - }, - }); + results.push(this._createDocumentRange(this._filePath, result, this._parseResults)); } } return results; } + + static createDocumentRange(filePath: string, result: CollectionResult, parseResults: ParseResults): DocumentRange { + return { + path: filePath, + range: { + start: convertOffsetToPosition(result.range.start, parseResults.tokenizerOutput.lines), + end: convertOffsetToPosition(TextRange.getEnd(result.range), parseResults.tokenizerOutput.lines), + }, + }; + } } export class ReferencesProvider { - constructor(private _program: ProgramView, private _token: CancellationToken) { + constructor( + private _program: ProgramView, + private _token: CancellationToken, + private readonly _createDocumentRange?: ( + filePath: string, + result: CollectionResult, + parseResults: ParseResults + ) => DocumentRange, + private readonly _convertToLocation?: (fs: ReadOnlyFileSystem, ranges: DocumentRange) => Location | undefined + ) { // empty } @@ -167,8 +189,15 @@ export class ReferencesProvider { const locations: Location[] = []; const reporter: ReferenceCallback = resultReporter - ? (range) => resultReporter.report(convertDocumentRangesToLocation(this._program.fileSystem, range)) - : (range) => appendArray(locations, convertDocumentRangesToLocation(this._program.fileSystem, range)); + ? (range) => + resultReporter.report( + convertDocumentRangesToLocation(this._program.fileSystem, range, this._convertToLocation) + ) + : (range) => + appendArray( + locations, + convertDocumentRangesToLocation(this._program.fileSystem, range, this._convertToLocation) + ); const invokedFromUserFile = isUserCode(sourceFileInfo); const referencesResult = ReferencesProvider.getDeclarationForPosition( @@ -176,7 +205,7 @@ export class ReferencesProvider { filePath, position, reporter, - DocumentSymbolCollectorUseCase.Reference, + ReferenceUseCase.References, this._token ); if (!referencesResult) { @@ -233,7 +262,8 @@ export class ReferencesProvider { referencesResult.nodeAtOffset, referencesResult.symbolNames, referencesResult.declarations, - referencesResult.useCase + referencesResult.useCase, + referencesResult.providers ); this.addReferencesToResult(declFileInfo.sourceFile.getFilePath(), includeDeclaration, tempResult); @@ -260,7 +290,8 @@ export class ReferencesProvider { filePath, referencesResult, includeDeclaration, - this._token + this._token, + this._createDocumentRange ); referencesResult.addLocations(...refTreeWalker.findReferences()); @@ -271,7 +302,7 @@ export class ReferencesProvider { filePath: string, node: NameNode, reporter: ReferenceCallback | undefined, - useCase: DocumentSymbolCollectorUseCase, + useCase: ReferenceUseCase, token: CancellationToken ) { throwIfCancellationRequested(token); @@ -280,7 +311,6 @@ export class ReferencesProvider { program, node, /* resolveLocalNames */ false, - useCase, token ); @@ -289,15 +319,26 @@ export class ReferencesProvider { } const requiresGlobalSearch = isVisibleOutside(program.evaluator!, filePath, node, declarations); - const symbolNames = new Set(declarations.map((d) => getNameFromDeclaration(d)!).filter((n) => !!n)); + const symbolNames = new Set(declarations.map((d) => getNameFromDeclaration(d)!).filter((n) => !!n)); symbolNames.add(node.value); + const providers = (program.serviceProvider.tryGet(ServiceKeys.symbolUsageProviderFactory) ?? []) + .map((f) => f.tryCreateProvider(useCase, declarations, token)) + .filter(isDefined); + + // Check whether we need to add new symbol names and declarations. + providers.forEach((p) => { + p.appendSymbolNamesTo(symbolNames); + p.appendDeclarationsTo(declarations); + }); + return new ReferencesResult( requiresGlobalSearch, node, Array.from(symbolNames.values()), declarations, useCase, + providers, reporter ); } @@ -307,7 +348,7 @@ export class ReferencesProvider { filePath: string, position: Position, reporter: ReferenceCallback | undefined, - useCase: DocumentSymbolCollectorUseCase, + useCase: ReferenceUseCase, token: CancellationToken ): ReferencesResult | undefined { throwIfCancellationRequested(token); diff --git a/packages/pyright-internal/src/languageService/renameProvider.ts b/packages/pyright-internal/src/languageService/renameProvider.ts index 655c7463d..74a222059 100644 --- a/packages/pyright-internal/src/languageService/renameProvider.ts +++ b/packages/pyright-internal/src/languageService/renameProvider.ts @@ -11,10 +11,9 @@ import { CancellationToken, WorkspaceEdit } from 'vscode-languageserver'; import { assertNever } from '../common/debug'; import { FileEditAction } from '../common/editAction'; -import { ProgramView } from '../common/extensibility'; +import { ProgramView, ReferenceUseCase } from '../common/extensibility'; import { convertTextRangeToRange } from '../common/positionUtils'; import { Position, Range } from '../common/textRange'; -import { DocumentSymbolCollectorUseCase } from '../languageService/documentSymbolCollector'; import { ReferencesProvider, ReferencesResult } from '../languageService/referencesProvider'; import { isUserCode } from '../analyzer/sourceFileInfoUtils'; import { throwIfCancellationRequested } from '../common/cancellationUtils'; @@ -177,7 +176,7 @@ export class RenameProvider { this._filePath, this._position, /* reporter */ undefined, - DocumentSymbolCollectorUseCase.Rename, + ReferenceUseCase.Rename, this._token ); if (!referencesResult) { @@ -199,7 +198,8 @@ export class RenameProvider { referencesResult.nodeAtOffset, referencesResult.symbolNames, referencesResult.nonImportDeclarations, - referencesResult.useCase + referencesResult.useCase, + referencesResult.providers ); } } diff --git a/packages/pyright-internal/src/languageService/tooltipUtils.ts b/packages/pyright-internal/src/languageService/tooltipUtils.ts index fcd5bf1b1..c9ed286ca 100644 --- a/packages/pyright-internal/src/languageService/tooltipUtils.ts +++ b/packages/pyright-internal/src/languageService/tooltipUtils.ts @@ -455,8 +455,6 @@ export function bindFunctionToClassOrObjectToolTip( baseType, memberType, /* memberClass */ undefined, - /* errorNode */ undefined, - /* recursiveCount */ undefined, treatConstructorAsClassMember ); diff --git a/packages/pyright-internal/src/localization/localize.ts b/packages/pyright-internal/src/localization/localize.ts index af4f23fff..e8bfc6ada 100644 --- a/packages/pyright-internal/src/localization/localize.ts +++ b/packages/pyright-internal/src/localization/localize.ts @@ -115,6 +115,8 @@ declare let navigator: { language: string } | undefined; let localeOverride: string | undefined; export function setLocaleOverride(locale: string) { + // Force a reload of the localized strings. + localizedStrings = undefined; localeOverride = locale.toLowerCase(); } @@ -281,9 +283,12 @@ export namespace Localizer { export const classMethodClsParam = () => getRawString('Diagnostic.classMethodClsParam'); export const classNotRuntimeSubscriptable = () => new ParameterizedString<{ name: string }>(getRawString('Diagnostic.classNotRuntimeSubscriptable')); - export const classPatternBuiltInArgCount = () => getRawString('Diagnostic.classPatternBuiltInArgCount'); export const classPatternBuiltInArgPositional = () => getRawString('Diagnostic.classPatternBuiltInArgPositional'); + export const classPatternPositionalArgCount = () => + new ParameterizedString<{ type: string; expected: number; received: number }>( + getRawString('Diagnostic.classPatternPositionalArgCount') + ); export const classPatternTypeAlias = () => new ParameterizedString<{ type: string }>(getRawString('Diagnostic.classPatternTypeAlias')); export const classTypeParametersIllegal = () => getRawString('Diagnostic.classTypeParametersIllegal'); @@ -373,10 +378,22 @@ export namespace Localizer { new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedClass')); export const deprecatedConstructor = () => new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedConstructor')); + export const deprecatedDescriptorDeleter = () => + new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedDescriptorDeleter')); + export const deprecatedDescriptorGetter = () => + new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedDescriptorGetter')); + export const deprecatedDescriptorSetter = () => + new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedDescriptorSetter')); export const deprecatedFunction = () => new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedFunction')); export const deprecatedMethod = () => new ParameterizedString<{ name: string; className: string }>(getRawString('Diagnostic.deprecatedMethod')); + export const deprecatedPropertyDeleter = () => + new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedPropertyDeleter')); + export const deprecatedPropertyGetter = () => + new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedPropertyGetter')); + export const deprecatedPropertySetter = () => + new ParameterizedString<{ name: string }>(getRawString('Diagnostic.deprecatedPropertySetter')); export const deprecatedType = () => new ParameterizedString<{ version: string; replacement: string }>( getRawString('Diagnostic.deprecatedType') @@ -709,8 +726,6 @@ export namespace Localizer { export const paramSpecDefaultNotTuple = () => getRawString('Diagnostic.paramSpecDefaultNotTuple'); export const paramSpecFirstArg = () => getRawString('Diagnostic.paramSpecFirstArg'); export const paramSpecKwargsUsage = () => getRawString('Diagnostic.paramSpecKwargsUsage'); - export const paramSpecNotBound = () => - new ParameterizedString<{ type: string }>(getRawString('Diagnostic.paramSpecNotBound')); export const paramSpecNotUsedByOuterScope = () => new ParameterizedString<{ name: string }>(getRawString('Diagnostic.paramSpecNotUsedByOuterScope')); export const paramSpecScopedToReturnType = () => @@ -1142,6 +1157,7 @@ export namespace Localizer { new ParameterizedString<{ baseClass: string; type: string }>( getRawString('DiagnosticAddendum.baseClassOverridesType') ); + export const bytesTypePromotions = () => getRawString('DiagnosticAddendum.bytesTypePromotions'); export const conditionalRequiresBool = () => new ParameterizedString<{ operandType: string; boolReturnType: string }>( getRawString('DiagnosticAddendum.conditionalRequiresBool') @@ -1171,6 +1187,8 @@ export namespace Localizer { new ParameterizedString<{ type: string }>(getRawString('DiagnosticAddendum.initMethodLocation')); export const initMethodSignature = () => new ParameterizedString<{ type: string }>(getRawString('DiagnosticAddendum.initMethodSignature')); + export const invariantSuggestionDict = () => getRawString('DiagnosticAddendum.invariantSuggestionDict'); + export const invariantSuggestionList = () => getRawString('DiagnosticAddendum.invariantSuggestionList'); export const functionTooManyParams = () => new ParameterizedString<{ expected: number; received: number }>( getRawString('DiagnosticAddendum.functionTooManyParams') @@ -1220,6 +1238,10 @@ export namespace Localizer { new ParameterizedString<{ name: string }>(getRawString('DiagnosticAddendum.memberTypeMismatch')); export const memberUnknown = () => new ParameterizedString<{ name: string }>(getRawString('DiagnosticAddendum.memberUnknown')); + export const metaclassConflict = () => + new ParameterizedString<{ metaclass1: string; metaclass2: string }>( + getRawString('DiagnosticAddendum.metaclassConflict') + ); export const missingProtocolMember = () => new ParameterizedString<{ name: string; classType: string }>( getRawString('DiagnosticAddendum.missingProtocolMember') @@ -1243,6 +1265,8 @@ export namespace Localizer { new ParameterizedString<{ type: string }>(getRawString('DiagnosticAddendum.noOverloadAssignable')); export const orPatternMissingName = () => new ParameterizedString<{ name: string }>(getRawString('DiagnosticAddendum.orPatternMissingName')); + export const overloadIndex = () => + new ParameterizedString<{ index: number }>(getRawString('DiagnosticAddendum.overloadIndex')); export const overloadSignature = () => getRawString('DiagnosticAddendum.overloadSignature'); export const overloadNotAssignable = () => new ParameterizedString<{ name: string }>(getRawString('DiagnosticAddendum.overloadNotAssignable')); diff --git a/packages/pyright-internal/src/localization/package.nls.cs.json b/packages/pyright-internal/src/localization/package.nls.cs.json index 67b691b16..e63e5d861 100644 --- a/packages/pyright-internal/src/localization/package.nls.cs.json +++ b/packages/pyright-internal/src/localization/package.nls.cs.json @@ -11,8 +11,8 @@ "renameShadowedFile": "Přejmenovat „{oldFile}“ na „{newFile}“" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Automatický import", + "indexValueDetail": "Hodnota indexu" }, "Diagnostic": { "abstractMethodInvocation": "Metodu {method} není možné volat, protože je abstraktní", @@ -67,8 +67,8 @@ "classGetItemClsParam": "Přepsání __class_getitem__ by mělo mít parametr cls", "classMethodClsParam": "Metody třídy by měly mít parametr „cls“", "classNotRuntimeSubscriptable": "Dolní index pro třídu {name} vygeneruje výjimku modulu runtime; anotaci typu uzavřete do uvozovek", - "classPatternBuiltInArgCount": "Vzor třídy přijímá maximálně 1 poziční dílčí vzor", "classPatternBuiltInArgPositional": "Vzor třídy přijímá pouze poziční dílčí vzor", + "classPatternPositionalArgCount": "Příliš mnoho pozičních vzorů pro třídu \"{type}\"; očekávalo se {expected}, ale přijalo se {received}", "classPatternTypeAlias": "Typ „{type}“ nelze použít ve vzorci třídy, protože se jedná o specializovaný alias typu", "classTypeParametersIllegal": "Syntaxe parametru typu třídy vyžaduje Python 312 nebo novější", "classVarFirstArgMissing": "Za ClassVar byl očekáván argument typu", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "Výraz se vždy vyhodnotí jako True, protože typy „{leftType}“ a „{rightType}“ se nepřekrývají.", "continueInFinally": "continue není možné použít v klauzuli finally", "continueOutsideLoop": "continue se dá použít jenom ve smyčce", + "coroutineInConditionalExpression": "Podmíněný výraz odkazuje na korutinu, která se vždy vyhodnotí jako True.", "dataClassBaseClassFrozen": "Nezablokovaná třída nemůže dědit z zmrazené třídy", "dataClassBaseClassNotFrozen": "Zablokovaná třída nemůže dědit z třídy, která není zablokovaná", "dataClassConverterFunction": "Argument typu {argType} není platný převaděč pro pole {fieldName} typu {fieldType}", @@ -114,7 +115,14 @@ "delTargetExpr": "Výraz se nedá odstranit", "deprecatedClass": "Třída {name} je zastaralá", "deprecatedConstructor": "Konstruktor pro třídu {name} je zastaralý", - "deprecatedFunction": "Tato funkce {name} je zastaralá", + "deprecatedDescriptorDeleter": "Metoda „__delete__“ pro popisovač „{name}“ je zastaralá", + "deprecatedDescriptorGetter": "Metoda „__get__“ pro popisovač „{name}“ je zastaralá", + "deprecatedDescriptorSetter": "Metoda „__set__“ pro popisovač „{name}“ je zastaralá", + "deprecatedFunction": "Funkce {name} je zastaralá.", + "deprecatedMethod": "Metoda {name} ve třídě {className} je zastaralá.", + "deprecatedPropertyDeleter": "Odstraňovač pro vlastnost „{name}“ je zastaralý", + "deprecatedPropertyGetter": "Metoda getter pro vlastnost „{name}“ je zastaralá", + "deprecatedPropertySetter": "Metoda setter pro vlastnost „{name}“ je zastaralá", "deprecatedType": "Tento typ je zastaralý jako Python {version}; místo toho použijte {replacement}", "dictExpandIllegalInComprehension": "Rozšíření slovníku není v porozumění povoleno", "dictInAnnotation": "Výraz slovníku není v poznámce typu povolený", @@ -228,8 +236,8 @@ "implicitStringConcat": "Implicitní zřetězení řetězců není povolené", "importCycleDetected": "V řetězci importu byl zjištěn cyklus", "importDepthExceeded": "Hloubka řetězu importu překročila {depth}", - "importResolveFailure": "Import {importName} se v prostředí {venv} nepovedlo najít.", - "importSourceResolveFailure": "Import {importName} se nepovedlo přeložit ze zdroje v prostředí {venv}.", + "importResolveFailure": "Import {importName} se nepovedlo vyřešit", + "importSourceResolveFailure": "Import {importName} se nepovedlo přeložit ze zdroje", "importSymbolUnknown": "{name} je neznámý symbol importu", "incompatibleMethodOverride": "Metoda {name} přepisuje třídu {className} nekompatibilním způsobem", "inconsistentIndent": "Množství zrušeného odsazení neodpovídá předchozímu odsazení", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "Očekávaly se tři tečky, výraz řazené kolekce členů nebo Parametr ParamSpec pro výchozí hodnotu ParamSpec", "paramSpecFirstArg": "Očekával se název parametru ParamSpec jako první argument", "paramSpecKwargsUsage": "Člen kwargs parametru ParamSpec je platný jenom v případě, že se používá s parametrem **kwargs", - "paramSpecNotBound": "Specifikace parametru {type} nemá žádnou vázanou hodnotu", "paramSpecNotUsedByOuterScope": "Parametr ParamSpec {name} nemá v tomto kontextu žádný význam", "paramSpecScopedToReturnType": "Parametr ParamSpec {name} je vymezený na volatelnou proměnnou v rámci návratového typu a nedá se na něj odkazovat v těle funkce jazyka", "paramSpecUnknownArg": "Parametr ParamSpec nepodporuje více než jeden argument", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "Základní třída {baseClass} je odvozená od třídy {subclass}, která není kompatibilní s typem {type}", "baseClassOverriddenType": "Základní třída {baseClass} poskytuje typ {type}, který je přepsán", "baseClassOverridesType": "Základní třída „{baseClass}“ přepisuje typ „{type}“", + "bytesTypePromotions": "Pokud chcete povolit chování povýšení typu pro „bytearray“ a „memoryview“, nastavte disableBytesTypePromotions na false", "conditionalRequiresBool": "Metoda __bool__ pro typ {operandType} vrací typ {boolReturnType} místo bool", "dataClassFieldLocation": "Deklarace pole", "dataClassFrozen": "{name} je zablokované", @@ -612,6 +620,8 @@ "incompatibleSetter": "Metoda setter vlastnosti je nekompatibilní", "initMethodLocation": "Metoda __init__ je definována ve třídě {type}", "initMethodSignature": "Podpis __init__ je {type}", + "invariantSuggestionDict": "Zvažte přepnutí z „diktování“ na „mapování“, které je v typu hodnoty kovariantní", + "invariantSuggestionList": "Zvažte přepnutí ze „seznamu“ na „sekvenci“, která je kovavariantní", "keyNotRequired": "„{name}! není v typu „{type}“ povinný klíč, takže přístup může vést k výjimce modulu runtime", "keyReadOnly": "{name} je klíč jen pro čtení v {type}", "keyRequiredDeleted": "{name} je povinný klíč a nedá se odstranit", @@ -632,6 +642,7 @@ "memberSetClassVar": "Člen „{name}“ nelze přiřadit prostřednictvím instance třídy, protože se jedná o třídu ClassVar", "memberTypeMismatch": "{name} je nekompatibilní typ", "memberUnknown": "Člen {name} je neznámý", + "metaclassConflict": "Metatřída {metaclass1} je v konfliktu s metatřídou {metaclass2}.", "missingDeleter": "Chybí metoda odstranění vlastnosti", "missingGetter": "Chybí metoda getter vlastnosti", "missingProtocolMember": "Člen {name} je deklarován ve třídě protokolu {classType}", @@ -643,10 +654,13 @@ "newMethodSignature": "Podpis __new__ je {type}", "noOverloadAssignable": "Typ {type} neodpovídá žádné přetížené funkci", "orPatternMissingName": "Chybějící názvy: {name}", + "overloadIndex": "Přetížení {index} je nejbližší shoda.", "overloadNotAssignable": "Nejméně jedno přetížení {name} není možné přiřadit", "overloadSignature": "Tady je definován podpis přetížení", "overriddenMethod": "Přepsaná metoda", "overriddenSymbol": "Přepsaný symbol", + "overrideInvariantMismatch": "Typ přepsání „{overrideType}“není stejný jako základní typ „{baseType}“", + "overrideIsInvariant": "Proměnná je proměnlivá, takže její typ je invariantní", "overrideNoOverloadMatches": "Signatura přetížení v přepsání není kompatibilní se základní metodou", "overrideNotClassMethod": "Základní metoda je deklarována jako metoda classmethod, ale přepsání není", "overrideNotInstanceMethod": "Základní metoda je deklarována jako instanční metoda, ale přepsání není", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "Typ TypeVarTuple nemůže být vázaný na řazenou kolekci členů neznámé délky", "typeVarUnsolvableRemedy": "Zadejte přetížení, které určuje návratový typ, pokud argument není zadán", "typeVarsMissing": "Chybějící proměnné typu: {names}", + "typedDictBaseClass": "Třída „{type}“ není TypedDict.", "typedDictFieldMissing": "V {type} chybí {name}", "typedDictFieldNotReadOnly": "{name} není v {type} jen pro čtení", "typedDictFieldNotRequired": "{name} se v typu {type} nevyžaduje", diff --git a/packages/pyright-internal/src/localization/package.nls.de.json b/packages/pyright-internal/src/localization/package.nls.de.json index c3ef9535f..06d863859 100644 --- a/packages/pyright-internal/src/localization/package.nls.de.json +++ b/packages/pyright-internal/src/localization/package.nls.de.json @@ -11,8 +11,8 @@ "renameShadowedFile": "\"{oldFile}\" in \"{newFile}\" umbenennen" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Autoimport", + "indexValueDetail": "Indexwert" }, "Diagnostic": { "abstractMethodInvocation": "Die Methode \"{method}\" kann nicht aufgerufen werden, da sie abstrakt ist.", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__ Außerkraftsetzung sollte einen \"cls\"-Parameter annehmen.", "classMethodClsParam": "Klassenmethoden sollten einen \"cls\"-Parameter verwenden.", "classNotRuntimeSubscriptable": "Durch das Tiefstellungsskript für die Klasse \"{name}\" wird eine Laufzeitausnahme generiert; schließen Sie die Typanmerkung in Anführungszeichen ein", - "classPatternBuiltInArgCount": "Das Klassenmuster akzeptiert höchstens 1 positionsbezogenes Untermuster.", "classPatternBuiltInArgPositional": "Das Klassenmuster akzeptiert nur positionsbezogenes Untermuster.", + "classPatternPositionalArgCount": "Zu viele Positionsmuster für Klasse \"{type}\". Erwartet: {expected}, empfangen: {received}.", "classPatternTypeAlias": "\"{type}\" kann nicht in einem Klassenmuster verwendet werden, da es sich um einen spezialisierten Typalias handelt.", "classTypeParametersIllegal": "Die Syntax des Klassentypparameters erfordert Python 3.12 oder höher.", "classVarFirstArgMissing": "Nach \"ClassVar\" wurde ein Typargument erwartet.", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "Der Ausdruck wird immer als True ausgewertet, da die Typen \"{leftType}\" und \"{rightType}\" keine Überlappung aufweisen.", "continueInFinally": "\"continue\" kann nicht innerhalb einer finally-Klausel verwendet werden.", "continueOutsideLoop": "\"continue\" kann nur innerhalb einer Schleife verwendet werden.", + "coroutineInConditionalExpression": "Bedingter Ausdruck verweist auf eine Coroutine, die immer zu \"True\" ausgewertet wird.", "dataClassBaseClassFrozen": "Eine nicht fixierte Klasse kann nicht von einer fixierten Klasse erben.", "dataClassBaseClassNotFrozen": "Eine fixierte Klasse kann nicht von einer nicht fixierten Klasse erben.", "dataClassConverterFunction": "Das Argument vom Typ \"{argType}\" ist kein gültiger Konverter für das Feld \"{fieldName}\" vom Typ \"{fieldType}\"", @@ -114,7 +115,14 @@ "delTargetExpr": "Der Ausdruck kann nicht gelöscht werden", "deprecatedClass": "Die Klasse \"{name}\" ist veraltet.", "deprecatedConstructor": "Der Konstruktor für die Klasse \"{name}\" ist veraltet.", + "deprecatedDescriptorDeleter": "Die Methode \"__delete__\" für den Deskriptor \"{name}\" ist veraltet.", + "deprecatedDescriptorGetter": "Die Methode \"__get__\" für den Deskriptor \"{name}\" ist veraltet.", + "deprecatedDescriptorSetter": "Die Methode \"__set__\" für den Deskriptor \"{name}\" ist veraltet.", "deprecatedFunction": "Die Funktion \"{name}\" ist veraltet.", + "deprecatedMethod": "Die Methode \"{name}\" in der Klasse \"{className}\" ist veraltet.", + "deprecatedPropertyDeleter": "Der Deleter für die Eigenschaft \"{name}\" ist veraltet.", + "deprecatedPropertyGetter": "Der Getter für die Eigenschaft \"{name}\" ist veraltet.", + "deprecatedPropertySetter": "Der Setter für die Eigenschaft \"{name}\" ist veraltet.", "deprecatedType": "Dieser Typ ist ab python-{version} veraltet; verwenden Sie stattdessen \"{replacement}\"", "dictExpandIllegalInComprehension": "Wörterbucherweiterung ist im Verständnis nicht zulässig.", "dictInAnnotation": "Ein Wörterbuchausdruck ist in der Typanmerkung nicht zulässig.", @@ -228,8 +236,8 @@ "implicitStringConcat": "Implizite Zeichenfolgenverkettung nicht zulässig", "importCycleDetected": "Zyklus in Importkette erkannt", "importDepthExceeded": "Importkettentiefe überschritten {depth}", - "importResolveFailure": "Der Import \"{importName}\" wurde in der Umgebung \"{venv}\" nicht gefunden.", - "importSourceResolveFailure": "Der Import \"{importName}\" konnte nicht aus der Quelle in der Umgebung \"{venv}\" aufgelöst werden.", + "importResolveFailure": "Import \"{importName}\" konnte nicht aufgelöst werden.", + "importSourceResolveFailure": "Import \"{importName}\" konnte aus der Quelle nicht aufgelöst werden.", "importSymbolUnknown": "\"{name}\" ist ein unbekanntes Importsymbol.", "incompatibleMethodOverride": "Die Methode \"{name}\" überschreibt die Klasse \"{className}\" auf inkompatible Weise.", "inconsistentIndent": "Der Betrag für Nichteinzug stimmt nicht mit dem vorherigen Einzug überein.", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "Es wurde ein Auslassungszeichen, ein Tupelausdruck oder ParamSpec für den Standardwert von ParamSpec erwartet.", "paramSpecFirstArg": "Der Name von ParamSpec wurde als erstes Argument erwartet.", "paramSpecKwargsUsage": "Das \"kwargs\"-Element von ParamSpec ist nur gültig, wenn es mit dem Parameter **kwargs verwendet wird.", - "paramSpecNotBound": "Die Parameterspezifikation \"{type}\" hat keinen gebundenen Wert.", "paramSpecNotUsedByOuterScope": "ParamSpec \"{name}\" hat in diesem Kontext keine Bedeutung.", "paramSpecScopedToReturnType": "ParamSpec \"{name}\" ist auf einen Aufruf innerhalb des Rückgabetyps beschränkt und kann im Funktionstext nicht referenziert werden.", "paramSpecUnknownArg": "ParamSpec unterstützt nur ein Argument.", @@ -420,7 +427,7 @@ "superCallArgCount": "Es werden nicht mehr als zwei Argumente für den Superaufruf erwartet.", "superCallFirstArg": "Klassentyp als erstes Argument für super-Aufruf erwartet, aber \"{type}\" empfangen", "superCallSecondArg": "Das zweite Argument für den \"super\"-Aufruf muss ein Objekt oder eine Klasse sein, das bzw. die von \"{type}\" abgeleitet wird.", - "superCallZeroArgForm": "Zero-argument form of \"super\" call is valid only within a method", + "superCallZeroArgForm": "Die Nullargumentform des „Superaufrufs“ ist nur innerhalb einer Methode gültig.", "symbolIsPossiblyUnbound": "\"{name}\" ist möglicherweise ungebunden.", "symbolIsUnbound": "\"{name}\" ist ungebunden.", "symbolIsUndefined": "\"{name}\" ist nicht definiert.", @@ -455,7 +462,7 @@ "typeAssignmentMismatch": "Ein Ausdruck vom Typ \"{sourceType}\" kann nicht dem deklarierten Typ \"{destType}\" zugewiesen werden.", "typeAssignmentMismatchWildcard": "Das Importsymbol \"{name}\" weist den Typ \"{sourceType}\" auf, der dem deklarierten Typ \"{destType}\" nicht zugewiesen werden kann.", "typeCallNotAllowed": "Der type()-Aufruf darf nicht in der Typanmerkung verwendet werden.", - "typeCheckOnly": "\"{name}\" is marked as @type_check_only and can be used only in type annotations", + "typeCheckOnly": "\"{name}\" ist als @type_check_only markiert und kann nur in Typanmerkungen verwendet werden.", "typeCommentDeprecated": "Die Verwendung von Typkommentaren ist veraltet; verwenden Sie stattdessen Typanmerkung", "typeExpectedClass": "Typausdruck erwartet, aber \"{type}\" empfangen", "typeGuardArgCount": "Nach \"TypeGuard\" wurde ein einzelnes Typargument erwartet.", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "Die Basisklasse \"{baseClass}\" wird von \"{subclass}\" abgeleitet, die mit dem Typ \"{type}\" nicht kompatibel ist.", "baseClassOverriddenType": "Die Basisklasse \"{baseClass}\" stellt einen Typ \"{type}\" bereit, der überschrieben wird.", "baseClassOverridesType": "Basisklasse \"{baseClass}\" überschreibt mit Typ \"{type}\"", + "bytesTypePromotions": "Legen Sie disableBytesTypePromotions auf FALSE fest, um das Typerweiterungsverhalten für \"bytearray\" und \"memoryview\" zu aktivieren.", "conditionalRequiresBool": "Die Methode __bool__ für den Typ \"{operandType}\" gibt den Typ \"{boolReturnType}\" anstelle von \"bool\" zurück", "dataClassFieldLocation": "Felddeklaration", "dataClassFrozen": "\"{name}\" ist fixiert", @@ -612,6 +620,8 @@ "incompatibleSetter": "Die Settermethode der Eigenschaft ist nicht kompatibel.", "initMethodLocation": "Die __init__ Methode ist in der Klasse \"{type}\" definiert.", "initMethodSignature": "Die Signatur von __init__ ist \"{type}\".", + "invariantSuggestionDict": "Erwägen Sie den Wechsel von \"dict\" zu \"Mapping\" (im Werttyp covariant).", + "invariantSuggestionList": "Erwägen Sie den Wechsel von \"list\" zu \"Sequence\" (covariant).", "keyNotRequired": "\"{name}\" ist kein erforderlicher Schlüssel in \"{type}\". Der Zugriff kann daher zu einer Laufzeitausnahme führen.", "keyReadOnly": "\"{name}\" ist ein schreibgeschützter Schlüssel in \"{type}\"", "keyRequiredDeleted": "\"{name}\" ist ein erforderlicher Schlüssel und kann nicht gelöscht werden.", @@ -632,6 +642,7 @@ "memberSetClassVar": "Der Member \"{name}\" kann nicht über eine Klasseninstanz zugewiesen werden, da es sich um eine ClassVar handelt.", "memberTypeMismatch": "\"{name}\" ist ein inkompatibler Typ.", "memberUnknown": "Das Member \"{name}\" ist unbekannt.", + "metaclassConflict": "Die Metaklasse \"{metaclass1}\" verursacht einen Konflikt mit \"{metaclass2}\"", "missingDeleter": "Die Eigenschaft-Deleter-Methode fehlt.", "missingGetter": "Die Eigenschaft-Getter-Methode fehlt.", "missingProtocolMember": "Member \"{name}\" ist in Protokollklasse \"{classType}\" deklariert.", @@ -643,10 +654,13 @@ "newMethodSignature": "Signatur von __new__ ist \"{type}\"", "noOverloadAssignable": "Keine überladene Funktion stimmt mit dem Typ \"{type}\" überein.", "orPatternMissingName": "Fehlende Namen: {name}", + "overloadIndex": "Überladung \"{index}\" ist die nächste Übereinstimmung.", "overloadNotAssignable": "Mindestens eine Überladung von \"{name}\" kann nicht zugewiesen werden.", "overloadSignature": "Die Überladungssignatur ist hier definiert.", "overriddenMethod": "Überschriebene Methode", "overriddenSymbol": "Außer Kraft gesetztes Symbol", + "overrideInvariantMismatch": "Der Überschreibungstyp \"{overrideType}\" ist nicht identisch mit dem Basistyp \"{baseType}\".", + "overrideIsInvariant": "Die Variable ist veränderlich, sodass ihr Typ unveränderlich ist.", "overrideNoOverloadMatches": "Keine Überladungssignatur in Überschreibung ist mit der Basismethode kompatibel.", "overrideNotClassMethod": "Die Basismethode ist als Klassenmethode deklariert, die Überschreibung jedoch nicht", "overrideNotInstanceMethod": "Die Basismethode ist als Instanz deklariert, die Überschreibung jedoch nicht", @@ -688,8 +702,8 @@ "seeVariableDeclaration": "Siehe Variablendeklaration", "tupleAssignmentMismatch": "Der Typ \"{type}\" ist nicht mit dem Zieltupel kompatibel.", "tupleEntryTypeMismatch": "Der Tupeleintrag {entry} ist ein falscher Typ.", - "tupleSizeIndeterminate": "Tuple size mismatch; expected {expected} but received indeterminate", - "tupleSizeMismatch": "Tuple size mismatch; expected {expected} but received {received}", + "tupleSizeIndeterminate": "Nicht übereinstimmende Tupelgröße; {expected} erwartet, aber unbestimmt empfangen", + "tupleSizeMismatch": "Nicht übereinstimmende Tupelgröße; {expected} erwartet, aber {received} empfangen", "typeAssignmentMismatch": "Der Typ \"{sourceType}\" kann dem Typ \"{destType}\" nicht zugewiesen werden.", "typeBound": "Der Typ \"{sourceType}\" ist nicht mit dem gebundenen Typ \"{destType}\" für die Typvariablen \"{name}\" kompatibel.", "typeConstrainedTypeVar": "Der Typ \"{type}\" ist mit der eingeschränkten Typvariablen nicht kompatibel \"{name}\"", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple kann nicht an ein Tupel unbekannter Länge gebunden werden.", "typeVarUnsolvableRemedy": "Geben Sie eine Überladung an, die den Rückgabetyp angibt, wenn das Argument nicht angegeben ist.", "typeVarsMissing": "Fehlende Typvariablen: {names}", + "typedDictBaseClass": "Die Klasse \"{type}\" ist kein TypedDict.", "typedDictFieldMissing": "\"{name}\" fehlt in \"{type}\"", "typedDictFieldNotReadOnly": "\"{name}\" ist in \"{type}\" nicht schreibgeschützt.", "typedDictFieldNotRequired": "\"{name}\" ist in \"{type}\" nicht erforderlich.", diff --git a/packages/pyright-internal/src/localization/package.nls.en-us.json b/packages/pyright-internal/src/localization/package.nls.en-us.json index 8df008c64..eb93dce2c 100644 --- a/packages/pyright-internal/src/localization/package.nls.en-us.json +++ b/packages/pyright-internal/src/localization/package.nls.en-us.json @@ -52,8 +52,8 @@ "classGetItemClsParam": "__class_getitem__ override should take a \"cls\" parameter", "classMethodClsParam": "Class methods should take a \"cls\" parameter", "classNotRuntimeSubscriptable": "Subscript for class \"{name}\" will generate runtime exception; enclose type annotation in quotes", - "classPatternBuiltInArgCount": "Class pattern accepts at most 1 positional sub-pattern", "classPatternBuiltInArgPositional": "Class pattern accepts only positional sub-pattern", + "classPatternPositionalArgCount": "Too many positional patterns for class \"{type}\"; expected {expected} but received {received}", "classPatternTypeAlias": "\"{type}\" cannot be used in a class pattern because it is a specialized type alias", "classTypeParametersIllegal": "Class type parameter syntax requires Python 3.12 or newer", "classVarNotAllowed": "\"ClassVar\" is not allowed in this context", @@ -99,8 +99,14 @@ "defaultValueNotAllowed": "Parameter with \"*\" or \"**\" cannot have default value", "deprecatedClass": "The class \"{name}\" is deprecated", "deprecatedConstructor": "The constructor for class \"{name}\" is deprecated", + "deprecatedDescriptorDeleter": "The \"__delete__\" method for descriptor \"{name}\" is deprecated", + "deprecatedDescriptorGetter": "The \"__get__\" method for descriptor \"{name}\" is deprecated", + "deprecatedDescriptorSetter": "The \"__set__\" method for descriptor \"{name}\" is deprecated", "deprecatedFunction": "The function \"{name}\" is deprecated", "deprecatedMethod": "The method \"{name}\" in class \"{className}\" is deprecated", + "deprecatedPropertyDeleter": "The deleter for property \"{name}\" is deprecated", + "deprecatedPropertyGetter": "The getter for property \"{name}\" is deprecated", + "deprecatedPropertySetter": "The setter for property \"{name}\" is deprecated", "deprecatedType": "This type is deprecated as of Python {version}; use \"{replacement}\" instead", "delTargetExpr": "Expression cannot be deleted", "dictExpandIllegalInComprehension": "Dictionary expansion not allowed in comprehension", @@ -329,7 +335,6 @@ "paramSpecDefaultNotTuple": "Expected ellipsis, a tuple expression, or ParamSpec for default value of ParamSpec", "paramSpecFirstArg": "Expected name of ParamSpec as first argument", "paramSpecKwargsUsage": "\"kwargs\" member of ParamSpec is valid only when used with **kwargs parameter", - "paramSpecNotBound": "Param spec \"{type}\" has no bound value", "paramSpecNotUsedByOuterScope": "ParamSpec \"{name}\" has no meaning in this context", "paramSpecScopedToReturnType": "ParamSpec \"{name}\" is scoped to a callable within the return type and cannot be referenced in the function body", "paramSpecUnknownArg": "ParamSpec does not support more than one argument", @@ -585,6 +590,7 @@ "baseClassIncompatibleSubclass": "Base class \"{baseClass}\" derives from \"{subclass}\" which is incompatible with type \"{type}\"", "baseClassOverriddenType": "Base class \"{baseClass}\" provides type \"{type}\", which is overridden", "baseClassOverridesType": "Base class \"{baseClass}\" overrides with type \"{type}\"", + "bytesTypePromotions": "Set disableBytesTypePromotions to false to enable type promotion behavior for \"bytearray\" and \"memoryview\"", "conditionalRequiresBool": "Method __bool__ for type \"{operandType}\" returns type \"{boolReturnType}\" rather than \"bool\"", "dataClassFieldLocation": "Field declaration", "dataClassFrozen": "\"{name}\" is frozen", @@ -603,6 +609,8 @@ "initMethodLocation": "The __init__ method is defined in class \"{type}\"", "incompatibleDeleter": "Property deleter method is incompatible", "initMethodSignature": "Signature of __init__ is \"{type}\"", + "invariantSuggestionDict": "Consider switching from \"dict\" to \"Mapping\" which is covariant in the value type", + "invariantSuggestionList": "Consider switching from \"list\" to \"Sequence\" which is covariant", "kwargsParamMissing": "Parameter \"**{paramName}\" has no corresponding parameter", "listAssignmentMismatch": "Type \"{type}\" is incompatible with target list", "literalAssignmentMismatch": "\"{sourceType}\" cannot be assigned to type \"{destType}\"", @@ -619,6 +627,7 @@ "memberIsWritableInProtocol": "\"{name}\" is writable in protocol", "memberTypeMismatch": "\"{name}\" is an incompatible type", "memberUnknown": "Member \"{name}\" is unknown", + "metaclassConflict": "Metaclass \"{metaclass1}\" conflicts with \"{metaclass2}\"", "missingProtocolMember": "Member \"{name}\" is declared in protocol class \"{classType}\"", "missingGetter": "Property getter method is missing", "missingSetter": "Property setter method is missing", @@ -630,6 +639,7 @@ "newMethodSignature": "Signature of __new__ is \"{type}\"", "noOverloadAssignable": "No overloaded function matches type \"{type}\"", "orPatternMissingName": "Missing names: {name}", + "overloadIndex": "Overload {index} is the closest match", "overloadSignature": "Overload signature is defined here", "overloadNotAssignable": "One or more overloads of \"{name}\" is not assignable", "overriddenMethod": "Overridden method", diff --git a/packages/pyright-internal/src/localization/package.nls.es.json b/packages/pyright-internal/src/localization/package.nls.es.json index d06d81ef4..8a798d645 100644 --- a/packages/pyright-internal/src/localization/package.nls.es.json +++ b/packages/pyright-internal/src/localization/package.nls.es.json @@ -11,8 +11,8 @@ "renameShadowedFile": "Cambie el nombre de \"{oldFile}\" a \"{newFile}\"" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Importación automática", + "indexValueDetail": "Valor de índice" }, "Diagnostic": { "abstractMethodInvocation": "El método \"{method}\" no puede ser llamado porque es abstracto", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__ debe tomar un parámetro \"cls\"", "classMethodClsParam": "Los métodos de clase deben tomar un parámetro \"cls\"", "classNotRuntimeSubscriptable": "El subíndice para la clase \"{name}\" generará una excepción en tiempo de ejecución; encierre la anotación de tipo entre comillas", - "classPatternBuiltInArgCount": "El patrón de clase acepta como máximo 1 subpatrón posicional", "classPatternBuiltInArgPositional": "El patrón de clase solo acepta subpatrones posicionales", + "classPatternPositionalArgCount": "Demasiados patrones posicionales para la clase \"{type}\"; esperado {expected} pero recibido {received}", "classPatternTypeAlias": "\"{type}\" no se puede usar en un patrón de clase porque es un alias de tipo especializado", "classTypeParametersIllegal": "La sintaxis de los parámetros de tipo de clase requiere Python 3.12 o posterior.", "classVarFirstArgMissing": "Se esperaba un argumento de tipo después de \"ClassVar\"", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "La expresión siempre se evaluará como True, ya que los tipos \"{leftType}\" y \"{rightType}\" no tienen superposición", "continueInFinally": "\"continue\" no puede utilizarse dentro de una cláusula finally", "continueOutsideLoop": "\"continue\" solo puede utilizarse dentro de un bucle", + "coroutineInConditionalExpression": "La expresión condicional hace referencia a una corrutina que siempre se evalúa como Verdadero", "dataClassBaseClassFrozen": "Una clase no inmovilizada no puede heredar de una clase inmovilizada", "dataClassBaseClassNotFrozen": "Una clase congelada no puede heredar de una clase que no esté congelada", "dataClassConverterFunction": "Argumento de tipo \"{argType}\" no es un convertidor válido para el campo \"{fieldName}\" de tipo \"{fieldType}\"", @@ -114,7 +115,14 @@ "delTargetExpr": "No se puede eliminar la expresión", "deprecatedClass": "La clase \"{name}\" está en desuso", "deprecatedConstructor": "El constructor de la clase \"{name}\" está obsoleto", - "deprecatedFunction": "Esta función \"{name}\" está obsoleta", + "deprecatedDescriptorDeleter": "El método \"__delete__\" para el \"{name}\" de descriptor está en desuso", + "deprecatedDescriptorGetter": "El método \"__get__\" para el \"{name}\" de descriptor está en desuso", + "deprecatedDescriptorSetter": "El método \"__set__\" para el \"{name}\" de descriptor está en desuso", + "deprecatedFunction": "La función \"{name}\" está obsoleta", + "deprecatedMethod": "El método \"{name}\" en la clase \"{className}\" está en desuso", + "deprecatedPropertyDeleter": "El eliminador de la propiedad \"{name}\" está en desuso", + "deprecatedPropertyGetter": "El captador de la propiedad \"{name}\" está en desuso", + "deprecatedPropertySetter": "El establecedor de la propiedad \"{name}\" está en desuso", "deprecatedType": "Este tipo está obsoleto a partir de la {version} de Python; utilice en su lugar \"{replacement}\".", "dictExpandIllegalInComprehension": "No se permite la ampliación del diccionario en la comprensión", "dictInAnnotation": "Expresión de diccionario no permitida en anotación de tipo", @@ -228,8 +236,8 @@ "implicitStringConcat": "No se permite la concatenación implícita de cadenas", "importCycleDetected": "Ciclo detectado en la cadena de importación", "importDepthExceeded": "La profundidad de la cadena de importación superó {depth}", - "importResolveFailure": "No se encontraron \"{importName}\" de importación en el entorno de \"{venv}\".", - "importSourceResolveFailure": "La importación \"{importName}\" no se ha podido resolver desde el origen en el entorno \"{venv}\".", + "importResolveFailure": "No se ha podido resolver la importación \"{importName}\".", + "importSourceResolveFailure": "La importación \"{importName}\" no se ha podido resolver desde el origen", "importSymbolUnknown": "\"{name}\" es un símbolo de importación desconocido", "incompatibleMethodOverride": "El método \"{name}\" sobrescribe la clase \"{className}\" de forma incompatible", "inconsistentIndent": "La cantidad sin sangría no coincide con la sangría anterior", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "Se esperaban puntos suspensivos, una expresión de tupla o ParamSpec para el valor predeterminado de ParamSpec", "paramSpecFirstArg": "Se esperaba el nombre de ParamSpec como primer argumento", "paramSpecKwargsUsage": "El miembro \"kwargs\" de ParamSpec solo es válido cuando se utiliza con el parámetro **kwargs", - "paramSpecNotBound": "La especificación de parámetro \"{type}\" no tiene valor vinculado", "paramSpecNotUsedByOuterScope": "ParamSpec \"{name}\" no tiene significado en este contexto", "paramSpecScopedToReturnType": "El ámbito de ParamSpec \"{name}\" es un ámbito al que se puede llamar dentro del tipo de valor devuelto y no se puede hacer referencia a él en el cuerpo de la función.", "paramSpecUnknownArg": "ParamSpec no admite más de un argumento", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "La clase base \"{baseClass}\" deriva de \"{subclass}\", que no es compatible con el tipo \"{type}\"", "baseClassOverriddenType": "La clase base \"{baseClass}\" proporciona el tipo \"{type}\", que se sobrescribe", "baseClassOverridesType": "Invalidaciones de clase base \"{baseClass}\" con el tipo \"{type}\"", + "bytesTypePromotions": "Establezca disableBytesTypePromotions en falso para activar el comportamiento de promoción de tipos para \"bytearray\" y \"memoryview\".", "conditionalRequiresBool": "El método __bool__ para el tipo \"{operandType}\" devuelve el tipo \"{boolReturnType}\" en lugar de \"bool\"", "dataClassFieldLocation": "en declaración de campo", "dataClassFrozen": "\"{name}\" está congelado", @@ -612,6 +620,8 @@ "incompatibleSetter": "El método setter de la propiedad no es compatible", "initMethodLocation": "El método __init__ se define en la clase \"{type}\"", "initMethodSignature": "La firma de __init__ es \"{type}\"", + "invariantSuggestionDict": "Considere cambiar de \"predicción\" a \" Asignación\" que es covariante en el tipo de valor", + "invariantSuggestionList": "Considere la posibilidad de cambiar de \"lista\" a \"Secuencia\" que es covariante", "keyNotRequired": "\"{name}\" no es una clave necesaria en \"{type}\", por lo que el acceso puede dar lugar a una excepción en tiempo de ejecución", "keyReadOnly": "\"{name}\" es una clave de solo lectura en \"{type}\"", "keyRequiredDeleted": "\"{name}\" es una clave necesaria y no se puede eliminar", @@ -632,6 +642,7 @@ "memberSetClassVar": "El miembro \"{name}\" no se puede asignar a través de una instancia de clase porque es un ClassVar.", "memberTypeMismatch": "\"{name}\" es un tipo incompatible", "memberUnknown": "El miembro \"{name}\" es desconocido", + "metaclassConflict": "La metaclase \"{metaclass1}\" entra en conflicto con \"{metaclass2}\"", "missingDeleter": "Falta el método de eliminación de propiedades", "missingGetter": "Falta el método Getter de la propiedad", "missingProtocolMember": "El miembro \"{name}\" está declarado en la clase de protocolo \"{classType}\"", @@ -643,10 +654,13 @@ "newMethodSignature": "La firma de __new__ es \"{type}\"", "noOverloadAssignable": "Ninguna función sobrecargada coincide con el tipo \"{type}\"", "orPatternMissingName": "Nombres que faltan: {name}", + "overloadIndex": "La sobrecarga {index} es la coincidencia más cercana", "overloadNotAssignable": "Una o más sobrecargas de \"{name}\" no es asignable", "overloadSignature": "Aquí se define la firma de la sobrecarga", "overriddenMethod": "Método reemplazado", "overriddenSymbol": "Símbolo anulado", + "overrideInvariantMismatch": "El tipo de invalidación “{overrideType}” no es el mismo que el tipo básico “{baseType}”", + "overrideIsInvariant": "La variable es mutable, por lo que su tipo es invariable", "overrideNoOverloadMatches": "Ninguna firma de sobrecarga en anulación es compatible con el método base", "overrideNotClassMethod": "El método base se declara como Método de clase pero el Reemplazar no", "overrideNotInstanceMethod": "El método base se declara como método de instancia, pero la invalidación no", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple no se puede enlazar a una tupla de longitud desconocida", "typeVarUnsolvableRemedy": "Proporciona una sobrecarga que especifica el tipo de retorno cuando no se proporciona el argumento", "typeVarsMissing": "Faltan variables de tipo: {names}", + "typedDictBaseClass": "La clase “{type}” no es un TypeDict", "typedDictFieldMissing": "\"{name}\" falta en \"{type}\"", "typedDictFieldNotReadOnly": "\"{name}\" no es de solo lectura en \"{type}\"", "typedDictFieldNotRequired": "\"{name}\" no es obligatorio en \"{type}\"", diff --git a/packages/pyright-internal/src/localization/package.nls.fr.json b/packages/pyright-internal/src/localization/package.nls.fr.json index 232286c1e..cc7f25b9b 100644 --- a/packages/pyright-internal/src/localization/package.nls.fr.json +++ b/packages/pyright-internal/src/localization/package.nls.fr.json @@ -11,8 +11,8 @@ "renameShadowedFile": "Renommez \"{oldFile}\" en \"{newFile}\"" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Importation automatique", + "indexValueDetail": "Valeur de l'indice" }, "Diagnostic": { "abstractMethodInvocation": "Impossible d’appeler la méthode « {method} », car elle est abstraite", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__ remplacement doit prendre un paramètre « cls »", "classMethodClsParam": "Les méthodes de classe doivent prendre un paramètre \"cls\"", "classNotRuntimeSubscriptable": "L’indice de la classe « {name} » génère une exception d’exécution ; placer l’annotation de type entre guillemets", - "classPatternBuiltInArgCount": "Le modèle de classe accepte au maximum 1 sous-modèle positionnel", "classPatternBuiltInArgPositional": "Le modèle de classe accepte uniquement le sous-modèle positionnel", + "classPatternPositionalArgCount": "Trop de modèles positionnels pour les \"{type}\" de classe ; {expected} attendue mais {received} reçues", "classPatternTypeAlias": "\"{type}\" ne peut pas être utilisé dans un modèle de classe car il s'agit d'un alias de type spécialisé", "classTypeParametersIllegal": "La syntaxe du paramètre de type de classe nécessite Python 3.12 ou version ultérieure", "classVarFirstArgMissing": "Attendu un argument de type après \"ClassVar\"", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "L'expression sera toujours évaluée à True puisque les types \"{leftType}\" et \"{rightType}\" ne se chevauchent pas", "continueInFinally": "« continuer » ne peut pas être utilisé dans une clause finally", "continueOutsideLoop": "« continuer » ne peut être utilisé qu’au sein d’une boucle", + "coroutineInConditionalExpression": "L'expression conditionnelle fait référence à une coroutine qui est toujours évaluée à True", "dataClassBaseClassFrozen": "Une classe non gelée ne peut pas hériter d'une classe gelée", "dataClassBaseClassNotFrozen": "Une classe figée ne peut pas hériter d’une classe qui n’est pas figée", "dataClassConverterFunction": "L’argument de type « {argType} » n’est pas un convertisseur valide pour le champ « {fieldName} » de type « {fieldType} »", @@ -114,7 +115,14 @@ "delTargetExpr": "L'expression ne peut pas être supprimée", "deprecatedClass": "La classe \"{name}\" est obsolète", "deprecatedConstructor": "Le constructeur de la classe « {name} » est déconseillé", - "deprecatedFunction": "Cette fonction « {name} » est déconseillée", + "deprecatedDescriptorDeleter": "La méthode « __delete__ » du descripteur « {name} » est déconseillée", + "deprecatedDescriptorGetter": "La méthode « __get__ » du descripteur « {name} » est déconseillée", + "deprecatedDescriptorSetter": "La méthode « __set__ » du descripteur « {name} » est déconseillée", + "deprecatedFunction": "La fonction \"{name}\" est obsolète", + "deprecatedMethod": "La méthode \"{name}\" dans la classe \"{className}\" est obsolète", + "deprecatedPropertyDeleter": "Le deleter de la propriété « {name} » est déconseillé", + "deprecatedPropertyGetter": "Le getter de la propriété « {name} » est déconseillé", + "deprecatedPropertySetter": "Le setter de la propriété « {name} » est déconseillé", "deprecatedType": "Ce type est déconseillé à compter de Python {version}; utiliser « {replacement} » à la place", "dictExpandIllegalInComprehension": "Expansion du dictionnaire non autorisée dans la compréhension", "dictInAnnotation": "Expression de dictionnaire non autorisée dans l’annotation de type", @@ -228,8 +236,8 @@ "implicitStringConcat": "Concaténation implicite de chaînes non autorisée", "importCycleDetected": "Cycle détecté dans la chaîne d'importation", "importDepthExceeded": "La profondeur de la chaîne d'importation a dépassé {depth}", - "importResolveFailure": "L'importation \"{importName}\" est introuvable dans l'environnement \"{venv}\".", - "importSourceResolveFailure": "L’importation « {importName} » n’a pas pu être résolue à partir de la source dans l’environnement « {venv} ».", + "importResolveFailure": "Impossible de résoudre l’importation « {importName} »", + "importSourceResolveFailure": "Impossible de résoudre l’importation « {importName} » à partir de la source", "importSymbolUnknown": "« {name} » est un symbole d’importation inconnu", "incompatibleMethodOverride": "La méthode « {name} » remplace la classe « {className} » de manière incompatible", "inconsistentIndent": "Le montant du retrait ne correspond pas au retrait précédent", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "Points de suspension attendus, expression de tuple ou ParamSpec pour la valeur par défaut de ParamSpec", "paramSpecFirstArg": "Nom attendu de ParamSpec comme premier argument", "paramSpecKwargsUsage": "Le membre « configurrgs » de ParamSpec n’est valide qu’en cas d’utilisation avec le paramètre **rgs", - "paramSpecNotBound": "La spec de paramètre « {type} » n’a pas de valeur liée", "paramSpecNotUsedByOuterScope": "ParamSpec « {name} » n’a aucune signification dans ce contexte", "paramSpecScopedToReturnType": "ParamSpec \"{name}\" est limité à un appelable dans le type de retour et ne peut pas être référencé dans le corps de la fonction", "paramSpecUnknownArg": "ParamSpec ne prend pas en charge plus d'un argument", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "La classe de base « {baseClass} » dérive de « {subclass} » qui est incompatible avec le type « {type} »", "baseClassOverriddenType": "La classe de base « {baseClass} » fournit le type « {type} », qui est remplacé", "baseClassOverridesType": "La classe de base \"{baseClass}\" remplace le type \"{type}\"", + "bytesTypePromotions": "Définir disableBytesTypePromotions sur false pour activer le comportement de promotion de type pour « bytearray » et « memoryview »", "conditionalRequiresBool": "La méthode __bool__ pour le type « {operandType} » retourne le type « {boolReturnType} » plutôt que « bool »", "dataClassFieldLocation": "Déclaration de champ", "dataClassFrozen": "« {name} » est figé", @@ -612,6 +620,8 @@ "incompatibleSetter": "La méthode setter de propriété n’est pas compatible", "initMethodLocation": "La méthode __init__ est définie dans la classe « {type} »", "initMethodSignature": "La signature de __init__ est « {type} »", + "invariantSuggestionDict": "Envisagez de passer de « dict » à « Mapping », qui est covariant dans le type valeur", + "invariantSuggestionList": "Envisagez de passer de « list » à « Sequence » qui est covariant", "keyNotRequired": "\"{name}\" n'est pas une clé requise dans \"{type}\", donc l'accès peut entraîner une exception d'exécution", "keyReadOnly": "« {name} » est une clé en lecture seule dans « {type} »", "keyRequiredDeleted": "« {name} » est une clé obligatoire et ne peut pas être supprimée", @@ -632,6 +642,7 @@ "memberSetClassVar": "Le membre \"{name}\" ne peut pas être attribué via une instance de classe car il s'agit d'une ClassVar", "memberTypeMismatch": "« {name} » est un type incompatible", "memberUnknown": "Le membre « {name} » est inconnu", + "metaclassConflict": "La métaclasse « {metaclass1} » est en conflit avec « {metaclass2} »", "missingDeleter": "La méthode de suppression de propriétés est manquante", "missingGetter": "La méthode getter de propriété est manquante", "missingProtocolMember": "Le membre « {name} » est déclaré dans la classe de protocole « {classType} »", @@ -643,10 +654,13 @@ "newMethodSignature": "La signature de __new__ est « {type} »", "noOverloadAssignable": "Aucune fonction surchargée ne correspond au type « {type} »", "orPatternMissingName": "Noms manquants : {name}", + "overloadIndex": "La surcharge {index} est la correspondance la plus proche", "overloadNotAssignable": "Une ou plusieurs surcharges de « {name} » ne sont pas assignables", "overloadSignature": "La signature de surcharge est définie ici", "overriddenMethod": "Méthode substituée", "overriddenSymbol": "Symbole substitué", + "overrideInvariantMismatch": "Le type de remplacement \"{overrideType}\" n'est pas le même que le type de base \"{baseType}\"", + "overrideIsInvariant": "La variable est mutable donc son type est invariant", "overrideNoOverloadMatches": "Aucune signature de surcharge dans le remplacement n’est compatible avec la méthode de base", "overrideNotClassMethod": "La méthode de base est déclarée en tant que classmethod, mais la substitution n’est pas", "overrideNotInstanceMethod": "La méthode de base est déclarée en tant que méthode d'instance mais la substitution n'est pas", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple ne peut pas être lié à un tuple de longueur inconnue", "typeVarUnsolvableRemedy": "Fournir une surcharge qui spécifie le type de retour lorsque l’argument n’est pas fourni", "typeVarsMissing": "Variables de type manquantes : {names}", + "typedDictBaseClass": "La classe \"{type}\" n'est pas un TypedDict", "typedDictFieldMissing": "« {name} » est manquant dans « {type} »", "typedDictFieldNotReadOnly": "« {name} » n’est pas en lecture seule dans « {type} »", "typedDictFieldNotRequired": "« {name} » n’est pas obligatoire dans « {type} »", diff --git a/packages/pyright-internal/src/localization/package.nls.it.json b/packages/pyright-internal/src/localization/package.nls.it.json index c28afc939..716366a8e 100644 --- a/packages/pyright-internal/src/localization/package.nls.it.json +++ b/packages/pyright-internal/src/localization/package.nls.it.json @@ -11,8 +11,8 @@ "renameShadowedFile": "Rinomina \"{oldFile}\" in \"{newFile}\"" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Importazione automatica", + "indexValueDetail": "Valore dell’indice" }, "Diagnostic": { "abstractMethodInvocation": "Impossibile chiamare il metodo \"{method}\" perché è astratto", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__ override deve accettare un parametro \"cls\"", "classMethodClsParam": "I metodi di classe devono accettare un parametro \"cls\"", "classNotRuntimeSubscriptable": "Il pedice per la classe \"{name}\" genererà un'eccezione di runtime; racchiudere l'annotazione di tipo tra virgolette", - "classPatternBuiltInArgCount": "Il modello di classe accetta al massimo 1 sotto pattern posizionale", "classPatternBuiltInArgPositional": "Il modello di classe accetta solo un sotto pattern posizionale", + "classPatternPositionalArgCount": "Troppi modelli posizionale per la classe \"{type}\"; previsto {expected} ma ottenuto {received}", "classPatternTypeAlias": "\"{type}\" non può essere usato in uno schema di classe, perché è un alias di tipo specializzato", "classTypeParametersIllegal": "La sintassi del parametro del tipo di classe richiede Python 3.12 o versione successiva", "classVarFirstArgMissing": "È previsto un argomento tipo dopo \"ClassVar\"", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "L'espressione restituisce sempre True perché i tipi \"{leftType}\" e \"{rightType}\" non si sovrappongono", "continueInFinally": "Non è possibile usare \"continue\" all'interno di una clausola finally", "continueOutsideLoop": "\"continue\" può essere usato solo all'interno di un ciclo", + "coroutineInConditionalExpression": "L'espressione condizionale fa riferimento a una coroutine che restituisce sempre True", "dataClassBaseClassFrozen": "Una classe non bloccata non può ereditare da una classe bloccata", "dataClassBaseClassNotFrozen": "Una classe bloccata non può ereditare da una classe non bloccata", "dataClassConverterFunction": "L'argomento di tipo \"{argType}\" non è un convertitore valido per il campo \"{fieldName}\" di tipo \"{fieldType}\"", @@ -114,7 +115,14 @@ "delTargetExpr": "Non è possibile eliminare l'espressione", "deprecatedClass": "La classe \"{name}\" è deprecata", "deprecatedConstructor": "Il costruttore per la classe \"{name}\" è deprecato", - "deprecatedFunction": "Questa funzione \"{name}\" è deprecata", + "deprecatedDescriptorDeleter": "Il metodo \"__delete__\" per il descrittore \"{name}\" è deprecato", + "deprecatedDescriptorGetter": "Il metodo \"__get__\" per il descrittore \"{name}\" è deprecato", + "deprecatedDescriptorSetter": "Il metodo \"__set__\" per il descrittore \"{name}\" è deprecato", + "deprecatedFunction": "La funzione \"{name}\" è deprecata", + "deprecatedMethod": "Il metodo \"{name}\" nella classe \"{className}\" è deprecato", + "deprecatedPropertyDeleter": "Il deleter per la proprietà \"{name}\" è deprecato", + "deprecatedPropertyGetter": "Il getter per la proprietà \"{name}\" è deprecato", + "deprecatedPropertySetter": "Il setter per la proprietà \"{name}\" è deprecato", "deprecatedType": "Questo tipo è deprecato a partire da Python {version}; usa \"{replacement}\"", "dictExpandIllegalInComprehension": "Espansione del dizionario non consentita nella comprensione", "dictInAnnotation": "Espressione dizionario non consentita nell'annotazione di tipo", @@ -228,8 +236,8 @@ "implicitStringConcat": "Concatenazione implicita di stringhe non consentita", "importCycleDetected": "Ciclo rilevato nella catena di importazione", "importDepthExceeded": "La profondità della catena di importazione ha superato {depth}", - "importResolveFailure": "Impossibile trovare l’importazione \"{importName}\" nell'ambiente \"{venv}\".", - "importSourceResolveFailure": "Impossibile risolvere l'importazione \"{importName}\" dall'origine nell'ambiente \"{venv}\".", + "importResolveFailure": "Non è stato possibile risolvere l'importazione \"{importName}\"", + "importSourceResolveFailure": "Non è stato possibile risolvere l'importazione \"{importName}\" dall’origine", "importSymbolUnknown": "\"{name}\" è un simbolo di importazione sconosciuto", "incompatibleMethodOverride": "Il metodo \"{name}\" esegue l'override della classe \"{className}\" in modo incompatibile", "inconsistentIndent": "Il valore dell'annullamento del rientro non corrisponde al rientro precedente", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "Sono previsti puntini di sospensione, un'espressione di tupla o ParamSpec per il valore predefinito di ParamSpec", "paramSpecFirstArg": "Nome previsto di ParamSpec come primo argomento", "paramSpecKwargsUsage": "Il membro \"kwargs\" di ParamSpec è valido solo se usato con il parametro **kwargs", - "paramSpecNotBound": "La specifica del parametro \"{type}\" non ha alcun valore associato", "paramSpecNotUsedByOuterScope": "ParamSpec \"{name}\" non ha significato in questo contesto", "paramSpecScopedToReturnType": "L’ambito ParamSpec \"{name}\" è un elemento richiamabile all'interno del tipo restituito e non può essere usato come riferimento nel corpo della funzione", "paramSpecUnknownArg": "ParamSpec non supporta più di un argomento", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "La classe base \"{baseClass}\" deriva da \"{subclass}\", che non è compatibile con il tipo \"{type}\"", "baseClassOverriddenType": "La classe di base \"{baseClass}\" fornisce il tipo \"{type}\", di cui viene eseguito l'override", "baseClassOverridesType": "Override della classe base \"{baseClass}\" con tipo \"{type}\"", + "bytesTypePromotions": "Imposta disableBytesTypePromotions su false per abilitare il comportamento di innalzamento di livello del tipo per \"bytearray\" e \"memoryview\"", "conditionalRequiresBool": "Il metodo __bool__ per il tipo \"{operandType}\" restituisce il tipo \"{boolReturnType}\" anziché \"bool\"", "dataClassFieldLocation": "Dichiarazione di campo", "dataClassFrozen": "\"{name}\" è bloccato", @@ -612,6 +620,8 @@ "incompatibleSetter": "Il metodo setter di proprietà non è compatibile", "initMethodLocation": "Il metodo __init__ è definito nella classe \"{type}\"", "initMethodSignature": "Firma del __init__ \"{type}\"", + "invariantSuggestionDict": "Prova a passare da \"dict\" a \"Mapping\", che è covariante nel tipo di valore", + "invariantSuggestionList": "Prova a passare da \"list\" a \"Sequence\", che è covariante", "keyNotRequired": "\"{name}\" non è una chiave obbligatoria in \"{type}\", quindi l'accesso potrebbe causare un'eccezione di runtime", "keyReadOnly": "\"{name}\" è una chiave di sola lettura in \"{type}\"", "keyRequiredDeleted": "\"{name}\" è una chiave obbligatoria e non può essere eliminata", @@ -632,6 +642,7 @@ "memberSetClassVar": "Non è possibile assegnare il membro \"{name}\" tramite un'istanza di classe perché è una ClassVar", "memberTypeMismatch": "\"{name}\" è un tipo non compatibile", "memberUnknown": "Il membro \"{name}\" è sconosciuto", + "metaclassConflict": "La metaclasse \"{metaclass1}\" è in conflitto con \"{metaclass2}\"", "missingDeleter": "Manca il metodo di eliminazione delle proprietà", "missingGetter": "Metodo getter proprietà mancante", "missingProtocolMember": "Il \"{name}\" membro è dichiarato nella classe di protocollo \"{classType}\"", @@ -643,10 +654,13 @@ "newMethodSignature": "La firma del __new__ è \"{type}\"", "noOverloadAssignable": "Nessuna funzione di overload corrisponde al tipo \"{type}\"", "orPatternMissingName": "Nomi mancanti: {name}", + "overloadIndex": "L'overload {index} è la corrispondenza più vicina", "overloadNotAssignable": "Uno o più overload di \"{name}\" non sono assegnabili", "overloadSignature": "La firma di overload è definita qui", "overriddenMethod": "Metodo sottoposto a override", "overriddenSymbol": "Simbolo sottoposto a override", + "overrideInvariantMismatch": "Il tipo di override \"{overrideType}\" non è uguale al tipo di base \"{baseType}\"", + "overrideIsInvariant": "La variabile è modificabile, quindi il relativo tipo è invariante", "overrideNoOverloadMatches": "Nessuna firma di overload nell'override è compatibile con il metodo di base", "overrideNotClassMethod": "Il metodo di base è dichiarato come metodo di classe, ma l'override non è", "overrideNotInstanceMethod": "Il metodo di base è dichiarato come metodo di istanza, ma l’override non lo è", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "Non è possibile associare TypeVarTuple a una tupla di lunghezza sconosciuta", "typeVarUnsolvableRemedy": "Specificare un overload che specifica il tipo restituito quando l'argomento non viene fornito", "typeVarsMissing": "Variabili di tipo mancanti: {names}", + "typedDictBaseClass": "La classe \"{type}\" non è un TypedDict", "typedDictFieldMissing": "\"{name}\" mancante nel \"{type}\"", "typedDictFieldNotReadOnly": "\"{name}\" non è di sola lettura in \"{type}\"", "typedDictFieldNotRequired": "\"{name}\" non è obbligatorio in \"{type}\"", diff --git a/packages/pyright-internal/src/localization/package.nls.ja.json b/packages/pyright-internal/src/localization/package.nls.ja.json index c63dcaaf1..a923d859b 100644 --- a/packages/pyright-internal/src/localization/package.nls.ja.json +++ b/packages/pyright-internal/src/localization/package.nls.ja.json @@ -11,8 +11,8 @@ "renameShadowedFile": "\"{oldFile}\" の名前を \"{newFile}\" に変更します" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "自動インポート", + "indexValueDetail": "インデックス値" }, "Diagnostic": { "abstractMethodInvocation": "メソッド \"{method}\" は抽象型であるため、呼び出すことができません", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__ override は \"cls\" パラメーターを受け取る必要があります", "classMethodClsParam": "クラス メソッドは \"cls\" パラメーターを受け取る必要があります", "classNotRuntimeSubscriptable": "クラス \"{name}\" の添字はランタイム例外を生成します。型の注釈を引用符で囲む", - "classPatternBuiltInArgCount": "クラス パターンは、最大 1 つの位置指定サブパターンを受け入れます", "classPatternBuiltInArgPositional": "クラス パターンは位置指定サブパターンのみを受け入れます", + "classPatternPositionalArgCount": "クラス \"{type}\" の位置指定パターンが多すぎます。{expected} が必要ですが、{received} を受信しました", "classPatternTypeAlias": "\"{type}\" は特殊な型エイリアスであるため、クラス パターンでは使用できません", "classTypeParametersIllegal": "クラス型パラメーターの構文には Python 3.12 以降が必要です", "classVarFirstArgMissing": "\"ClassVar\" の後に型引数が必要です", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "型 \"{leftType}\" と \"{rightType}\" に重複がないため、式は常に True に評価されます", "continueInFinally": "finally 句内では \"continue\" を使用できません", "continueOutsideLoop": "\"continue\" はループ内でのみ使用できます", + "coroutineInConditionalExpression": "常に True に評価される条件式参照コルーチン", "dataClassBaseClassFrozen": "固定されていないクラスは、固定されているクラスから継承できません", "dataClassBaseClassNotFrozen": "固定されたクラスは、固定されていないクラスから継承できません", "dataClassConverterFunction": "型 \"{argType}\" の引数は、型 \"{fieldType}\" のフィールド \"{fieldName}\" の有効なコンバーターではありません", @@ -114,7 +115,14 @@ "delTargetExpr": "式を削除できません", "deprecatedClass": "クラス \"{name}\" は非推奨です", "deprecatedConstructor": "クラス \"{name}\" のコンストラクターは非推奨です", - "deprecatedFunction": "この関数 \"{name}\" は非推奨です", + "deprecatedDescriptorDeleter": "記述子 \"{name}\" の \"__delete__\" メソッドは非推奨です", + "deprecatedDescriptorGetter": "記述子 \"{name}\" の \"__get__\" メソッドは非推奨です", + "deprecatedDescriptorSetter": "記述子 \"{name}\" の \"__set__\" メソッドは非推奨です", + "deprecatedFunction": "関数 \"{name}\" は非推奨です", + "deprecatedMethod": "クラス \"{className}\" のメソッド \"{name}\" は非推奨です", + "deprecatedPropertyDeleter": "プロパティ \"{name}\" の削除子は非推奨です", + "deprecatedPropertyGetter": "プロパティ \"{name}\" のゲッターは非推奨です", + "deprecatedPropertySetter": "プロパティ \"{name}\" のセッターは非推奨です", "deprecatedType": "この型は Python {version} では非推奨です。代わりに\"{replacement}\"を使用してください", "dictExpandIllegalInComprehension": "辞書の展開は理解できません", "dictInAnnotation": "辞書式は型注釈では使用できません", @@ -228,8 +236,8 @@ "implicitStringConcat": "暗黙的な文字列連結は許可されていません", "importCycleDetected": "インポート チェーンで循環が検出されました", "importDepthExceeded": "インポート チェーンの深さが {depth} を超えました", - "importResolveFailure": "インポート \"{importName}\" が \"{venv}\" 環境に見つかりませんでした。", - "importSourceResolveFailure": "インポート \"{importName}\" を \"{venv}\" 環境のソースから解決できませんでした。", + "importResolveFailure": "インポート \"{importName}\" を解決できませんでした", + "importSourceResolveFailure": "インポート \"{importName}\" をソースから解決できませんでした", "importSymbolUnknown": "\"{name}\" は不明なインポート シンボルです", "incompatibleMethodOverride": "メソッド \"{name}\" は互換性のない方法でクラス \"{className}\" をオーバーライドします", "inconsistentIndent": "元のサイズが前のインデントと一致しません", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "ParamSpec の既定値には、省略記号、タプル式、または ParamSpec が必要です", "paramSpecFirstArg": "最初の引数として ParamSpec の名前が必要です", "paramSpecKwargsUsage": "ParamSpec の \"kwargs\" メンバーは、**kwargs パラメーターと共に使用する場合にのみ有効です", - "paramSpecNotBound": "パラメーター 仕様 \"{type}\" にバインドされた値がありません", "paramSpecNotUsedByOuterScope": "ParamSpec \"{name}\" はこのコンテキストでは意味がありません", "paramSpecScopedToReturnType": "ParamSpec \"{name}\" は、戻り値の型内の呼び出し可能なスコープであり、関数本体では参照できません", "paramSpecUnknownArg": "ParamSpec は複数の引数をサポートしていません", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "基底クラス \"{baseClass}\" は、型 \"{type}\" と互換性のない \"{subclass}\" から派生しています", "baseClassOverriddenType": "基底クラス \"{baseClass}\" は、オーバーライドされる型 \"{type}\" を提供します", "baseClassOverridesType": "基底クラス \"{baseClass}\" は型 \"{type}\" でオーバーライドします", + "bytesTypePromotions": "disableBytesTypePromotions を false に設定して、\"bytearray\" と \"memoryview\" の型昇格動作を有効にします", "conditionalRequiresBool": "型 \"{operandType}\" のメソッド __bool__は、\"bool\" ではなく型 \"{boolReturnType}\" を返します", "dataClassFieldLocation": "フィールド宣言", "dataClassFrozen": "\"{name}\" は固定されています", @@ -612,6 +620,8 @@ "incompatibleSetter": "プロパティ セッター メソッドに互換性がありません", "initMethodLocation": "__init__ メソッドはクラス \"{type}\" で定義されています", "initMethodSignature": "__init__の署名は \"{type}\" です", + "invariantSuggestionDict": "\"dict\" から値の型の共変である \"Mapping\" への切り替えを検討してください", + "invariantSuggestionList": "\"list\" から共変である \"Sequence\" への切り替えを検討してください", "keyNotRequired": "\"{name}\" は \"{type}\" の必須キーではないため、アクセスすると実行時例外が発生する可能性があります", "keyReadOnly": "\"{name}\" は \"{type}\" の読み取り専用キーです", "keyRequiredDeleted": "\"{name}\" は必須キーであり、削除できません", @@ -632,6 +642,7 @@ "memberSetClassVar": "メンバー \"{name}\" は ClassVar であるため、クラス インスタンスを介して割り当てることはできません", "memberTypeMismatch": "\"{name}\" は互換性のない型です", "memberUnknown": "メンバー \"{name}\" が不明です", + "metaclassConflict": "メタクラス \"{metaclass1}\" が \"{metaclass2}\" と競合しています", "missingDeleter": "プロパティ削除メソッドがありません", "missingGetter": "プロパティ getter メソッドがありません", "missingProtocolMember": "メンバー \"{name}\" はプロトコル クラス \"{classType}\" で宣言されています", @@ -643,10 +654,13 @@ "newMethodSignature": "__new__の署名は \"{type}\" です", "noOverloadAssignable": "型 \"{type}\" に一致するオーバーロードされた関数はありません", "orPatternMissingName": "名前がありません: {name}", + "overloadIndex": "オーバーロード {index} が最も近い一致です", "overloadNotAssignable": "\"{name}\" の 1 つ以上のオーバーロードが割り当て可能ではありません", "overloadSignature": "オーバーロードシグネチャはここで定義されています", "overriddenMethod": "オーバーライドされたメソッド", "overriddenSymbol": "オーバーライドされたシンボル", + "overrideInvariantMismatch": "オーバーライドの型 \"{overrideType}\" が基本データ型 \"{baseType}\" と同じではありません", + "overrideIsInvariant": "変数は変更可能であるため、その型は不変です", "overrideNoOverloadMatches": "オーバーライドのオーバーロード シグネチャが基本メソッドと互換性がありません", "overrideNotClassMethod": "基本メソッドは classmethod として宣言されていますが、オーバーライドはされていません", "overrideNotInstanceMethod": "基本メソッドはインスタンス メソッドとして宣言されていますが、オーバーライドは宣言されていません", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple を不明な長さのタプルにバインドすることはできません", "typeVarUnsolvableRemedy": "引数が指定されていない場合に戻り値の型を指定するオーバーロードを指定します", "typeVarsMissing": "型変数がありません: {names}", + "typedDictBaseClass": "クラス \"{type}\" は TypedDict ではありません", "typedDictFieldMissing": "\"{name}\" が \"{type}\" に見つかりません", "typedDictFieldNotReadOnly": "\"{name}\" は \"{type}\" では読み取り専用ではありません", "typedDictFieldNotRequired": "\"{name}\" は \"{type}\" には必要ありません", diff --git a/packages/pyright-internal/src/localization/package.nls.ko.json b/packages/pyright-internal/src/localization/package.nls.ko.json index 060d36717..aa259a1e2 100644 --- a/packages/pyright-internal/src/localization/package.nls.ko.json +++ b/packages/pyright-internal/src/localization/package.nls.ko.json @@ -11,8 +11,8 @@ "renameShadowedFile": "‘{oldFile}’에서 ‘{newFile}’(으)로 이름 바꾸기" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "자동 가져오기", + "indexValueDetail": "인덱스 값" }, "Diagnostic": { "abstractMethodInvocation": "\"{method}\" 메서드는 추상이므로 호출할 수 없습니다.", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__ 재정의는 \"cls\" 매개 변수를 사용해야 합니다.", "classMethodClsParam": "클래스 메서드는 ‘cls’ 매개 변수를 사용해야 합니다.", "classNotRuntimeSubscriptable": "클래스 \"{name}\"에 대한 첨자는 런타임 예외를 생성합니다. 따옴표로 형식 주석 묶기", - "classPatternBuiltInArgCount": "클래스 패턴은 최대 1개의 위치 하위 패턴을 허용합니다.", "classPatternBuiltInArgPositional": "클래스 패턴은 위치 하위 패턴만 허용합니다.", + "classPatternPositionalArgCount": "클래스 \"{type}\"에 대한 위치 패턴이 너무 많습니다. {expected}이(가) 필요하지만 {received}을(를) 받았습니다.", "classPatternTypeAlias": "‘{type}’은(는) 특수 형식 별칭이므로 클래스 패턴에서 사용할 수 없습니다.", "classTypeParametersIllegal": "클래스 형식 매개 변수 구문에는 Python 3.12 이상이 필요합니다.", "classVarFirstArgMissing": "‘ClassVar’ 뒤에 형식 인수가 필요합니다.", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "‘{leftType}’ 및 ‘{rightType}’ 형식이 겹치지 않으므로 식은 항상 True로 평가됩니다.", "continueInFinally": "finally 절 내에서는 \"continue\"를 사용할 수 없습니다.", "continueOutsideLoop": "\"continue\"는 루프 내에서만 사용할 수 있습니다.", + "coroutineInConditionalExpression": "조건식은 항상 True로 평가되는 코루틴을 참조합니다.", "dataClassBaseClassFrozen": "고정되지 않은 클래스는 고정된 클래스에서 상속할 수 없습니다.", "dataClassBaseClassNotFrozen": "고정 클래스는 고정되지 않은 클래스에서 상속할 수 없습니다.", "dataClassConverterFunction": "\"{argType}\" 형식의 인수는 \"{fieldType}\" 형식의 \"{fieldName}\" 필드에 유효한 변환기가 아닙니다.", @@ -114,7 +115,14 @@ "delTargetExpr": "식을 삭제할 수 없습니다.", "deprecatedClass": "‘{name}’ 클래스는 사용되지 않습니다.", "deprecatedConstructor": "클래스 \"{name}\"의 생성자는 더 이상 사용되지 않습니다.", - "deprecatedFunction": "이 함수 \"{name}\"은(는) 더 이상 사용되지 않습니다.", + "deprecatedDescriptorDeleter": "\"{name}\" 설명자에 대한 \"____delete____\" 메서드는 사용되지 않습니다.", + "deprecatedDescriptorGetter": "\"{name}\" 설명자에 대한 \"__get__\" 메서드는 사용되지 않습니다.", + "deprecatedDescriptorSetter": "\"{name}\" 설명자에 대한 \"__set__\" 메서드는 사용되지 않습니다.", + "deprecatedFunction": "\"{name}\" 함수는 더 이상 사용되지 않습니다.", + "deprecatedMethod": "\"{className}\" 클래스의 \"{name}\" 메서드는 더 이상 사용되지 않습니다.", + "deprecatedPropertyDeleter": "\"{name}\" 속성에 대한 deleter는 사용되지 않습니다.", + "deprecatedPropertyGetter": "\"{name}\" 속성에 대한 getter는 사용되지 않습니다.", + "deprecatedPropertySetter": "\"{name}\" 속성에 대한 setter는 사용되지 않습니다.", "deprecatedType": "이 형식은 Python {version}부터 사용되지 않습니다. 대신 \"{replacement}\"을(를) 사용하세요.", "dictExpandIllegalInComprehension": "사전 확장은 이해에 사용할 수 없습니다.", "dictInAnnotation": "형식 주석에는 사전 식을 사용할 수 없습니다.", @@ -228,8 +236,8 @@ "implicitStringConcat": "암시적 문자열 연결이 허용되지 않습니다.", "importCycleDetected": "가져오기 체인에서 순환이 검색되었습니다.", "importDepthExceeded": "가져오기 체인 깊이가 {depth}을(를) 초과했습니다.", - "importResolveFailure": "\"{venv}\" 환경에서 \"{importName}\" 가져오기를 찾을 수 없습니다.", - "importSourceResolveFailure": "\"{importName}\" 가져오기를 \"{venv}\" 환경의 원본에서 확인할 수 없습니다.", + "importResolveFailure": "가져오기 \"{importName}\"을(를) 확인할 수 없습니다.", + "importSourceResolveFailure": "원본에서 가져오기 \"{importName}\"을(를) 확인할 수 없습니다.", "importSymbolUnknown": "\"{name}\"은(는) 알 수 없는 가져오기 기호입니다.", "incompatibleMethodOverride": "\"{name}\" 메서드가 호환되지 않는 방식으로 \"{className}\" 클래스를 재정의합니다.", "inconsistentIndent": "들여쓰기하지 않은 양이 이전 들여쓰기와 일치하지 않습니다.", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "ParamSpec의 기본값에는 줄임표, 튜플 식 또는 ParamSpec이 필요합니다.", "paramSpecFirstArg": "첫 번째 인수로 ParamSpec의 이름이 필요합니다.", "paramSpecKwargsUsage": "ParamSpec의 \"kwargs\" 멤버는 **kwargs 매개 변수와 함께 사용할 때만 유효합니다.", - "paramSpecNotBound": "매개 변수 사양 \"{type}\"에 바인딩된 값이 없습니다.", "paramSpecNotUsedByOuterScope": "ParamSpec \"{name}\"은(는) 이 컨텍스트에서 의미가 없습니다.", "paramSpecScopedToReturnType": "ParamSpec ‘{name}’은 반환 형식 내에서 호출 가능으로 범위가 지정되며 함수 본문에서 참조할 수 없습니다.", "paramSpecUnknownArg": "ParamSpec은 한 개 이상의 인수를 지원하지 않습니다.", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "기본 클래스 \"{baseClass}\"은(는) \"{type}\" 유형과 호환되지 않는 \"{subclass}\"에서 파생됩니다.", "baseClassOverriddenType": "기본 클래스 \"{baseClass}\"이(가) 재정의된 \"{type}\" 형식을 제공합니다.", "baseClassOverridesType": "‘{baseClass}’ 기본 클래스가 ‘{type}’ 형식을 재정의합니다.", + "bytesTypePromotions": "disableBytesTypePromotions를 false로 설정하여 \"bytearray\" 및 \"memoryview\"에 대한 형식 승격 동작을 사용하도록 설정합니다.", "conditionalRequiresBool": "\"{operandType}\" 형식에 대한 메서드 __bool__에서 \"bool\" 대신 \"{boolReturnType}\" 형식을 반환합니다.", "dataClassFieldLocation": "필드 선언", "dataClassFrozen": "\"{name}\"이(가) 고정되어 있습니다.", @@ -612,6 +620,8 @@ "incompatibleSetter": "속성 setter 메서드가 호환되지 않습니다.", "initMethodLocation": "__init__ 메서드가 \"{type}\" 클래스에 정의되어 있습니다.", "initMethodSignature": "__init__의 서명은 \"{type}\"입니다.", + "invariantSuggestionDict": "값 형식에서 공변(covariant)인 \"dict\"에서 \"Mapping\"(매핑)으로 전환하는 것이 좋습니다.", + "invariantSuggestionList": "공변(covariant)인 \"list\"에서 \"Sequence\"로 전환하는 것이 좋습니다.", "keyNotRequired": "‘{name}’은(는) ‘{type}’에서 필수 키가 아니므로 액세스로 인해 런타임 예외가 발생할 수 있습니다.", "keyReadOnly": "\"{name}\"은(는) \"{type}\"의 읽기 전용 키입니다.", "keyRequiredDeleted": "\"{name}\"은(는) 필수 키이므로 삭제할 수 없습니다.", @@ -632,6 +642,7 @@ "memberSetClassVar": "‘{name}’ 멤버는 ClassVar이므로 클래스 인스턴스를 통해 할당할 수 없습니다.", "memberTypeMismatch": "\"{name}\"은(는) 호환되지 않는 형식입니다.", "memberUnknown": "멤버 \"{name}\"을(를) 알 수 없습니다.", + "metaclassConflict": "메타클래스 \"{metaclass1}\"이(가) \"{metaclass2}\"과(와) 충돌합니다.", "missingDeleter": "속성 삭제자 메서드가 없습니다.", "missingGetter": "속성 getter 메서드가 없습니다.", "missingProtocolMember": "\"{name}\" 멤버가 프로토콜 클래스 \"{classType}\"로 선언되었습니다.", @@ -643,10 +654,13 @@ "newMethodSignature": "__new__ 의 서명은 \"{type}\"입니다.", "noOverloadAssignable": "\"{type}\" 형식과 일치하는 오버로드된 함수가 없습니다.", "orPatternMissingName": "누락된 이름: {name}", + "overloadIndex": "오버로드 {index}이(가) 가장 가까운 일치 항목입니다.", "overloadNotAssignable": "\"{name}\"의 오버로드를 하나 이상 할당할 수 없습니다.", "overloadSignature": "오버로드 서명은 여기에 정의되어 있습니다.", "overriddenMethod": "재정의된 메서드", "overriddenSymbol": "재정의된 기호", + "overrideInvariantMismatch": "\"{overrideType}\" 재정의 형식이 \"{baseType}\" 기본 형식과 같지 않습니다.", + "overrideIsInvariant": "변수를 변경할 수 있으므로 해당 형식은 고정됩니다.", "overrideNoOverloadMatches": "재정의의 오버로드 서명이 기본 메서드와 호환되지 않습니다.", "overrideNotClassMethod": "기본 메서드가 classmethod로 선언되었지만 재정의는 그렇지 않은 경우", "overrideNotInstanceMethod": "기본 메서드가 instance 메서드로 선언되었지만 재정의가", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple을 알 수 없는 길이의 튜플에 바인딩할 수 없습니다.", "typeVarUnsolvableRemedy": "인수가 제공되지 않을 때 반환 형식을 지정하는 오버로드를 제공합니다.", "typeVarsMissing": "누락된 형식 변수: {names}", + "typedDictBaseClass": "\"{type}\" 클래스는 TypedDict가 아닙니다.", "typedDictFieldMissing": "\"{name}\"이(가) \"{type}\"에 없습니다.", "typedDictFieldNotReadOnly": "\"{name}\"은(는) \"{type}\"에서 읽기 전용이 아닙니다.", "typedDictFieldNotRequired": "\"{name}\"은(는) \"{type}\"에 필요하지 않습니다.", diff --git a/packages/pyright-internal/src/localization/package.nls.pl.json b/packages/pyright-internal/src/localization/package.nls.pl.json index 954556a3a..2af0aefa7 100644 --- a/packages/pyright-internal/src/localization/package.nls.pl.json +++ b/packages/pyright-internal/src/localization/package.nls.pl.json @@ -11,8 +11,8 @@ "renameShadowedFile": "Zmień nazwę „{oldFile}” na „{newFile}”" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Automatyczne importowanie", + "indexValueDetail": "Wartość indeksu" }, "Diagnostic": { "abstractMethodInvocation": "Nie można wywołać metody „{method}”, ponieważ jest abstrakcyjna", @@ -67,8 +67,8 @@ "classGetItemClsParam": "Przesłonięcie __class_getitem__ powinno przyjmować parametr „cls”.", "classMethodClsParam": "Metody klasy powinny przyjmować parametr „cls”", "classNotRuntimeSubscriptable": "Indeks dolny dla klasy „{name}” wygeneruje wyjątek czasu uruchamiania; umieść adnotację typu w cudzysłowie", - "classPatternBuiltInArgCount": "Wzorzec klasy akceptuje co najwyżej 1 podwzorzec pozycyjny", "classPatternBuiltInArgPositional": "Wzorzec klasy akceptuje tylko podwzorzec pozycyjny", + "classPatternPositionalArgCount": "Zbyt wiele wzorców pozycyjnych dla klasy „{type}”; oczekiwano {expected}, ale otrzymano {received}", "classPatternTypeAlias": "„{type}” nie może być używany we wzorcu klasy, ponieważ jest to alias typu specjalnego", "classTypeParametersIllegal": "Składnia parametru typu klasy wymaga języka Python w wersji 3.12 lub nowszej", "classVarFirstArgMissing": "Oczekiwano argumentu typu po wartości „ClassVar”", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "Warunek zawsze będzie miał wartość „True”, ponieważ typy „{leftType}” i „{rightType}” nie nakładają się na siebie", "continueInFinally": "Wartość „continue” nie może być używana w klauzuli finally", "continueOutsideLoop": "Wartość „continue” może być używana tylko w pętli", + "coroutineInConditionalExpression": "Wyrażenie warunkowe odwołuje się do koprocedury, która zawsze wyznacza wartość True", "dataClassBaseClassFrozen": "Klasa niezablokowana nie może dziedziczyć po klasie zablokowanej", "dataClassBaseClassNotFrozen": "Zamrożona klasa nie może dziedziczyć po klasie niezamrożonej", "dataClassConverterFunction": "Argument typu „{argType}” nie jest prawidłowym konwerterem pola „{fieldName}” typu „{fieldType}”", @@ -114,7 +115,14 @@ "delTargetExpr": "Nie można usunąć wyrażenia", "deprecatedClass": "Klasa „{name}” jest przestarzała", "deprecatedConstructor": "Konstruktor klasy „{name}” jest przestarzały", + "deprecatedDescriptorDeleter": "Metoda „__set__” dla deskryptora „{name}” jest przestarzała", + "deprecatedDescriptorGetter": "Metoda „__set__” dla deskryptora „{name}” jest przestarzała", + "deprecatedDescriptorSetter": "Metoda „__set__” dla deskryptora „{name}” jest przestarzała", "deprecatedFunction": "Ta funkcja „{name}” jest przestarzała", + "deprecatedMethod": "Metoda „{name}” w klasie „{className}” jest przestarzała", + "deprecatedPropertyDeleter": "Metoda usuwająca dla właściwości „{name}” jest przestarzała", + "deprecatedPropertyGetter": "Metoda pobierająca dla właściwości „{name}” jest przestarzała", + "deprecatedPropertySetter": "Metoda pobierająca dla właściwości „{name}” jest przestarzała", "deprecatedType": "Ten typ jest przestarzały dla języka Python w wersji {version}; zamiast tego użyj „{replacement}”.", "dictExpandIllegalInComprehension": "Rozszerzanie słownika jest niedozwolone w rozumieniu", "dictInAnnotation": "Wyrażenie słownikowe jest niedozwolone w adnotacji typu", @@ -228,8 +236,8 @@ "implicitStringConcat": "Niejawne łączenie ciągów jest niedozwolone", "importCycleDetected": "Wykryto cykl w łańcuchu importu", "importDepthExceeded": "Głębokość łańcucha importu przekroczyła {depth}", - "importResolveFailure": "Nie można odnaleźć importu„{importName}” w środowisku „{venv}”.", - "importSourceResolveFailure": "Nie można rozpoznać importu „{importName}” ze źródła w środowisku „{venv}”.", + "importResolveFailure": "Nie można rozpoznać importu „{importName}”.", + "importSourceResolveFailure": "Nie można rozpoznać importu „{importName}” ze źródła", "importSymbolUnknown": "Nazwa „{name}” jest nieznanym symbolem importu", "incompatibleMethodOverride": "Metoda „{name}” przesłania klasę „{className}” w niezgodny sposób", "inconsistentIndent": "Wartość zmniejszenia wcięcia jest niezgodna z poprzednim wcięciem", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "Oczekiwano wielokropka, wyrażenia krotki lub parametru ParamSpec dla domyślnej wartości ParamSpec", "paramSpecFirstArg": "Oczekiwano nazwy parametru ParamSpec jako pierwszego argumentu", "paramSpecKwargsUsage": "Składowa „kwargs” parametru ParamSpec jest ważna tylko wtedy, gdy jest używana z parametrem **kwargs", - "paramSpecNotBound": "Specyfikacja parametru „{type}” nie ma wartości powiązanej", "paramSpecNotUsedByOuterScope": "Element ParamSpec „{name}” nie ma znaczenia w tym kontekście", "paramSpecScopedToReturnType": "Parametr ParamSpec „{name}” jest objęty zakresem możliwości wywołania w ramach zwracanego typu i nie można odwoływać się do niego w treści funkcji", "paramSpecUnknownArg": "Parametr ParamSpec nie obsługuje więcej niż jednego argumentu", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "Klasa bazowa „{baseClass}” pochodzi od klasy podrzędnej „{subclass}”, która jest niezgodna z typem „{type}”", "baseClassOverriddenType": "Klasa bazowa „{baseClass}” udostępnia typ „{type}”, który jest przesłonięty", "baseClassOverridesType": "Zastąpienie klasy bazowej „{baseClass}” typem „{type}”", + "bytesTypePromotions": "Ustaw właściwość disableBytesTypePromotions na wartość false, aby włączyć zachowanie promocji typu dla elementów „bytearray” i „memoryview”", "conditionalRequiresBool": "Metoda __bool__ dla typu „{operandType}” zwraca typ \"{boolReturnType}\" zamiast „bool”", "dataClassFieldLocation": "Deklaracja pola", "dataClassFrozen": "Nazwa „{name}” jest zamrożona", @@ -612,6 +620,8 @@ "incompatibleSetter": "Metoda ustawiająca właściwości jest niezgodna", "initMethodLocation": "Metoda __init__ jest zdefiniowana w klasie „{type}”", "initMethodSignature": "Sygnatura __init__ to typ „{type}”", + "invariantSuggestionDict": "Rozważ przełączenie z wartości „dict” na „Mapping”, która jest kowariantna w typie wartości", + "invariantSuggestionList": "Rozważ zmianę wartości „list” na „Sequence”, która jest kowariantna", "keyNotRequired": "„{name}” nie jest wymaganym kluczem w typie „{type}”, więc dostęp może spowodować wyjątek środowiska uruchomieniowego", "keyReadOnly": "Nazwa „{name}” jest kluczem tylko do odczytu w typie „{type}”", "keyRequiredDeleted": "Nazwa „{name}” jest wymaganym kluczem i nie można go usunąć", @@ -632,6 +642,7 @@ "memberSetClassVar": "Nie można przypisać składowej „{name}” przez wystąpienie klasy, ponieważ jest to element ClassVar", "memberTypeMismatch": "Nazwa „{name}” jest niezgodnym typem", "memberUnknown": "Składowa „{name}” jest nieznana", + "metaclassConflict": "Metaklasa „{metaclass1}” powoduje konflikt z „{metaclass2}”", "missingDeleter": "Brak metody usuwania właściwości", "missingGetter": "Brak metody pobierającej właściwości", "missingProtocolMember": "Składowa „{name}” jest zadeklarowana w klasie protokołu „{classType}”", @@ -643,10 +654,13 @@ "newMethodSignature": "Sygnatura __new__ to typ „{type}”", "noOverloadAssignable": "Żadna przeciążona funkcja nie pasuje do typu „{type}”", "orPatternMissingName": "Brak nazw: {name}", + "overloadIndex": "Przeciążenie {index} jest najbardziej zbliżonym dopasowaniem", "overloadNotAssignable": "Nie można przypisać jednego lub więcej przeciążeń „{name}”.", "overloadSignature": "Sygnatura przeciążenia jest zdefiniowana tutaj", "overriddenMethod": "Przesłonięta metoda", "overriddenSymbol": "Przesłonięty symbol", + "overrideInvariantMismatch": "Typ zastąpienia „{overrideType}” nie jest taki sam jak typ podstawowy „{baseType}”", + "overrideIsInvariant": "Zmienna podlega przeobrażeniom, dlatego jej typ jest niezmienny", "overrideNoOverloadMatches": "Żadna sygnatura przeciążenia w przesłonięciu nie jest zgodna z metodą bazową", "overrideNotClassMethod": "Metoda bazowa jest zadeklarowana jako metoda classmethod, ale przesłonięcie nie", "overrideNotInstanceMethod": "Metoda bazowa jest zadeklarowana jako metoda wystąpienia, ale zastąpienie nie jest", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "Nie można powiązać parametru TypeVarTuple z krotką o nieznanej długości", "typeVarUnsolvableRemedy": "Podaj przeciążenie, które określa zwracany typ, gdy nie podano argumentu", "typeVarsMissing": "Brak zmiennych typu: {names}", + "typedDictBaseClass": "Klasa „{type}” nie jest typem TypedDict", "typedDictFieldMissing": "Brak nazwy „{name}” w „{type}”", "typedDictFieldNotReadOnly": "Nazwa „{name}” nie jest tylko do odczytu w „{type}”", "typedDictFieldNotRequired": "Nazwa „{name}” nie jest wymagana w typie „{type}”", diff --git a/packages/pyright-internal/src/localization/package.nls.pt-br.json b/packages/pyright-internal/src/localization/package.nls.pt-br.json index b2fa56b51..948ca7b41 100644 --- a/packages/pyright-internal/src/localization/package.nls.pt-br.json +++ b/packages/pyright-internal/src/localization/package.nls.pt-br.json @@ -11,8 +11,8 @@ "renameShadowedFile": "Renomear \"{oldFile}\" para \"{newFile}\"" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Importação automática", + "indexValueDetail": "Valor do índice" }, "Diagnostic": { "abstractMethodInvocation": "O método \"{method}\" não pode ser chamado porque é abstrato", @@ -67,8 +67,8 @@ "classGetItemClsParam": "A substituição__class_getitem__ deve usar um parâmetro \"cls\"", "classMethodClsParam": "Os métodos de classe devem usar um parâmetro \"cls\"", "classNotRuntimeSubscriptable": "O subscrito para a classe \"{name}\" gerará uma exceção de runtime. Coloque a anotação de tipo entre aspas", - "classPatternBuiltInArgCount": "O padrão de classe aceita no máximo 1 sub-padrão posicional", "classPatternBuiltInArgPositional": "O padrão de classe aceita apenas sub-padrão posicional", + "classPatternPositionalArgCount": "Muitos padrões posicionais para a classe \"{type}\"; esperado {expected} mas recebido {received}", "classPatternTypeAlias": "\"{type}\" não pode ser usado em um padrão de classe porque é um alias de tipo especializado", "classTypeParametersIllegal": "A sintaxe do parâmetro de tipo de classe requer o Python 3.12 ou mais recente", "classVarFirstArgMissing": "Um argumento de tipo era esperado após \"ClassVar\"", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "A expressão sempre será avaliada como True, pois os tipos \"{leftType}\" e \"{rightType}\" não têm sobreposição", "continueInFinally": "\"continue\" não pode ser usado em uma cláusula finally", "continueOutsideLoop": "\"continue\" só pode ser usado dentro de um loop", + "coroutineInConditionalExpression": "A expressão condicional faz referência à corrotina, que sempre é avaliada como True", "dataClassBaseClassFrozen": "Uma classe não congelada não pode herdar de uma classe congelada", "dataClassBaseClassNotFrozen": "Uma classe congelada não pode herdar de uma classe que não está congelada", "dataClassConverterFunction": "O argumento do tipo \"{argType}\" não é um conversor válido para o campo \"{fieldName}\" do tipo \"{fieldType}\"", @@ -114,7 +115,14 @@ "delTargetExpr": "A expressão não pode ser excluída", "deprecatedClass": "A classe \"{name}\" foi preterida", "deprecatedConstructor": "O construtor da classe \"{name}\" foi preterido", - "deprecatedFunction": "A função \"{name}\" foi preterida", + "deprecatedDescriptorDeleter": "O método \"__delete__\" para o descritor \"{name}\" está preterido", + "deprecatedDescriptorGetter": "O método \"__get__\" para o descritor \"{name}\" está preterido", + "deprecatedDescriptorSetter": "O método \"__set__\" para o descritor \"{name}\" está preterido", + "deprecatedFunction": "A função \"{name}\" está obsoleta", + "deprecatedMethod": "O método \"{name}\" na classe \"{className}\" está obsoleto", + "deprecatedPropertyDeleter": "O excluídor da propriedade \"{name}\" foi preterido", + "deprecatedPropertyGetter": "O getter da propriedade \"{name}\" foi preterido", + "deprecatedPropertySetter": "O setter da propriedade \"{name}\" está preterido", "deprecatedType": "Este tipo foi preterido no Python {version}. Use \"{replacement}\" em vez disso", "dictExpandIllegalInComprehension": "Expansão de dicionário não permitida na compreensão", "dictInAnnotation": "Expressão de dicionário não permitida na anotação de tipo", @@ -228,8 +236,8 @@ "implicitStringConcat": "Concatenação de cadeia de caracteres implícita não permitida", "importCycleDetected": "Ciclo detectado na cadeia de importação", "importDepthExceeded": "A profundidade da cadeia de importação excedeu {depth}", - "importResolveFailure": "Não foi possível localizar a importação \"{importName}\" no ambiente \"{venv}\".", - "importSourceResolveFailure": "A importação \"{importName}\" não pôde ser resolvida a partir da origem no ambiente \"{venv}\".", + "importResolveFailure": "Não foi possível resolver a importação \"{importName}\"", + "importSourceResolveFailure": "Não foi possível resolver a importação \"{importName}\" da origem", "importSymbolUnknown": "\"{name}\" é um símbolo de importação desconhecido", "incompatibleMethodOverride": "O método \"{name}\" substitui a classe \"{className}\" de maneira incompatível", "inconsistentIndent": "O valor de recuo não corresponde ao recuo anterior", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "Reticências esperadas, uma expressão de tupla ou ParamSpec para o valor padrão de ParamSpec", "paramSpecFirstArg": "Nome esperado de ParamSpec como primeiro argumento", "paramSpecKwargsUsage": "O membro \"kwargs\" de ParamSpec é válido somente quando usado com o parâmetro **kwargs", - "paramSpecNotBound": "A especificação de parâmetro \"{type}\" não tem nenhum valor associado", "paramSpecNotUsedByOuterScope": "O ParamSpec \"{name}\" não tem significado neste contexto", "paramSpecScopedToReturnType": "ParamSpec \"{name}\" tem como escopo um chamador dentro do tipo de retorno e não pode ser referenciado no corpo da função", "paramSpecUnknownArg": "ParamSpec não é compatível com mais de um argumento", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "A classe base \"{baseClass}\" deriva de \"{subclass}\" que é incompatível com o tipo \"{type}\"", "baseClassOverriddenType": "A classe base \"{baseClass}\" fornece o tipo \"{type}\", que é substituído", "baseClassOverridesType": "A classe base \"{baseClass}\" substitui pelo tipo \"{type}\"", + "bytesTypePromotions": "Defina disableBytesTypePromotions como false para habilitar o comportamento de promoção de tipo para \"bytearray\" e \"memoryview\"", "conditionalRequiresBool": "O método __bool__ para o tipo \"{operandType}\" retorna o tipo \"{boolReturnType}\" em vez de \"bool\"", "dataClassFieldLocation": "Declaração de campo", "dataClassFrozen": "\"{name}\" está congelado", @@ -612,6 +620,8 @@ "incompatibleSetter": "O método setter de propriedade é incompatível", "initMethodLocation": "O método __init__ é definido na classe \"{type}\"", "initMethodSignature": "A assinatura de __init__ é \"{type}\"", + "invariantSuggestionDict": "Considere alternar de \"dict\" para \"Mapping\", que é covariante no tipo de valor", + "invariantSuggestionList": "Considere alternar de \"list\" para \"Sequence\", que é covariante", "keyNotRequired": "\"{name}\" não é uma chave necessária em \"{type}\", portanto, o acesso pode resultar em exceção de runtime", "keyReadOnly": "\"{name}\" é uma chave somente leitura em \"{type}\"", "keyRequiredDeleted": "\"{name}\" é uma chave obrigatória e não pode ser excluída", @@ -632,6 +642,7 @@ "memberSetClassVar": "O membro \"{name}\" não pode ser atribuído por meio de uma instância de classe porque é um ClassVar", "memberTypeMismatch": "\"{name}\" é um tipo incompatível", "memberUnknown": "O membro \"{name}\" é desconhecido", + "metaclassConflict": "A metaclasse \"{metaclass1}\" entra em conflito com \"{metaclass2}\"", "missingDeleter": "O método de exclusão de propriedade está ausente", "missingGetter": "O método getter da propriedade está ausente", "missingProtocolMember": "O membro \"{name}\" está declarado na classe de protocolo \"{classType}\"", @@ -643,10 +654,13 @@ "newMethodSignature": "A assinatura de__new__ é \"{type}\"", "noOverloadAssignable": "Nenhuma função sobrecarregada corresponde ao tipo \"{type}\"", "orPatternMissingName": "Nomes ausentes: {name}", + "overloadIndex": "Sobrecarga {index} é a correspondência mais próxima", "overloadNotAssignable": "Uma ou mais sobrecargas de \"{name}\" não podem ser atribuídas", "overloadSignature": "A assinatura de sobrecarga é definida aqui", "overriddenMethod": "Método substituído", "overriddenSymbol": "Símbolo substituído", + "overrideInvariantMismatch": "O tipo da substituição \"{overrideType}\" não é o mesmo do tipo básico \"{baseType}\"", + "overrideIsInvariant": "A variável é mutável, então seu tipo é invariável", "overrideNoOverloadMatches": "Nenhuma assinatura de sobrecarga na substituição é compatível com o método base", "overrideNotClassMethod": "O método base é declarado como um classmethod, mas a substituição não é", "overrideNotInstanceMethod": "O método base é declarado como um método de instância, mas a substituição não é", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple não pode ser associado a uma tupla de comprimento desconhecido", "typeVarUnsolvableRemedy": "Forneça uma sobrecarga que especifica o tipo de retorno quando o argumento não é fornecido", "typeVarsMissing": "Variáveis de tipo ausentes: {names}", + "typedDictBaseClass": "A classe \"{type}\" não é um TypedDict", "typedDictFieldMissing": "\"{name}\" está ausente de \"{type}\"", "typedDictFieldNotReadOnly": "\"{name}\" não é somente leitura em \"{type}\"", "typedDictFieldNotRequired": "\"{name}\" não é obrigatório em \"{type}\"", diff --git a/packages/pyright-internal/src/localization/package.nls.qps-ploc.json b/packages/pyright-internal/src/localization/package.nls.qps-ploc.json index a6c3d5c5b..dae66ed31 100644 --- a/packages/pyright-internal/src/localization/package.nls.qps-ploc.json +++ b/packages/pyright-internal/src/localization/package.nls.qps-ploc.json @@ -67,8 +67,8 @@ "classGetItemClsParam": "[A2iHF][นั้__çlæss_gëtïtëm__ øvërrïðë shøµlð tækë æ \"çls\" pæræmëtërẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", "classMethodClsParam": "[aWMN3][นั้Çlæss mëthøðs shøµlð tækë æ \"çls\" pæræmëtërẤğ倪İЂҰक्र्तिृまẤğ倪นั้ढूँ]", "classNotRuntimeSubscriptable": "[O9BL6][นั้§µþsçrïpt før çlæss \"{ñæmë}\" wïll gëñërætë rµñtïmë ëxçëptïøñ; ëñçløsë tÿpë æññøtætïøñ ïñ qµøtësẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", - "classPatternBuiltInArgCount": "[moI4V][นั้Çlæss pættërñ æççëpts æt møst 1 pøsïtïøñæl sµþ-pættërñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", "classPatternBuiltInArgPositional": "[DOfs5][นั้Çlæss pættërñ æççëpts øñlÿ pøsïtïøñæl sµþ-pættërñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", + "classPatternPositionalArgCount": "[B65y5][นั้Tøø mæñÿ pøsïtïøñæl pættërñs før çlæss \"{tÿpë}\"; ëxpëçtëð {ëxpëçtëð} þµt rëçëïvëð {rëçëïvëð}Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", "classPatternTypeAlias": "[AxDtv][นั้\"{tÿpë}\" çæññøt þë µsëð ïñ æ çlæss pættërñ þëçæµsë ït ïs æ spëçïælïzëð tÿpë ælïæsẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", "classTypeParametersIllegal": "[GybXD][นั้Çlæss tÿpë pæræmëtër sÿñtæx rëqµïrës Pÿthøñ 3.12 ør ñëwërẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", "classVarFirstArgMissing": "[VtcEd][นั้Ëxpëçtëð æ tÿpë ærgµmëñt æftër \"ÇlæssVær\"Ấğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "[8OhUO][นั้Ëxprëssïøñ wïll ælwæÿs ëvælµætë tø Trµë sïñçë thë tÿpës \"{lëftTÿpë}\" æñð \"{rïghtTÿpë}\" hævë ñø øvërlæpẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]", "continueInFinally": "[RZIyI][นั้\"çøñtïñµë\" çæññøt þë µsëð wïthïñ æ fïñællÿ çlæµsëẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", "continueOutsideLoop": "[6ACvd][นั้\"çøñtïñµë\" çæñ þë µsëð øñlÿ wïthïñ æ løøpẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", + "coroutineInConditionalExpression": "[ygK2r][นั้Çøñðïtïøñæl ëxprëssïøñ rëfërëñçës çørøµtïñë whïçh ælwæÿs ëvælµætës tø TrµëẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", "dataClassBaseClassFrozen": "[jjiw4][นั้Æ ñøñ-frøzëñ çlæss çæññøt ïñhërït frøm æ çlæss thæt ïs frøzëñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", "dataClassBaseClassNotFrozen": "[KOz4K][นั้Æ frøzëñ çlæss çæññøt ïñhërït frøm æ çlæss thæt ïs ñøt frøzëñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", "dataClassConverterFunction": "[FxD8r][นั้Ærgµmëñt øf tÿpë \"{ærgTÿpë}\" ïs ñøt æ vælïð çøñvërtër før fïëlð \"{fïëlðÑæmë}\" øf tÿpë \"{fïëlðTÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]", @@ -114,7 +115,14 @@ "delTargetExpr": "[VLtXk][นั้Ëxprëssïøñ çæññøt þë ðëlëtëðẤğ倪İЂҰक्र्तिृนั้ढूँ]", "deprecatedClass": "[DIyRn][นั้Thë çlæss \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृนั้ढूँ]", "deprecatedConstructor": "[jq4aQ][นั้Thë çøñstrµçtør før çlæss \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]", - "deprecatedFunction": "[GdF0l][นั้Thïs fµñçtïøñ \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまนั้ढूँ]", + "deprecatedDescriptorDeleter": "[ljYHS][นั้Thë \"__ðëlëtë__\" mëthøð før ðësçrïptør \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", + "deprecatedDescriptorGetter": "[06Y3N][นั้Thë \"__gët__\" mëthøð før ðësçrïptør \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", + "deprecatedDescriptorSetter": "[6nQQu][นั้Thë \"__sët__\" mëthøð før ðësçrïptør \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", + "deprecatedFunction": "[GdF0l][นั้Thë fµñçtïøñ \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまนั้ढूँ]", + "deprecatedMethod": "[GxfND][นั้Thë mëthøð \"{ñæmë}\" ïñ çlæss \"{çlæssÑæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", + "deprecatedPropertyDeleter": "[BUlI2][นั้Thë ðëlëtër før prøpërtÿ \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]", + "deprecatedPropertyGetter": "[54BuI][นั้Thë gëttër før prøpërtÿ \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", + "deprecatedPropertySetter": "[EHGoz][นั้Thë sëttër før prøpërtÿ \"{ñæmë}\" ïs ðëprëçætëðẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", "deprecatedType": "[IWdSs][นั้Thïs tÿpë ïs ðëprëçætëð æs øf Pÿthøñ {vërsïøñ}; µsë \"{rëplæçëmëñt}\" ïñstëæðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", "dictExpandIllegalInComprehension": "[3B8LL][นั้Ðïçtïøñærÿ ëxpæñsïøñ ñøt ælløwëð ïñ çømprëhëñsïøñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", "dictInAnnotation": "[0UcII][นั้Ðïçtïøñærÿ ëxprëssïøñ ñøt ælløwëð ïñ tÿpë æññøtætïøñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", @@ -228,8 +236,8 @@ "implicitStringConcat": "[t0D1l][นั้Ïmplïçït strïñg çøñçætëñætïøñ ñøt ælløwëðẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", "importCycleDetected": "[FFPSZ][นั้Çÿçlë ðëtëçtëð ïñ ïmpørt çhæïñẤğ倪İЂҰक्र्तिृนั้ढूँ]", "importDepthExceeded": "[8G4s1][นั้Ïmpørt çhæïñ ðëpth ëxçëëðëð {ðëpth}Ấğ倪İЂҰक्र्तिृまนั้ढूँ]", - "importResolveFailure": "[oBYA4][นั้Ïmpørt \"{ïmpørtÑæmë}\" çøµlð ñøt þë føµñð ïñ thë \"{vëñv}\" ëñvïrøñmëñt.Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまนั้ढूँ]", - "importSourceResolveFailure": "[hjHFa][นั้Ïmpørt \"{ïmpørtÑæmë}\" çøµlð ñøt þë rësølvëð frøm søµrçë ïñ thë \"{vëñv}\" ëñvïrøñmëñt.Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", + "importResolveFailure": "[oBYA4][นั้Ïmpørt \"{ïmpørtÑæmë}\" çøµlð ñøt þë rësølvëðẤğ倪İЂҰक्र्तिृまẤğ倪นั้ढूँ]", + "importSourceResolveFailure": "[hjHFa][นั้Ïmpørt \"{ïmpørtÑæmë}\" çøµlð ñøt þë rësølvëð frøm søµrçëẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", "importSymbolUnknown": "[jY9ZH][นั้\"{ñæmë}\" ïs µñkñøwñ ïmpørt sÿmþølẤğ倪İЂҰक्र्तिृนั้ढूँ]", "incompatibleMethodOverride": "[i45Ka][นั้Mëthøð \"{ñæmë}\" øvërrïðës çlæss \"{çlæssÑæmë}\" ïñ æñ ïñçømpætïþlë mæññërẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまนั้ढूँ]", "inconsistentIndent": "[gdrcy][นั้Üñïñðëñt æmøµñt ðøës ñøt mætçh prëvïøµs ïñðëñtẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "[6Tdff][นั้Ëxpëçtëð ëllïpsïs, æ tµplë ëxprëssïøñ, ør Pæræm§pëç før ðëfæµlt vælµë øf Pæræm§pëçẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]", "paramSpecFirstArg": "[W2Y3X][นั้Ëxpëçtëð ñæmë øf Pæræm§pëç æs fïrst ærgµmëñtẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", "paramSpecKwargsUsage": "[2UE71][นั้\"kwærgs\" mëmþër øf Pæræm§pëç ïs vælïð øñlÿ whëñ µsëð wïth **kwærgs pæræmëtërẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", - "paramSpecNotBound": "[xnsuv][นั้Pæræm spëç \"{tÿpë}\" hæs ñø þøµñð vælµëẤğ倪İЂҰक्र्तिृまẤนั้ढूँ]", "paramSpecNotUsedByOuterScope": "[5Pk7H][นั้Pæræm§pëç \"{ñæmë}\" hæs ñø mëæñïñg ïñ thïs çøñtëxtẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", "paramSpecScopedToReturnType": "[vVuXS][นั้Pæræm§pëç \"{ñæmë}\" ïs sçøpëð tø æ çællæþlë wïthïñ thë rëtµrñ tÿpë æñð çæññøt þë rëfërëñçëð ïñ thë fµñçtïøñ þøðÿẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", "paramSpecUnknownArg": "[6zeYc][นั้Pæræm§pëç ðøës ñøt sµppørt mørë thæñ øñë ærgµmëñtẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "[mMUCH][นั้ßæsë çlæss \"{þæsëÇlæss}\" ðërïvës frøm \"{sµþçlæss}\" whïçh ïs ïñçømpætïþlë wïth tÿpë \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", "baseClassOverriddenType": "[Hp8Sl][นั้ßæsë çlæss \"{þæsëÇlæss}\" prøvïðës tÿpë \"{tÿpë}\", whïçh ïs øvërrïððëñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]", "baseClassOverridesType": "[P7N4Y][นั้ßæsë çlæss \"{þæsëÇlæss}\" øvërrïðës wïth tÿpë \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", + "bytesTypePromotions": "[qIXYb][นั้§ët ðïsæþlëßÿtësTÿpëPrømøtïøñs tø fælsë tø ëñæþlë tÿpë prømøtïøñ þëhævïør før \"þÿtëærræÿ\" æñð \"mëmørÿvïëw\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまนั้ढूँ]", "conditionalRequiresBool": "[k1G9a][นั้Mëthøð __þøøl__ før tÿpë \"{øpëræñðTÿpë}\" rëtµrñs tÿpë \"{þøølRëtµrñTÿpë}\" ræthër thæñ \"þøøl\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", "dataClassFieldLocation": "[vQxtf][นั้Fïëlð ðëçlærætïøñẤğ倪İЂҰक्นั้ढूँ]", "dataClassFrozen": "[d4uiK][นั้\"{ñæmë}\" ïs frøzëñẤğ倪İЂҰक्นั้ढूँ]", @@ -612,6 +620,8 @@ "incompatibleSetter": "[GDoso][นั้Prøpërtÿ sëttër mëthøð ïs ïñçømpætïþlëẤğ倪İЂҰक्र्तिृまẤนั้ढूँ]", "initMethodLocation": "[D4O2l][นั้Thë __ïñït__ mëthøð ïs ðëfïñëð ïñ çlæss \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]", "initMethodSignature": "[EULjB][นั้§ïgñætµrë øf __ïñït__ ïs \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृนั้ढूँ]", + "invariantSuggestionDict": "[OIoHo][นั้Çøñsïðër swïtçhïñg frøm \"ðïçt\" tø \"Mæppïñg\" whïçh ïs çøværïæñt ïñ thë vælµë tÿpëẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", + "invariantSuggestionList": "[irYWI][นั้Çøñsïðër swïtçhïñg frøm \"lïst\" tø \"§ëqµëñçë\" whïçh ïs çøværïæñtẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]", "keyNotRequired": "[K1bDP][นั้\"{ñæmë}\" ïs ñøt æ rëqµïrëð këÿ ïñ \"{tÿpë}\", sø æççëss mæÿ rësµlt ïñ rµñtïmë ëxçëptïøñẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", "keyReadOnly": "[dhAH3][นั้\"{ñæmë}\" ïs æ rëæð-øñlÿ këÿ ïñ \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğนั้ढूँ]", "keyRequiredDeleted": "[YeZa5][นั้\"{ñæmë}\" ïs æ rëqµïrëð këÿ æñð çæññøt þë ðëlëtëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂนั้ढूँ]", @@ -632,6 +642,7 @@ "memberSetClassVar": "[2pVfQ][นั้Mëmþër \"{ñæmë}\" çæññøt þë æssïgñëð thrøµgh æ çlæss ïñstæñçë þëçæµsë ït ïs æ ÇlæssVærẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", "memberTypeMismatch": "[IHN4x][นั้\"{ñæmë}\" ïs æñ ïñçømpætïþlë tÿpëẤğ倪İЂҰक्र्तिृนั้ढूँ]", "memberUnknown": "[7kDIF][นั้Mëmþër \"{ñæmë}\" ïs µñkñøwñẤğ倪İЂҰक्र्นั้ढूँ]", + "metaclassConflict": "[fjWW1][นั้Mëtæçlæss \"{mëtæçlæss1}\" çøñflïçts wïth \"{mëtæçlæss2}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्นั้ढूँ]", "missingDeleter": "[5IVNI][นั้Prøpërtÿ ðëlëtër mëthøð ïs mïssïñgẤğ倪İЂҰक्र्तिृまนั้ढूँ]", "missingGetter": "[Mzn4K][นั้Prøpërtÿ gëttër mëthøð ïs mïssïñgẤğ倪İЂҰक्र्तिृนั้ढूँ]", "missingProtocolMember": "[ZIqwL][นั้Mëmþër \"{ñæmë}\" ïs ðëçlærëð ïñ prøtøçøl çlæss \"{çlæssTÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", @@ -643,10 +654,13 @@ "newMethodSignature": "[NeWKO][นั้§ïgñætµrë øf __ñëw__ ïs \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृนั้ढूँ]", "noOverloadAssignable": "[FJ88c][นั้Ñø øvërløæðëð fµñçtïøñ mætçhës tÿpë \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", "orPatternMissingName": "[kgiPM][นั้Mïssïñg ñæmës: {ñæmë}Ấğ倪İЂҰक्นั้ढूँ]", + "overloadIndex": "[vNPxL][นั้Øvërløæð {ïñðëx} ïs thë çløsëst mætçhẤğ倪İЂҰक्र्तिृまẤนั้ढूँ]", "overloadNotAssignable": "[BA2kK][นั้Øñë ør mørë øvërløæðs øf \"{ñæmë}\" ïs ñøt æssïgñæþlëẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", "overloadSignature": "[NPzwf][นั้Øvërløæð sïgñætµrë ïs ðëfïñëð hërëẤğ倪İЂҰक्र्तिृまนั้ढूँ]", "overriddenMethod": "[CcUB2][นั้Øvërrïððëñ mëthøðẤğ倪İЂҰक्นั้ढूँ]", "overriddenSymbol": "[cvpXz][นั้Øvërrïððëñ sÿmþølẤğ倪İЂҰक्นั้ढूँ]", + "overrideInvariantMismatch": "[uODzM][นั้Øvërrïðë tÿpë \"{øvërrïðëTÿpë}\" ïs ñøt thë sæmë æs þæsë tÿpë \"{þæsëTÿpë}\"Ấğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤนั้ढूँ]", + "overrideIsInvariant": "[j45KZ][นั้Værïæþlë ïs mµtæþlë sø ïts tÿpë ïs ïñværïæñtẤğ倪İЂҰक्र्तिृまẤğ倪İนั้ढूँ]", "overrideNoOverloadMatches": "[vG14w][นั้Ñø øvërløæð sïgñætµrë ïñ øvërrïðë ïs çømpætïþlë wïth þæsë mëthøðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]", "overrideNotClassMethod": "[t5OaH][นั้ßæsë mëthøð ïs ðëçlærëð æs æ çlæssmëthøð þµt øvërrïðë ïs ñøtẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", "overrideNotInstanceMethod": "[e2Xo5][นั้ßæsë mëthøð ïs ðëçlærëð æs æñ ïñstæñçë mëthøð þµt øvërrïðë ïs ñøtẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृนั้ढूँ]", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "[GGttd][นั้TÿpëVærTµplë çæññøt þë þøµñð tø æ tµplë øf µñkñøwñ lëñgthẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्นั้ढूँ]", "typeVarUnsolvableRemedy": "[PaRa7][นั้Prøvïðë æñ øvërløæð thæt spëçïfïës thë rëtµrñ tÿpë whëñ thë ærgµmëñt ïs ñøt sµpplïëðẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰक्र्तिृまẤğ倪İЂҰนั้ढूँ]", "typeVarsMissing": "[R1SEV][นั้Mïssïñg tÿpë værïæþlës: {ñæmës}Ấğ倪İЂҰक्र्तिृนั้ढूँ]", + "typedDictBaseClass": "[Zv6vP][นั้Çlæss \"{tÿpë}\" ïs ñøt æ TÿpëðÐïçtẤğ倪İЂҰक्र्तिृนั้ढूँ]", "typedDictFieldMissing": "[rNzn7][นั้\"{ñæmë}\" ïs mïssïñg frøm \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृนั้ढूँ]", "typedDictFieldNotReadOnly": "[BJy1V][นั้\"{ñæmë}\" ïs ñøt rëæð-øñlÿ ïñ \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまẤนั้ढूँ]", "typedDictFieldNotRequired": "[eqatW][นั้\"{ñæmë}\" ïs ñøt rëqµïrëð ïñ \"{tÿpë}\"Ấğ倪İЂҰक्र्तिृまนั้ढूँ]", diff --git a/packages/pyright-internal/src/localization/package.nls.ru.json b/packages/pyright-internal/src/localization/package.nls.ru.json index c378ddce3..ee6e24107 100644 --- a/packages/pyright-internal/src/localization/package.nls.ru.json +++ b/packages/pyright-internal/src/localization/package.nls.ru.json @@ -11,8 +11,8 @@ "renameShadowedFile": "Переименовать \"{oldFile}\" в \"{newFile}\"" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Автоматический импорт", + "indexValueDetail": "Значение индекса" }, "Diagnostic": { "abstractMethodInvocation": "Метод \"{method}\" не может быть вызван, так как является абстрактным", @@ -67,8 +67,8 @@ "classGetItemClsParam": "Переопределение метода __class_getitem__ должно принимать параметр \"cls\"", "classMethodClsParam": "Методы класса должны принимать параметр cls", "classNotRuntimeSubscriptable": "Операция взятия подстроки для класса \"{name}\" создаст исключение среды выполнения; заключите заметку типа в кавычки", - "classPatternBuiltInArgCount": "Шаблон класса принимает не более одного позиционного вложенного шаблона", "classPatternBuiltInArgPositional": "Шаблон класса принимает только позиционный вложенный шаблон", + "classPatternPositionalArgCount": "Слишком много позиционных шаблонов для класса \"{type}\"; ожидается {expected}, но получено {received}", "classPatternTypeAlias": "\"{type}\" нельзя использовать в шаблоне класса, поскольку это псевдоним специализированного типа", "classTypeParametersIllegal": "Синтаксис параметра типа класса может использоваться в Python версии не ниже 3.12.", "classVarFirstArgMissing": "Ожидается аргумент типа после \"ClassVar\"", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "Выражение всегда будет оцениваться как ИСТИНА, так как типы \"{leftType}\" и \"{rightType}\" не перекрываются", "continueInFinally": "Невозможно использовать \"continue\" в предложении finally", "continueOutsideLoop": "Ключевое слово \"continue\" можно использовать только внутри цикла", + "coroutineInConditionalExpression": "Условное выражение ссылается на сопрограмму, которая всегда возвращает значение True", "dataClassBaseClassFrozen": "Незафиксированный класс не может наследоваться от зафиксированного класса", "dataClassBaseClassNotFrozen": "Незафиксированный класс не может наследоваться от зафиксированного класса", "dataClassConverterFunction": "Аргумент типа \"{argType}\" не является допустимым преобразователем для поля \"{fieldName}\" типа \"{fieldType}\"", @@ -114,7 +115,14 @@ "delTargetExpr": "Не удается удалить выражение", "deprecatedClass": "Класс \"{name}\" является нерекомендуемым", "deprecatedConstructor": "Конструктор для класса \"{name}\" больше не рекомендуется к использованию", + "deprecatedDescriptorDeleter": "Метод \"__delete__\" для дескриптора \"{name}\" не рекомендуется", + "deprecatedDescriptorGetter": "Метод \"__get__\" для дескриптора \"{name}\" не рекомендуется", + "deprecatedDescriptorSetter": "Метод \"__set__\" для дескриптора \"{name}\" не рекомендуется", "deprecatedFunction": "Функция \"{name}\" больше не рекомендуется к использованию", + "deprecatedMethod": "Метод \"{name}\" в классе \"{className}\" не рекомендуется к использованию", + "deprecatedPropertyDeleter": "Метод удаления для свойства \"{name}\" не рекомендуется", + "deprecatedPropertyGetter": "Метод получения для свойства \"{name}\" не рекомендуется", + "deprecatedPropertySetter": "Метод задания для свойства \"{name}\" не рекомендуется", "deprecatedType": "Этот тип больше не рекомендуется к использованию начиная с версии Python {version}; используйте вместо него \"{replacement}\"", "dictExpandIllegalInComprehension": "Расширение словаря в понимании не допускается", "dictInAnnotation": "Словарные выражения не разрешены в заметках типа", @@ -228,8 +236,8 @@ "implicitStringConcat": "Неявное объединение строк не разрешено", "importCycleDetected": "Обнаружен цикл в цепочке импорта", "importDepthExceeded": "Глубина цепочки импорта превысила {depth}", - "importResolveFailure": "Импорт \"{importName}\" не найден в среде \"{venv}\".", - "importSourceResolveFailure": "Не удалось разрешить импорт \"{importName}\" из источника в среде \"{venv}\".", + "importResolveFailure": "Не удается разрешить импорт \"{importName}\"", + "importSourceResolveFailure": "Не удается разрешить импорт \"{importName}\" из источника", "importSymbolUnknown": "\"{name}\" — неизвестный символ импорта", "incompatibleMethodOverride": "Метод \"{name}\" переопределяет класс \"{className}\" несовместимым образом", "inconsistentIndent": "Сумма отступа не соответствует предыдущему отступу", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "Для значения ParamSpec по умолчанию ожидается многоточие, выражение кортежа или ParamSpec", "paramSpecFirstArg": "Ожидается имя ParamSpec в качестве первого аргумента", "paramSpecKwargsUsage": "Элемент \"kwargs\" ParamSpec допустим только при использовании с параметром **kwargs.", - "paramSpecNotBound": "Спецификация параметра \"{type}\" не имеет привязанного значения", "paramSpecNotUsedByOuterScope": "ParamSpec \"{name}\" не имеет смысла в этом контексте", "paramSpecScopedToReturnType": "ParamSpec \"{name}\" относится к области вызываемого объекта в возвращаемом типе, и на него нельзя ссылаться в тексте функции.", "paramSpecUnknownArg": "ParamSpec не поддерживает более одного аргумента", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "Базовый класс \"{baseClass}\" является производным от \"{subclass}\", который несовместим с типом \"{type}\"", "baseClassOverriddenType": "Базовый класс \"{baseClass}\" предоставляет тип \"{type}\", который переопределен", "baseClassOverridesType": "Базовый класс \"{baseClass}\" переопределяет тип \"{type}\"", + "bytesTypePromotions": "Установите для параметра DisableBytesTypePromotions значение ЛОЖЬ, чтобы включить повышение типа для \"bytearray\" и \"memoryview\"", "conditionalRequiresBool": "Метод __bool__ для типа \"{operandType}\" возвращает тип \"{boolReturnType}\", а не \"bool\"", "dataClassFieldLocation": "Объявление поля", "dataClassFrozen": "Элемент \"{name}\" зафиксирован", @@ -612,6 +620,8 @@ "incompatibleSetter": "Метод задания свойства является несовместимым", "initMethodLocation": "Метод __init__ определен в классе \"{type}\"", "initMethodSignature": "Сигнатура __init__ — \"{type}\"", + "invariantSuggestionDict": "Рассмотрите возможность перехода с \"dict\" на \"Mapping\", являющийся ковариантным по типу значения.", + "invariantSuggestionList": "Рассмотрите возможность перехода с \"list\" на \"Sequence\", являющийся ковариантным.", "keyNotRequired": "\"{name}\" не является обязательным ключом в \"{type}\", поэтому доступ может вызвать исключение во время выполнения", "keyReadOnly": "\"{name}\" является ключом только для чтения в \"{type}\"", "keyRequiredDeleted": "\"{name}\" является обязательным ключом и не подлежит удалению", @@ -632,6 +642,7 @@ "memberSetClassVar": "Элемент \"{name}\" не может быть назначен через экземпляр класса, так как это ClassVar", "memberTypeMismatch": "\"{name}\" является несовместимым типом", "memberUnknown": "Элемент \"{name}\" неизвестен", + "metaclassConflict": "Метакласс \"{metaclass1}\" конфликтует с \"{metaclass2}\"", "missingDeleter": "Отсутствует метод удаления свойства", "missingGetter": "Отсутствует метод получения свойства", "missingProtocolMember": "Элемент \"{name}\" объявлен в классе протокола \"{classType}\"", @@ -643,10 +654,13 @@ "newMethodSignature": "Сигнатура метода __new__ требует \"{type}\"", "noOverloadAssignable": "Нет перегруженной функции, соответствующей типу \"{type}\"", "orPatternMissingName": "Отсутствуют имена: {name}", + "overloadIndex": "Наилучшее совпадение: {index} перегрузки", "overloadNotAssignable": "Одна или несколько перегрузок \"{name}\" не подлежат присвоению", "overloadSignature": "Здесь определена сигнатура перегрузки", "overriddenMethod": "Переопределенный метод", "overriddenSymbol": "Переопределенный символ", + "overrideInvariantMismatch": "Тип переопределения \"{overrideType}\" не совпадает с базовым типом \"{baseType}\"", + "overrideIsInvariant": "Переменная изменяема, поэтому ее тип является инвариантным", "overrideNoOverloadMatches": "В переопределении нет сигнатуры перегрузки, совместимой с базовым методом", "overrideNotClassMethod": "Базовый метод объявлен как classmethod, а его переопределение — нет", "overrideNotInstanceMethod": "Базовый метод объявлен как метод экземпляра, а его переопределение — нет", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple не может граничить с кортежем неизвестной длины", "typeVarUnsolvableRemedy": "Укажите перегрузку, которая указывает тип возвращаемого значения, если аргумент не передается", "typeVarsMissing": "Отсутствуют переменные типа: {names}", + "typedDictBaseClass": "Класс \"{type}\" не является TypedDict", "typedDictFieldMissing": "\"{name}\" отсутствует в \"{type}\"", "typedDictFieldNotReadOnly": "\"{name}\" не является элементом \"{type}\" только для чтения", "typedDictFieldNotRequired": "\"{name}\" не является обязательным в \"{type}\"", diff --git a/packages/pyright-internal/src/localization/package.nls.tr.json b/packages/pyright-internal/src/localization/package.nls.tr.json index ba96a49f0..59c115bba 100644 --- a/packages/pyright-internal/src/localization/package.nls.tr.json +++ b/packages/pyright-internal/src/localization/package.nls.tr.json @@ -11,8 +11,8 @@ "renameShadowedFile": "\"{oldFile}\" dosyasını \"{newFile}\" olarak yeniden adlandır" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "Otomatik içeri aktarma", + "indexValueDetail": "Dizin değeri" }, "Diagnostic": { "abstractMethodInvocation": "\"{method}\" metodu soyut olduğundan çağrılamaz", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__ geçersiz kılması bir \"cls\" parametresi almalı", "classMethodClsParam": "Sınıf metotları bir \"cls\" parametresi almalıdır", "classNotRuntimeSubscriptable": "\"{name}\" sınıfına ait alt simge çalışma zamanı özel durumunu oluşturur; tür ek açıklamalarını tırnak içine alın", - "classPatternBuiltInArgCount": "Sınıf deseni en fazla 1 konumsal alt deseni kabul eder", "classPatternBuiltInArgPositional": "Sınıf deseni yalnızca konumsal alt desen kabul eder", + "classPatternPositionalArgCount": "\"{type}\" sınıfı için çok fazla konumsal desen var; {expected} bekleniyordu ancak {received} alındı", "classPatternTypeAlias": "\"{type}\" özel bir tür diğer adı olduğundan sınıf deseninde kullanılamaz", "classTypeParametersIllegal": "Sınıf türü parametresi söz dizimi için Python 3.12 veya daha yeni bir sürümü gerekiyor", "classVarFirstArgMissing": "\"ClassVar\" sonrasında tür bağımsız değişkeni bekleniyordu", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "\"{leftType}\" türleri ve \"{rightType}\" türleri çakışmadığından ifade her zaman True olarak değerlendirilir", "continueInFinally": "\"continue\" finally yan tümcesi içinde kullanılamaz", "continueOutsideLoop": "\"continue\" yalnızca bir döngü içinde kullanılabilir", + "coroutineInConditionalExpression": "Koşullu ifade, her zaman True olarak değerlendirilen eş yordama başvurur", "dataClassBaseClassFrozen": "Dondurulmuş olmayan bir sınıf dondurulmuş bir sınıftan devralamaz", "dataClassBaseClassNotFrozen": "Dondurulmuş sınıf, dondurulmuş olmayan bir sınıftan devralamaz", "dataClassConverterFunction": "\"{argType}\" türündeki bağımsız değişken, \"{fieldName}\" türündeki \"{fieldType}\" alanı için geçerli bir dönüştürücü değil", @@ -114,7 +115,14 @@ "delTargetExpr": "İfade silinemiyor", "deprecatedClass": "\"{name}\" sınıfı kullanım dışı", "deprecatedConstructor": "\"{name}\" sınıfının oluşturucusu kullanım dışı", - "deprecatedFunction": "Bu \"{name}\" işlevi kullanım dışı", + "deprecatedDescriptorDeleter": "\"{name}\" tanımlayıcısı için \"__delete__\" yöntemi kullanım dışı", + "deprecatedDescriptorGetter": "\"{name}\" tanımlayıcısı için \"__get__\" yöntemi kullanım dışı", + "deprecatedDescriptorSetter": "\"{name}\" tanımlayıcısı için \"__set__\" yöntemi kullanım dışı", + "deprecatedFunction": "\"{name}\" işlevi kullanım dışı", + "deprecatedMethod": "\"{className}\" sınıfındaki \"{name}\" yöntemi kullanım dışı", + "deprecatedPropertyDeleter": "\"{name}\" özelliği silicisi kullanım dışı", + "deprecatedPropertyGetter": "\"{name}\" özelliği alıcısı kullanım dışı", + "deprecatedPropertySetter": "\"{name}\" özelliği ayarlayıcısı kullanım dışı", "deprecatedType": "Bu tür Python {version} sürümünden itibaren kullanım dışı; bunun yerine \"{replacement}\" kullanın", "dictExpandIllegalInComprehension": "Sözlük genişletmeye anlamada izin verilmiyor", "dictInAnnotation": "Tür ek açıklamasında sözlük ifadesi kullanılamaz", @@ -228,8 +236,8 @@ "implicitStringConcat": "Örtük dize birleştirmesine izin verilmiyor", "importCycleDetected": "İçeri aktarma zincirinde döngü algılandı", "importDepthExceeded": "İçeri aktarma zinciri derinliği {depth} sınırını aştı", - "importResolveFailure": "\"{importName}\", \"{venv}\" ortamında bulunamadı.", - "importSourceResolveFailure": "\"{importName}\" adlı içeri aktarma \"{venv}\" ortamındaki kaynaktan çözümlenemedi.", + "importResolveFailure": "\"{importName}\" adlı içeri aktarma çözümlenemedi", + "importSourceResolveFailure": "\"{importName}\" adlı içeri aktarma kaynaktan çözümlenemedi", "importSymbolUnknown": "\"{name}\" alma simgesi bilinmiyor", "incompatibleMethodOverride": "\"{name}\" metodu \"{className}\" sınıfını uyumsuz bir şekilde geçersiz kılıyor", "inconsistentIndent": "Girintisiz miktar önceki girintiyle eşleşmiyor", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "ParamSpec varsayılan değeri için üç nokta, demet ifadesi veya ParamSpec bekleniyordu", "paramSpecFirstArg": "İlk bağımsız değişken olarak ParamSpec adı bekleniyordu", "paramSpecKwargsUsage": "ParamSpec'in \"kwargs\" üyesi yalnızca *kwargs parametresiyle kullanıldığında geçerlidir", - "paramSpecNotBound": "\"{type}\" parametre belirtimi bağlı bir değere sahip değil", "paramSpecNotUsedByOuterScope": "\"{name}\" adlı ParamSpec bu bağlamda bir anlam ifade etmiyor", "paramSpecScopedToReturnType": "ParamSpec \"{name}\" dönüş türü içinde çağrılabilir kapsamına alındı ve işlev gövdesinde başvurulamaz", "paramSpecUnknownArg": "ParamSpec birden fazla bağımsız değişkeni desteklemiyor", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "\"{baseClass}\" temel sınıfı, \"{type}\" türüyle uyumlu olmayan \"{subclass}\" alt sınıfından türetiliyor", "baseClassOverriddenType": "\"{baseClass}\" temel sınıfı geçersiz kılınan \"{type}\" türünü sağlar", "baseClassOverridesType": "Temel sınıf \"{baseClass}\", \"{type}\" türünü geçersiz kılıyor", + "bytesTypePromotions": "“bytearray” ve “memoryview” için tür yükseltme davranışını etkinleştirmek için disableBytesTypePromotions seçeneğini “false” olarak ayarlayın", "conditionalRequiresBool": "\"{operandType}\" türü için __bool__ metodu \"bool\" yerine \"{boolReturnType}\" türü döndürür", "dataClassFieldLocation": "Alan bildirimi", "dataClassFrozen": "\"{name}\" donduruldu", @@ -612,6 +620,8 @@ "incompatibleSetter": "Özellik ayarlayıcı metodu uyumsuz", "initMethodLocation": "\"{type}\" sınıfı içinde __init__ metodu tanımlandı", "initMethodSignature": "__init__ imzası \"{type}\"", + "invariantSuggestionDict": "“dict” öğesinden değer türünde eş değişken olan “Mapping” öğesine geçmeyi deneyin", + "invariantSuggestionList": "“list” öğesinden eş değişken olan “Sequence” öğesine geçmeyi deneyin", "keyNotRequired": "\"{name}\", \"{type}\" türünde gerekli bir anahtar olmadığından çalışma zamanı özel durumuna neden olabilir", "keyReadOnly": "\"{name}\", \"{type}\" içinde salt okunur", "keyRequiredDeleted": "\"{name}\" gerekli bir anahtar olduğundan silinemez", @@ -632,6 +642,7 @@ "memberSetClassVar": "\"{name}\" üyesi bir ClassVar olduğundan sınıf örneği aracılığıyla atanamaz", "memberTypeMismatch": "\"{name}\" uyumsuz bir tür", "memberUnknown": "\"{name}\" üyesi bilinmiyor", + "metaclassConflict": "Metaclass \"{metaclass1}\", \"{metaclass2}\" ile çakışıyor", "missingDeleter": "Özellik silici metodu eksik", "missingGetter": "Özellik alıcı metodu eksik", "missingProtocolMember": "\"{name}\" üyesi \"{classType}\" protokol sınıfında bildirildi", @@ -643,10 +654,13 @@ "newMethodSignature": "__new__ imzası \"{type}\"", "noOverloadAssignable": "Aşırı yüklenmiş işlevlerden hiçbiri \"{type}\" türüyle uyuşmuyor", "orPatternMissingName": "Eksik adlar: {name}", + "overloadIndex": "Aşırı yükleme {index} en yakın eşleşmedir", "overloadNotAssignable": "Bir veya daha fazla \"{name}\" aşırı yüklemesi atanabilir değil", "overloadSignature": "Aşırı yükleme imzası burada tanımlı", "overriddenMethod": "Geçersiz kılınan metot", "overriddenSymbol": "Geçersiz kılınan simge", + "overrideInvariantMismatch": "\"{overrideType}\" geçersiz kılma türü \"{baseType}\" temel türüyle aynı değil", + "overrideIsInvariant": "Değişken değişebilir, bu nedenle türü sabit", "overrideNoOverloadMatches": "Geçersiz kılmadaki hiçbir aşırı yükleme imzası temel metotla uyumlu değil", "overrideNotClassMethod": "Temel metot bir örnek metodu olarak bildirilir, ancak geçersiz kılma bu şekilde bildirilmez", "overrideNotInstanceMethod": "Temel metot bir örnek metodu olarak bildirilir, ancak geçersiz kılma bu şekilde bildirilmez", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple, uzunluğu bilinmeyen bir demete bağlanamaz", "typeVarUnsolvableRemedy": "Bağımsız değişken sağlanmamışken dönüş türünü belirten bir aşırı yükleme belirtin", "typeVarsMissing": "Eksik tür değişkenleri: {names}", + "typedDictBaseClass": "\"{type}\" sınıfı bir TypedDict değil", "typedDictFieldMissing": "\"{type}\" için \"{name}\" eksik", "typedDictFieldNotReadOnly": "\"{name}\", \"{type}\" içinde salt okunur değil", "typedDictFieldNotRequired": "\"{type}\" içinde \"{name}\" gerekli değil", diff --git a/packages/pyright-internal/src/localization/package.nls.zh-cn.json b/packages/pyright-internal/src/localization/package.nls.zh-cn.json index 464c81637..0bf674e0d 100644 --- a/packages/pyright-internal/src/localization/package.nls.zh-cn.json +++ b/packages/pyright-internal/src/localization/package.nls.zh-cn.json @@ -11,8 +11,8 @@ "renameShadowedFile": "将“{oldFile}”重命名为“{newFile}”" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "自动导入", + "indexValueDetail": "索引值" }, "Diagnostic": { "abstractMethodInvocation": "无法调用方法\"{method}\",因为它是抽象的", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__替代应采用“cls”参数", "classMethodClsParam": "类方法应采用“cls”参数", "classNotRuntimeSubscriptable": "类“{name}”的下标将生成运行时异常;将类型批注括在引号中", - "classPatternBuiltInArgCount": "类模式最多接受 1 个位置子模式", "classPatternBuiltInArgPositional": "类模式仅接受位置子模式", + "classPatternPositionalArgCount": "类“{type}”的位置模式太多; 应为 {expected},但收到了 {received}", "classPatternTypeAlias": "无法在类模式中使用“{type}”,因为它是专用类型别名", "classTypeParametersIllegal": "类类型参数语法需要 Python 3.12 或更高版本", "classVarFirstArgMissing": "\"ClassVar\"后应为类型参数", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "表达式的计算结果始终为 True,因为类型“{leftType}”和“{rightType}”没有重叠", "continueInFinally": "“continue”不能在 finally 子句中使用", "continueOutsideLoop": "“continue”只能在循环中使用", + "coroutineInConditionalExpression": "始终计算结果为 True 的条件表达式引用协同例程", "dataClassBaseClassFrozen": "非冻结类不能从已冻结类继承", "dataClassBaseClassNotFrozen": "冻结类不能从未冻结的类继承", "dataClassConverterFunction": "类型“{argType}”的参数不是类型为“{fieldType}”的字段“{fieldName}”的有效转换器", @@ -114,7 +115,14 @@ "delTargetExpr": "无法删除表达式", "deprecatedClass": "类\"{name}\"已弃用", "deprecatedConstructor": "类\"{name}\"的构造函数已弃用", - "deprecatedFunction": "此函数“{name}”已弃用", + "deprecatedDescriptorDeleter": "已弃用描述符“{name}”的“__delete__”方法", + "deprecatedDescriptorGetter": "已弃用描述符“{name}”的“__get__”方法", + "deprecatedDescriptorSetter": "已弃用描述符“{name}”的“__set__”方法", + "deprecatedFunction": "函数“{name}”已弃用", + "deprecatedMethod": "类“{className}”中的“{name}”方法已弃用", + "deprecatedPropertyDeleter": "已弃用属性“{name}”的删除程序", + "deprecatedPropertyGetter": "已弃用属性“{name}”的 getter", + "deprecatedPropertySetter": "已弃用属性“{name}”的资源库", "deprecatedType": "自 Python {version} 起,此类型已弃用;请改用“{replacement}”", "dictExpandIllegalInComprehension": "理解中不允许字典扩展", "dictInAnnotation": "类型批注中不允许使用字典表达式", @@ -228,8 +236,8 @@ "implicitStringConcat": "不允许隐式字符串串联", "importCycleDetected": "在导入链中检测到的周期数", "importDepthExceeded": "导入链深度超过 {depth}", - "importResolveFailure": "在“{venv}”环境中找不到导入“{importName}”。", - "importSourceResolveFailure": "无法从“{venv}”环境源解析导入“{importName}”。", + "importResolveFailure": "无法解析导入“{importName}”", + "importSourceResolveFailure": "无法从源解析导入“{importName}”", "importSymbolUnknown": "“{name}”是未知的导入符号", "incompatibleMethodOverride": "方法“{name}”以不兼容的方式替代类“{className}”", "inconsistentIndent": "取消缩进量与以前的缩进不匹配", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "ParamSpec 的默认值应为省略号、元组表达式或 ParamSpec", "paramSpecFirstArg": "ParamSpec 作为第一个参数的预期名称", "paramSpecKwargsUsage": "ParamSpec 的“kwargs”成员仅在与 **kwargs 参数一起使用时有效", - "paramSpecNotBound": "参数规范“{type}”没有绑定值", "paramSpecNotUsedByOuterScope": "ParamSpec“{name}”在此上下文中没有意义", "paramSpecScopedToReturnType": "ParamSpec \"{name}\"在返回类型内的作用域为可调用,不能在函数体中引用", "paramSpecUnknownArg": "ParamSpec 不支持多个参数", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "基类“{baseClass}”派生自与类型“{type}”不兼容的“{subclass}”", "baseClassOverriddenType": "基类\"{baseClass}\"提供被替代的类型\"{type}\"", "baseClassOverridesType": "基类“{baseClass}”替代类型{type}”", + "bytesTypePromotions": "将 disableBytesTypePromotions 设置为 false,以启用“bytearray”和“memoryview”的类型提升行为", "conditionalRequiresBool": "类型“{operandType}”的方法__bool__返回类型“{boolReturnType}”而不是“bool”", "dataClassFieldLocation": "字段声明", "dataClassFrozen": "\"{name}\"已冻结", @@ -612,6 +620,8 @@ "incompatibleSetter": "属性 setter 方法不兼容", "initMethodLocation": "__init__方法已在类“{type}”中定义", "initMethodSignature": "__init__的签名为“{type}”", + "invariantSuggestionDict": "请考虑从 “dict” 切换到 “Mapping”(在值类型中为协变)", + "invariantSuggestionList": "考虑从“list”切换到“Sequence”(协变)", "keyNotRequired": "“{type}”中“{name}”不是必需的密钥,因此访问可能会导致运行时异常", "keyReadOnly": "“{name}”是“{type}”中的只读密钥", "keyRequiredDeleted": "“{name}”是必需的密钥,无法删除", @@ -632,6 +642,7 @@ "memberSetClassVar": "无法通过类实例分配成员“{name}”,因为它是 ClassVar", "memberTypeMismatch": "\"{name}\"是不兼容的类型", "memberUnknown": "成员\"{name}\"未知", + "metaclassConflict": "元类“{metaclass1}”与“{metaclass2}”存在冲突", "missingDeleter": "缺少属性 deleter方法", "missingGetter": "缺少属性 getter 方法", "missingProtocolMember": "成员\"{name}\"已在协议类\"{classType}\"中声明", @@ -643,10 +654,13 @@ "newMethodSignature": "__new__的签名为“{type}”", "noOverloadAssignable": "没有重载函数与类型“{type}”匹配", "orPatternMissingName": "缺少名称: {name}", + "overloadIndex": "重载 {index} 是最接近的匹配项", "overloadNotAssignable": "无法分配“{name}”的一个或多个重载", "overloadSignature": "此处定义了重载签名", "overriddenMethod": "替代的方法", "overriddenSymbol": "替代符号", + "overrideInvariantMismatch": "替代类型“{overrideType}”与基类型“{baseType}”不同", + "overrideIsInvariant": "变量是可变的,因此其类型是固定的", "overrideNoOverloadMatches": "替代中没有与基本方法兼容的重载签名", "overrideNotClassMethod": "基方法声明为 classmethod,但替代不是", "overrideNotInstanceMethod": "基方法声明为实例方法,但替代不是", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple 不能绑定到长度未知的元组", "typeVarUnsolvableRemedy": "提供一个重载,该重载指定未提供参数时的返回类型", "typeVarsMissing": "缺少类型变量: {names}", + "typedDictBaseClass": "类“{type}”不是 TypedDict", "typedDictFieldMissing": "\"{type}\"中缺少\"{name}\"", "typedDictFieldNotReadOnly": "\"{name}\"在\"{type}\"中不是只读的", "typedDictFieldNotRequired": "“{type}”中不需要“{name}”", diff --git a/packages/pyright-internal/src/localization/package.nls.zh-tw.json b/packages/pyright-internal/src/localization/package.nls.zh-tw.json index 86dbf8867..ec2bd1ab2 100644 --- a/packages/pyright-internal/src/localization/package.nls.zh-tw.json +++ b/packages/pyright-internal/src/localization/package.nls.zh-tw.json @@ -11,8 +11,8 @@ "renameShadowedFile": "將 \"{oldFile}\" 重新命名為 \"{newFile}\"" }, "Completion": { - "autoImportDetail": "Auto-import", - "indexValueDetail": "Index value" + "autoImportDetail": "自動匯入", + "indexValueDetail": "索引值" }, "Diagnostic": { "abstractMethodInvocation": "不能呼叫方法 \"{method}\",因為它是抽象", @@ -67,8 +67,8 @@ "classGetItemClsParam": "__class_getitem__ 覆寫應接受 \"cls\" 參數", "classMethodClsParam": "類別方法應採用 \"cls\" 參數", "classNotRuntimeSubscriptable": "類別 \"{name}\" 的下標會產生執行階段例外; 以引號括住類型註釋", - "classPatternBuiltInArgCount": "類別模式最多接受 1 個位置子模式", "classPatternBuiltInArgPositional": "類別模式僅接受位置子模式", + "classPatternPositionalArgCount": "類別 \"{type}\" 的位置模式太多;預期 {expected} 但收到 {received}", "classPatternTypeAlias": "無法在類別模式中使用 \"{type}\",因為它是特殊的型別別名", "classTypeParametersIllegal": "類別類型參數語法需要 Python 3.12 或更新版本", "classVarFirstArgMissing": "\"ClassVar\" 後面應有一個型別引數", @@ -93,6 +93,7 @@ "containmentAlwaysTrue": "運算式一律會評估為 True,因為型別 \"{leftType}\" 和 \"{rightType}\" 沒有重疊", "continueInFinally": "\"continue\" 不能在 finally 子句內使用", "continueOutsideLoop": "\"continue\" 只能在 loop 內使用", + "coroutineInConditionalExpression": "條件運算式參考協同程式,一律評估為 True", "dataClassBaseClassFrozen": "未凍結的類別無法繼承已凍結的類別", "dataClassBaseClassNotFrozen": "凍結的類別不能從未凍結的類別繼承", "dataClassConverterFunction": "類型 \"{argType}\" 的引數不是類型 \"{fieldType}\" 欄位 \"{fieldName}\" 的有效轉換程式", @@ -114,7 +115,14 @@ "delTargetExpr": "無法刪除運算式", "deprecatedClass": "類別 \"{name}\" 已淘汰", "deprecatedConstructor": "類別 \"{name}\" 的建構函式已取代", - "deprecatedFunction": "此函式 \"{name}\" 已取代", + "deprecatedDescriptorDeleter": "描述項 \"{name}\" 的 \"__delete__\" 方法已被取代", + "deprecatedDescriptorGetter": "描述項 \"{name}\" 的 \"__get__\" 方法已被取代", + "deprecatedDescriptorSetter": "描述項 \"{name}\" 的 \"__set__\" 方法已被取代", + "deprecatedFunction": "函式 \"{name}\" 已取代", + "deprecatedMethod": "類別 \"{className}\" 中的方法 \"{name}\" 已取代", + "deprecatedPropertyDeleter": "屬性 \"{name}\" 的 deleter 已被取代", + "deprecatedPropertyGetter": "屬性 \"{name}\" 的 getter 已被取代", + "deprecatedPropertySetter": "屬性 \"{name}\" 的 setter 已被取代", "deprecatedType": "此類型已隨著 Python {version} 取代; 請改為使用 \"{replacement}\"", "dictExpandIllegalInComprehension": "理解中不允許字典擴充", "dictInAnnotation": "類型註釋中不允許字典運算式", @@ -228,8 +236,8 @@ "implicitStringConcat": "不允許隱含字串串連", "importCycleDetected": "在匯入鏈結中偵測到迴圈", "importDepthExceeded": "匯入鏈結深度超過 {depth}", - "importResolveFailure": "在 \"{venv}\" 環境中找不到匯入 \"{importName}\"。", - "importSourceResolveFailure": "無法從 \"{venv}\" 環境中的來源解析匯入 \"{importName}\"。", + "importResolveFailure": "無法解析匯入 \"{importName}\"", + "importSourceResolveFailure": "無法從來源解析匯入 \"{importName}\"", "importSymbolUnknown": "\"{name}\" 是未知的匯入符號", "incompatibleMethodOverride": "方法 \"{name}\" 會以不相容的方式覆寫類別 \"{className}\"", "inconsistentIndent": "取消縮排量與先前縮排不符", @@ -343,7 +351,6 @@ "paramSpecDefaultNotTuple": "ParamSpec 的預設值必須是省略符號、元組運算式或 ParamSpec", "paramSpecFirstArg": "應以 ParamSpec 的名稱作為第一個引數", "paramSpecKwargsUsage": "ParamSpec 的 \"kwargs\" 成員只有在與 **kwargs 參數搭配使用時有效", - "paramSpecNotBound": "參數規格 \"{type}\" 沒有繫結值", "paramSpecNotUsedByOuterScope": "ParamSpec \"{name}\" 在此內容中沒有意義", "paramSpecScopedToReturnType": "ParamSpec \"{name}\" 的範圍為傳回型別內的可呼叫項目,無法在函式主體中參考", "paramSpecUnknownArg": "ParamSpec 不支援一個以上的引數", @@ -598,6 +605,7 @@ "baseClassIncompatibleSubclass": "基底類別 \"{baseClass}\" 衍生自與類型 \"{type}\" 不相容的 \"{subclass}\"", "baseClassOverriddenType": "基底類別 \"{baseClass}\" 提供類型 \"{type}\",其已覆寫", "baseClassOverridesType": "基底類別 \"{baseClass}\" 以型別 \"{type}\" 來覆寫", + "bytesTypePromotions": "將 disableBytesTypePromotions 設定為 false,以啟用「bytearray」和「memoryview」的類型升級行為", "conditionalRequiresBool": "類型 \"{operandType}\" 的方法 __bool__ 傳回類型 \"{boolReturnType}\" 而非 \"bool\"", "dataClassFieldLocation": "欄位宣告", "dataClassFrozen": "\"{name}\" 已凍結", @@ -612,6 +620,8 @@ "incompatibleSetter": "屬性 setter 方法不相容", "initMethodLocation": "__init__ 方法於類別 \"{type}\" 中定義", "initMethodSignature": "__init__ 的簽章為 \"{type}\"", + "invariantSuggestionDict": "請考慮從「dict」切換到實值型別中共變數的「Mapping」", + "invariantSuggestionList": "請考慮從共變數的「list」切換到「Sequence」", "keyNotRequired": "\"{name}\" 在 \"{type}\" 中不是必要的索引鍵,因此存取可能會導致執行階段例外狀況", "keyReadOnly": "\"{name}\" 是 \"{type}\" 中的唯讀金鑰", "keyRequiredDeleted": "\"{name}\" 是必要的金鑰,因此不能刪除", @@ -632,6 +642,7 @@ "memberSetClassVar": "無法透過類別執行個體指派成員 \"{name}\",因為它是 ClassVar", "memberTypeMismatch": "\"{name}\" 是不相容的類型", "memberUnknown": "成員 \"{name}\" 未知", + "metaclassConflict": "Metaclass「{metaclass1}」與「{metaclass2}」衝突", "missingDeleter": "屬性 deleter 方法遺失", "missingGetter": "屬性 getter 方法遺失", "missingProtocolMember": "成員 \"{name}\" 已在通訊協定類別 \"{classType}\" 中宣告", @@ -643,10 +654,13 @@ "newMethodSignature": "__new__ 的簽章為 \"{type}\"", "noOverloadAssignable": "沒有任何多載函式符合類型 \"{type}\"", "orPatternMissingName": "遺失名稱: {name}", + "overloadIndex": "多載 {index} 是最接近的相符項目", "overloadNotAssignable": "\"{name}\" 的一或多個多載無法指派", "overloadSignature": "多載簽章在這裡定義", "overriddenMethod": "覆寫方法", "overriddenSymbol": "覆寫的符號", + "overrideInvariantMismatch": "覆寫類型 \"{overrideType}\" 與基底類型 \"{baseType}\" 不同", + "overrideIsInvariant": "變數是可變動的,所以其類型是不變的", "overrideNoOverloadMatches": "覆寫中沒有任何多載簽章與基底方法相容", "overrideNotClassMethod": "基底方法宣告為 classmethod,但無法覆寫", "overrideNotInstanceMethod": "基底方法已宣告為執行個體方法,但無法覆寫", @@ -708,6 +722,7 @@ "typeVarTupleRequiresKnownLength": "TypeVarTuple 無法繫結至長度不明的元組", "typeVarUnsolvableRemedy": "提供多載,其指定未提供引數時的傳回類型", "typeVarsMissing": "遺失類型變數: {names}", + "typedDictBaseClass": "類別 \"{type}\" 不是 TypedDict", "typedDictFieldMissing": "\"{type}\" 遺失 \"{name}\"", "typedDictFieldNotReadOnly": "\"{name}\" 在 \"{type}\" 中不是唯讀", "typedDictFieldNotRequired": "\"{type}\" 中不需要 \"{name}\"", diff --git a/packages/pyright-internal/src/parser/stringTokenUtils.ts b/packages/pyright-internal/src/parser/stringTokenUtils.ts index bbe8073e9..75318e83b 100644 --- a/packages/pyright-internal/src/parser/stringTokenUtils.ts +++ b/packages/pyright-internal/src/parser/stringTokenUtils.ts @@ -9,6 +9,7 @@ */ import { Char } from '../common/charCodes'; +import { maxStringTokenLength } from './tokenizer'; import { FStringMiddleToken, StringToken, StringTokenFlags } from './tokenizerTypes'; export const enum UnescapeErrorType { @@ -88,11 +89,14 @@ export function getUnescapedString(stringToken: StringToken | FStringMiddleToken const addInvalidEscapeOffset = () => { // Invalid escapes are not reported for raw strings. if (!isRaw) { - output.unescapeErrors.push({ - offset: strOffset - 1, - length: 2, - errorType: UnescapeErrorType.InvalidEscapeSequence, - }); + // If this is the last character of a truncated string, don't report. + if ((stringToken.flags & StringTokenFlags.ExceedsMaxSize) === 0 || strOffset < maxStringTokenLength) { + output.unescapeErrors.push({ + offset: strOffset - 1, + length: 2, + errorType: UnescapeErrorType.InvalidEscapeSequence, + }); + } } }; diff --git a/packages/pyright-internal/src/parser/tokenizer.ts b/packages/pyright-internal/src/parser/tokenizer.ts index 2816f65e4..e7a9df04b 100644 --- a/packages/pyright-internal/src/parser/tokenizer.ts +++ b/packages/pyright-internal/src/parser/tokenizer.ts @@ -141,10 +141,10 @@ const _operatorInfo: { [key: number]: OperatorFlags } = { const _byteOrderMarker = 0xfeff; -const _maxStringTokenLength = 32 * 1024; - const defaultTabSize = 8; +export const maxStringTokenLength = 32 * 1024; + export interface TokenizerOutput { // List of all tokens. tokens: TextRangeCollection; @@ -1631,7 +1631,7 @@ export class Tokenizer { } } } else if (this._cs.currentChar === Char.LineFeed || this._cs.currentChar === Char.CarriageReturn) { - if (!isTriplicate) { + if (!isTriplicate && !isFString) { // Unterminated single-line string flags |= StringTokenFlags.Unterminated; return { escapedValue: String.fromCharCode.apply(undefined, escapedValueParts), flags }; @@ -1691,8 +1691,8 @@ export class Tokenizer { // that is too long. Cut off the extra characters in this case to avoid // the crash. It's unlikely that the full string value will be used as // a string literal or a docstring, so this should be fine. - if (escapedValueParts.length > _maxStringTokenLength) { - escapedValueParts = escapedValueParts.slice(0, _maxStringTokenLength); + if (escapedValueParts.length > maxStringTokenLength) { + escapedValueParts = escapedValueParts.slice(0, maxStringTokenLength); flags |= StringTokenFlags.ExceedsMaxSize; } diff --git a/packages/pyright-internal/src/pyright.ts b/packages/pyright-internal/src/pyright.ts index 91167b1bd..4d23248fd 100644 --- a/packages/pyright-internal/src/pyright.ts +++ b/packages/pyright-internal/src/pyright.ts @@ -30,7 +30,7 @@ import { FileDiagnostics } from './common/diagnosticSink'; import { FullAccessHost } from './common/fullAccessHost'; import { combinePaths, normalizePath } from './common/pathUtils'; import { versionFromString } from './common/pythonVersion'; -import { createFromRealFileSystem } from './common/realFileSystem'; +import { RealTempFile, createFromRealFileSystem } from './common/realFileSystem'; import { Range, isEmptyRange } from './common/textRange'; import { PyrightFileSystem } from './pyrightFileSystem'; import { createServiceProvider } from './common/serviceProviderExtensions'; @@ -346,7 +346,8 @@ async function processArgs(): Promise { // up the JSON output, which goes to stdout. const output = args.outputjson ? new StderrConsole(logLevel) : new StandardConsole(logLevel); const fileSystem = new PyrightFileSystem(createFromRealFileSystem(output, new ChokidarFileWatcherProvider(output))); - const serviceProvider = createServiceProvider(fileSystem, output); + const tempFile = new RealTempFile(); + const serviceProvider = createServiceProvider(fileSystem, output, tempFile); // The package type verification uses a different path. if (args['verifytypes'] !== undefined) { diff --git a/packages/pyright-internal/src/pyrightFileSystem.ts b/packages/pyright-internal/src/pyrightFileSystem.ts index a3c8bc442..5240c6623 100644 --- a/packages/pyright-internal/src/pyrightFileSystem.ts +++ b/packages/pyright-internal/src/pyrightFileSystem.ts @@ -36,20 +36,7 @@ export namespace SupportPartialStubs { } } -export interface SupportUriToPathMapping { - hasUriMapEntry(uriString: string, mappedPath: string): boolean; - addUriMap(uriString: string, mappedPath: string): boolean; - removeUriMap(uriString: string, mappedPath: string): boolean; - pendingRequest(mappedPath: string, hasPendingRequest: boolean): void; -} - -export namespace SupportUriToPathMapping { - export function is(value: any): value is SupportUriToPathMapping { - return value.hasUriMapEntry && value.addUriMap && value.removeUriMap && value.pendingRequest; - } -} - -export interface IPyrightFileSystem extends FileSystem, SupportPartialStubs, SupportUriToPathMapping {} +export interface IPyrightFileSystem extends FileSystem, SupportPartialStubs {} export class PyrightFileSystem extends ReadOnlyAugmentedFileSystem implements IPyrightFileSystem { // Root paths processed @@ -58,8 +45,6 @@ export class PyrightFileSystem extends ReadOnlyAugmentedFileSystem implements IP // Partial stub package paths processed private readonly _partialStubPackagePaths = new Set(); - private readonly _customUriMap = new Map(); - constructor(realFS: FileSystem) { super(realFS); } @@ -93,69 +78,9 @@ export class PyrightFileSystem extends ReadOnlyAugmentedFileSystem implements IP } override getUri(originalPath: string): string { - const entry = this._customUriMap.get(this.getMappedFilePath(originalPath)); - if (entry) { - return entry.uri; - } - return this.realFS.getUri(originalPath); } - hasUriMapEntry(uriString: string, mappedPath: string): boolean { - const entry = this._customUriMap.get(mappedPath); - if (!entry || entry.uri !== uriString) { - // We don't support having 2 uri pointing to same file. - return false; - } - - return true; - } - - addUriMap(uriString: string, mappedPath: string): boolean { - const entry = this._customUriMap.get(mappedPath); - if (!entry) { - this._customUriMap.set(mappedPath, { uri: uriString, closed: false, hasPendingRequest: false }); - return true; - } - - if (entry.uri !== uriString) { - // We don't support having 2 uri pointing to same file. - return false; - } - - entry.closed = false; - return true; - } - - removeUriMap(uriString: string, mappedPath: string): boolean { - const entry = this._customUriMap.get(mappedPath); - if (!entry || entry.uri !== uriString) { - return false; - } - - if (entry.hasPendingRequest) { - entry.closed = true; - return true; - } - - this._customUriMap.delete(mappedPath); - return true; - } - - pendingRequest(mappedPath: string, hasPendingRequest: boolean): void { - const entry = this._customUriMap.get(mappedPath); - if (!entry) { - return; - } - - if (!hasPendingRequest && entry.closed) { - this._customUriMap.delete(mappedPath); - return; - } - - entry.hasPendingRequest = hasPendingRequest; - } - isPartialStubPackagesScanned(execEnv: ExecutionEnvironment): boolean { return this.isPathScanned(execEnv.root ?? ''); } @@ -237,10 +162,6 @@ export class PyrightFileSystem extends ReadOnlyAugmentedFileSystem implements IP } } - override dispose(): void { - this.realFS.dispose(); - } - clearPartialStubs(): void { super.clear(); diff --git a/packages/pyright-internal/src/readonlyAugmentedFileSystem.ts b/packages/pyright-internal/src/readonlyAugmentedFileSystem.ts index 275ffba00..2ed8b1c59 100644 --- a/packages/pyright-internal/src/readonlyAugmentedFileSystem.ts +++ b/packages/pyright-internal/src/readonlyAugmentedFileSystem.ts @@ -10,7 +10,7 @@ import type * as fs from 'fs'; import { appendArray, getOrAdd } from './common/collectionUtils'; -import { FileSystem, MkDirOptions, Stats, TmpfileOptions, VirtualDirent } from './common/fileSystem'; +import { FileSystem, MkDirOptions, Stats, VirtualDirent } from './common/fileSystem'; import { FileWatcher, FileWatcherEventHandler } from './common/fileWatcher'; import { combinePaths, ensureTrailingDirectorySeparator, getDirectoryPath, getFileName } from './common/pathUtils'; @@ -133,15 +133,6 @@ export class ReadOnlyAugmentedFileSystem implements FileSystem { return this.realFS.readFileText(this.getOriginalPath(path), encoding); } - // The directory returned by tmpdir must exist and be the same each time tmpdir is called. - tmpdir(): string { - return this.realFS.tmpdir(); - } - - tmpfile(options?: TmpfileOptions): string { - return this.realFS.tmpfile(options); - } - realCasePath(path: string): string { return this.realFS.realCasePath(path); } @@ -170,10 +161,6 @@ export class ReadOnlyAugmentedFileSystem implements FileSystem { return this.realFS.isInZip(path); } - dispose(): void { - this.realFS.dispose(); - } - protected recordMovedEntry(mappedPath: string, originalPath: string, reversible = true, isFile = true) { this._entryMap.set(mappedPath, originalPath); diff --git a/packages/pyright-internal/src/server.ts b/packages/pyright-internal/src/server.ts index de19f2e40..19a423ab7 100644 --- a/packages/pyright-internal/src/server.ts +++ b/packages/pyright-internal/src/server.ts @@ -16,6 +16,7 @@ import { } from 'vscode-languageserver'; import { AnalysisResults } from './analyzer/analysis'; +import { CacheManager } from './analyzer/cacheManager'; import { ImportResolver } from './analyzer/importResolver'; import { isPythonBinary } from './analyzer/pythonPathUtils'; import { BackgroundAnalysis } from './backgroundAnalysis'; @@ -31,7 +32,7 @@ import { FullAccessHost } from './common/fullAccessHost'; import { Host } from './common/host'; import { realCasePath, resolvePaths } from './common/pathUtils'; import { ProgressReporter } from './common/progressReporter'; -import { WorkspaceFileWatcherProvider, createFromRealFileSystem } from './common/realFileSystem'; +import { RealTempFile, WorkspaceFileWatcherProvider, createFromRealFileSystem } from './common/realFileSystem'; import { ServiceProvider } from './common/serviceProvider'; import { createServiceProvider } from './common/serviceProviderExtensions'; import { LanguageServerBase, ServerSettings } from './languageServerBase'; @@ -57,7 +58,10 @@ export class PyrightServer extends LanguageServerBase { const fileWatcherProvider = new WorkspaceFileWatcherProvider(); const fileSystem = createFromRealFileSystem(console, fileWatcherProvider); const pyrightFs = new PyrightFileSystem(fileSystem); - const serviceProvider = createServiceProvider(pyrightFs, console); + const tempFile = new RealTempFile(); + const cacheManager = new CacheManager(); + + const serviceProvider = createServiceProvider(pyrightFs, tempFile, console, cacheManager); const realPathRoot = realCasePath(rootDirectory, pyrightFs); super( @@ -167,6 +171,10 @@ export class PyrightServer extends LanguageServerBase { .map((p) => resolvePaths(workspace.rootPath, expandPathVariables(workspace.rootPath, p))); } + serverSettings.fileSpecs = this._getStringValues(pythonAnalysisSection.include); + serverSettings.excludeFileSpecs = this._getStringValues(pythonAnalysisSection.exclude); + serverSettings.ignoreFileSpecs = this._getStringValues(pythonAnalysisSection.ignore); + if (pythonAnalysisSection.typeCheckingMode !== undefined) { serverSettings.typeCheckingMode = pythonAnalysisSection.typeCheckingMode; } @@ -310,4 +318,12 @@ export class PyrightServer extends LanguageServerBase { }, }; } + + private _getStringValues(values: any) { + if (!values || !Array.isArray(values) || values.length === 0) { + return []; + } + + return values.filter((p) => p && isString(p)) as string[]; + } } diff --git a/packages/pyright-internal/src/tests/checker.test.ts b/packages/pyright-internal/src/tests/checker.test.ts index 0740cf1d9..2bf3780fd 100644 --- a/packages/pyright-internal/src/tests/checker.test.ts +++ b/packages/pyright-internal/src/tests/checker.test.ts @@ -568,3 +568,14 @@ test('Deprecated3', () => { const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated3.py'], configOptions); TestUtils.validateResults(analysisResults2, 5); }); + +test('Deprecated4', () => { + const configOptions = new ConfigOptions('.'); + + const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['deprecated4.py'], configOptions); + TestUtils.validateResults(analysisResults1, 0, 0, 0, undefined, undefined, 6); + + configOptions.diagnosticRuleSet.reportDeprecated = 'error'; + const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['deprecated4.py'], configOptions); + TestUtils.validateResults(analysisResults2, 6); +}); diff --git a/packages/pyright-internal/src/tests/config.test.ts b/packages/pyright-internal/src/tests/config.test.ts index 56d216862..5bdb652db 100644 --- a/packages/pyright-internal/src/tests/config.test.ts +++ b/packages/pyright-internal/src/tests/config.test.ts @@ -193,7 +193,7 @@ test('FindExecEnv1', () => { test('PythonPlatform', () => { const cwd = normalizePath(process.cwd()); - const nullConsole = new NullConsole(); + const configOptions = new ConfigOptions(cwd); const json = JSON.parse(`{ @@ -206,7 +206,10 @@ test('PythonPlatform', () => { }]}`); const fs = new TestFileSystem(/* ignoreCase */ false); - configOptions.initializeFromJson(json, undefined, nullConsole, fs, new NoAccessHost()); + const nullConsole = new NullConsole(); + + const sp = createServiceProvider(fs, nullConsole); + configOptions.initializeFromJson(json, undefined, sp, new NoAccessHost()); const env = configOptions.executionEnvironments[0]; assert.strictEqual(env.pythonPlatform, 'platform'); @@ -323,7 +326,8 @@ test('verify config fileSpecs after cloning', () => { }; const config = new ConfigOptions(process.cwd()); - config.initializeFromJson(configFile, undefined, new NullConsole(), fs, new TestAccessHost()); + const sp = createServiceProvider(fs, new NullConsole()); + config.initializeFromJson(configFile, undefined, sp, new TestAccessHost()); const cloned = createConfigOptionsFrom(config); assert.deepEqual(config.ignore, cloned.ignore); diff --git a/packages/pyright-internal/src/tests/documentSymbolCollector.test.ts b/packages/pyright-internal/src/tests/documentSymbolCollector.test.ts index e5db1ff3c..4bf83a5ad 100644 --- a/packages/pyright-internal/src/tests/documentSymbolCollector.test.ts +++ b/packages/pyright-internal/src/tests/documentSymbolCollector.test.ts @@ -6,19 +6,8 @@ * Tests documentSymbolCollector */ -import assert from 'assert'; -import { CancellationToken } from 'vscode-languageserver'; - -import { findNodeByOffset } from '../analyzer/parseTreeUtils'; -import { Program } from '../analyzer/program'; -import { createMapFromItems } from '../common/collectionUtils'; -import { ConfigOptions } from '../common/configOptions'; -import { isArray } from '../common/core'; -import { TextRange } from '../common/textRange'; -import { DocumentSymbolCollector, DocumentSymbolCollectorUseCase } from '../languageService/documentSymbolCollector'; -import { NameNode } from '../parser/parseNodes'; -import { Range } from './harness/fourslash/fourSlashTypes'; import { parseAndGetTestState } from './harness/fourslash/testState'; +import { verifyReferencesAtPosition } from './testStateUtils'; test('folder reference', () => { const code = ` @@ -408,443 +397,3 @@ test('string in __all__', () => { const ranges1 = state.getRangesByText().get('A')!; verifyReferencesAtPosition(state.program, state.configOptions, 'A', marker1.fileName, marker1.position, ranges1); }); - -test('overridden symbols test', () => { - const code = ` -// @filename: test.py -//// class B: -//// def [|foo|](self): -//// pass -//// -//// class C(B): -//// def [|foo|](self): -//// pass -//// -//// B().[|foo|]() -//// C().[|foo|]() - `; - - const state = parseAndGetTestState(code).state; - - const ranges = state.getRangesByText().get('foo')!; - for (const range of ranges) { - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', range.fileName, range.pos, ranges); - } -}); - -test('overridden symbols multi inheritance test', () => { - const code = ` -// @filename: test.py -//// class A: -//// def [|foo|](self): -//// pass -//// -//// class B: -//// def [|foo|](self): -//// pass -//// -//// class C(A, B): -//// def [|/*marker*/foo|](self): -//// pass -//// -//// A().[|foo|]() -//// B().[|foo|]() -//// C().[|foo|]() - `; - - const state = parseAndGetTestState(code).state; - - const marker = state.getMarkerByName('marker'); - const ranges = state.getRangesByText().get('foo')!; - - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', marker.fileName, marker.position, ranges); -}); - -test('__init__ test', () => { - const code = ` -// @filename: test.py -//// class A: -//// def __init__(self): -//// pass -//// -//// class B: -//// def __init__(self): -//// pass -//// -//// class C(A, B): -//// def [|/*marker*/__init__|](self): -//// pass -//// -//// A() -//// B() -//// [|C|]() - `; - - const state = parseAndGetTestState(code).state; - - const marker = state.getMarkerByName('marker'); - const ranges = state.getRangesByText().get('__init__')!; - ranges.push(...state.getRangesByText().get('C')!); - - verifyReferencesAtPosition( - state.program, - state.configOptions, - ['__init__', 'C'], - marker.fileName, - marker.position, - ranges - ); -}); - -test('super __init__ test', () => { - const code = ` -// @filename: test.py -//// class A: -//// def [|__init__|](self): -//// pass -//// -//// class B: -//// def __init__(self): -//// pass -//// -//// class C(A, B): -//// def __init__(self): -//// super().[|/*marker*/__init__|]() -//// pass -//// -//// [|A|]() -//// B() -//// C() - `; - - const state = parseAndGetTestState(code).state; - - const marker = state.getMarkerByName('marker'); - const ranges = state.getRangesByText().get('__init__')!; - ranges.push(...state.getRangesByText().get('A')!); - - verifyReferencesAtPosition( - state.program, - state.configOptions, - ['__init__', 'A'], - marker.fileName, - marker.position, - ranges - ); -}); - -test('__init__ internal class test', () => { - const code = ` -// @filename: test.py -//// class A: -//// def __init__(self): -//// class A_inner: -//// def [|/*marker*/__init__|](self): -//// pass -//// self.inner = [|A_inner|]() -//// -//// -//// class B: -//// def __init__(self): -//// pass -//// -//// class C(A, B): -//// def __init__(self): -//// pass -//// -//// A() -//// B() -//// C() - `; - - const state = parseAndGetTestState(code).state; - - const marker = state.getMarkerByName('marker'); - const ranges = state.getRangesByText().get('__init__')!; - ranges.push(...state.getRangesByText().get('A_inner')!); - - verifyReferencesAtPosition( - state.program, - state.configOptions, - ['__init__', 'A_inner'], - marker.fileName, - marker.position, - ranges - ); -}); - -test('overridden symbols multi inheritance with multiple base with same name test', () => { - const code = ` -// @filename: test.py -//// class A: -//// def [|/*marker*/foo|](self): -//// pass -//// -//// class B: -//// def foo(self): -//// pass -//// -//// class C(A, B): -//// def [|foo|](self): -//// pass -//// -//// A().[|foo|]() -//// B().foo() -//// C().[|foo|]() - `; - - const state = parseAndGetTestState(code).state; - - const marker = state.getMarkerByName('marker'); - const ranges = state.getRangesByText().get('foo')!; - - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', marker.fileName, marker.position, ranges); -}); - -test('protocol member symbol test', () => { - const code = ` -// @filename: test.py -//// from typing import Protocol -//// -//// class A: -//// def foo(self): -//// pass -//// -//// class P(Protocol): -//// def [|foo|](self): ... -//// -//// def foo(p: P): -//// p.[|/*marker*/foo|]() -//// -//// foo(A().foo()) - `; - - const state = parseAndGetTestState(code).state; - - const marker = state.getMarkerByName('marker'); - const ranges = state.getRangesByText().get('foo')!; - - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', marker.fileName, marker.position, ranges); -}); - -test('overridden symbols nested inheritance test', () => { - const code = ` -// @filename: test.py -//// class A: -//// def [|foo|](self): -//// pass -//// -//// class B(A): -//// def [|foo|](self): -//// pass -//// -//// class C(B): -//// def [|foo|](self): -//// pass -//// -//// A().[|foo|]() -//// B().[|foo|]() -//// C().[|foo|]() - `; - - const state = parseAndGetTestState(code).state; - - const ranges = state.getRangesByText().get('foo')!; - for (const range of ranges) { - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', range.fileName, range.pos, ranges); - } -}); - -test('overridden symbols nested inheritance no direct override test', () => { - const code = ` -// @filename: test.py -//// class A: -//// def [|foo|](self): -//// pass -//// -//// class B(A): -//// def [|foo|](self): -//// pass -//// -//// class C(B): -//// pass -//// -//// A().[|foo|]() -//// B().[|foo|]() -//// C().[|foo|]() - `; - - const state = parseAndGetTestState(code).state; - - const ranges = state.getRangesByText().get('foo')!; - for (const range of ranges) { - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', range.fileName, range.pos, ranges); - } -}); - -test('overridden symbols different type test', () => { - const code = ` -// @filename: test.py -//// class A: -//// def [|foo|](self): -//// pass -//// -//// class B: -//// foo: int -//// -//// class C(A, B): -//// def [|foo|](self): -//// pass -//// -//// A().[|foo|]() -//// B().foo = 1 -//// C().[|/*marker*/foo|]() - `; - - const state = parseAndGetTestState(code).state; - - const marker = state.getMarkerByName('marker'); - const ranges = state.getRangesByText().get('foo')!; - - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', marker.fileName, marker.position, ranges); -}); - -test('overridden and overloaded symbol test', () => { - const code = ` -// @filename: test.py -//// from typing import overload -//// -//// class A: -//// def [|foo|](self): -//// pass -//// -//// class B(A): -//// @overload -//// def [|foo|](self): -//// pass -//// @overload -//// def [|foo|](self, a): -//// pass -//// -//// A().[|foo|]() -//// B().[|foo|](1) - `; - - const state = parseAndGetTestState(code).state; - - const ranges = state.getRangesByText().get('foo')!; - for (const range of ranges) { - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', range.fileName, range.pos, ranges); - } -}); - -test('library method override test', () => { - const code = ` -// @filename: test.py -//// from lib import BaseType -//// -//// class A(BaseType): -//// def [|foo|](self): -//// pass -//// -//// A().[|foo|]() - -// @filename: lib/__init__.py -// @library: true -//// class BaseType: -//// def foo(self): -//// pass - `; - - const state = parseAndGetTestState(code).state; - - const ranges = state.getRangesByText().get('foo')!; - for (const range of ranges) { - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', range.fileName, range.pos, ranges); - } -}); - -test('variable overridden test 1', () => { - const code = ` -// @filename: test.py -//// class A: -//// [|foo|] = 1 -//// -//// class B(A): -//// foo = 2 -//// -//// a = A().[|foo|] -//// b = B().foo - `; - - const state = parseAndGetTestState(code).state; - - const ranges = state.getRangesByText().get('foo')!; - for (const range of ranges) { - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', range.fileName, range.pos, ranges); - } -}); - -test('variable overridden test 2', () => { - const code = ` -// @filename: test.py -//// class A: -//// foo = 1 -//// -//// class B(A): -//// [|foo|] = 2 -//// -//// a = A().foo -//// b = B().[|foo|] - `; - - const state = parseAndGetTestState(code).state; - - const ranges = state.getRangesByText().get('foo')!; - for (const range of ranges) { - verifyReferencesAtPosition(state.program, state.configOptions, 'foo', range.fileName, range.pos, ranges); - } -}); - -function verifyReferencesAtPosition( - program: Program, - configOption: ConfigOptions, - symbolNames: string | string[], - fileName: string, - position: number, - ranges: Range[] -) { - const sourceFile = program.getBoundSourceFile(fileName); - assert(sourceFile); - - const node = findNodeByOffset(sourceFile.getParseResults()!.parseTree, position); - const decls = DocumentSymbolCollector.getDeclarationsForNode( - program, - node as NameNode, - /* resolveLocalName */ true, - DocumentSymbolCollectorUseCase.Reference, - CancellationToken.None - ); - - const rangesByFile = createMapFromItems(ranges, (r) => r.fileName); - for (const rangeFileName of rangesByFile.keys()) { - const collector = new DocumentSymbolCollector( - program, - isArray(symbolNames) ? symbolNames : [symbolNames], - decls, - CancellationToken.None, - program.getBoundSourceFile(rangeFileName)!.getParseResults()!.parseTree, - /* treatModuleInImportAndFromImportSame */ true, - /* skipUnreachableCode */ false, - DocumentSymbolCollectorUseCase.Reference - ); - - const results = collector.collect(); - const rangesOnFile = rangesByFile.get(rangeFileName)!; - assert.strictEqual(results.length, rangesOnFile.length, `${rangeFileName}@${symbolNames}`); - - for (const result of results) { - assert(rangesOnFile.some((r) => r.pos === result.range.start && r.end === TextRange.getEnd(result.range))); - } - } -} diff --git a/packages/pyright-internal/src/tests/fourslash/completions.importInterimFile.fourslash.disabled.ts b/packages/pyright-internal/src/tests/fourslash/completions.importInterimFile.fourslash.disabled.ts new file mode 100644 index 000000000..615b3d752 --- /dev/null +++ b/packages/pyright-internal/src/tests/fourslash/completions.importInterimFile.fourslash.disabled.ts @@ -0,0 +1,52 @@ +/// + +// @filename: test1.py +//// import al[|/*marker1*/|] + +// @filename: altair/__init__.py +// @library: true +//// """module docstring""" +//// +//// __all__ = [ "selection_interval" ] +//// +//// from .vegalite import ( +//// selection, +//// selection_interval +//// ) + +// @filename: altair/vegalite/__init__.py +// @library: true +//// def selection(): pass +//// def selection_interval(): pass + +// @filename: altair/py.typed +// @library: true +//// # has to contain something for file to be written + +{ + // Force interim file to be created + // @ts-ignore + await helper.verifyCompletion('included', 'markdown', { + marker1: { + completions: [ + { label: 'altair', kind: Consts.CompletionItemKind.Module, documentation: 'module docstring' }, + ], + }, + }); + + helper.replace(helper.BOF, helper.getMarkerByName('marker1').position, 'import altair as alt\n\nalt.'); + + // @ts-ignore + await helper.verifyCompletion('included', 'markdown', { + marker1: { + completions: [{ label: 'selection_interval', kind: Consts.CompletionItemKind.Function }], + }, + }); + + // @ts-ignore + await helper.verifyCompletion('excluded', 'markdown', { + marker1: { + completions: [{ label: 'selection', kind: Consts.CompletionItemKind.Function }], + }, + }); +} diff --git a/packages/pyright-internal/src/tests/fourslash/completions.indexer.keys.getitem.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/completions.indexer.keys.getitem.fourslash.ts index c88e81ed3..28c9a5332 100644 --- a/packages/pyright-internal/src/tests/fourslash/completions.indexer.keys.getitem.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/completions.indexer.keys.getitem.fourslash.ts @@ -1,20 +1,34 @@ /// // @filename: getitem.py -//// from typing import Literal -//// class Foo: +//// from typing import Literal, Generic, TypeVar, overload +//// class ClassA: //// def __getitem__(self, key: Literal['a', 'b']): //// pass +//// T = TypeVar("T") +//// class ClassB(Generic[T]): +//// @overload +//// def __getitem__(self, key: T): +//// pass +//// @overload +//// def __getitem__(self, key: Literal['foo']): +//// pass // @filename: test1.py -//// from getitem import Foo -//// f = Foo() -//// f[[|/*marker1*/|]] +//// from typing import Literal +//// from getitem import ClassA, ClassB +//// a = ClassA() +//// a[[|/*marker1*/|]] +//// b = ClassB[Literal['x']]() +//// b[[|/*marker2*/|]] // @filename: test2.py -//// from getitem import Foo -//// f = Foo() -//// f[[|"/*marker2*/"|]] +//// from typing import Literal +//// from getitem import ClassA, ClassB +//// a = ClassA() +//// a[[|"/*marker3*/"|]] +//// b = ClassB[Literal['x']]() +//// b[[|"/*marker4*/"|]] { helper.openFiles(helper.getMarkers().map((m) => m.fileName)); @@ -38,17 +52,49 @@ ], }, marker2: { + completions: [ + { + label: "'x'", + kind: Consts.CompletionItemKind.Constant, + textEdit: { range: helper.getPositionRange('marker2'), newText: "'x'" }, + detail: Consts.IndexValueDetail, + }, + { + label: "'foo'", + kind: Consts.CompletionItemKind.Constant, + textEdit: { range: helper.getPositionRange('marker2'), newText: "'foo'" }, + detail: Consts.IndexValueDetail, + }, + ], + }, + marker3: { completions: [ { label: '"a"', kind: Consts.CompletionItemKind.Constant, - textEdit: { range: helper.getPositionRange('marker2'), newText: '"a"' }, + textEdit: { range: helper.getPositionRange('marker3'), newText: '"a"' }, detail: Consts.IndexValueDetail, }, { label: '"b"', kind: Consts.CompletionItemKind.Constant, - textEdit: { range: helper.getPositionRange('marker2'), newText: '"b"' }, + textEdit: { range: helper.getPositionRange('marker3'), newText: '"b"' }, + detail: Consts.IndexValueDetail, + }, + ], + }, + marker4: { + completions: [ + { + label: '"x"', + kind: Consts.CompletionItemKind.Constant, + textEdit: { range: helper.getPositionRange('marker4'), newText: '"x"' }, + detail: Consts.IndexValueDetail, + }, + { + label: '"foo"', + kind: Consts.CompletionItemKind.Constant, + textEdit: { range: helper.getPositionRange('marker4'), newText: '"foo"' }, detail: Consts.IndexValueDetail, }, ], diff --git a/packages/pyright-internal/src/tests/fourslash/completions.wildcardimports.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/completions.wildcardimports.fourslash.ts index e2ba11c1c..3b3aa7b16 100644 --- a/packages/pyright-internal/src/tests/fourslash/completions.wildcardimports.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/completions.wildcardimports.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: lib1/definition.py // @library: true //// def func(): diff --git a/packages/pyright-internal/src/tests/fourslash/findDefinitions.classes.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/findDefinitions.classes.fourslash.ts index 0e3413667..01606096b 100644 --- a/packages/pyright-internal/src/tests/fourslash/findDefinitions.classes.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/findDefinitions.classes.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: testLib1/__init__.pyi // @library: true //// class C: ... diff --git a/packages/pyright-internal/src/tests/fourslash/findDefinitions.fields.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/findDefinitions.fields.fourslash.ts index e0fa1a8b6..f4a1eeab7 100644 --- a/packages/pyright-internal/src/tests/fourslash/findDefinitions.fields.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/findDefinitions.fields.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: testLib1/__init__.pyi // @library: true //// from typing import ClassVar diff --git a/packages/pyright-internal/src/tests/fourslash/findDefinitions.functions.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/findDefinitions.functions.fourslash.ts index 2a172d4c3..8b25643a4 100644 --- a/packages/pyright-internal/src/tests/fourslash/findDefinitions.functions.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/findDefinitions.functions.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: testLib1/__init__.pyi // @library: true //// def C(): ... diff --git a/packages/pyright-internal/src/tests/fourslash/findDefinitions.methods.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/findDefinitions.methods.fourslash.ts index 8383803a1..5b1c983ef 100644 --- a/packages/pyright-internal/src/tests/fourslash/findDefinitions.methods.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/findDefinitions.methods.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: testLib1/__init__.pyi // @library: true //// from typing import overload diff --git a/packages/pyright-internal/src/tests/fourslash/findDefinitions.parameters.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/findDefinitions.parameters.fourslash.ts index 060a406e8..27f850b1c 100644 --- a/packages/pyright-internal/src/tests/fourslash/findDefinitions.parameters.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/findDefinitions.parameters.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: testLib1/__init__.pyi // @library: true //// from typing import overload diff --git a/packages/pyright-internal/src/tests/fourslash/findDefinitions.variables.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/findDefinitions.variables.fourslash.ts index 817f3cc76..75dbe8c2a 100644 --- a/packages/pyright-internal/src/tests/fourslash/findDefinitions.variables.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/findDefinitions.variables.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: testLib1/__init__.pyi // @library: true //// C = ... diff --git a/packages/pyright-internal/src/tests/fourslash/findDefinitions.wildcardimports.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/findDefinitions.wildcardimports.fourslash.ts index e8b37b13a..368982e61 100644 --- a/packages/pyright-internal/src/tests/fourslash/findDefinitions.wildcardimports.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/findDefinitions.wildcardimports.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: lib1/definition.py // @library: true //// def [|func|](): diff --git a/packages/pyright-internal/src/tests/fourslash/findTypeDefinitions.classes.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/findTypeDefinitions.classes.fourslash.ts index 88c7a52f1..e9cf8f459 100644 --- a/packages/pyright-internal/src/tests/fourslash/findTypeDefinitions.classes.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/findTypeDefinitions.classes.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: testLib1/__init__.pyi // @library: true //// class [|C|]: ... diff --git a/packages/pyright-internal/src/tests/fourslash/fourslash.ts b/packages/pyright-internal/src/tests/fourslash/fourslash.ts index ea9813142..4dcd4ac61 100644 --- a/packages/pyright-internal/src/tests/fourslash/fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/fourslash.ts @@ -234,6 +234,8 @@ declare namespace _ { ): Range[]; getPositionRange(markerString: string): PositionRange; getPosition(markerString: string): Position; + get BOF(): number; + get EOF(): number; expandPositionRange(range: PositionRange, start: number, end: number): PositionRange; convertPositionRange(range: Range): PositionRange; convertPathToUri(path: string): string; @@ -347,11 +349,11 @@ declare namespace _ { isUntitled?: boolean ): void; + replace(start: number, length: number, text: string): void; + /* not tested yet paste(text: string): void; - type(text: string): void; - replace(start: number, length: number, text: string): void; deleteChar(count: number): void; deleteLineRange(startIndex: number, endIndexInclusive: number): void; deleteCharBehindMarker(count: number): void; diff --git a/packages/pyright-internal/src/tests/fourslash/hover.class.docString.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/hover.class.docString.fourslash.ts index d0244358d..125c16014 100644 --- a/packages/pyright-internal/src/tests/fourslash/hover.class.docString.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/hover.class.docString.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: test.py //// import lib //// diff --git a/packages/pyright-internal/src/tests/fourslash/hover.docFromSrc.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/hover.docFromSrc.fourslash.ts index 09dc75aa5..670bcdd10 100644 --- a/packages/pyright-internal/src/tests/fourslash/hover.docFromSrc.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/hover.docFromSrc.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: module1.py //// '''module1 docs''' //// diff --git a/packages/pyright-internal/src/tests/fourslash/hover.docFromScr.stringFormat.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/hover.docFromSrc.stringFormat.fourslash.ts similarity index 100% rename from packages/pyright-internal/src/tests/fourslash/hover.docFromScr.stringFormat.fourslash.ts rename to packages/pyright-internal/src/tests/fourslash/hover.docFromSrc.stringFormat.fourslash.ts diff --git a/packages/pyright-internal/src/tests/fourslash/hover.unpackedTypedDict.key.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/hover.unpackedTypedDict.key.fourslash.ts new file mode 100644 index 000000000..f6b0edce3 --- /dev/null +++ b/packages/pyright-internal/src/tests/fourslash/hover.unpackedTypedDict.key.fourslash.ts @@ -0,0 +1,24 @@ +/// + +// @filename: test.py +//// from typing import TypedDict, Unpack +//// +//// class User(TypedDict): +//// name: str +//// """The fullname of the User""" +//// +//// age: int +//// """The age of the User, will not be over 200""" +//// +//// def foo(**user: Unpack[User]) -> None: +//// ... +//// +//// foo(name='Robert', [|/*marker1*/age|]=100) +//// foo(name='Robert', [|/*marker2*/age|]=) +//// foo([|/*marker3*/name|]='Robert') + +helper.verifyHover('markdown', { + marker1: '```python\n(variable) age: int\n```\n---\nThe age of the User, will not be over 200', + marker2: '```python\n(variable) age: int\n```\n---\nThe age of the User, will not be over 200', + marker3: '```python\n(variable) name: str\n```\n---\nThe fullname of the User', +}); diff --git a/packages/pyright-internal/src/tests/fourslash/hover.wildcardimports.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/hover.wildcardimports.fourslash.ts index aed7ab929..63c634efe 100644 --- a/packages/pyright-internal/src/tests/fourslash/hover.wildcardimports.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/hover.wildcardimports.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: lib1/definition.py // @library: true //// def func(): diff --git a/packages/pyright-internal/src/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.ts deleted file mode 100644 index ddaa50e32..000000000 --- a/packages/pyright-internal/src/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.ts +++ /dev/null @@ -1,41 +0,0 @@ -/// - -// @filename: callHierarchy.py -//// import abc -//// -//// class Base(abc.ABC): -//// @abc.abstractmethod -//// def method(self): -//// pass -//// -//// class Derived(Base): -//// def method(self): -//// pass -//// -//// class BaseConsumer: -//// def [|consumer_base|](self, base: Base): -//// base./*marker1*/method() -//// -//// class DerivedConsumer: -//// def [|consumer_derived|](self, derived: Derived): -//// derived./*marker2*/method() - -{ - const ranges = helper.getRanges(); - const references = ranges.map((range) => { - return { path: range.fileName, range: helper.convertPositionRange(range) }; - }); - const itemList = [ - { filePath: references[0].path, range: references[0].range, name: 'consumer_base' }, - { filePath: references[1].path, range: references[1].range, name: 'consumer_derived' }, - ]; - - helper.verifyShowCallHierarchyGetIncomingCalls({ - marker1: { - items: itemList, - }, - marker2: { - items: itemList, - }, - }); -} diff --git a/packages/pyright-internal/src/tests/fourslash/signature.docstrings.wildcardimports.fourslash.ts b/packages/pyright-internal/src/tests/fourslash/signature.docstrings.wildcardimports.fourslash.ts index 07aa4e62e..93efefcc8 100644 --- a/packages/pyright-internal/src/tests/fourslash/signature.docstrings.wildcardimports.fourslash.ts +++ b/packages/pyright-internal/src/tests/fourslash/signature.docstrings.wildcardimports.fourslash.ts @@ -1,5 +1,10 @@ /// +// @filename: pyrightconfig.json +//// { +//// "useLibraryCodeForTypes": true +//// } + // @filename: lib1/definition.py // @library: true //// def func(): diff --git a/packages/pyright-internal/src/tests/harness/fourslash/testLanguageService.ts b/packages/pyright-internal/src/tests/harness/fourslash/testLanguageService.ts index b32e2e268..26d4598ee 100644 --- a/packages/pyright-internal/src/tests/harness/fourslash/testLanguageService.ts +++ b/packages/pyright-internal/src/tests/harness/fourslash/testLanguageService.ts @@ -13,7 +13,6 @@ import { BackgroundAnalysisProgram, BackgroundAnalysisProgramFactory, } from '../../../analyzer/backgroundAnalysisProgram'; -import { CacheManager } from '../../../analyzer/cacheManager'; import { ImportResolver, ImportResolverFactory } from '../../../analyzer/importResolver'; import { MaxAnalysisTime } from '../../../analyzer/program'; import { AnalyzerService } from '../../../analyzer/service'; @@ -45,8 +44,7 @@ export class TestFeatures implements HostSpecificFeatures { configOptions: ConfigOptions, importResolver: ImportResolver, backgroundAnalysis?: BackgroundAnalysisBase, - maxAnalysisTime?: MaxAnalysisTime, - cacheManager?: CacheManager + maxAnalysisTime?: MaxAnalysisTime ) => new BackgroundAnalysisProgram( serviceId, @@ -55,8 +53,7 @@ export class TestFeatures implements HostSpecificFeatures { importResolver, backgroundAnalysis, maxAnalysisTime, - /* disableChecker */ undefined, - cacheManager + /* disableChecker */ undefined ); runIndexer(workspace: Workspace, noStdLib: boolean, options?: string): void { diff --git a/packages/pyright-internal/src/tests/harness/fourslash/testState.ts b/packages/pyright-internal/src/tests/harness/fourslash/testState.ts index 23f828a5b..44062293d 100644 --- a/packages/pyright-internal/src/tests/harness/fourslash/testState.ts +++ b/packages/pyright-internal/src/tests/harness/fourslash/testState.ts @@ -18,6 +18,7 @@ import { DocumentHighlight, DocumentHighlightKind, ExecuteCommandParams, + Location, MarkupContent, MarkupKind, TextEdit, @@ -37,6 +38,7 @@ import { Comparison, isNumber, isString, toBoolean } from '../../../common/core' import * as debug from '../../../common/debug'; import { DiagnosticCategory } from '../../../common/diagnostic'; import { FileEditAction } from '../../../common/editAction'; +import { ReadOnlyFileSystem } from '../../../common/fileSystem'; import { combinePaths, convertPathToUri, @@ -48,6 +50,9 @@ import { setTestingMode, } from '../../../common/pathUtils'; import { convertOffsetToPosition, convertPositionToOffset } from '../../../common/positionUtils'; +import { ServiceProvider } from '../../../common/serviceProvider'; +import { createServiceProvider } from '../../../common/serviceProviderExtensions'; +import { compareStringsCaseInsensitive, compareStringsCaseSensitive } from '../../../common/stringUtils'; import { DocumentRange, Position, Range as PositionRange, TextRange, rangesAreEqual } from '../../../common/textRange'; import { TextRangeCollection } from '../../../common/textRangeCollection'; import { convertToWorkspaceEdit } from '../../../common/workspaceEditUtils'; @@ -60,6 +65,7 @@ import { TypeDefinitionProvider, } from '../../../languageService/definitionProvider'; import { DocumentHighlightProvider } from '../../../languageService/documentHighlightProvider'; +import { CollectionResult } from '../../../languageService/documentSymbolCollector'; import { HoverProvider } from '../../../languageService/hoverProvider'; import { convertDocumentRangesToLocation } from '../../../languageService/navigationUtils'; import { ReferencesProvider } from '../../../languageService/referencesProvider'; @@ -94,9 +100,6 @@ import { import { TestFeatures, TestLanguageService } from './testLanguageService'; import { createVfsInfoFromFourSlashData, getMarkerByName, getMarkerName, getMarkerNames } from './testStateUtils'; import { verifyWorkspaceEdit } from './workspaceEditTestUtils'; -import { ServiceProvider } from '../../../common/serviceProvider'; -import { createServiceProvider } from '../../../common/serviceProviderExtensions'; -import { compareStringsCaseInsensitive, compareStringsCaseSensitive } from '../../../common/stringUtils'; export interface TextChange { span: TextRange; @@ -166,23 +169,23 @@ export class TestState { mountPaths ); + this.fs = new PyrightFileSystem(this.testFS); this.console = new NullConsole(); + this.serviceProvider = createServiceProvider(this.testFS, this.fs, this.console); + this._cancellationToken = new TestCancellationToken(); this._hostSpecificFeatures = hostSpecificFeatures ?? new TestFeatures(); - this.fs = new PyrightFileSystem(this.testFS); this.files = vfsInfo.sourceFileNames; this.rawConfigJson = vfsInfo.rawConfigJson; const configOptions = this._convertGlobalOptionsToConfigOptions(vfsInfo.projectRoot, mountPaths); if (this.rawConfigJson) { - configOptions.initializeFromJson(this.rawConfigJson, 'basic', this.console, this.fs, testAccessHost); + configOptions.initializeFromJson(this.rawConfigJson, 'basic', this.serviceProvider, testAccessHost); this._applyTestConfigOptions(configOptions); } - this.serviceProvider = createServiceProvider(this.fs, this.console); - const service = this._createAnalysisService( this.console, this._hostSpecificFeatures.importResolverFactory, @@ -233,6 +236,16 @@ export class TestState { return this.workspace.service.test_program; } + // eslint-disable-next-line @typescript-eslint/naming-convention + get BOF(): number { + return 0; + } + + // eslint-disable-next-line @typescript-eslint/naming-convention + get EOF(): number { + return this.getFileContent(this.activeFile.fileName).length; + } + initializeFiles() { if (this.files.length > 0) { // Open the first file by default @@ -426,12 +439,11 @@ export class TestState { } goToBOF() { - this.goToPosition(0); + this.goToPosition(this.BOF); } goToEOF() { - const len = this.getFileContent(this.activeFile.fileName).length; - this.goToPosition(len); + this.goToPosition(this.EOF); } moveCaretRight(count = 1) { @@ -680,7 +692,7 @@ export class TestState { verifyMode: _.FourSlashVerificationMode, map: { [marker: string]: { - codeActions: { title: string; kind: string; command?: Command; edit?: WorkspaceEdit[] }[]; + codeActions: { title: string; kind: string; command?: Command; edit?: WorkspaceEdit }[]; }; } ): Promise { @@ -1136,16 +1148,20 @@ export class TestState { } } - verifyFindAllReferences(map: { - [marker: string]: { - references: DocumentRange[]; - }; - }) { + verifyFindAllReferences( + map: { + [marker: string]: { + references: DocumentRange[]; + }; + }, + createDocumentRange?: (filePath: string, result: CollectionResult, parseResults: ParseResults) => DocumentRange, + convertToLocation?: (fs: ReadOnlyFileSystem, ranges: DocumentRange) => Location | undefined + ) { this.analyze(); - for (const marker of this.getMarkers()) { + for (const name of this.getMarkerNames()) { + const marker = this.getMarkerByName(name); const fileName = marker.fileName; - const name = this.getMarkerName(marker); if (!(name in map)) { continue; @@ -1155,14 +1171,15 @@ export class TestState { const position = this.convertOffsetToPosition(fileName, marker.position); - const actual = new ReferencesProvider(this.program, CancellationToken.None).reportReferences( - fileName, - position, - /* includeDeclaration */ true - ); + const actual = new ReferencesProvider( + this.program, + CancellationToken.None, + createDocumentRange, + convertToLocation + ).reportReferences(fileName, position, /* includeDeclaration */ true); assert.strictEqual(actual?.length ?? 0, expected.length, `${name} has failed`); - for (const r of convertDocumentRangesToLocation(this.program.fileSystem, expected)) { + for (const r of convertDocumentRangesToLocation(this.program.fileSystem, expected, convertToLocation)) { assert.equal(actual?.filter((d) => this._deepEqual(d, r)).length, 1); } } @@ -1612,14 +1629,14 @@ export class TestState { configOptions.stubPath = normalizePath(combinePaths(vfs.MODULE_PATH, 'typings')); } - configOptions.include.push(getFileSpec(this.fs, configOptions.projectRoot, '.')); - configOptions.exclude.push(getFileSpec(this.fs, configOptions.projectRoot, typeshedFolder)); - configOptions.exclude.push(getFileSpec(this.fs, configOptions.projectRoot, distlibFolder)); - configOptions.exclude.push(getFileSpec(this.fs, configOptions.projectRoot, libFolder)); + configOptions.include.push(getFileSpec(this.serviceProvider, configOptions.projectRoot, '.')); + configOptions.exclude.push(getFileSpec(this.serviceProvider, configOptions.projectRoot, typeshedFolder)); + configOptions.exclude.push(getFileSpec(this.serviceProvider, configOptions.projectRoot, distlibFolder)); + configOptions.exclude.push(getFileSpec(this.serviceProvider, configOptions.projectRoot, libFolder)); if (mountPaths) { for (const mountPath of mountPaths.keys()) { - configOptions.exclude.push(getFileSpec(this.fs, configOptions.projectRoot, mountPath)); + configOptions.exclude.push(getFileSpec(this.serviceProvider, configOptions.projectRoot, mountPath)); } } @@ -1632,12 +1649,15 @@ export class TestState { private _getParseResult(fileName: string) { const file = this.program.getBoundSourceFile(fileName)!; - return file.getParseResults()!; + return file?.getParseResults(); } private _getTextRangeCollection(fileName: string): TextRangeCollection { - if (fileName in this.files) { - return this._getParseResult(fileName).tokenizerOutput.lines; + if (this.files.includes(fileName)) { + const parseResults = this._getParseResult(fileName); + if (parseResults) { + return parseResults.tokenizerOutput.lines; + } } // slow path @@ -1658,7 +1678,13 @@ export class TestState { } private _editScriptAndUpdateMarkers(fileName: string, editStart: number, editEnd: number, newText: string) { - // this.languageServiceAdapterHost.editScript(fileName, editStart, editEnd, newText); + let fileContent = this.getFileContent(fileName); + fileContent = fileContent.slice(0, editStart) + newText + fileContent.slice(editEnd); + + this.testFS.writeFileSync(fileName, fileContent, 'utf8'); + const newVersion = (this.program.getSourceFile(fileName)?.getClientVersion() ?? -1) + 1; + this.program.setFileOpened(fileName, newVersion, fileContent); + for (const marker of this.testData.markers) { if (marker.fileName === fileName) { marker.position = this._updatePosition(marker.position, editStart, editEnd, newText); diff --git a/packages/pyright-internal/src/tests/harness/vfs/filesystem.ts b/packages/pyright-internal/src/tests/harness/vfs/filesystem.ts index 7bd402ff9..471dd5891 100644 --- a/packages/pyright-internal/src/tests/harness/vfs/filesystem.ts +++ b/packages/pyright-internal/src/tests/harness/vfs/filesystem.ts @@ -10,7 +10,7 @@ import { Dirent, ReadStream, WriteStream } from 'fs'; import { URI } from 'vscode-uri'; -import { FileSystem, MkDirOptions, TmpfileOptions } from '../../../common/fileSystem'; +import { FileSystem, MkDirOptions, TempFile, TmpfileOptions } from '../../../common/fileSystem'; import { FileWatcher, FileWatcherEventHandler, FileWatcherEventType } from '../../../common/fileWatcher'; import * as pathUtil from '../../../common/pathUtils'; import { bufferFrom, createIOError } from '../utils'; @@ -49,7 +49,7 @@ export class TestFileSystemWatcher implements FileWatcher { /** * Represents a virtual POSIX-like file system. */ -export class TestFileSystem implements FileSystem { +export class TestFileSystem implements FileSystem, TempFile { /** Indicates whether the file system is case-sensitive (`false`) or case-insensitive (`true`). */ readonly ignoreCase: boolean; @@ -90,7 +90,7 @@ export class TestFileSystem implements FileSystem { } let cwd = options.cwd; - if ((!cwd || !pathUtil.isDiskPathRoot(cwd)) && this._lazy.links) { + if ((!cwd || (!pathUtil.isDiskPathRoot(cwd) && !pathUtil.isUri(cwd))) && this._lazy.links) { const iterator = getIterator(this._lazy.links.keys()); try { for (let i = nextResult(iterator); i; i = nextResult(iterator)) { @@ -383,6 +383,11 @@ export class TestFileSystem implements FileSystem { } getUri(path: string): string { + // If this is not a file path, just return the original path. + if (pathUtil.isUri(path)) { + return path; + } + return URI.file(path).toString(); } diff --git a/packages/pyright-internal/src/tests/harness/vfs/pathValidation.ts b/packages/pyright-internal/src/tests/harness/vfs/pathValidation.ts index f32bfdbc8..1af7b87f7 100644 --- a/packages/pyright-internal/src/tests/harness/vfs/pathValidation.ts +++ b/packages/pyright-internal/src/tests/harness/vfs/pathValidation.ts @@ -8,6 +8,7 @@ import { sep } from 'path'; import * as pu from '../../../common/pathUtils'; import { createIOError } from '../utils'; +import { URI } from 'vscode-uri'; const invalidRootComponentRegExp = getInvalidRootComponentRegExp(); const invalidNavigableComponentRegExp = /[:*?"<>|]/; @@ -123,7 +124,13 @@ function validateComponents(components: string[], flags: ValidationFlags, hasTra } // Validate component strings - if (invalidRootComponentRegExp.test(components[0])) { + if (pu.isUri(components[0])) { + try { + URI.parse(components[0]); + } catch { + return false; + } + } else if (invalidRootComponentRegExp.test(components[0])) { return false; } for (let i = 1; i < components.length; i++) { diff --git a/packages/pyright-internal/src/tests/importResolver.test.ts b/packages/pyright-internal/src/tests/importResolver.test.ts index e7490dd31..5c310f794 100644 --- a/packages/pyright-internal/src/tests/importResolver.test.ts +++ b/packages/pyright-internal/src/tests/importResolver.test.ts @@ -6,602 +6,678 @@ import assert from 'assert'; +import { Dirent, ReadStream, WriteStream } from 'fs'; import { ImportResolver } from '../analyzer/importResolver'; import { ConfigOptions } from '../common/configOptions'; +import { FileSystem, MkDirOptions, Stats } from '../common/fileSystem'; +import { FileWatcher, FileWatcherEventHandler } from '../common/fileWatcher'; +import { FullAccessHost } from '../common/fullAccessHost'; +import { Host } from '../common/host'; import { lib, sitePackages, typeshedFallback } from '../common/pathConsts'; import { combinePaths, getDirectoryPath, normalizeSlashes } from '../common/pathUtils'; +import { createFromRealFileSystem } from '../common/realFileSystem'; +import { ServiceProvider } from '../common/serviceProvider'; +import { createServiceProvider } from '../common/serviceProviderExtensions'; import { PyrightFileSystem } from '../pyrightFileSystem'; import { TestAccessHost } from './harness/testAccessHost'; import { TestFileSystem } from './harness/vfs/filesystem'; -import { ServiceProvider } from '../common/serviceProvider'; -import { createServiceProvider } from '../common/serviceProviderExtensions'; const libraryRoot = combinePaths(normalizeSlashes('/'), lib, sitePackages); -test('partial stub file exists', () => { - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'partialStub.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), - content: 'partial\n', - }, - { - path: combinePaths(libraryRoot, 'myLib', 'partialStub.py'), - content: 'def test(): pass', - }, - ]; - - const importResult = getImportResult(files, ['myLib', 'partialStub']); - assert(importResult.isImportFound); - assert(importResult.isStubFile); - assert.strictEqual( - 1, - importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', 'partialStub.pyi')).length - ); -}); +function usingTrueVenv() { + return process.env.CI_IMPORT_TEST_VENVPATH !== undefined || process.env.CI_IMPORT_TEST_PYTHONPATH !== undefined; +} -test('partial stub __init__ exists', () => { - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), - content: 'partial\n', - }, - { - path: combinePaths(libraryRoot, 'myLib', '__init__.py'), - content: 'def test(): pass', - }, - ]; - - const importResult = getImportResult(files, ['myLib']); - assert(importResult.isImportFound); - assert(importResult.isStubFile); - assert.strictEqual( - 1, - importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')).length - ); -}); +if (!usingTrueVenv()) { + describe('Import tests that cannot run in a true venv', () => { + test('partial stub file exists', () => { + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'partialStub.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), + content: 'partial\n', + }, + { + path: combinePaths(libraryRoot, 'myLib', 'partialStub.py'), + content: 'def test(): pass', + }, + ]; + + const importResult = getImportResult(files, ['myLib', 'partialStub']); + assert(importResult.isImportFound); + assert(importResult.isStubFile); + assert.strictEqual( + 1, + importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', 'partialStub.pyi')) + .length + ); + }); -test('side by side files', () => { - const myFile = combinePaths('src', 'file.py'); - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'partialStub.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), - content: 'partial\n', - }, - { - path: combinePaths(libraryRoot, 'myLib', 'partialStub.pyi'), - content: '# empty', - }, - { - path: combinePaths(libraryRoot, 'myLib', 'partialStub.py'), - content: 'def test(): pass', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'partialStub2.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'myLib', 'partialStub2.py'), - content: 'def test(): pass', - }, - { - path: myFile, - content: '# not used', - }, - ]; + test('partial stub __init__ exists', () => { + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), + content: 'partial\n', + }, + { + path: combinePaths(libraryRoot, 'myLib', '__init__.py'), + content: 'def test(): pass', + }, + ]; + + const importResult = getImportResult(files, ['myLib']); + assert(importResult.isImportFound); + assert(importResult.isStubFile); + assert.strictEqual( + 1, + importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')) + .length + ); + }); - const sp = createServiceProviderFromFiles(files); - const configOptions = new ConfigOptions(normalizeSlashes('/')); - const importResolver = new ImportResolver( - sp, - configOptions, - new TestAccessHost(sp.fs().getModulePath(), [libraryRoot]) - ); - - // Stub package wins over original package (per PEP 561 rules). - const sideBySideResult = importResolver.resolveImport(myFile, configOptions.findExecEnvironment(myFile), { - leadingDots: 0, - nameParts: ['myLib', 'partialStub'], - importedSymbols: new Set(), - }); + test('stub package', () => { + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'stub.pyi'), + content: '# empty', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), + content: '# empty', + }, + { + path: combinePaths(libraryRoot, 'myLib', 'partialStub.py'), + content: 'def test(): pass', + }, + ]; + + // If fully typed stub package exists, that wins over the real package. + const importResult = getImportResult(files, ['myLib', 'partialStub']); + assert(!importResult.isImportFound); + }); - assert(sideBySideResult.isImportFound); - assert(sideBySideResult.isStubFile); + test('partial stub package in typing folder', () => { + const typingFolder = combinePaths(normalizeSlashes('/'), 'typing'); + const files = [ + { + path: combinePaths(typingFolder, 'myLib-stubs', '__init__.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(typingFolder, 'myLib-stubs', 'py.typed'), + content: 'partial\n', + }, + { + path: combinePaths(libraryRoot, 'myLib', '__init__.py'), + content: 'def test(): pass', + }, + ]; + + const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = typingFolder)); + assert(importResult.isImportFound); + assert(importResult.isStubFile); + assert.strictEqual( + 1, + importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')) + .length + ); + }); - const sideBySideStubFile = combinePaths(libraryRoot, 'myLib', 'partialStub.pyi'); - assert.strictEqual(1, sideBySideResult.resolvedPaths.filter((f) => f === sideBySideStubFile).length); - assert.strictEqual('def test(): ...', sp.fs().readFileSync(sideBySideStubFile, 'utf8')); + test('typeshed folder', () => { + const typeshedFolder = combinePaths(normalizeSlashes('/'), 'ts'); + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), + content: 'partial\n', + }, + { + path: combinePaths(typeshedFolder, 'stubs', 'myLibPackage', 'myLib.pyi'), + content: '# empty', + }, + { + path: combinePaths(libraryRoot, 'myLib', '__init__.py'), + content: 'def test(): pass', + }, + ]; + + // Stub packages win over typeshed. + const importResult = getImportResult(files, ['myLib'], (c) => (c.typeshedPath = typeshedFolder)); + assert(importResult.isImportFound); + assert(importResult.isStubFile); + assert.strictEqual( + 1, + importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')) + .length + ); + }); - // Side by side stub doesn't completely disable partial stub. - const partialStubResult = importResolver.resolveImport(myFile, configOptions.findExecEnvironment(myFile), { - leadingDots: 0, - nameParts: ['myLib', 'partialStub2'], - importedSymbols: new Set(), - }); + test('typeshed fallback folder', () => { + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), + content: 'partial\n', + }, + { + path: combinePaths('/', typeshedFallback, 'stubs', 'myLibPackage', 'myLib.pyi'), + content: '# empty', + }, + { + path: combinePaths(libraryRoot, 'myLib', '__init__.py'), + content: 'def test(): pass', + }, + ]; + + // Stub packages win over typeshed. + const importResult = getImportResult(files, ['myLib']); + assert(importResult.isImportFound); + assert(importResult.isStubFile); + assert.strictEqual( + 1, + importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')) + .length + ); + }); - assert(partialStubResult.isImportFound); - assert(partialStubResult.isStubFile); + test('py.typed file', () => { + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), + content: 'partial\n', + }, + { + path: combinePaths(libraryRoot, 'myLib', '__init__.py'), + content: 'def test(): pass', + }, + { + path: combinePaths(libraryRoot, 'myLib', 'py.typed'), + content: '# typed', + }, + ]; + + // Partial stub package always overrides original package. + const importResult = getImportResult(files, ['myLib']); + assert(importResult.isImportFound); + assert(importResult.isStubFile); + }); - const partialStubFile = combinePaths(libraryRoot, 'myLib', 'partialStub2.pyi'); - assert.strictEqual(1, partialStubResult.resolvedPaths.filter((f) => f === partialStubFile).length); -}); + test('py.typed library', () => { + const files = [ + { + path: combinePaths(libraryRoot, 'os', '__init__.py'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'os', 'py.typed'), + content: '', + }, + { + path: combinePaths('/', typeshedFallback, 'stubs', 'os', 'os', '__init__.pyi'), + content: '# empty', + }, + ]; + + const importResult = getImportResult(files, ['os']); + assert(importResult.isImportFound); + assert.strictEqual(files[0].path, importResult.resolvedPaths[importResult.resolvedPaths.length - 1]); + }); -test('stub package', () => { - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'stub.pyi'), - content: '# empty', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), - content: '# empty', - }, - { - path: combinePaths(libraryRoot, 'myLib', 'partialStub.py'), - content: 'def test(): pass', - }, - ]; - - // If fully typed stub package exists, that wins over the real package. - const importResult = getImportResult(files, ['myLib', 'partialStub']); - assert(!importResult.isImportFound); -}); + test('import side by side file sub under lib folder', () => { + const files = [ + { + path: combinePaths('/lib/site-packages/myLib', 'file1.py'), + content: 'def test1(): ...', + }, + { + path: combinePaths('/lib/site-packages/myLib', 'file2.py'), + content: 'def test2(): ...', + }, + ]; + + const importResult = getImportResult(files, ['file1']); + assert(!importResult.isImportFound); + }); + }); +} +describe('Import tests that can run with or without a true venv', () => { + test('side by side files', () => { + const myFile = combinePaths('src', 'file.py'); + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'partialStub.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), + content: 'partial\n', + }, + { + path: combinePaths(libraryRoot, 'myLib', 'partialStub.pyi'), + content: '# empty', + }, + { + path: combinePaths(libraryRoot, 'myLib', 'partialStub.py'), + content: 'def test(): pass', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'partialStub2.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'myLib', 'partialStub2.py'), + content: 'def test(): pass', + }, + { + path: myFile, + content: '# not used', + }, + ]; + + const sp = createServiceProviderFromFiles(files); + const configOptions = new ConfigOptions(normalizeSlashes('/')); + const importResolver = new ImportResolver( + sp, + configOptions, + new TestAccessHost(sp.fs().getModulePath(), [libraryRoot]) + ); + + // Stub package wins over original package (per PEP 561 rules). + const sideBySideResult = importResolver.resolveImport(myFile, configOptions.findExecEnvironment(myFile), { + leadingDots: 0, + nameParts: ['myLib', 'partialStub'], + importedSymbols: new Set(), + }); -test('stub namespace package', () => { - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'stub.pyi'), - content: '# empty', - }, - { - path: combinePaths(libraryRoot, 'myLib', 'partialStub.py'), - content: 'def test(): pass', - }, - ]; - - // If fully typed stub package exists, that wins over the real package. - const importResult = getImportResult(files, ['myLib', 'partialStub']); - assert(importResult.isImportFound); - assert(!importResult.isStubFile); - assert.strictEqual( - 1, - importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', 'partialStub.py')).length - ); -}); + assert(sideBySideResult.isImportFound); + assert(sideBySideResult.isStubFile); -test('stub in typing folder over partial stub package', () => { - const typingFolder = combinePaths(normalizeSlashes('/'), 'typing'); - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), - content: 'partial\n', - }, - { - path: combinePaths(typingFolder, 'myLib.pyi'), - content: '# empty', - }, - { - path: combinePaths(libraryRoot, 'myLib', '__init__.py'), - content: 'def test(): pass', - }, - ]; - - // If the package exists in typing folder, that gets picked up first. - const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = typingFolder)); - assert(importResult.isImportFound); - assert(importResult.isStubFile); - assert.strictEqual( - 0, - importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')).length - ); -}); + const sideBySideStubFile = combinePaths(libraryRoot, 'myLib', 'partialStub.pyi'); + assert.strictEqual(1, sideBySideResult.resolvedPaths.filter((f) => f === sideBySideStubFile).length); + assert.strictEqual('def test(): ...', sp.fs().readFileSync(sideBySideStubFile, 'utf8')); -test('partial stub package in typing folder', () => { - const typingFolder = combinePaths(normalizeSlashes('/'), 'typing'); - const files = [ - { - path: combinePaths(typingFolder, 'myLib-stubs', '__init__.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(typingFolder, 'myLib-stubs', 'py.typed'), - content: 'partial\n', - }, - { - path: combinePaths(libraryRoot, 'myLib', '__init__.py'), - content: 'def test(): pass', - }, - ]; - - const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = typingFolder)); - assert(importResult.isImportFound); - assert(importResult.isStubFile); - assert.strictEqual( - 1, - importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')).length - ); -}); + // Side by side stub doesn't completely disable partial stub. + const partialStubResult = importResolver.resolveImport(myFile, configOptions.findExecEnvironment(myFile), { + leadingDots: 0, + nameParts: ['myLib', 'partialStub2'], + importedSymbols: new Set(), + }); -test('typeshed folder', () => { - const typeshedFolder = combinePaths(normalizeSlashes('/'), 'ts'); - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), - content: 'partial\n', - }, - { - path: combinePaths(typeshedFolder, 'stubs', 'myLibPackage', 'myLib.pyi'), - content: '# empty', - }, - { - path: combinePaths(libraryRoot, 'myLib', '__init__.py'), - content: 'def test(): pass', - }, - ]; - - // Stub packages win over typeshed. - const importResult = getImportResult(files, ['myLib'], (c) => (c.typeshedPath = typeshedFolder)); - assert(importResult.isImportFound); - assert(importResult.isStubFile); - assert.strictEqual( - 1, - importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')).length - ); -}); + assert(partialStubResult.isImportFound); + assert(partialStubResult.isStubFile); -test('typeshed fallback folder', () => { - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), - content: 'partial\n', - }, - { - path: combinePaths('/', typeshedFallback, 'stubs', 'myLibPackage', 'myLib.pyi'), - content: '# empty', - }, - { - path: combinePaths(libraryRoot, 'myLib', '__init__.py'), - content: 'def test(): pass', - }, - ]; - - // Stub packages win over typeshed. - const importResult = getImportResult(files, ['myLib']); - assert(importResult.isImportFound); - assert(importResult.isStubFile); - assert.strictEqual( - 1, - importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')).length - ); -}); + const partialStubFile = combinePaths(libraryRoot, 'myLib', 'partialStub2.pyi'); + assert.strictEqual(1, partialStubResult.resolvedPaths.filter((f) => f === partialStubFile).length); + }); -test('py.typed file', () => { - const files = [ - { - path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), - content: 'partial\n', - }, - { - path: combinePaths(libraryRoot, 'myLib', '__init__.py'), - content: 'def test(): pass', - }, - { - path: combinePaths(libraryRoot, 'myLib', 'py.typed'), - content: '# typed', - }, - ]; - - // Partial stub package always overrides original package. - const importResult = getImportResult(files, ['myLib']); - assert(importResult.isImportFound); - assert(importResult.isStubFile); -}); + test('stub namespace package', () => { + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'stub.pyi'), + content: '# empty', + }, + { + path: combinePaths(libraryRoot, 'myLib', 'partialStub.py'), + content: 'def test(): pass', + }, + ]; + + // If fully typed stub package exists, that wins over the real package. + const importResult = getImportResult(files, ['myLib', 'partialStub']); + assert(importResult.isImportFound); + assert(!importResult.isStubFile); + assert.strictEqual( + 1, + importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', 'partialStub.py')).length + ); + }); -test('py.typed library', () => { - const files = [ - { - path: combinePaths(libraryRoot, 'os', '__init__.py'), - content: 'def test(): ...', - }, - { - path: combinePaths(libraryRoot, 'os', 'py.typed'), - content: '', - }, - { - path: combinePaths('/', typeshedFallback, 'stubs', 'os', 'os', '__init__.pyi'), - content: '# empty', - }, - ]; - - const importResult = getImportResult(files, ['os']); - assert(importResult.isImportFound); - assert.strictEqual(files[0].path, importResult.resolvedPaths[importResult.resolvedPaths.length - 1]); -}); + test('stub in typing folder over partial stub package', () => { + const typingFolder = combinePaths(normalizeSlashes('/'), 'typing'); + const files = [ + { + path: combinePaths(libraryRoot, 'myLib-stubs', '__init__.pyi'), + content: 'def test(): ...', + }, + { + path: combinePaths(libraryRoot, 'myLib-stubs', 'py.typed'), + content: 'partial\n', + }, + { + path: combinePaths(typingFolder, 'myLib.pyi'), + content: '# empty', + }, + { + path: combinePaths(libraryRoot, 'myLib', '__init__.py'), + content: 'def test(): pass', + }, + ]; + + // If the package exists in typing folder, that gets picked up first. + const importResult = getImportResult(files, ['myLib'], (c) => (c.stubPath = typingFolder)); + assert(importResult.isImportFound); + assert(importResult.isStubFile); + assert.strictEqual( + 0, + importResult.resolvedPaths.filter((f) => f === combinePaths(libraryRoot, 'myLib', '__init__.pyi')).length + ); + }); -test('non py.typed library', () => { - const files = [ - { - path: combinePaths(libraryRoot, 'os', '__init__.py'), - content: 'def test(): ...', - }, - { - path: combinePaths('/', typeshedFallback, 'stubs', 'os', 'os', '__init__.pyi'), - content: '# empty', - }, - ]; - - const importResult = getImportResult(files, ['os']); - assert(importResult.isImportFound); - assert.strictEqual(files[1].path, importResult.resolvedPaths[importResult.resolvedPaths.length - 1]); -}); + test('non py.typed library', () => { + const files = [ + { + path: combinePaths(libraryRoot, 'os', '__init__.py'), + content: 'def test(): ...', + }, + { + path: combinePaths('/', typeshedFallback, 'stubs', 'os', 'os', '__init__.pyi'), + content: '# empty', + }, + ]; + + const importResult = getImportResult(files, ['os']); + assert(importResult.isImportFound); + assert.strictEqual(files[1].path, importResult.resolvedPaths[importResult.resolvedPaths.length - 1]); + }); -test('no empty import roots', () => { - const sp = createServiceProviderFromFiles([]); - const configOptions = new ConfigOptions(''); // Empty, like open-file mode. - const importResolver = new ImportResolver( - sp, - configOptions, - new TestAccessHost(sp.fs().getModulePath(), [libraryRoot]) - ); - importResolver.getImportRoots(configOptions.getDefaultExecEnvironment()).forEach((path) => assert(path)); -}); + test('no empty import roots', () => { + const sp = createServiceProviderFromFiles([]); + const configOptions = new ConfigOptions(''); // Empty, like open-file mode. + const importResolver = new ImportResolver( + sp, + configOptions, + new TestAccessHost(sp.fs().getModulePath(), [libraryRoot]) + ); + importResolver.getImportRoots(configOptions.getDefaultExecEnvironment()).forEach((path) => assert(path)); + }); -test('multiple typeshedFallback', () => { - const files = [ - { - path: combinePaths('/', typeshedFallback, 'stubs', 'aLib', 'aLib', '__init__.pyi'), - content: '# empty', - }, - { - path: combinePaths('/', typeshedFallback, 'stubs', 'bLib', 'bLib', '__init__.pyi'), - content: '# empty', - }, - ]; - - const sp = createServiceProviderFromFiles(files); - const configOptions = new ConfigOptions(''); // Empty, like open-file mode. - const importResolver = new ImportResolver( - sp, - configOptions, - new TestAccessHost(sp.fs().getModulePath(), [libraryRoot]) - ); - const importRoots = importResolver.getImportRoots(configOptions.getDefaultExecEnvironment()); - - assert.strictEqual(1, importRoots.filter((f) => f === combinePaths('/', typeshedFallback, 'stubs', 'aLib')).length); - assert.strictEqual(1, importRoots.filter((f) => f === combinePaths('/', typeshedFallback, 'stubs', 'bLib')).length); -}); + test('multiple typeshedFallback', () => { + const files = [ + { + path: combinePaths('/', typeshedFallback, 'stubs', 'aLib', 'aLib', '__init__.pyi'), + content: '# empty', + }, + { + path: combinePaths('/', typeshedFallback, 'stubs', 'bLib', 'bLib', '__init__.pyi'), + content: '# empty', + }, + ]; + + const sp = createServiceProviderFromFiles(files); + const configOptions = new ConfigOptions(''); // Empty, like open-file mode. + const importResolver = new ImportResolver( + sp, + configOptions, + new TestAccessHost(sp.fs().getModulePath(), [libraryRoot]) + ); + const importRoots = importResolver.getImportRoots(configOptions.getDefaultExecEnvironment()); + + assert.strictEqual( + 1, + importRoots.filter((f) => f === combinePaths('/', typeshedFallback, 'stubs', 'aLib')).length + ); + assert.strictEqual( + 1, + importRoots.filter((f) => f === combinePaths('/', typeshedFallback, 'stubs', 'bLib')).length + ); + }); -test('import side by side file root', () => { - const files = [ - { - path: combinePaths('/', 'file1.py'), - content: 'def test1(): ...', - }, - { - path: combinePaths('/', 'file2.py'), - content: 'def test2(): ...', - }, - ]; - - const importResult = getImportResult(files, ['file1']); - assert(importResult.isImportFound); - assert.strictEqual(1, importResult.resolvedPaths.filter((f) => f === combinePaths('/', 'file1.py')).length); -}); + test('import side by side file root', () => { + const files = [ + { + path: combinePaths('/', 'file1.py'), + content: 'def test1(): ...', + }, + { + path: combinePaths('/', 'file2.py'), + content: 'def test2(): ...', + }, + ]; + + const importResult = getImportResult(files, ['file1']); + assert(importResult.isImportFound); + assert.strictEqual(1, importResult.resolvedPaths.filter((f) => f === combinePaths('/', 'file1.py')).length); + }); -test('import side by side file sub folder', () => { - const files = [ - { - path: combinePaths('/test', 'file1.py'), - content: 'def test1(): ...', - }, - { - path: combinePaths('/test', 'file2.py'), - content: 'def test2(): ...', - }, - ]; - - const importResult = getImportResult(files, ['file1']); - assert(importResult.isImportFound); - assert.strictEqual(1, importResult.resolvedPaths.filter((f) => f === combinePaths('/test', 'file1.py')).length); -}); + test('import side by side file sub folder', () => { + const files = [ + { + path: combinePaths('/test', 'file1.py'), + content: 'def test1(): ...', + }, + { + path: combinePaths('/test', 'file2.py'), + content: 'def test2(): ...', + }, + ]; + + const importResult = getImportResult(files, ['file1']); + assert(importResult.isImportFound); + assert.strictEqual(1, importResult.resolvedPaths.filter((f) => f === combinePaths('/test', 'file1.py')).length); + }); -test('import side by side file sub under src folder', () => { - const files = [ - { - path: combinePaths('/src/nested', 'file1.py'), - content: 'def test1(): ...', - }, - { - path: combinePaths('/src/nested', 'file2.py'), - content: 'def test2(): ...', - }, - ]; - - const importResult = getImportResult(files, ['file1']); - assert(importResult.isImportFound); - assert.strictEqual( - 1, - importResult.resolvedPaths.filter((f) => f === combinePaths('/src/nested', 'file1.py')).length - ); -}); + test('import side by side file sub under src folder', () => { + const files = [ + { + path: combinePaths('/src/nested', 'file1.py'), + content: 'def test1(): ...', + }, + { + path: combinePaths('/src/nested', 'file2.py'), + content: 'def test2(): ...', + }, + ]; + + const importResult = getImportResult(files, ['file1']); + assert(importResult.isImportFound); + assert.strictEqual( + 1, + importResult.resolvedPaths.filter((f) => f === combinePaths('/src/nested', 'file1.py')).length + ); + }); -test('import file sub under containing folder', () => { - const files = [ - { - path: combinePaths('/src/nested', 'file1.py'), - content: 'def test1(): ...', - }, - { - path: combinePaths('/src/nested/nested2', 'file2.py'), - content: 'def test2(): ...', - }, - ]; - - const importResult = getImportResult(files, ['file1']); - assert(importResult.isImportFound); - assert.strictEqual( - 1, - importResult.resolvedPaths.filter((f) => f === combinePaths('/src/nested', 'file1.py')).length - ); -}); + test('import file sub under containing folder', () => { + const files = [ + { + path: combinePaths('/src/nested', 'file1.py'), + content: 'def test1(): ...', + }, + { + path: combinePaths('/src/nested/nested2', 'file2.py'), + content: 'def test2(): ...', + }, + ]; + + const importResult = getImportResult(files, ['file1']); + assert(importResult.isImportFound); + assert.strictEqual( + 1, + importResult.resolvedPaths.filter((f) => f === combinePaths('/src/nested', 'file1.py')).length + ); + }); -test('import side by side file sub under lib folder', () => { - const files = [ - { - path: combinePaths('/lib/site-packages/myLib', 'file1.py'), - content: 'def test1(): ...', - }, - { - path: combinePaths('/lib/site-packages/myLib', 'file2.py'), - content: 'def test2(): ...', - }, - ]; - - const importResult = getImportResult(files, ['file1']); - assert(!importResult.isImportFound); -}); + test("don't walk up the root", () => { + const files = [ + { + path: combinePaths('/', 'file1.py'), + content: 'def test1(): ...', + }, + ]; -test("don't walk up the root", () => { - const files = [ - { - path: combinePaths('/', 'file1.py'), - content: 'def test1(): ...', - }, - ]; + const importResult = getImportResult(files, ['notExist'], (c) => (c.projectRoot = '')); + assert(!importResult.isImportFound); + }); - const importResult = getImportResult(files, ['notExist'], (c) => (c.projectRoot = '')); - assert(!importResult.isImportFound); -}); + test('nested namespace package 1', () => { + const files = [ + { + path: combinePaths('/', 'packages1', 'a', 'b', 'c', 'd.py'), + content: 'def f(): pass', + }, + { + path: combinePaths('/', 'packages1', 'a', '__init__.py'), + content: '', + }, + { + path: combinePaths('/', 'packages2', 'a', '__init__.py'), + content: '', + }, + ]; + + const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => { + config.defaultExtraPaths = [combinePaths('/', 'packages1'), combinePaths('/', 'packages2')]; + }); + assert(importResult.isImportFound); + }); -test('nested namespace package 1', () => { - const files = [ - { - path: combinePaths('/', 'packages1', 'a', 'b', 'c', 'd.py'), - content: 'def f(): pass', - }, - { - path: combinePaths('/', 'packages1', 'a', '__init__.py'), - content: '', - }, - { - path: combinePaths('/', 'packages2', 'a', '__init__.py'), - content: '', - }, - ]; - - const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => { - config.defaultExtraPaths = [combinePaths('/', 'packages1'), combinePaths('/', 'packages2')]; + test('nested namespace package 2', () => { + const files = [ + { + path: combinePaths('/', 'packages1', 'a', 'b', 'c', 'd.py'), + content: 'def f(): pass', + }, + { + path: combinePaths('/', 'packages1', 'a', 'b', 'c', '__init__.py'), + content: '', + }, + { + path: combinePaths('/', 'packages2', 'a', 'b', 'c', '__init__.py'), + content: '', + }, + ]; + + const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => { + config.defaultExtraPaths = [combinePaths('/', 'packages1'), combinePaths('/', 'packages2')]; + }); + assert(importResult.isImportFound); }); - assert(importResult.isImportFound); -}); -test('nested namespace package 2', () => { - const files = [ - { - path: combinePaths('/', 'packages1', 'a', 'b', 'c', 'd.py'), - content: 'def f(): pass', - }, - { - path: combinePaths('/', 'packages1', 'a', 'b', 'c', '__init__.py'), - content: '', - }, - { - path: combinePaths('/', 'packages2', 'a', 'b', 'c', '__init__.py'), - content: '', - }, - ]; - - const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => { - config.defaultExtraPaths = [combinePaths('/', 'packages1'), combinePaths('/', 'packages2')]; + test('nested namespace package 3', () => { + const files = [ + { + path: combinePaths('/', 'packages1', 'a', 'b', 'c', 'd.py'), + content: 'def f(): pass', + }, + { + path: combinePaths('/', 'packages2', 'a', '__init__.py'), + content: '', + }, + ]; + + const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => { + config.defaultExtraPaths = [combinePaths('/', 'packages1'), combinePaths('/', 'packages2')]; + }); + assert(!importResult.isImportFound); }); - assert(importResult.isImportFound); -}); -test('nested namespace package 3', () => { - const files = [ - { - path: combinePaths('/', 'packages1', 'a', 'b', 'c', 'd.py'), - content: 'def f(): pass', - }, - { - path: combinePaths('/', 'packages2', 'a', '__init__.py'), - content: '', - }, - ]; - - const importResult = getImportResult(files, ['a', 'b', 'c', 'd'], (config) => { - config.defaultExtraPaths = [combinePaths('/', 'packages1'), combinePaths('/', 'packages2')]; + test('nested namespace package 4', () => { + const files = [ + { + path: combinePaths('/', 'packages1', 'a', 'b', '__init__.py'), + content: '', + }, + { + path: combinePaths('/', 'packages1', 'a', 'b', 'c.py'), + content: 'def f(): pass', + }, + { + path: combinePaths('/', 'packages2', 'a', '__init__.py'), + content: '', + }, + { + path: combinePaths('/', 'packages2', 'a', 'b', '__init__.py'), + content: '', + }, + ]; + + const importResult = getImportResult(files, ['a', 'b', 'c'], (config) => { + config.defaultExtraPaths = [combinePaths('/', 'packages1'), combinePaths('/', 'packages2')]; + }); + assert(!importResult.isImportFound); }); - assert(!importResult.isImportFound); }); -test('nested namespace package 4', () => { - const files = [ - { - path: combinePaths('/', 'packages1', 'a', 'b', '__init__.py'), - content: '', - }, - { - path: combinePaths('/', 'packages1', 'a', 'b', 'c.py'), - content: 'def f(): pass', - }, - { - path: combinePaths('/', 'packages2', 'a', '__init__.py'), - content: '', - }, - { - path: combinePaths('/', 'packages2', 'a', 'b', '__init__.py'), - content: '', - }, - ]; - - const importResult = getImportResult(files, ['a', 'b', 'c'], (config) => { - config.defaultExtraPaths = [combinePaths('/', 'packages1'), combinePaths('/', 'packages2')]; +if (usingTrueVenv()) { + describe('Import tests that have to run with a venv', () => { + test('venv can find imports', () => { + const files = [ + { + path: combinePaths('/', 'file1.py'), + content: 'import pytest', + }, + ]; + + const importResult = getImportResult(files, ['pytest']); + assert(importResult.isImportFound, `Import not found: ${importResult.importFailureInfo?.join('\n')}`); + }); }); - assert(!importResult.isImportFound); -}); +} function getImportResult( files: { path: string; content: string }[], nameParts: string[], setup?: (c: ConfigOptions) => void ) { - setup = + const defaultHostFactory = (sp: ServiceProvider) => new TestAccessHost(sp.fs().getModulePath(), [libraryRoot]); + const defaultSetup = setup ?? ((c) => { /* empty */ }); + const defaultSpFactory = (files: { path: string; content: string }[]) => createServiceProviderFromFiles(files); + + // Use environment variables to determine how to create a host and how to modify the config options. + // These are set in the CI to test imports with different options. + let hostFactory: (sp: ServiceProvider) => Host = defaultHostFactory; + let configModifier = defaultSetup; + let spFactory = defaultSpFactory; + + if (process.env.CI_IMPORT_TEST_VENVPATH) { + configModifier = (c: ConfigOptions) => { + defaultSetup(c); + c.venvPath = process.env.CI_IMPORT_TEST_VENVPATH; + c.venv = process.env.CI_IMPORT_TEST_VENV; + }; + spFactory = (files: { path: string; content: string }[]) => createServiceProviderWithCombinedFs(files); + } else if (process.env.CI_IMPORT_TEST_PYTHONPATH) { + configModifier = (c: ConfigOptions) => { + defaultSetup(c); + c.pythonPath = process.env.CI_IMPORT_TEST_PYTHONPATH; + }; + hostFactory = (sp: ServiceProvider) => new TruePythonTestAccessHost(); + spFactory = (files: { path: string; content: string }[]) => createServiceProviderWithCombinedFs(files); + } - const sp = createServiceProviderFromFiles(files); + return getImportResultImpl(files, nameParts, spFactory, configModifier, hostFactory); +} + +function getImportResultImpl( + files: { path: string; content: string }[], + nameParts: string[], + spFactory: (files: { path: string; content: string }[]) => ServiceProvider, + configModifier: (c: ConfigOptions) => void, + hostFactory: (sp: ServiceProvider) => Host +) { + const sp = spFactory(files); const configOptions = new ConfigOptions(normalizeSlashes('/')); - setup(configOptions); + configModifier(configOptions); const file = files.length > 0 ? files[files.length - 1].path : combinePaths('src', 'file.py'); if (files.length === 0) { @@ -611,11 +687,7 @@ function getImportResult( }); } - const importResolver = new ImportResolver( - sp, - configOptions, - new TestAccessHost(sp.fs().getModulePath(), [libraryRoot]) - ); + const importResolver = new ImportResolver(sp, configOptions, hostFactory(sp)); const importResult = importResolver.resolveImport(file, configOptions.findExecEnvironment(file), { leadingDots: 0, nameParts: nameParts, @@ -624,8 +696,7 @@ function getImportResult( return importResult; } - -function createFileSystem(files: { path: string; content: string }[]): PyrightFileSystem { +function createTestFileSystem(files: { path: string; content: string }[]): TestFileSystem { const fs = new TestFileSystem(/* ignoreCase */ false, { cwd: normalizeSlashes('/') }); for (const file of files) { @@ -636,10 +707,146 @@ function createFileSystem(files: { path: string; content: string }[]): PyrightFi fs.writeFileSync(path, file.content); } - return new PyrightFileSystem(fs); + return fs; } - function createServiceProviderFromFiles(files: { path: string; content: string }[]): ServiceProvider { - const fs = createFileSystem(files); + const fs = new PyrightFileSystem(createTestFileSystem(files)); return createServiceProvider(fs); } + +function createServiceProviderWithCombinedFs(files: { path: string; content: string }[]): ServiceProvider { + const fs = new PyrightFileSystem(new CombinedFileSystem(createTestFileSystem(files))); + return createServiceProvider(fs); +} + +class TruePythonTestAccessHost extends FullAccessHost { + constructor() { + super(createFromRealFileSystem()); + } +} + +class CombinedFileSystem implements FileSystem { + private _realFS = createFromRealFileSystem(); + + constructor(private _testFS: FileSystem) {} + + mkdirSync(path: string, options?: MkDirOptions | undefined): void { + this._testFS.mkdirSync(path, options); + } + + writeFileSync(path: string, data: string | Buffer, encoding: BufferEncoding | null): void { + this._testFS.writeFileSync(path, data, encoding); + } + + unlinkSync(path: string): void { + this._testFS.unlinkSync(path); + } + + rmdirSync(path: string): void { + this._testFS.rmdirSync(path); + } + + createFileSystemWatcher(paths: string[], listener: FileWatcherEventHandler): FileWatcher { + return this._testFS.createFileSystemWatcher(paths, listener); + } + + createReadStream(path: string): ReadStream { + return this._testFS.createReadStream(path); + } + + createWriteStream(path: string): WriteStream { + return this._testFS.createWriteStream(path); + } + + copyFileSync(src: string, dst: string): void { + this._testFS.copyFileSync(src, dst); + } + + existsSync(path: string): boolean { + return this._testFS.existsSync(path) || this._realFS.existsSync(path); + } + + chdir(path: string): void { + this._testFS.chdir(path); + } + + readdirEntriesSync(path: string): Dirent[] { + if (this._testFS.existsSync(path)) { + return this._testFS.readdirEntriesSync(path); + } + return this._realFS.readdirEntriesSync(path); + } + + readdirSync(path: string): string[] { + if (this._testFS.existsSync(path)) { + return this._testFS.readdirSync(path); + } + return this._realFS.readdirSync(path); + } + + readFileSync(path: string, encoding?: null): Buffer; + readFileSync(path: string, encoding: BufferEncoding): string; + readFileSync(path: string, encoding?: BufferEncoding | null): string | Buffer; + readFileSync(path: string, encoding: BufferEncoding | null = null) { + if (this._testFS.existsSync(path)) { + return this._testFS.readFileSync(path, encoding); + } + return this._realFS.readFileSync(path, encoding); + } + + statSync(path: string): Stats { + if (this._testFS.existsSync(path)) { + return this._testFS.statSync(path); + } + return this._realFS.statSync(path); + } + + realpathSync(path: string): string { + if (this._testFS.existsSync(path)) { + return this._testFS.realpathSync(path); + } + return this._realFS.realpathSync(path); + } + + getModulePath(): string { + return this._testFS.getModulePath(); + } + + readFile(path: string): Promise { + if (this._testFS.existsSync(path)) { + return this._testFS.readFile(path); + } + return this._realFS.readFile(path); + } + + readFileText(path: string, encoding?: BufferEncoding | undefined): Promise { + if (this._testFS.existsSync(path)) { + return this._testFS.readFileText(path, encoding); + } + return this._realFS.readFileText(path, encoding); + } + + realCasePath(path: string): string { + return this._testFS.realCasePath(path); + } + + isMappedFilePath(filepath: string): boolean { + return this._testFS.isMappedFilePath(filepath); + } + + getOriginalFilePath(mappedFilePath: string): string { + return this._testFS.getOriginalFilePath(mappedFilePath); + } + + getMappedFilePath(originalFilepath: string): string { + return this._testFS.getMappedFilePath(originalFilepath); + } + + getUri(path: string): string { + return this._testFS.getUri(path); + } + + isInZip(path: string): boolean { + return this._testFS.isInZip(path); + } +} diff --git a/packages/pyright-internal/src/tests/ipythonMode.test.ts b/packages/pyright-internal/src/tests/ipythonMode.test.ts index c479215d6..7f50eaeb1 100644 --- a/packages/pyright-internal/src/tests/ipythonMode.test.ts +++ b/packages/pyright-internal/src/tests/ipythonMode.test.ts @@ -441,40 +441,6 @@ test('try implicitly load ipython display module but fail', async () => { }); }); -test('implicitly load ipython display module', async () => { - const code = ` -// @filename: pyrightconfig.json -//// { -//// "useLibraryCodeForTypes": true -//// } - -// @filename: test.py -// @ipythonMode: true -//// [|display/*marker*/|] - -// @filename: IPython/__init__.py -// @library: true -//// - -// @filename: IPython/display.py -// @library: true -//// def display(): pass - `; - - const state = parseAndGetTestState(code).state; - - await state.verifyCompletion('included', MarkupKind.Markdown, { - marker: { - completions: [ - { - label: 'display', - kind: CompletionItemKind.Function, - }, - ], - }, - }); -}); - test('magics at the end', async () => { const code = ` // @filename: test.py diff --git a/packages/pyright-internal/src/tests/logger.test.ts b/packages/pyright-internal/src/tests/logger.test.ts index 9a1efff6a..82835280e 100644 --- a/packages/pyright-internal/src/tests/logger.test.ts +++ b/packages/pyright-internal/src/tests/logger.test.ts @@ -59,10 +59,6 @@ describe('TypeEvaluatorWithTracker tests', () => { TestUtils.typeAnalyzeSampleFiles(['badToken1.py'], config, console); assert.ok(consoleInterface.logs.length > 10, `No calls logged`); - assert.ok( - consoleInterface.logs.some((s) => s.includes('evaluateTypesForStatement')), - `Inner evaluateTypesForStatement not found` - ); }); test('Log not generated when level is error', () => { diff --git a/packages/pyright-internal/src/tests/pathUtils.test.ts b/packages/pyright-internal/src/tests/pathUtils.test.ts index 4870a9714..871f2064e 100644 --- a/packages/pyright-internal/src/tests/pathUtils.test.ts +++ b/packages/pyright-internal/src/tests/pathUtils.test.ts @@ -8,9 +8,9 @@ */ import assert from 'assert'; +import * as nodefs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; -import * as nodefs from 'fs-extra'; import { expandPathVariables } from '../common/envVarUtils'; import { @@ -23,25 +23,29 @@ import { ensureTrailingDirectorySeparator, getAnyExtensionFromPath, getBaseFileName, + getDirectoryPath, getFileExtension, getFileName, getPathComponents, getRelativePath, getRelativePathFromDirectory, + getRootLength, getWildcardRegexPattern, getWildcardRoot, hasTrailingDirectorySeparator, isDirectoryWildcardPatternPresent, isFileSystemCaseSensitiveInternal, isRootedDiskPath, + isUri, normalizeSlashes, + realCasePath, reducePathComponents, resolvePaths, stripFileExtension, stripTrailingDirectorySeparator, } from '../common/pathUtils'; -import * as vfs from './harness/vfs/filesystem'; import { createFromRealFileSystem } from '../common/realFileSystem'; +import * as vfs from './harness/vfs/filesystem'; test('getPathComponents1', () => { const components = getPathComponents(''); @@ -78,11 +82,38 @@ test('getPathComponents5', () => { assert.equal(components[1], 'hello.py'); }); +test('getPathComponents6', () => { + const components = getPathComponents(fixSeparators('//server/share/dir/file.py')); + assert.equal(components.length, 4); + assert.equal(components[0], fixSeparators('//server/')); + assert.equal(components[1], 'share'); + assert.equal(components[2], 'dir'); + assert.equal(components[3], 'file.py'); +}); + +test('getPathComponents7', () => { + const components = getPathComponents('ab:cdef/test'); + assert.equal(components.length, 3); + assert.equal(components[0], 'ab:'); + assert.equal(components[1], 'cdef'); + assert.equal(components[2], 'test'); +}); + test('combinePaths1', () => { const p = combinePaths('/user', '1', '2', '3'); assert.equal(p, normalizeSlashes('/user/1/2/3')); }); +test('combinePaths2', () => { + const p = combinePaths('/foo', 'ab:c'); + assert.equal(p, normalizeSlashes('/foo/ab:c')); +}); + +test('combinePaths3', () => { + const p = combinePaths('untitled:foo', 'ab:c'); + assert.equal(p, normalizeSlashes('untitled:foo/ab%3Ac')); +}); + test('ensureTrailingDirectorySeparator1', () => { const p = ensureTrailingDirectorySeparator('hello'); assert.equal(p, normalizeSlashes('hello/')); @@ -161,6 +192,13 @@ test('getWildcardRegexPattern3', () => { assert.ok(!regex.test(fixSeparators('/users/me/.blah/foo.py'))); }); +test('getWildcardRegexPattern4', () => { + const pattern = getWildcardRegexPattern('//server/share/dir', '.'); + const regex = new RegExp(pattern); + assert.ok(regex.test(fixSeparators('//server/share/dir/foo.py'))); + assert.ok(!regex.test(fixSeparators('//server/share/dix/foo.py'))); +}); + test('isDirectoryWildcardPatternPresent1', () => { const isPresent = isDirectoryWildcardPatternPresent('./**/*.py'); assert.equal(isPresent, true); @@ -315,6 +353,42 @@ test('getRelativePathFromDirectory2', () => { assert.equal(getRelativePathFromDirectory('/a', '/b/c/d', true), normalizeSlashes('../b/c/d')); }); +test('getRootLength1', () => { + assert.equal(getRootLength('a'), 0); +}); + +test('getRootLength2', () => { + assert.equal(getRootLength(fixSeparators('/')), 1); +}); + +test('getRootLength3', () => { + assert.equal(getRootLength('c:'), 2); +}); + +test('getRootLength4', () => { + assert.equal(getRootLength('c:d'), 0); +}); + +test('getRootLength5', () => { + assert.equal(getRootLength(fixSeparators('c:/')), 3); +}); + +test('getRootLength6', () => { + assert.equal(getRootLength(fixSeparators('//server')), 8); +}); + +test('getRootLength7', () => { + assert.equal(getRootLength(fixSeparators('//server/share')), 9); +}); + +test('getRootLength8', () => { + assert.equal(getRootLength('scheme:/no/authority'), 7); +}); + +test('getRootLength9', () => { + assert.equal(getRootLength('scheme://with/authority'), 9); +}); + test('isRootedDiskPath1', () => { assert(isRootedDiskPath(normalizeSlashes('C:/a/b'))); }); @@ -336,7 +410,11 @@ test('isDiskPathRoot2', () => { }); test('isDiskPathRoot3', () => { - assert(!isRootedDiskPath(normalizeSlashes('c:'))); + assert(isRootedDiskPath(normalizeSlashes('c:'))); +}); + +test('isDiskPathRoot4', () => { + assert(!isRootedDiskPath(normalizeSlashes('c:d'))); }); test('getRelativePath', () => { @@ -346,14 +424,32 @@ test('getRelativePath', () => { ); }); +test('getDirectoryPath', () => { + assert.equal(getDirectoryPath(normalizeSlashes('/a/b/c/d/e/f')), normalizeSlashes('/a/b/c/d/e')); + assert.equal( + getDirectoryPath(normalizeSlashes('untitled:/a/b/c/d/e/f?query#frag')), + normalizeSlashes('untitled:/a/b/c/d/e') + ); +}); + +test('isUri', () => { + assert.ok(isUri('untitled:/a/b/c/d/e/f?query#frag')); + assert.ok(isUri('untitled:/a/b/c/d/e/f')); + assert.ok(isUri('untitled:a/b/c/d/e/f')); + assert.ok(isUri('untitled:/a/b/c/d/e/f?query')); + assert.ok(isUri('untitled:/a/b/c/d/e/f#frag')); + assert.ok(!isUri('c:/foo/bar')); + assert.ok(!isUri('c:/foo#/bar')); + assert.ok(!isUri('222/dd:/foo/bar')); +}); test('CaseSensitivity', () => { const cwd = normalizeSlashes('/'); const fsCaseInsensitive = new vfs.TestFileSystem(/*ignoreCase*/ true, { cwd }); - assert.equal(isFileSystemCaseSensitiveInternal(fsCaseInsensitive), false); + assert.equal(isFileSystemCaseSensitiveInternal(fsCaseInsensitive, fsCaseInsensitive), false); const fsCaseSensitive = new vfs.TestFileSystem(/*ignoreCase*/ false, { cwd }); - assert.equal(isFileSystemCaseSensitiveInternal(fsCaseSensitive), true); + assert.equal(isFileSystemCaseSensitiveInternal(fsCaseSensitive, fsCaseSensitive), true); }); test('deduplicateFolders', () => { @@ -390,7 +486,7 @@ test('convert UNC path', () => { test('Realcase', () => { const fs = createFromRealFileSystem(); const cwd = process.cwd(); - const dir = path.join(cwd, 'src', 'tests'); + const dir = path.join(cwd, 'src', 'tests', '..', 'tests'); const entries = nodefs.readdirSync(dir).map((entry) => path.basename(nodefs.realpathSync(path.join(dir, entry)))); const fsentries = fs.readdirSync(dir); assert.deepStrictEqual(entries, fsentries); @@ -398,4 +494,50 @@ test('Realcase', () => { const paths = entries.map((entry) => nodefs.realpathSync(path.join(dir, entry))); const fspaths = fsentries.map((entry) => fs.realCasePath(path.join(dir, entry))); assert.deepStrictEqual(paths, fspaths); + + // Check that the '..' has been removed. + assert.ok(!fspaths.some((p) => p.indexOf('..') >= 0)); + + // If windows, check that the case is correct. + if (process.platform === 'win32') { + for (const p of fspaths) { + const upper = p.toUpperCase(); + const real = fs.realCasePath(upper); + assert.strictEqual(p, real); + } + } +}); + +test('Realcase use cwd implicitly', () => { + const fs = createFromRealFileSystem(); + const empty = realCasePath('', fs); + assert.deepStrictEqual(empty, ''); + const cwd = process.cwd(); + const dir = path.join(cwd, 'src', 'tests'); + + const entries = nodefs.readdirSync(dir).map((entry) => path.basename(nodefs.realpathSync(path.join(dir, entry)))); + const fsentries = fs.readdirSync(path.join('src', 'tests')); + const paths = entries.map((entry) => nodefs.realpathSync(path.join(dir, entry))); + const fspaths = fsentries.map((entry) => fs.realCasePath(path.join(dir, entry))); + assert.deepStrictEqual(paths, fspaths); +}); + +test('Realcase drive letter', () => { + const fs = createFromRealFileSystem(); + + const cwd = process.cwd(); + + assert.strictEqual( + getDriveLetter(fs.realCasePath(cwd)), + getDriveLetter(fs.realCasePath(combinePaths(cwd.toLowerCase(), 'notExist.txt'))) + ); + + function getDriveLetter(path: string) { + const driveLetter = getRootLength(path); + if (driveLetter === 0) { + return ''; + } + + return path.substring(0, driveLetter); + } }); diff --git a/packages/pyright-internal/src/tests/pyrightFileSystem.test.ts b/packages/pyright-internal/src/tests/pyrightFileSystem.test.ts index b63237906..93af834d5 100644 --- a/packages/pyright-internal/src/tests/pyrightFileSystem.test.ts +++ b/packages/pyright-internal/src/tests/pyrightFileSystem.test.ts @@ -141,33 +141,6 @@ test('multiple package installed', () => { assert.strictEqual(2, fs.readdirEntriesSync(combinePaths(extraRoot, 'myLib')).length); }); -test('uri tests', () => { - const files = [ - { - path: combinePaths('/', 'test.pyi'), - content: '', - }, - ]; - - const file = files[0].path; - const fs = createFileSystem(files); - - assert(fs.addUriMap('file://test.pyi', file)); - assert(fs.addUriMap('file://test.pyi', file)); - assert(!fs.addUriMap('memvfs://test.pyi', file)); - - assert(fs.hasUriMapEntry('file://test.pyi', file)); - assert(!fs.hasUriMapEntry('memvfs://test.pyi', file)); - - assert(!fs.removeUriMap('memfs://test.pyi', file)); - - fs.pendingRequest(file, true); - assert(fs.removeUriMap('file://test.pyi', file)); - - fs.pendingRequest(file, false); - assert(!fs.removeUriMap('file://test.pyi', file)); -}); - test('bundled partial stubs', () => { const bundledPath = combinePaths(normalizeSlashes('/'), 'bundled'); diff --git a/packages/pyright-internal/src/tests/samples/abstractClass1.py b/packages/pyright-internal/src/tests/samples/abstractClass1.py index 7cfe2126a..5a4f916d2 100644 --- a/packages/pyright-internal/src/tests/samples/abstractClass1.py +++ b/packages/pyright-internal/src/tests/samples/abstractClass1.py @@ -4,7 +4,7 @@ from abc import ABC, abstractmethod -class AbstractFoo(ABC): +class AbstractClassA(ABC): @abstractmethod def foo1(self): pass @@ -26,26 +26,30 @@ def foo4(cls): return cls() +v1 = [subclass() for subclass in AbstractClassA.__subclasses__()] +reveal_type(v1, expected_text="list[AbstractClassA]") + + # This should generate an error because AbstractFoo # is an abstract class. -a = AbstractFoo() +a = AbstractClassA() -class AbstractBar1(AbstractFoo): +class AbstractClassB(AbstractClassA): def foo1(self): pass # This should generate an error because AbstractBar1 # is an abstract class. -b = AbstractBar1() +b = AbstractClassB() -class AbstractBar2(AbstractBar1): +class AbstractClassC(AbstractClassB): def foo2(self): pass # This should not generate an error because AbstractBar2 # overrides all of the abstract methods it inherits. -c = AbstractBar2() +c = AbstractClassC() diff --git a/packages/pyright-internal/src/tests/samples/any1.py b/packages/pyright-internal/src/tests/samples/any1.py new file mode 100644 index 000000000..60da8c2fd --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/any1.py @@ -0,0 +1,36 @@ +# This sample tests certain uses of Any that should be flagged as illegal. + +from typing import Any, cast +import typing + + +isinstance(0, Any) +isinstance(0, typing.Any) + +v1 = cast(Any, 0) +v2 = cast(typing.Any, 0) + + +class A(Any): + ... + + +class B(typing.Any): + ... + + +# This should generate an error because Any is not callable. +Any() + +# This should generate an error because Any is not callable. +typing.Any() + + +def func1() -> int: + # This should generate an error because Any cannot be used as a value. + return Any + + +def func2() -> int: + # This should generate an error because Any cannot be used as a value. + return typing.Any diff --git a/packages/pyright-internal/src/tests/samples/assignment10.py b/packages/pyright-internal/src/tests/samples/assignment10.py index e430cef39..56f5e3416 100644 --- a/packages/pyright-internal/src/tests/samples/assignment10.py +++ b/packages/pyright-internal/src/tests/samples/assignment10.py @@ -71,3 +71,14 @@ def func4(y: list[Any]): def func5(v1: list[Any | None]): x1: list[int | None] = v1 reveal_type(x1, expected_text="list[int | None]") + + +def func6(v1: tuple[Any], v2: tuple[int, Any], v3: tuple[Any, ...]): + x1: tuple[int] = v1 + reveal_type(x1, expected_text="tuple[int]") + + x2: tuple[int, str] = v2 + reveal_type(x2, expected_text="tuple[int, str]") + + x3: tuple[str, ...] = v3 + reveal_type(x3, expected_text="tuple[str, ...]") diff --git a/packages/pyright-internal/src/tests/samples/call12.py b/packages/pyright-internal/src/tests/samples/call12.py index 27bdba1c6..b499fef89 100644 --- a/packages/pyright-internal/src/tests/samples/call12.py +++ b/packages/pyright-internal/src/tests/samples/call12.py @@ -38,3 +38,10 @@ class C(TypedDict): func1(**A(a=(v5 := 1)), b=(v5 + 1)) func1(b=(v6 + 1), *[(v6 := 1)], **C(c=(v6 + 2))) + + +def func2(a: int, b: int): + pass + + +func2(b=1, *(2,)) diff --git a/packages/pyright-internal/src/tests/samples/capturedVariable1.py b/packages/pyright-internal/src/tests/samples/capturedVariable1.py index 768a31c45..5878ffa3e 100644 --- a/packages/pyright-internal/src/tests/samples/capturedVariable1.py +++ b/packages/pyright-internal/src/tests/samples/capturedVariable1.py @@ -119,3 +119,10 @@ def inner1(): def inner2(): reveal_type(x, expected_text="str | None") reveal_type(y, expected_text="str") + + +def func11(foo: list[int] | None): + if isinstance(foo, list): + + def inner() -> list[int]: + return [x for x in foo] diff --git a/packages/pyright-internal/src/tests/samples/classes3.py b/packages/pyright-internal/src/tests/samples/classes3.py index 01790b77c..81620f117 100644 --- a/packages/pyright-internal/src/tests/samples/classes3.py +++ b/packages/pyright-internal/src/tests/samples/classes3.py @@ -35,7 +35,8 @@ class TestClass: instance.__doc__ instance.__module__ -# These should generate an error because they are not visible to instances. +# These should generate an error because they are not visible to instances, +# but the "type" class in builtins.pyi defines these as instance variables. instance.__name__ instance.__qualname__ @@ -47,7 +48,8 @@ def method1(self) -> str: class NonMeta: def method1(self) -> str: - # This should generate an error + # This should generate an error, but the "type" class in builtins.pyi + # defines this as an instance variable. return self.__name__ diff --git a/packages/pyright-internal/src/tests/samples/classes8.py b/packages/pyright-internal/src/tests/samples/classes8.py index 5db67309c..a8442a903 100644 --- a/packages/pyright-internal/src/tests/samples/classes8.py +++ b/packages/pyright-internal/src/tests/samples/classes8.py @@ -42,6 +42,6 @@ def thing(value: AnyStr): if isinstance(file.name, str): if file.name.endswith(".xml"): ... - else: + elif isinstance(file.name, bytes): if file.name.endswith(b".xml"): ... diff --git a/packages/pyright-internal/src/tests/samples/constrainedTypeVar1.py b/packages/pyright-internal/src/tests/samples/constrainedTypeVar1.py index adcad679f..02f4a4b8c 100644 --- a/packages/pyright-internal/src/tests/samples/constrainedTypeVar1.py +++ b/packages/pyright-internal/src/tests/samples/constrainedTypeVar1.py @@ -17,8 +17,8 @@ def constrained(first: S, second: S) -> S: class Foo(Generic[U]): - def generic_func1(self, a: U, b: U = ..., **kwargs: U) -> U: - return b + def generic_func1(self, a: U, b: str = "", **kwargs: U) -> U: + return a foo = Foo[str]() diff --git a/packages/pyright-internal/src/tests/samples/constructor17.py b/packages/pyright-internal/src/tests/samples/constructor17.py index bd34e5d52..2de95a72d 100644 --- a/packages/pyright-internal/src/tests/samples/constructor17.py +++ b/packages/pyright-internal/src/tests/samples/constructor17.py @@ -9,7 +9,7 @@ class A(Generic[T]): def __new__(cls, *args, **kwargs): - ... + return super().__new__(cls, *args, **kwargs) class B(Generic[T]): @@ -19,7 +19,7 @@ def __init__(self): class C(Generic[T]): def __new__(cls, *args, **kwargs): - ... + return super().__new__(cls, *args, **kwargs) def __init__(self): ... @@ -27,7 +27,7 @@ def __init__(self): class D(Generic[T]): def __new__(cls, *args, **kwargs): - ... + return super().__new__(cls, *args, **kwargs) def __init__(self, a: T): ... diff --git a/packages/pyright-internal/src/tests/samples/constructor8.py b/packages/pyright-internal/src/tests/samples/constructor8.py index c525cf600..5859bbea6 100644 --- a/packages/pyright-internal/src/tests/samples/constructor8.py +++ b/packages/pyright-internal/src/tests/samples/constructor8.py @@ -2,18 +2,20 @@ # type if its constructor conforms to that type. from dataclasses import dataclass -from typing import Any, Callable, Generic, Literal, TypeVar, Union, overload +from typing import Any, Callable, Generic, Literal, ParamSpec, TypeVar, Union, overload -_T1 = TypeVar("_T1") -_S = TypeVar("_S") +T1 = TypeVar("T1") +T2 = TypeVar("T2") +P = ParamSpec("P") +R = TypeVar("R") -def func1(callback: Callable[[_T1], _S], val: _T1) -> _S: +def func1(callback: Callable[[T1], T2], val: T1) -> T2: ... -class A(Generic[_T1]): - def __new__(cls, x: _T1) -> "A[_T1]": +class A(Generic[T1]): + def __new__(cls, x: T1) -> "A[T1]": ... @@ -27,16 +29,16 @@ def __new__(cls, x: _T1) -> "A[_T1]": reveal_type(a3, expected_text="A[int]") -class B(Generic[_T1]): +class B(Generic[T1]): @overload def __new__(cls, x: int, y: Literal[True]) -> "B[None]": ... @overload - def __new__(cls, x: _T1, y: bool = ...) -> "B[_T1]": + def __new__(cls, x: T1, y: bool = ...) -> "B[T1]": ... - def __new__(cls, x: Union[_T1, int], y: bool = False) -> "B[Any]": + def __new__(cls, x: Union[T1, int], y: bool = False) -> "B[Any]": ... @@ -56,8 +58,8 @@ def __new__(cls, x: Union[_T1, int], y: bool = False) -> "B[Any]": reveal_type(b5, expected_text="B[int | str]") -class C(Generic[_T1]): - def __init__(self: "C[_T1]", x: _T1) -> None: +class C(Generic[T1]): + def __init__(self: "C[T1]", x: T1) -> None: ... @@ -71,13 +73,13 @@ def __init__(self: "C[_T1]", x: _T1) -> None: reveal_type(c3, expected_text="C[int]") -class D(Generic[_T1]): +class D(Generic[T1]): @overload def __init__(self: "D[None]", x: int, y: Literal[True]) -> None: ... @overload - def __init__(self: "D[_T1]", x: _T1, y: bool = ...) -> None: + def __init__(self: "D[T1]", x: T1, y: bool = ...) -> None: ... def __init__(self, x: Any, y: bool = False) -> None: @@ -101,14 +103,14 @@ def __init__(self, x: Any, y: bool = False) -> None: @dataclass(frozen=True, slots=True) -class E(Generic[_T1]): - x: _T1 +class E(Generic[T1]): + x: T1 e1: Callable[[int], E[int]] = E -def func2(x: _T1) -> E[_T1]: +def func2(x: T1) -> E[T1]: ... diff --git a/packages/pyright-internal/src/tests/samples/dataclassConverter2.py b/packages/pyright-internal/src/tests/samples/dataclassConverter2.py index 83c68b673..d6c2ba177 100644 --- a/packages/pyright-internal/src/tests/samples/dataclassConverter2.py +++ b/packages/pyright-internal/src/tests/samples/dataclassConverter2.py @@ -1,5 +1,5 @@ # This sample tests assignment of dataclass fields that use -# the coverter parameter described in PEP 712. +# the converter parameter described in PEP 712. from dataclasses import dataclass, field diff --git a/packages/pyright-internal/src/tests/samples/dataclassFrozen1.py b/packages/pyright-internal/src/tests/samples/dataclassFrozen1.py index dde92e784..faa6817d6 100644 --- a/packages/pyright-internal/src/tests/samples/dataclassFrozen1.py +++ b/packages/pyright-internal/src/tests/samples/dataclassFrozen1.py @@ -11,7 +11,7 @@ class DC1: @dataclass(frozen=True) class DC2: - val2: int = 4 + val2: float = 4 # This should generate an error because a frozen dataclass @@ -47,3 +47,8 @@ class DC5(DC2): # This should generate an error because the dataclass is frozen. b.val4 = 3 + + +@dataclass(frozen=True) +class DC6(DC2): + val2: int = 6 diff --git a/packages/pyright-internal/src/tests/samples/del1.py b/packages/pyright-internal/src/tests/samples/del1.py index 0cabe438f..5a430f4b0 100644 --- a/packages/pyright-internal/src/tests/samples/del1.py +++ b/packages/pyright-internal/src/tests/samples/del1.py @@ -27,3 +27,22 @@ class ClassA: z1 = 1 del z1 + + +class ClassB: + x: int + + +b = ClassB() +b.x = 3 +reveal_type(b.x, expected_text="Literal[3]") +del b.x +reveal_type(b.x, expected_text="Unbound") + +x2: list[str | int] = ["a", 1, "b", 2] +reveal_type(x2[0], expected_text="str | int") +x2[0] = 0 +reveal_type(x2[0], expected_text="Literal[0]") +reveal_type(x2[1], expected_text="str | int") +del x2[0] +reveal_type(x2[0], expected_text="str | int") diff --git a/packages/pyright-internal/src/tests/samples/deprecated4.py b/packages/pyright-internal/src/tests/samples/deprecated4.py new file mode 100644 index 000000000..e5793731b --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/deprecated4.py @@ -0,0 +1,97 @@ +# This sample tests the handling of deprecated properties and decorators. + +from typing import overload +from typing_extensions import deprecated + + +class A: + @property + @deprecated("Deprecated v1 getter") + def v1(self) -> str: + return "" + + @v1.setter + def v1(self, value: str) -> None: + ... + + @v1.deleter + def v1(self) -> None: + ... + + @property + def v2(self) -> str: + return "" + + @deprecated("Deprecated v2 setter") + @v2.setter + def v2(self, value: str) -> None: + ... + + @v2.deleter + @deprecated("Deprecated v2 deleter") + def v2(self) -> None: + ... + + +a = A() + +# This should generate an error if reportDeprecated is enabled. +v1 = a.v1 + +a.v1 = "" +del a.v1 + + +v2 = a.v2 + +# This should generate an error if reportDeprecated is enabled. +a.v2 = "" + +# This should generate an error if reportDeprecated is enabled. +del a.v2 + + +class DescB1: + @overload + @deprecated("DescB1 __get__") + def __get__(self, obj: None, owner: object) -> str: + ... + + @overload + def __get__(self, obj: object, owner: object) -> str: + ... + + def __get__(self, obj: object | None, owner: object) -> str: + return "" + + +class DescB2: + def __get__(self, obj: object | None, owner: object) -> str: + return "" + + @deprecated("DescB2 __set__") + def __set__(self, obj: object | None, value: str) -> None: + ... + + @deprecated("DescB2 __delete__") + def __delete__(self, obj: object | None) -> None: + ... + + +class B: + b1: DescB1 = DescB1() + b2: DescB2 = DescB2() + + +# This should generate an error if reportDeprecated is enabled. +v3 = B.b1 + +b = B() +v4 = b.b1 + + +# This should generate an error if reportDeprecated is enabled. +b.b2 = "" + +# This should generate an error if reportDeprecated is enabled. +del b.b2 diff --git a/packages/pyright-internal/src/tests/samples/fstring1.py b/packages/pyright-internal/src/tests/samples/fstring1.py index 96065e22a..8da53165f 100644 --- a/packages/pyright-internal/src/tests/samples/fstring1.py +++ b/packages/pyright-internal/src/tests/samples/fstring1.py @@ -146,3 +146,9 @@ def func1(x): v2 = f'x \ y' + +w1 = 1 + +w2 = f"__{ + w1:d +}__" diff --git a/packages/pyright-internal/src/tests/samples/isinstance2.py b/packages/pyright-internal/src/tests/samples/isinstance2.py index af3bdd62b..e280b8abd 100644 --- a/packages/pyright-internal/src/tests/samples/isinstance2.py +++ b/packages/pyright-internal/src/tests/samples/isinstance2.py @@ -15,14 +15,21 @@ class DbModel(Document): pass -def foo() -> Union[int, DbModel]: +def func1() -> Union[int, DbModel]: return DbModel() # This should not generate an error even though DbModel is # derived from an unknown base class. -isinstance(foo(), int) +isinstance(func1(), int) -def bar(obj: object, typ: type): +def func2(obj: object, typ: type): return isinstance(obj, typ) + + +def func3(obj: float): + if isinstance(obj, float): + reveal_type(obj, expected_text="float") + else: + reveal_type(obj, expected_text="int") diff --git a/packages/pyright-internal/src/tests/samples/isinstance3.py b/packages/pyright-internal/src/tests/samples/isinstance3.py index 8e40b5657..b8eb13b14 100644 --- a/packages/pyright-internal/src/tests/samples/isinstance3.py +++ b/packages/pyright-internal/src/tests/samples/isinstance3.py @@ -3,9 +3,14 @@ # tuple of classes. +import sys from abc import abstractmethod -from typing import Any, Generic, Sequence, Tuple, Type, TypeVar, Union +from typing import Any, Callable, Generic, Sequence, Tuple, Type, TypeVar, Union +if sys.version_info >= (3, 10): + from types import NoneType +else: + NoneType = type(None) _T = TypeVar("_T", int, str) @@ -29,6 +34,12 @@ class A(Generic[_T]): if issubclass(A, Union[A, int]): pass +if issubclass(A, type(None)): + pass + +if issubclass(A, NoneType): + pass + class ClassA(Generic[_T]): v1: _T @@ -55,3 +66,15 @@ def execute(self, var: Union[_T, Tuple[_T]]) -> None: def func1(exceptions: Sequence[type[BaseException]], exception: Exception): return isinstance(exception, tuple(exceptions)) + + +if isinstance(a, Callable): + ... + +# This should generate an error because a subscripted Callable +# will result in a runtime exception. +if isinstance(a, Callable[[], Any]): + ... + +if isinstance(a, type(len)): + ... diff --git a/packages/pyright-internal/src/tests/samples/lambda1.py b/packages/pyright-internal/src/tests/samples/lambda1.py index 668ab0885..b386076a4 100644 --- a/packages/pyright-internal/src/tests/samples/lambda1.py +++ b/packages/pyright-internal/src/tests/samples/lambda1.py @@ -1,5 +1,5 @@ # This sample tests type checking for lambdas and their parameters. -from typing import Callable, Iterable, TypeVar +from typing import Any, Callable, Iterable, TypeVar #------------------------------------------------------ # Test basic lambda matching @@ -75,3 +75,19 @@ def reduce(function: Callable[[_T1, _T1], _T1], sequence: Iterable[_T1]) -> _T1: a: object = reduce((lambda x, y: x * y), [1, 2, 3, 4]) + + +#------------------------------------------------------ +# Test lambdas with *args + +b1: Callable[[int, int, int], Any] = lambda _, *b: reveal_type( + b, expected_text="tuple[int, ...]" +) + +b2: Callable[[str, str], Any] = lambda *b: reveal_type( + b, expected_text="tuple[str, ...]" +) + +b3: Callable[[int], Any] = lambda _, *b: reveal_type( + b, expected_text="tuple[Unknown, ...]" +) diff --git a/packages/pyright-internal/src/tests/samples/lambda10.py b/packages/pyright-internal/src/tests/samples/lambda10.py index 50831696f..8195e4e4e 100644 --- a/packages/pyright-internal/src/tests/samples/lambda10.py +++ b/packages/pyright-internal/src/tests/samples/lambda10.py @@ -16,11 +16,11 @@ v2 = (lambda a, b: a + b)(3, 4) -reveal_type(v2, expected_text="Literal[7]") +reveal_type(v2, expected_text="int") v3 = (lambda a, b: a + b)("foo", "bar") -reveal_type(v3, expected_text="Literal['foobar']") +reveal_type(v3, expected_text="LiteralString") v4 = (lambda a, b: a + b)("foo", (lambda c, d: c + d)("b", "ar")) -reveal_type(v4, expected_text="Literal['foobar']") +reveal_type(v4, expected_text="LiteralString") diff --git a/packages/pyright-internal/src/tests/samples/literalString1.py b/packages/pyright-internal/src/tests/samples/literalString1.py index 3da49f106..56c99fc45 100644 --- a/packages/pyright-internal/src/tests/samples/literalString1.py +++ b/packages/pyright-internal/src/tests/samples/literalString1.py @@ -72,7 +72,7 @@ def func6(a: LiteralString): a = "hi" - v3: list[str] = "1 2 3".split(" ") + v3: list[LiteralString] = "1 2 3".split(" ") def func7(a: Literal["a", "b"], b: Literal["a", 1]): @@ -80,3 +80,11 @@ def func7(a: Literal["a", "b"], b: Literal["a", 1]): # This should generate an error because "b" is not a string literal. v2: LiteralString = f"{b}" + + +def func8(a: list[LiteralString], b: list[Literal["a"]]): + # This should generate an error because of invariance rules. + v1: list[str] = a + + # This should generate an error because of invariance rules. + v2: list[LiteralString] = b diff --git a/packages/pyright-internal/src/tests/samples/loop39.py b/packages/pyright-internal/src/tests/samples/loop39.py new file mode 100644 index 000000000..7d4d0d5ac --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/loop39.py @@ -0,0 +1,20 @@ +# This sample tests a loop where there are multiple symbols +# that depend on each other. + +# pyright: strict + + +def func1() -> str | None: + ... + + +s1: str | None = None +s2 = None +while True: + obj = func1() + + x = s2 + condition = obj and obj != s1 + + s1 = obj + s2 = obj diff --git a/packages/pyright-internal/src/tests/samples/loop40.py b/packages/pyright-internal/src/tests/samples/loop40.py new file mode 100644 index 000000000..afb3990cf --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/loop40.py @@ -0,0 +1,12 @@ +# This sample verifies that unknown types are properly eliminated from +# a loop. + +# pyright: strict + +def func1(a: int, b: str, c: str): + v1: list[tuple[str, str, str]] = [] + for _ in range(0): + if a == 0: + print(v1[-1][0]) + last = v1[-1] + v1[-1] = (b, last[1], c) diff --git a/packages/pyright-internal/src/tests/samples/matchClass1.py b/packages/pyright-internal/src/tests/samples/matchClass1.py index a32770bb9..86e707a12 100644 --- a/packages/pyright-internal/src/tests/samples/matchClass1.py +++ b/packages/pyright-internal/src/tests/samples/matchClass1.py @@ -390,3 +390,33 @@ def func15(x: IntPair | None) -> None: case IntPair((y, z)): reveal_type(y, expected_text="int") reveal_type(z, expected_text="int") + + +def func16(x: str | float | bool | None): + match x: + case str(v) | bool(v) | float(v): + reveal_type(v, expected_text="str | bool | float") + reveal_type(x, expected_text="str | bool | float") + case v: + reveal_type(v, expected_text="int | None") + reveal_type(x, expected_text="int | None") + reveal_type(x, expected_text="str | bool | float | int | None") + + +def func17(x: str | float | bool | None): + match x: + case str() | float() | bool(): + reveal_type(x, expected_text="str | float | bool") + case _: + reveal_type(x, expected_text="int | None") + reveal_type(x, expected_text="str | float | bool | int | None") + + +def func18(x: str | float | bool | None): + match x: + case str(v) | float(v) | bool(v): + reveal_type(v, expected_text="str | float | bool") + reveal_type(x, expected_text="str | float | bool") + case _: + reveal_type(x, expected_text="int | None") + reveal_type(x, expected_text="str | float | bool | int | None") diff --git a/packages/pyright-internal/src/tests/samples/matchClass2.py b/packages/pyright-internal/src/tests/samples/matchClass2.py index 3a2bc6417..835ca4d54 100644 --- a/packages/pyright-internal/src/tests/samples/matchClass2.py +++ b/packages/pyright-internal/src/tests/samples/matchClass2.py @@ -16,4 +16,5 @@ class Point: reveal_type(x, expected_text="int") reveal_type(y, expected_text="int") reveal_type(opt, expected_text="int | None") - distance = (x ** 2 + y ** 2) ** 0.5 \ No newline at end of file + distance = (x ** 2 + y ** 2) ** 0.5 + diff --git a/packages/pyright-internal/src/tests/samples/matchClass5.py b/packages/pyright-internal/src/tests/samples/matchClass5.py new file mode 100644 index 000000000..1503305ae --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/matchClass5.py @@ -0,0 +1,63 @@ +# This sample tests the detection of too many positional patterns. + +from dataclasses import dataclass + + +@dataclass +class A: + a: int + + +class B: + a: int + b: int + + __match_args__ = ("a", "b") + + +class C(B): + ... + +class D(int): ... + +def func1(subj: A | B): + match subj: + # This should generate an error because A accepts only + # one positional pattern. + case A(1, 2): + pass + + case A(1): + pass + + case A(): + pass + + case B(1, 2): + pass + + # This should generate an error because B accepts only + # two positional patterns. + case B(1, 2, 3): + pass + + # This should generate an error because B accepts only + # two positional patterns. + case C(1, 2, 3): + pass + + case D(1): + pass + + # This should generate an error because D accepts only + # one positional pattern. + case D(1, 2): + pass + + case int(1): + pass + + # This should generate an error because int accepts only + # one positional pattern. + case int(1, 2): + pass diff --git a/packages/pyright-internal/src/tests/samples/matchExhaustion1.py b/packages/pyright-internal/src/tests/samples/matchExhaustion1.py index 3200ef5d2..a08e9e322 100644 --- a/packages/pyright-internal/src/tests/samples/matchExhaustion1.py +++ b/packages/pyright-internal/src/tests/samples/matchExhaustion1.py @@ -109,7 +109,7 @@ def func10(subj: Color | None = None) -> list[str]: def func11(subj: int | float | None): match subj: case float(): - reveal_type(subj, expected_text="int | float") + reveal_type(subj, expected_text="float") case int(): reveal_type(subj, expected_text="int") case NoneType(): diff --git a/packages/pyright-internal/src/tests/samples/matchSequence1.py b/packages/pyright-internal/src/tests/samples/matchSequence1.py index 388b063da..ad52fe47f 100644 --- a/packages/pyright-internal/src/tests/samples/matchSequence1.py +++ b/packages/pyright-internal/src/tests/samples/matchSequence1.py @@ -5,6 +5,8 @@ def test_unknown(value_to_match): match value_to_match: + case []: + reveal_type(value_to_match, expected_text="Sequence[Unknown]") case a1, a2: reveal_type(a1, expected_text="Unknown") reveal_type(a2, expected_text="Unknown") @@ -34,6 +36,8 @@ def test_unknown(value_to_match): def test_any(value_to_match: Any): match value_to_match: + case []: + reveal_type(value_to_match, expected_text="Sequence[Any]") case [*a1]: reveal_type(a1, expected_text="list[Any]") case b1: diff --git a/packages/pyright-internal/src/tests/samples/memberAccess23.py b/packages/pyright-internal/src/tests/samples/memberAccess23.py index 365203ffa..9135ca41b 100644 --- a/packages/pyright-internal/src/tests/samples/memberAccess23.py +++ b/packages/pyright-internal/src/tests/samples/memberAccess23.py @@ -23,6 +23,9 @@ def attr5(cls) -> int: attr6 = 6 + def __getattr__(self, name: str) -> complex: + ... + class A(metaclass=MyMeta): @property @@ -48,3 +51,4 @@ def attr4(self) -> int: reveal_type(A.attr4, expected_text="property") reveal_type(A.attr5, expected_text="int") reveal_type(A.attr6, expected_text="int") +reveal_type(A.attr7, expected_text="complex") diff --git a/packages/pyright-internal/src/tests/samples/memberAccess24.py b/packages/pyright-internal/src/tests/samples/memberAccess24.py new file mode 100644 index 000000000..459370409 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/memberAccess24.py @@ -0,0 +1,20 @@ +# This sample tests the case where an attribute is accessed from a +# class that derives from an unknown type or Any. + +from typing import Any +from dummy import UnknownX # type: ignore + + +class DerivesFromUnknown(UnknownX): + pass + + +class DerivesFromAny(Any): + pass + + +v1 = DerivesFromUnknown().x +reveal_type(v1, expected_text="Unknown") + +v2 = DerivesFromAny().x +reveal_type(v2, expected_text="Any") diff --git a/packages/pyright-internal/src/tests/samples/metaclass1.py b/packages/pyright-internal/src/tests/samples/metaclass1.py index e4adb7081..661805101 100644 --- a/packages/pyright-internal/src/tests/samples/metaclass1.py +++ b/packages/pyright-internal/src/tests/samples/metaclass1.py @@ -20,6 +20,10 @@ class Custom(metaclass=CustomMeta): ... +class OtherMeta(type): + ... + + # This should generate an error because the class isn't # Generic even though it supports a metaclass with a # __getitem__. @@ -31,3 +35,15 @@ class Custom(metaclass=CustomMeta): # This should generate an error. y3: TypeAlias = Custom[int] + + +def func1(m: CustomMeta): + v1: type = m + v2: type[object] = m + v3: type[Custom] = m + + +def func2(m: OtherMeta): + # This should generate an error because OtherMeta + # and the metaclass for Custom are not compatible. + v3: type[Custom] = m diff --git a/packages/pyright-internal/src/tests/samples/metaclass11.py b/packages/pyright-internal/src/tests/samples/metaclass11.py index 976d6e2c2..98963b25f 100644 --- a/packages/pyright-internal/src/tests/samples/metaclass11.py +++ b/packages/pyright-internal/src/tests/samples/metaclass11.py @@ -1,29 +1,50 @@ # This sample verifies that the type checker allows access # to instance variables provided by a metaclass. -from enum import Enum -from typing import Mapping +from typing import Any -class Meta(type): +class MetaA(type): var0 = 3 def __init__(cls, name, bases, dct): cls.var1 = "hi" -class MyClass(metaclass=Meta): +class ClassA(metaclass=MetaA): pass # This should generate an error because var0 isn't # accessible via an instance of this class. -MyClass().var0 -reveal_type(MyClass.var0, expected_text="int") -MyClass.var0 = 1 +ClassA().var0 +reveal_type(ClassA.var0, expected_text="int") +ClassA.var0 = 1 -reveal_type(MyClass().var1, expected_text="str") -reveal_type(MyClass.var1, expected_text="str") +reveal_type(ClassA().var1, expected_text="str") +reveal_type(ClassA.var1, expected_text="str") -MyClass.var1 = "hi" -MyClass().var1 = "hi" +ClassA.var1 = "hi" +ClassA().var1 = "hi" + + +class MetaB(type): + def __setattr__(cls, key: str, value: Any) -> None: + ... + + +class ClassB(metaclass=MetaB): + var0: int + + +# This should generate an error +ClassB.var0 = "" +ClassB.var1 = "" + +ClassB().var0 = 1 + +# This should generate an error +ClassB().var0 = "" + +# This should generate an error +ClassB().var1 = "" diff --git a/packages/pyright-internal/src/tests/samples/methodOverride2.py b/packages/pyright-internal/src/tests/samples/methodOverride2.py index e9c44577c..ad9b4671d 100644 --- a/packages/pyright-internal/src/tests/samples/methodOverride2.py +++ b/packages/pyright-internal/src/tests/samples/methodOverride2.py @@ -2,7 +2,7 @@ # diagnostic check. -from typing import Any, Generic, ParamSpec, TypeVar +from typing import Any, Generic, ParamSpec, Self, TypeVar class Base1: @@ -95,3 +95,23 @@ def method1(self, *args: P.args, **kwargs: P.kwargs) -> R: def method2(self, *args: Any, **kwargs: Any) -> R: ... + + +T = TypeVar("T") + + +class Base3: + def method1(self, x: Self) -> Self: + ... + + def method2(self, x: Self) -> Self: + ... + + +class Derived3(Generic[T], Base3): + def method1(self, x: "Derived3[T]") -> "Derived3[T]": + ... + + # This should generate an error. + def method2(self, x: "Derived3[int]") -> "Derived3[int]": + ... diff --git a/packages/pyright-internal/src/tests/samples/operator8.py b/packages/pyright-internal/src/tests/samples/operator8.py index 7aa3e9442..03e630fe2 100644 --- a/packages/pyright-internal/src/tests/samples/operator8.py +++ b/packages/pyright-internal/src/tests/samples/operator8.py @@ -2,7 +2,8 @@ # are applied when all operands are literal types with the same associated # class. -from typing import Literal +from functools import reduce +from typing import Iterable, Literal def func1(a: Literal[1, 2], b: Literal[0, 4], c: Literal[3, 4]): @@ -123,3 +124,23 @@ def func6(x: Literal[1, 3, 5, 7, 11, 13]): y *= x reveal_type(y, expected_text="int") + + +def func7(values: Iterable[str]) -> tuple[str, int]: + return reduce( + lambda x, value: (x[0] + value, x[1] + 1), + values, + ("", 0), + ) + + +def func8(values: Iterable[float]) -> float: + total, num_of_values = reduce( + lambda total_and_count, value: ( + total_and_count[0] + value, + total_and_count[1] + 1, + ), + values, + (0, 0), + ) + return total / num_of_values diff --git a/packages/pyright-internal/src/tests/samples/overload12.py b/packages/pyright-internal/src/tests/samples/overload12.py index 3d2eee77b..3af8b8fa1 100644 --- a/packages/pyright-internal/src/tests/samples/overload12.py +++ b/packages/pyright-internal/src/tests/samples/overload12.py @@ -276,7 +276,7 @@ def overload9(x: object, y: int, z: str, a: None) -> str: ... -def overload9(x, y, z=..., a=...) -> Any: +def overload9(x, y, z="", a=None) -> Any: pass diff --git a/packages/pyright-internal/src/tests/samples/overload15.py b/packages/pyright-internal/src/tests/samples/overload15.py index ed8df7767..37f111f3e 100644 --- a/packages/pyright-internal/src/tests/samples/overload15.py +++ b/packages/pyright-internal/src/tests/samples/overload15.py @@ -117,7 +117,7 @@ def callable4(func: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R: # This should generate an error. callable4(func3, 1.0) -# This should generate an error. +# This should generate two errors because x is missing and y is unknown. callable4(func3, y=1) diff --git a/packages/pyright-internal/src/tests/samples/overload16.py b/packages/pyright-internal/src/tests/samples/overload16.py new file mode 100644 index 000000000..a7b887ad7 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/overload16.py @@ -0,0 +1,32 @@ +# This sample tests that overload matching for partially-overlapping overload +# signatures considers the "expected type" when using bidirectional type +# inference. + +from typing import Any, Generic, LiteralString, TypeVar, overload + + +T = TypeVar("T") + + +class A(Generic[T]): + @overload + def func1(self: "A[bool]", x: "A[bool]") -> list[LiteralString]: + ... + + @overload + def func1(self, x: "A[Any]") -> list[str]: + ... + + def func1(self, x: "A[Any]") -> list[str] | list[LiteralString]: + return [] + + +def func2(a: A[bool], b: A[str]): + v1: list[LiteralString] = a.func1(a) + + # This should generate an error. + v2: list[str] = a.func1(a) + + # This should generate an error. + v3: list[LiteralString] = b.func1(b) + v4: list[str] = b.func1(b) diff --git a/packages/pyright-internal/src/tests/samples/paramSpec10.py b/packages/pyright-internal/src/tests/samples/paramSpec10.py index b63458c98..90f611e07 100644 --- a/packages/pyright-internal/src/tests/samples/paramSpec10.py +++ b/packages/pyright-internal/src/tests/samples/paramSpec10.py @@ -54,4 +54,4 @@ def test_3(cls: MyClass, param1: int) -> str: reveal_type(res3, expected_text="str") res4: Callable[[MyClass, int], str] = with_lock(test_3) -reveal_type(res4, expected_text="(MyClass, int) -> str") +reveal_type(res4, expected_text="(MyClass, param1: int) -> str") diff --git a/packages/pyright-internal/src/tests/samples/paramSpec3.py b/packages/pyright-internal/src/tests/samples/paramSpec3.py index 059301ae2..f4c8cbb81 100644 --- a/packages/pyright-internal/src/tests/samples/paramSpec3.py +++ b/packages/pyright-internal/src/tests/samples/paramSpec3.py @@ -56,3 +56,18 @@ def __init__(self, func: Callable[P, R]): def func4(f: Callable[P, R]) -> ClassA[P, R]: return ClassA(f) + + +T1 = TypeVar("T1") +T2 = TypeVar("T2") + + +def decorator2(f: Callable[P, R]) -> Callable[P, R]: + return f + + +def func5(f: Callable[[], list[T1]]) -> Callable[[list[T2]], list[T1 | T2]]: + def inner(res: list[T2]) -> list[T1 | T2]: + ... + + return decorator2(inner) diff --git a/packages/pyright-internal/src/tests/samples/paramSpec36.py b/packages/pyright-internal/src/tests/samples/paramSpec36.py index 4690e4ab5..5887e3229 100644 --- a/packages/pyright-internal/src/tests/samples/paramSpec36.py +++ b/packages/pyright-internal/src/tests/samples/paramSpec36.py @@ -36,7 +36,7 @@ def foo(a: int, b: int, c: int) -> int: submit(foo, a=1, b=2, c=3) submit(foo, 1, 2, 3) - # This should generate an error. + # This should generate two errors. submit(foo, a=1, b=2, d=3) # This should generate an error. diff --git a/packages/pyright-internal/src/tests/samples/paramSpec40.py b/packages/pyright-internal/src/tests/samples/paramSpec40.py index 41dac064a..6ee738cad 100644 --- a/packages/pyright-internal/src/tests/samples/paramSpec40.py +++ b/packages/pyright-internal/src/tests/samples/paramSpec40.py @@ -2,7 +2,7 @@ # with a ParamSpec and another generic callable that is parameterized # with a TypeVar. -from typing import Callable, ParamSpec, TypeVar +from typing import Callable, ParamSpec, TypeVar, TypedDict, Unpack _P = ParamSpec("_P") _R = TypeVar("_R") @@ -25,3 +25,19 @@ def func2(): result2 = map(call, [func1, func2]) reveal_type(result2, expected_text="map[float]") + + +class TD1(TypedDict, total=False): + e: str + f: str + + +def func3( + a: int, b: int, /, *, c: str = ..., d: str = ..., **kwargs: Unpack[TD1] +) -> float: + ... + + +call(func3, 1, 2, e="", c="") +call(func3, 1, 2, c="", d="", e="") +call(func3, 1, 2, e="") diff --git a/packages/pyright-internal/src/tests/samples/paramSpec47.py b/packages/pyright-internal/src/tests/samples/paramSpec47.py index f683b6d45..fa74a1f0d 100644 --- a/packages/pyright-internal/src/tests/samples/paramSpec47.py +++ b/packages/pyright-internal/src/tests/samples/paramSpec47.py @@ -26,5 +26,8 @@ def func2(a: int) -> int: # This should generate an error. func1(func1, func2, "42") -v4 = func1(func1) +# This should generate an error. +func1(func1) + +v4 = func1(func1, lambda: None) reveal_type(v4, expected_text="str") diff --git a/packages/pyright-internal/src/tests/samples/paramSpec49.py b/packages/pyright-internal/src/tests/samples/paramSpec49.py new file mode 100644 index 000000000..44ce563f5 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/paramSpec49.py @@ -0,0 +1,59 @@ +# This sample tests the case where a function parameterized with a +# ParamSpec P is called with *args: P.args and **kwargs: P.kwargs. + +from typing import Any, Generic, ParamSpec + +P = ParamSpec("P") + + +class TaskDeclaration(Generic[P]): + pass + + +class Dispatcher: + def dispatch( + self, + task_declaration: TaskDeclaration[P], + count: int, + /, + *args: P.args, + **kwargs: P.kwargs, + ) -> None: + pass + + +class Queue: + dispatcher: Dispatcher + + def method1(self, stub: TaskDeclaration[P]) -> Any: + def inner0(*args: P.args, **kwargs: P.kwargs) -> None: + self.dispatcher.dispatch(stub, 1, *args, **kwargs) + + def inner1(*args: P.args, **kwargs: P.kwargs) -> None: + self.dispatcher.dispatch(stub, 1, **kwargs, *args) + + def inner2(*args: P.args, **kwargs: P.kwargs) -> None: + # This should generate an error because it's missing + # a positional argument for 'count'. + self.dispatcher.dispatch(stub, *args, **kwargs) + + def inner3(*args: P.args, **kwargs: P.kwargs) -> None: + # This should generate an error because it has an + # additional positional argument. + self.dispatcher.dispatch(stub, 1, 1, *args, **kwargs) + + def inner4(*args: P.args, **kwargs: P.kwargs) -> None: + # This should generate an error because it is missing + # the *args argument. + self.dispatcher.dispatch(stub, 1, **kwargs) + + def inner5(*args: P.args, **kwargs: P.kwargs) -> None: + # This should generate an error because it is missing + # the *kwargs argument. + self.dispatcher.dispatch(stub, 1, *args) + + def inner6(*args: P.args, **kwargs: P.kwargs) -> None: + # This should generate an error because it has an + # extra *args argument. + self.dispatcher.dispatch(stub, 1, *args, *args, **kwargs) + diff --git a/packages/pyright-internal/src/tests/samples/paramSpec9.py b/packages/pyright-internal/src/tests/samples/paramSpec9.py index 643e40ae9..c0945cc3d 100644 --- a/packages/pyright-internal/src/tests/samples/paramSpec9.py +++ b/packages/pyright-internal/src/tests/samples/paramSpec9.py @@ -27,7 +27,7 @@ def a_int_b_str(a: int, b: str) -> int: # This should generate an error because a is a incorrect type. twice(a_int_b_str, "1", b="2") # Rejected -# This should generate an error because c is unknown. +# This should generate two errors because c is unknown and b is missing. twice(a_int_b_str, 1, c=2) # Rejected # This should generate an error because c is unknown. diff --git a/packages/pyright-internal/src/tests/samples/property11.py b/packages/pyright-internal/src/tests/samples/property11.py index daff981ce..ad66316e5 100644 --- a/packages/pyright-internal/src/tests/samples/property11.py +++ b/packages/pyright-internal/src/tests/samples/property11.py @@ -19,11 +19,12 @@ def prop1(cls, value: str): reveal_type(Class1.prop1, expected_text="str") -reveal_type(Class1().prop1, expected_text="str") +# This should generate an error. +Class1().prop1 Class1.prop1 = "hi" -# This should generate an error +# This should generate an error. Class1.prop1 = 1 diff --git a/packages/pyright-internal/src/tests/samples/protocol3.py b/packages/pyright-internal/src/tests/samples/protocol3.py index 3a17e6dad..113a6b1ee 100644 --- a/packages/pyright-internal/src/tests/samples/protocol3.py +++ b/packages/pyright-internal/src/tests/samples/protocol3.py @@ -2,6 +2,7 @@ # include property declarations. from typing import ContextManager, NamedTuple, Protocol, TypeVar +from dataclasses import dataclass class Class1(Protocol): @@ -158,3 +159,52 @@ class Class8(NamedTuple): b: Proto8 = Class8("") + + +class Proto9(Protocol): + @property + def x(self) -> str: + ... + + @x.setter + def x(self, n: str) -> None: + ... + + +class Proto10(Protocol): + x: str + + +class NT9(NamedTuple): + x: str = "" + + +@dataclass(frozen=False) +class DC9: + x: str = "" + + +@dataclass(frozen=True) +class DCFrozen9: + x: str = "" + + +# This should generate an error because named tuple +# attributes are immutable. +p9_1: Proto9 = NT9() + +# This should generate an error because frozen dataclass +# attributes are immutable. +p9_2: Proto9 = DCFrozen9() + +p9_3: Proto9 = DC9() + +# This should generate an error because named tuple +# attributes are immutable. +p10_1: Proto10 = NT9() + +# This should generate an error because frozen dataclass +# attributes are immutable. +p10_2: Proto10 = DCFrozen9() + +p10_3: Proto10 = DC9() diff --git a/packages/pyright-internal/src/tests/samples/protocol45.py b/packages/pyright-internal/src/tests/samples/protocol45.py new file mode 100644 index 000000000..894b327b6 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/protocol45.py @@ -0,0 +1,34 @@ +# This sample tests a case where a protocol method has a method-scoped +# type parameter. + +from typing import Callable, Generic, Protocol, TypeVar + +S = TypeVar("S") +T = TypeVar("T") +Input = TypeVar("Input") +Output = TypeVar("Output") + + +class Proto1(Protocol): + def __call__(self, item: S, /) -> S: + ... + + +class Impl1: + def __call__(self, item: T, /) -> T: + return item + + +class Wrapper(Generic[Input, Output]): + def __init__(self, f: Callable[[Input], Output]) -> None: + self.__f = f + + def __call__(self, item: Input, /) -> Output: + return self.__f(item) + + +y = Wrapper(Impl1()) +reveal_type(y, expected_text="Wrapper[T@__call__, T@__call__]") +x: Proto1 = y + + diff --git a/packages/pyright-internal/src/tests/samples/protocol46.py b/packages/pyright-internal/src/tests/samples/protocol46.py new file mode 100644 index 000000000..845b446ba --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/protocol46.py @@ -0,0 +1,51 @@ +# This sample tests protocol matching for multiple protocols that refer +# to each other in a recursive fashion. In particular, this sample tests +# the case where a "cls" parameter is annotated with a protocol type. + +from typing import Never, Self, TypeVar, Protocol + +T_contra = TypeVar("T_contra", contravariant=True) +T = TypeVar("T") + + +class ProtoA(Protocol[T_contra, T]): + def method1(self) -> "ProtoA[T_contra, T]": + ... + + @classmethod + def method2(cls, value: T) -> None: + ... + + +class ProtoB(Protocol[T_contra, T]): + def method3(self) -> ProtoA[T_contra, T]: + ... + + +class ImplA: + def method1(self) -> Self: + ... + + @classmethod + def method2(cls, value: int) -> None: + ... + + +class ImplB: + def method3(self) -> ImplA: + ... + + def method1(self) -> Self: + ... + + @classmethod + def method2(cls: type[ProtoB[Never, T]], value: list[T]) -> None: + ... + + +def func1(x: ProtoA[Never, T]) -> T: + ... + + +v1 = func1(ImplB()) +reveal_type(v1, expected_text="list[int]") diff --git a/packages/pyright-internal/src/tests/samples/protocol47.py b/packages/pyright-internal/src/tests/samples/protocol47.py new file mode 100644 index 000000000..c175b4417 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/protocol47.py @@ -0,0 +1,33 @@ +# This sample tests protocol matching for a protocol and an implementation +# that use a mixture of class-scoped and function-scoped TypeVars. + +from typing import TypeVar, Protocol, Generic + + +T1 = TypeVar("T1", covariant=True) +T2 = TypeVar("T2") + + +class ProtoA(Protocol[T1]): + def method1(self, __key: str, __default: T2) -> "T1 | T2": + ... + + +T3 = TypeVar("T3", covariant=True) +T4 = TypeVar("T4") + + +class A(Generic[T3]): + def method1(self, key: str, default: T4) -> "T3 | T4": + raise NotImplementedError + + +a1: A[str] = A() + + +def func1(storage: ProtoA[int]): + ... + + +v1: ProtoA[int] = a1 +func1(a1) diff --git a/packages/pyright-internal/src/tests/samples/protocol6.py b/packages/pyright-internal/src/tests/samples/protocol6.py index e84c4aafd..418738ca7 100644 --- a/packages/pyright-internal/src/tests/samples/protocol6.py +++ b/packages/pyright-internal/src/tests/samples/protocol6.py @@ -52,7 +52,7 @@ class Cow: a: Mammal[str] = Sloth() -# This should generage an error because Armadillo +# This should generate an error because Armadillo # uses bytes for its attributes, not str. b: Mammal[str] = Armadillo() diff --git a/packages/pyright-internal/src/tests/samples/protocol9.py b/packages/pyright-internal/src/tests/samples/protocol9.py index 6d3bb9352..4aee00c45 100644 --- a/packages/pyright-internal/src/tests/samples/protocol9.py +++ b/packages/pyright-internal/src/tests/samples/protocol9.py @@ -1,4 +1,5 @@ -# This sample tests a protocol class that refers to itself. +# This sample tests a recursive protocol class (i.e. a protocol +# that refers to itself). from typing import Protocol @@ -33,3 +34,19 @@ def __init__(self, value: int) -> None: root: TreeLike = SimpleTree(0) + + +class ProtoA(Protocol): + def method1(self) -> "ProtoA": + ... + + +class ImplA: + class CallableClass: + def __call__(self) -> "ImplA": + return ImplA() + + method1 = CallableClass() + + +v1: ProtoA = ImplA() diff --git a/packages/pyright-internal/src/tests/samples/protocolModule2.py b/packages/pyright-internal/src/tests/samples/protocolModule2.py index 32c145c9b..bbf1e7d25 100644 --- a/packages/pyright-internal/src/tests/samples/protocolModule2.py +++ b/packages/pyright-internal/src/tests/samples/protocolModule2.py @@ -81,3 +81,28 @@ def func3(): reveal_type(my_module, expected_text="P1") else: reveal_type(my_module, expected_text="ModuleType") + + +_T1 = TypeVar("_T1") + + +class P5(Protocol[_T1]): + def func_1(self, a: int, b: _T1) -> _T1: + ... + + +def func4(x: P5[_T1]) -> _T1: + ... + + +v5 = func4(protocolModule1) +reveal_type(v5, expected_text="str") + + +class P6(Protocol): + @property + def var_1(self) -> int: + ... + + +v6: P6 = protocolModule1 diff --git a/packages/pyright-internal/src/tests/samples/recursiveTypeAlias8.py b/packages/pyright-internal/src/tests/samples/recursiveTypeAlias8.py index c20b7b8ec..bf410c9ee 100644 --- a/packages/pyright-internal/src/tests/samples/recursiveTypeAlias8.py +++ b/packages/pyright-internal/src/tests/samples/recursiveTypeAlias8.py @@ -3,36 +3,36 @@ from __future__ import annotations -from typing import Union, TypedDict, List +from typing import TypedDict -class _FooOptional(TypedDict, total=False): - options: List[AllBar] +class ClassA(TypedDict, total=False): + options: list[CorD] type: int -class Foo(_FooOptional): +class ClassB(ClassA): id: int name: str -class BarA(TypedDict): +class ClassC(TypedDict): type: int -class BarB(TypedDict): - options: List[AllBar] +class ClassD(TypedDict): + options: list[CorD] type: int -AllBar = Union[BarA, BarB] +CorD = ClassC | ClassD -def foo(a: AllBar): - reveal_type(a, expected_text="BarA | BarB") +def foo(a: CorD): + reveal_type(a, expected_text="ClassC | ClassD") options = a.get("options", []) - reveal_type(options, expected_text="Any | List[BarA | BarB]") + reveal_type(options, expected_text="Any | list[Any] | list[ClassC | ClassD]") for option in options: - reveal_type(option, expected_text="Any | BarA | BarB") + reveal_type(option, expected_text="Any | ClassC | ClassD") reveal_type(option["type"], expected_text="Any | int") diff --git a/packages/pyright-internal/src/tests/samples/solver30.py b/packages/pyright-internal/src/tests/samples/solver30.py new file mode 100644 index 000000000..d9cbc4a57 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/solver30.py @@ -0,0 +1,37 @@ +# This sample tests the case where a deeply nested set of calls requires +# the use of bidirectional type inference to evaluate the type of a lambda. + +from typing import Any, Callable, Iterable, Iterator, TypeVar + +X = TypeVar("X") +Y = TypeVar("Y") +Z = TypeVar("Z") + + +class Item: + foo: bool + + +items = [Item()] + + +def func1(a: Iterable[X]) -> X: + ... + + +def func2(a: Iterable[Y]) -> Iterable[Y]: + ... + + +class func3(Iterator[Z]): + def __init__(self, a: Callable[[Z], Any], b: Iterable[Z]) -> None: + ... + + +def func4(a: Callable[[Z], Any], b: Iterable[Z]) -> Iterator[Z]: + ... + + +func1(func2(func3(lambda x: reveal_type(x.foo, expected_text="bool"), items))) + +func1(func2(func4(lambda x: reveal_type(x.foo, expected_text="bool"), items))) diff --git a/packages/pyright-internal/src/tests/samples/super1.py b/packages/pyright-internal/src/tests/samples/super1.py index 9a2754e7c..3c3c3e6b8 100644 --- a/packages/pyright-internal/src/tests/samples/super1.py +++ b/packages/pyright-internal/src/tests/samples/super1.py @@ -1,25 +1,28 @@ # This sample tests the type analyzer's handling of the super() call. -class FooBase: +class ClassA: @staticmethod - def ccc(): + def method1(): pass + def method5(self) -> type: + return ClassA -class Foo1(FooBase): + +class ClassB(ClassA): def __init__(self): pass - def hello1(self): + def method2(self): pass -class Foo2(FooBase): +class ClassC(ClassA): def __init__(self): pass - def hello2(self): + def method3(self): return self.__class__() @staticmethod @@ -27,31 +30,40 @@ def aaa(): pass -class Bar(Foo1, Foo2): +class Bar(ClassB, ClassC): def __init__(self): - super().hello1() - super().hello2() + super().method2() + super().method3() # This should generate an error - super().goodbye() + super().non_method1() super(Bar) # This should generate an error -super(Bar).bbb() +super(Bar).non_method2() -super(Foo1, Bar).ccc() +super(ClassB, Bar).method1() # This should generate an error because Foo2 # is not a subclass of Foo1. -super(Foo1, Foo2).ccc() +super(ClassB, ClassC).method1() -bar = Bar() -super(Foo1, bar).ccc() +v1 = Bar() +super(ClassB, v1).method1() -foo2 = Foo2() +v2 = ClassC() # This should generate an error because Foo2 # is not a subclass of Foo1. -super(Foo1, foo2).ccc() +super(ClassB, v2).method1() + + +class ClassD(ClassA): + def method5(self): + class ClassDInner(super().method5()): + # This should generate an error. + x = super().method5() + + return ClassDInner diff --git a/packages/pyright-internal/src/tests/samples/typeAlias1.py b/packages/pyright-internal/src/tests/samples/typeAlias1.py index b4df6aea7..4ece1d350 100644 --- a/packages/pyright-internal/src/tests/samples/typeAlias1.py +++ b/packages/pyright-internal/src/tests/samples/typeAlias1.py @@ -5,16 +5,16 @@ # Make sure it works with and without forward references. TupleAlias = tuple["int", int] -foo1: tuple[int, int] -bar1: TupleAlias +v1: tuple[int, int] +v2: TupleAlias -foo1 = (1, 2) -bar1 = (1, 2) +v1 = (1, 2) +v2 = (1, 2) AnyAlias = Any -baz1: AnyAlias = 3 +v3: AnyAlias = 3 class A: @@ -29,9 +29,16 @@ class A: Alias1 = Literal[0, 1] -foo2: dict[Alias1, Any] = {} +v4: dict[Alias1, Any] = {} -if foo2: +if v4: pass -baz2: list[Alias1] = [] +v5: list[Alias1] = [] + + +Alias2 = int | str + + +def func1(x: Alias2): + reveal_type(type(x), expected_text="type[int] | type[str]") diff --git a/packages/pyright-internal/src/tests/samples/typeAliasStatement1.py b/packages/pyright-internal/src/tests/samples/typeAliasStatement1.py index 494c606e7..135ef12a5 100644 --- a/packages/pyright-internal/src/tests/samples/typeAliasStatement1.py +++ b/packages/pyright-internal/src/tests/samples/typeAliasStatement1.py @@ -55,6 +55,8 @@ def func1() -> type[int]: # This should generate an error. TA10(0) +list[TA10]() + # This should generate an error. class DerivedInt(TA10): pass diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingFalsy1.py b/packages/pyright-internal/src/tests/samples/typeNarrowingFalsy1.py index cfaabe07c..cdb87bb28 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingFalsy1.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingFalsy1.py @@ -1,6 +1,6 @@ # This sample tests type narrowing for falsey and truthy values. -from typing import AnyStr, Iterable, Literal, NamedTuple, Union +from typing import AnyStr, Iterable, Literal, NamedTuple, TypeVar, Union, final class A: @@ -22,7 +22,7 @@ def __bool__(self) -> Literal[True]: ... -def func1(x: Union[int, list[int], A, B, C, D, None]) -> None: +def func1(x: int | list[int] | A | B | C | D | None) -> None: if x: reveal_type(x, expected_text="int | list[int] | A | B | D") else: @@ -36,61 +36,68 @@ def func2(maybe_int: int | None): reveal_type(maybe_int, expected_text="Literal[0] | None") -def func3(maybe_a: A | None): +def func3_1(maybe_a: A | None): if bool(maybe_a): reveal_type(maybe_a, expected_text="A") else: reveal_type(maybe_a, expected_text="None") -def func4(foo: Iterable[int]) -> None: - if foo: - reveal_type(foo, expected_text="Iterable[int]") +def func3_2(maybe_a: A | None): + if bool(maybe_a): + reveal_type(maybe_a, expected_text="A") + else: + reveal_type(maybe_a, expected_text="None") + + +def func4(val: Iterable[int]) -> None: + if val: + reveal_type(val, expected_text="Iterable[int]") else: - reveal_type(foo, expected_text="Iterable[int]") + reveal_type(val, expected_text="Iterable[int]") -def func5(foo: tuple[int]) -> None: - if foo: - reveal_type(foo, expected_text="tuple[int]") +def func5(val: tuple[int]) -> None: + if val: + reveal_type(val, expected_text="tuple[int]") else: - reveal_type(foo, expected_text="Never") + reveal_type(val, expected_text="Never") -def func6(foo: tuple[int, ...]) -> None: - if foo: - reveal_type(foo, expected_text="tuple[int, ...]") +def func6(val: tuple[int, ...]) -> None: + if val: + reveal_type(val, expected_text="tuple[int, ...]") else: - reveal_type(foo, expected_text="tuple[int, ...]") + reveal_type(val, expected_text="tuple[int, ...]") -def func7(foo: tuple[()]) -> None: - if foo: - reveal_type(foo, expected_text="Never") +def func7(val: tuple[()]) -> None: + if val: + reveal_type(val, expected_text="Never") else: - reveal_type(foo, expected_text="tuple[()]") + reveal_type(val, expected_text="tuple[()]") class NT1(NamedTuple): - foo: int + val: int -def func8(foo: NT1) -> None: - if foo: - reveal_type(foo, expected_text="NT1") +def func8(val: NT1) -> None: + if val: + reveal_type(val, expected_text="NT1") else: - reveal_type(foo, expected_text="Never") + reveal_type(val, expected_text="Never") class NT2(NT1): pass -def func9(foo: NT2) -> None: - if foo: - reveal_type(foo, expected_text="NT2") +def func9(val: NT2) -> None: + if val: + reveal_type(val, expected_text="NT2") else: - reveal_type(foo, expected_text="Never") + reveal_type(val, expected_text="Never") class E: @@ -113,3 +120,15 @@ def func10(val: AnyStr | None): def func11(val: AnyStr | None): assert val reveal_type(val, expected_text="AnyStr@func11") + + +T = TypeVar("T") + + +def func12(val: T) -> T: + if val: + reveal_type(val, expected_text="T@func12") + else: + reveal_type(val, expected_text="T@func12") + + return val diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance14.py b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance14.py index 467d35be0..4e8613f0e 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance14.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance14.py @@ -18,7 +18,7 @@ def func1(cls: type[T], obj: Any) -> T: def func2(klass: type[T], obj: T | int) -> T: assert isinstance(obj, klass) - reveal_type(obj, expected_text="T@func2") + reveal_type(obj, expected_text="object*") return obj diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance16.py b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance16.py index a7b7281b7..1477455cd 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance16.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance16.py @@ -16,4 +16,4 @@ def baz(self, other: object): reveal_type(other, expected_text="Self@ClassA") if isinstance(other, (int, type(self))): - reveal_type(other, expected_text="Self@ClassA | int") + reveal_type(other, expected_text="ClassA | int | Self@ClassA") diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance17.py b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance17.py index 3d3046f52..0f49cd080 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance17.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance17.py @@ -1,6 +1,7 @@ # This sample tests basic type narrowing behavior for # the isinstance call. +from types import NoneType from typing import Any, TypedDict @@ -40,14 +41,14 @@ def func5(x: int | str | complex): if isinstance(x, (int, str)): reveal_type(x, expected_text="int | str") else: - reveal_type(x, expected_text="complex") + reveal_type(x, expected_text="complex | float") def func6(x: type[int] | type[str] | type[complex]): if issubclass(x, (int, str)): reveal_type(x, expected_text="type[int] | type[str]") else: - reveal_type(x, expected_text="type[complex]") + reveal_type(x, expected_text="type[complex] | type[float]") def func7(x: int | SomeTypedDict | None): @@ -55,3 +56,24 @@ def func7(x: int | SomeTypedDict | None): reveal_type(x, expected_text="SomeTypedDict | None") else: reveal_type(x, expected_text="int") + + +def func8(x: type[int] | type[SomeTypedDict] | type[None]): + if issubclass(x, (dict, type(None))): + reveal_type(x, expected_text="type[SomeTypedDict] | type[None]") + else: + reveal_type(x, expected_text="type[int]") + + +def func9(x: int | None): + if isinstance(x, NoneType): + reveal_type(x, expected_text="None") + else: + reveal_type(x, expected_text="int") + + +def func10(x: type[int] | type[None]): + if issubclass(x, NoneType): + reveal_type(x, expected_text="type[None]") + else: + reveal_type(x, expected_text="type[int]") diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance19.py b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance19.py new file mode 100644 index 000000000..e37c64467 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance19.py @@ -0,0 +1,67 @@ +# This sample tests the logic for narrowing a metaclass using an +# issubclass call. + +from abc import ABC, ABCMeta +from typing import Any, ClassVar +from typing_extensions import reveal_type + + +class Meta1(ABCMeta): + pass + + +class Parent1(ABC, metaclass=Meta1): + pass + + +class Child1(Parent1): + x: ClassVar[tuple[int, int]] = (0, 1) + + +def func1(m: Meta1) -> None: + if issubclass(m, Parent1): + reveal_type(m, expected_text="type[Parent1]") + else: + reveal_type(m, expected_text="Meta1") + + +def func2(m: Meta1) -> None: + if issubclass(m, Child1): + reveal_type(m, expected_text="type[Child1]") + else: + reveal_type(m, expected_text="Meta1") + + +def func3(m: ABCMeta) -> None: + if issubclass(m, Child1): + reveal_type(m, expected_text="type[Child1]") + else: + reveal_type(m, expected_text="ABCMeta") + + +def func4(m: ABCMeta) -> None: + if issubclass(m, (Parent1, Child1, int)): + reveal_type(m, expected_text="type[Parent1] | type[Child1]") + else: + reveal_type(m, expected_text="ABCMeta") + + +def func5(m: Meta1) -> None: + if issubclass(m, (Parent1, Child1)): + reveal_type(m, expected_text="type[Parent1] | type[Child1]") + else: + reveal_type(m, expected_text="Meta1") + + +def func6(m: Meta1, x: type[Any]) -> None: + if issubclass(m, x): + reveal_type(m, expected_text="Meta1") + else: + reveal_type(m, expected_text="Meta1") + + +def func7(m: Meta1, x: type[Parent1] | type[Child1]) -> None: + if issubclass(m, x): + reveal_type(m, expected_text="type[Parent1] | type[Child1]") + else: + reveal_type(m, expected_text="Meta1") diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance2.py b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance2.py index 5d995ee35..af624238d 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance2.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance2.py @@ -2,13 +2,49 @@ # on "self" and other bound TypeVars. -class Base: +from typing import Self, TypeVar + + +class ClassA: def get_value(self) -> int: - if isinstance(self, Derived): + if isinstance(self, ChildB): return self.calculate() return 7 -class Derived(Base): +class ChildB(ClassA): def calculate(self) -> int: return 2 * 2 + + +TC = TypeVar("TC") + + +class ClassC: + @classmethod + def test(cls: type[TC], id: int | TC): + if isinstance(id, cls): + reveal_type(id, expected_text="object*") + else: + reveal_type(id, expected_text="int") + + +TD = TypeVar("TD", bound="ClassD") + + +class ClassD: + @classmethod + def test(cls: type[TD], id: int | TD): + if isinstance(id, cls): + reveal_type(id, expected_text="ClassD*") + else: + reveal_type(id, expected_text="int") + + +class ClassE: + @classmethod + def test(cls: type[Self], id: int | Self): + if isinstance(id, cls): + reveal_type(id, expected_text="ClassE") + else: + reveal_type(id, expected_text="int") diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance4.py b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance4.py index 427acd9e7..74b74e348 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance4.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance4.py @@ -57,3 +57,10 @@ def check_callable5(fn: Callable[P, None]) -> None: reveal_type(fn, expected_text="ClassA") else: reveal_type(fn, expected_text="(**P@check_callable5) -> None") + + +def check_callable6(o: object | Callable[[int], int]): + if isinstance(o, Callable): + reveal_type(o, expected_text="((...) -> Unknown) | ((int) -> int)") + else: + reveal_type(o, expected_text="object") diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance8.py b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance8.py index 3999e4fe1..52fa8efa9 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance8.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingIsinstance8.py @@ -16,10 +16,13 @@ def f(self) -> None: def func1(cls: Any): assert issubclass(cls, Base) + reveal_type(cls, expected_text="type[Base]") _ = cls() def func2(cls: Any): assert isinstance(cls, type) + reveal_type(cls, expected_text="type") assert issubclass(cls, Base) + reveal_type(cls, expected_text="type[Base]") _ = cls() diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingLiteral2.py b/packages/pyright-internal/src/tests/samples/typeNarrowingLiteral2.py index f10d82154..7d08f2805 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingLiteral2.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingLiteral2.py @@ -2,7 +2,7 @@ # types that have enumerated literals (bool and enums). from enum import Enum -from typing import Literal, Union +from typing import Any, Literal, Union class SomeEnum(Enum): @@ -61,3 +61,17 @@ def func5(x: Union[MyEnum, str]): reveal_type(x, expected_text="Literal[MyEnum.ONE]") else: reveal_type(x, expected_text="str") + + +def func6(x: Any): + if x is MyEnum.ZERO: + reveal_type(x, expected_text="Literal[MyEnum.ZERO]") + else: + reveal_type(x, expected_text="Any") + + +def func7(x: Any): + if x == MyEnum.ZERO: + reveal_type(x, expected_text="Literal[MyEnum.ZERO]") + else: + reveal_type(x, expected_text="Any") diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingTupleLength1.py b/packages/pyright-internal/src/tests/samples/typeNarrowingTupleLength1.py index 0136908c3..922c39d38 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingTupleLength1.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingTupleLength1.py @@ -1,6 +1,6 @@ # This sample tests type narrowing of tuples based on len(x) test. -from typing import TypeVar +from typing import Literal, TypeVar def func1(val: tuple[int] | tuple[int, int] | tuple[str, str]): @@ -28,7 +28,8 @@ def func2(val: tuple[int] | tuple[int, ...]): def func3(val: tuple[int] | tuple[()]): - if len(val) == 0: + N = 0 + if len(val) == N: reveal_type(val, expected_text="tuple[()]") else: reveal_type(val, expected_text="tuple[int]") @@ -52,9 +53,10 @@ def func5( | tuple[str] | tuple[str, str, str] | tuple[int, *tuple[str, ...], str] - | tuple[int, *tuple[float, ...]] + | tuple[int, *tuple[float, ...]], + length: Literal[2], ): - if len(val) == 2: + if len(val) == length: reveal_type( val, expected_text="tuple[int, int] | tuple[int, str] | tuple[int, float]" ) diff --git a/packages/pyright-internal/src/tests/samples/typeNarrowingTypeIs1.py b/packages/pyright-internal/src/tests/samples/typeNarrowingTypeIs1.py index 9bd3a24a8..a6ec7832a 100644 --- a/packages/pyright-internal/src/tests/samples/typeNarrowingTypeIs1.py +++ b/packages/pyright-internal/src/tests/samples/typeNarrowingTypeIs1.py @@ -110,3 +110,20 @@ def func8(a: _TC, b: _TC) -> _TC: return a reveal_type(a, expected_text="CParent*") return a + + +class F: + def method1(self, v: object): + if type(self) == type(v): + reveal_type(self, expected_text="Self@F") + else: + reveal_type(self, expected_text="Self@F") + + +class G(str): + @classmethod + def method1(cls, v: str): + if type(v) is cls: + reveal_type(v, expected_text="G") + else: + reveal_type(v, expected_text="str") diff --git a/packages/pyright-internal/src/tests/samples/typePromotions1.py b/packages/pyright-internal/src/tests/samples/typePromotions1.py index 99c38e0bf..6b6b774b6 100644 --- a/packages/pyright-internal/src/tests/samples/typePromotions1.py +++ b/packages/pyright-internal/src/tests/samples/typePromotions1.py @@ -28,3 +28,17 @@ def func3(x: IntSubclass) -> float: def func4(x: IntNewType) -> float: return x + + +def func5(f: float): + if isinstance(f, float): + reveal_type(f, expected_text="float") + else: + reveal_type(f, expected_text="int") + + +def func6(f: complex): + if isinstance(f, float): + reveal_type(f, expected_text="float") + else: + reveal_type(f, expected_text="complex | int") diff --git a/packages/pyright-internal/src/tests/samples/typeVar8.py b/packages/pyright-internal/src/tests/samples/typeVar8.py index 7696997fc..8805e059c 100644 --- a/packages/pyright-internal/src/tests/samples/typeVar8.py +++ b/packages/pyright-internal/src/tests/samples/typeVar8.py @@ -1,30 +1,88 @@ -# This sample tests the handling of a TypeVar symbol that is -# not representing another type. +# This sample tests the handling of a TypeVar symbol when it is +# used as a runtime object rather than a special form. -from typing import TypeVar +import typing as t +import typing_extensions as te -T = TypeVar("T") -S = TypeVar("S", bound=str) +T1 = t.TypeVar("T1") +S1 = t.TypeVar("S1", bound=str) +Ts1 = t.TypeVarTuple("Ts1") +P1 = t.ParamSpec("P1") # In these cases, the TypeVar symbol simply represents the TypeVar # object itself, rather than representing a type variable. -T.__name__ -S.__name__ -S.__bound__ +T1.__name__ +S1.__name__ +S1.__bound__ +Ts1.__name__ +P1.__name__ -def func1(x: bool, a: T, b: S) -> T | S: - reveal_type(T.__name__, expected_text="str") - reveal_type(S.__name__, expected_text="str") +def func1(x: bool, a: T1, b: S1) -> T1 | S1: + reveal_type(T1.__name__, expected_text="str") + reveal_type(S1.__name__, expected_text="str") + reveal_type(Ts1.__name__, expected_text="str") + reveal_type(P1.__name__, expected_text="str") - # This should generate an error + # This should generate an error, but it doesn't because + # "type.__name__" is defined as an instance variable in + # builtins.pyi. a.__name__ - # This should generate an error + # This should generate an error, but it doesn't because + # "type.__name__" is defined as an instance variable in + # builtins.pyi. b.__name__ if x: return a else: return b + + +T2 = te.TypeVar("T2") +S2 = te.TypeVar("S2", bound=str) +Ts2 = te.TypeVarTuple("Ts2") +P2 = te.ParamSpec("P2") + +T2.__name__ +S2.__name__ +S2.__bound__ +Ts2.__name__ +P2.__name__ + + +def func2(x: bool, a: T2, b: S2) -> T2 | S2: + reveal_type(T2.__name__, expected_text="str") + reveal_type(S2.__name__, expected_text="str") + reveal_type(Ts2.__name__, expected_text="str") + reveal_type(P2.__name__, expected_text="str") + + if x: + return a + else: + return b + + +def func3(t: t.TypeVar, ts: t.TypeVarTuple = ..., p: t.ParamSpec = ...) -> None: + ... + + +func3(T1, Ts1, P1) + +# This should generate an error because the runtime object typing.TypeVar +# is not the same as typing_extensions.TypeVar. +func3(T2) + + +def func4(t: te.TypeVar, ts: te.TypeVarTuple = ..., p: te.ParamSpec = ...) -> None: + ... + + +func4(T2, Ts2, P2) + + +# This should generate an error because the runtime object typing.TypeVar +# is not the same as typing_extensions.TypeVar. +func4(T1) diff --git a/packages/pyright-internal/src/tests/samples/typeVarDefaultClass4.py b/packages/pyright-internal/src/tests/samples/typeVarDefaultClass4.py new file mode 100644 index 000000000..c51bb9355 --- /dev/null +++ b/packages/pyright-internal/src/tests/samples/typeVarDefaultClass4.py @@ -0,0 +1,23 @@ +# This sample tests the handling of TypeVar defaults with isinstance type +# narrowing. + +from typing import Any, Generic, ParamSpec, TypeVar + + +P = ParamSpec("P", default=...) +R = TypeVar("R", default=Any) + + +class ParentA(Generic[P, R]): + ... + + +class ChildA(ParentA[P, R]): + pass + + +def func(x: ParentA[[int], int]): + if isinstance(x, ChildA): + reveal_type(x, expected_text="ChildA[(int), int]") + else: + reveal_type(x, expected_text="ParentA[(int), int]") diff --git a/packages/pyright-internal/src/tests/samples/typedDict23.py b/packages/pyright-internal/src/tests/samples/typedDict23.py index 5cf04cd65..4458b9efd 100644 --- a/packages/pyright-internal/src/tests/samples/typedDict23.py +++ b/packages/pyright-internal/src/tests/samples/typedDict23.py @@ -14,15 +14,23 @@ class TD2(TD1): td1: TD1 = {"a": 3} -reveal_type(td1.update, expected_text="(__m: Partial[TD1], /) -> None") +reveal_type( + td1.update, + expected_text="Overload[(__m: Iterable[tuple[Literal['a'], int] | tuple[Literal['b'], str]], /) -> None, (__m: Partial[TD1], /) -> None, (*, a: int = ..., b: str = ...) -> None]", +) td1.update({}) td1.update({"b": ""}) td2: TD2 = {"a": 0, "c": 3} -reveal_type(td2.update, expected_text="(__m: Partial[TD2], /) -> None") +reveal_type( + td2.update, + expected_text="Overload[(__m: Iterable[tuple[Literal['a'], int] | tuple[Literal['b'], str] | tuple[Literal['c'], int]], /) -> None, (__m: Partial[TD2], /) -> None, (*, a: int = ..., b: str = ..., c: int = ...) -> None]", +) +# This should generate an error because "c" within TD1 may be incompatible with "int". +# A second error is generated to indicate that no overloads are compatible. td2.update(td1) @@ -31,4 +39,7 @@ class TD3(TypedDict): td3: TD3 = {} -reveal_type(td3.update, expected_text="(__m: Partial[TD3], /) -> None") +reveal_type( + td3.update, + expected_text="Overload[(__m: Iterable[tuple[Literal['a'], str]], /) -> None, (__m: Partial[TD3], /) -> None, (*, a: str = ...) -> None]", +) diff --git a/packages/pyright-internal/src/tests/samples/typedDict5.py b/packages/pyright-internal/src/tests/samples/typedDict5.py index ff830fa62..5b9abe144 100644 --- a/packages/pyright-internal/src/tests/samples/typedDict5.py +++ b/packages/pyright-internal/src/tests/samples/typedDict5.py @@ -24,6 +24,11 @@ class Movie4(TypedDict, total=True): earnings: float +class Movie5(TypedDict, total=True): + name: str + year: float + + movie1: Movie1 = Movie2(name="hello", year=1971) # This should generate an error because @@ -34,7 +39,7 @@ class Movie4(TypedDict, total=True): # items are required in Movie3 but not Movie2. movie3: Movie3 = Movie2(name="hello", year=1971) -# This should generate an error +# This should generate an error. movie4: Movie4 = Movie3(name="hello", year=1971) movie5: Movie3 = Movie4(name="hello", year=1971, earnings=23) @@ -48,3 +53,9 @@ class Movie4(TypedDict, total=True): movie8: Movie2 = {"year": 1981, "name": "test"} movie8["year"] = 1982 + +movie9 = Movie3(name="", year=1971) + +# This should generate an error because "year" is mutable, +# so its type must match exactly. +movie10: Movie5 = movie9 diff --git a/packages/pyright-internal/src/tests/samples/typedDictReadOnly1.py b/packages/pyright-internal/src/tests/samples/typedDictReadOnly1.py index 345decfb6..d5473ca84 100644 --- a/packages/pyright-internal/src/tests/samples/typedDictReadOnly1.py +++ b/packages/pyright-internal/src/tests/samples/typedDictReadOnly1.py @@ -14,25 +14,14 @@ class TD1(TypedDict): d: ReadOnly[ReadOnly[str]] -TD2 = TypedDict("TD2", {"a": ReadOnly[str]}, total=True, readonly=True) -TD3 = TypedDict("TD3", {"a": ReadOnly[str]}, readonly=False, total=True) - -# This should generate an error because readonly accepts only bool literals. -TD4 = TypedDict("TD4", {"a": ReadOnly[str]}, total=True, readonly=1) - -# This should generate an error because TypedDict doesn't accept additional parameters. -TD5 = TypedDict("TD5", {"a": ReadOnly[str]}, total=True, readonly=True, foo=1) +TD2 = TypedDict("TD2", {"a": ReadOnly[str]}, total=True) +TD3 = TypedDict("TD3", {"a": ReadOnly[str]}, total=True) class F1(TypedDict): a: Required[int] -class F2(F1, readonly=True): - # This should generate an error because it is redefined as read-only. - a: int - - class F3(F1): # This should generate an error because it is redefined as read-only. a: ReadOnly[int] diff --git a/packages/pyright-internal/src/tests/samples/typedDictReadOnly2.py b/packages/pyright-internal/src/tests/samples/typedDictReadOnly2.py index 138419a65..7f8502f99 100644 --- a/packages/pyright-internal/src/tests/samples/typedDictReadOnly2.py +++ b/packages/pyright-internal/src/tests/samples/typedDictReadOnly2.py @@ -5,6 +5,7 @@ Generic, Literal, Mapping, + Never, NotRequired, Required, TypeVar, @@ -44,22 +45,38 @@ class TD2(TD1[_T]): class TD3(TypedDict, total=True): a: str + b: NotRequired[str] + c: NotRequired[str] class TD4(TypedDict, total=True): a: ReadOnly[str] + b: NotRequired[str] + c: NotRequired[str] td3: TD3 = {"a": ""} td4: TD4 = {"a": ""} -reveal_type(td4.update, expected_text="(__m: Never, /) -> None") - -# This should generate an error. +# This should generate an error because "a" is ReadOnly. +# It generates a second error because no overloads are found. td4.update({"a", ""}) -# This should generate an error. -td4.update({}) +# This should generate an error because "a" is ReadOnly. +td4.update(a="") + +# This should generate an error because "a" is ReadOnly. +# It generates a second error because no overloads are found. +td4.update([("a", "")]) + +td4.update({"b": ""}) +td4.update({"b": "", "c": ""}) +td4.update(b="") +td4.update(c="") +td4.update(c="", b="") +td4.update([("b", "")]) +td4.update([("c", "")]) +td4.update([("b", ""), ("c", "")]) td5 = td3 | td4 @@ -102,7 +119,7 @@ class TD7(TD6): class TD8(TypedDict): - a: NotRequired[ReadOnly[int]] + a: ReadOnly[NotRequired[int]] class TD9(TypedDict): @@ -120,3 +137,74 @@ class TD10(TypedDict): # and required in TD10 but writable and not required in # TD9, which means it can be deleted. n2: TD9 = td10 + + +class TD11(TypedDict): + a: int + + +class TD12(TypedDict): + a: ReadOnly[float] + + +class TD13(TypedDict): + a: float + + +v1 = TD11(a=2) +v2: TD12 = v1 + +# This should generate an error because "a" is writable +# and is therefore invariant. +v3: TD13 = v1 + + +class TD14(TypedDict): + x: int + + +class TD15(TypedDict): + x: int + y: ReadOnly[NotRequired[str]] + + +td14: TD14 = {"x": 1} + +# This should generate an error because 'str' is not +# compatible with 'object'. +td15: TD15 = td14 + + +class TD16(TypedDict): + x: int + + +class TD17(TypedDict): + x: int + y: ReadOnly[NotRequired[object]] + + +td16: TD16 = {"x": 1} +ted17: TD17 = td16 + + +class TD18(TypedDict): + x: NotRequired[ReadOnly[int]] + y: int + + +td18_1: TD18 = {"x": 1, "y": 2} +td18_2: TD18 = {"x": 2, "y": 4} + +# This should generate an error because "x" is read-only. +# It generates a second error because no overloads are found. +td18_1.update(td18_2) + + +class TD19(TypedDict): + x: NotRequired[Never] + y: ReadOnly[int] + + +def update_a(a: TD18, b: TD19) -> None: + a.update(b) diff --git a/packages/pyright-internal/src/tests/sourceFile.test.ts b/packages/pyright-internal/src/tests/sourceFile.test.ts index c0f8c9deb..31088f087 100644 --- a/packages/pyright-internal/src/tests/sourceFile.test.ts +++ b/packages/pyright-internal/src/tests/sourceFile.test.ts @@ -20,7 +20,8 @@ import { createServiceProvider } from '../common/serviceProviderExtensions'; test('Empty', () => { const filePath = combinePaths(process.cwd(), 'src/tests/samples/test_file1.py'); const fs = createFromRealFileSystem(); - const sourceFile = new SourceFile(fs, filePath, '', false, false, { isEditMode: false }); + const serviceProvider = createServiceProvider(fs); + const sourceFile = new SourceFile(serviceProvider, filePath, '', false, false, { isEditMode: false }); const configOptions = new ConfigOptions(process.cwd()); const sp = createServiceProvider(fs); const importResolver = new ImportResolver(sp, configOptions, new FullAccessHost(fs)); diff --git a/packages/pyright-internal/src/tests/testStateUtils.ts b/packages/pyright-internal/src/tests/testStateUtils.ts index 80adce605..fdd1dd85f 100644 --- a/packages/pyright-internal/src/tests/testStateUtils.ts +++ b/packages/pyright-internal/src/tests/testStateUtils.ts @@ -14,11 +14,17 @@ import { assertNever } from '../common/debug'; import { FileEditAction, FileEditActions, FileOperations } from '../common/editAction'; import { FileSystem } from '../common/fileSystem'; import { convertUriToPath, getDirectoryPath, isFile } from '../common/pathUtils'; -import { rangesAreEqual } from '../common/textRange'; +import { TextRange, rangesAreEqual } from '../common/textRange'; import { applyTextEditsToString } from '../common/workspaceEditUtils'; import { Range } from './harness/fourslash/fourSlashTypes'; import { TestState } from './harness/fourslash/testState'; -import { CreateFile, DeleteFile, RenameFile, TextDocumentEdit } from 'vscode-languageserver'; +import { CancellationToken, CreateFile, DeleteFile, RenameFile, TextDocumentEdit } from 'vscode-languageserver'; +import { Program } from '../analyzer/program'; +import { ConfigOptions } from '../common/configOptions'; +import { findNodeByOffset } from '../analyzer/parseTreeUtils'; +import { DocumentSymbolCollector } from '../languageService/documentSymbolCollector'; +import { NameNode } from '../parser/parseNodes'; +import { isArray } from '../common/core'; export function convertFileEditActionToString(edit: FileEditAction): string { return `'${edit.replacementText.replace(/\n/g, '!n!')}'@'${edit.filePath}:(${edit.range.start.line},${ @@ -165,3 +171,46 @@ export function convertWorkspaceEditToFileEditActions(fs: FileSystem, edit: Work } return { edits, fileOperations: fileOperations }; } + +export function verifyReferencesAtPosition( + program: Program, + configOption: ConfigOptions, + symbolNames: string | string[], + fileName: string, + position: number, + ranges: Range[] +) { + const sourceFile = program.getBoundSourceFile(fileName); + assert(sourceFile); + + const node = findNodeByOffset(sourceFile.getParseResults()!.parseTree, position); + const decls = DocumentSymbolCollector.getDeclarationsForNode( + program, + node as NameNode, + /* resolveLocalName */ true, + CancellationToken.None + ); + + const rangesByFile = createMapFromItems(ranges, (r) => r.fileName); + for (const rangeFileName of rangesByFile.keys()) { + const collector = new DocumentSymbolCollector( + program, + isArray(symbolNames) ? symbolNames : [symbolNames], + decls, + program.getBoundSourceFile(rangeFileName)!.getParseResults()!.parseTree, + CancellationToken.None, + { + treatModuleInImportAndFromImportSame: true, + skipUnreachableCode: false, + } + ); + + const results = collector.collect(); + const rangesOnFile = rangesByFile.get(rangeFileName)!; + assert.strictEqual(results.length, rangesOnFile.length, `${rangeFileName}@${symbolNames}`); + + for (const result of results) { + assert(rangesOnFile.some((r) => r.pos === result.range.start && r.end === TextRange.getEnd(result.range))); + } + } +} diff --git a/packages/pyright-internal/src/tests/testUtils.ts b/packages/pyright-internal/src/tests/testUtils.ts index 02fae3bb3..46ec0c540 100644 --- a/packages/pyright-internal/src/tests/testUtils.ts +++ b/packages/pyright-internal/src/tests/testUtils.ts @@ -25,8 +25,8 @@ import { Diagnostic, DiagnosticCategory } from '../common/diagnostic'; import { DiagnosticSink, TextRangeDiagnosticSink } from '../common/diagnosticSink'; import { FullAccessHost } from '../common/fullAccessHost'; import { createFromRealFileSystem } from '../common/realFileSystem'; -import { ParseOptions, Parser, ParseResults } from '../parser/parser'; import { createServiceProvider } from '../common/serviceProviderExtensions'; +import { ParseOptions, Parser, ParseResults } from '../parser/parser'; // This is a bit gross, but it's necessary to allow the fallback typeshed // directory to be located when running within the jest environment. This @@ -122,6 +122,7 @@ export function buildAnalyzerFileInfo( isTypingStubFile: false, isInPyTypedPackage: false, isTypingExtensionsStubFile: false, + isTypeshedStubFile: false, isBuiltInStubFile: false, ipythonMode: IPythonMode.None, accessedSymbolSet: new Set(), diff --git a/packages/pyright-internal/src/tests/typeEvaluator1.test.ts b/packages/pyright-internal/src/tests/typeEvaluator1.test.ts index 32a630df2..5b7557599 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator1.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator1.test.ts @@ -459,6 +459,12 @@ test('TypeNarrowingIsinstance18', () => { TestUtils.validateResults(analysisResults, 0); }); +test('TypeNarrowingIsinstance19', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeNarrowingIsinstance19.py']); + + TestUtils.validateResults(analysisResults, 0); +}); + test('TypeNarrowingTupleLength1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeNarrowingTupleLength1.py']); @@ -1101,7 +1107,7 @@ test('Property10', () => { test('Property11', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['property11.py']); - TestUtils.validateResults(analysisResults, 1); + TestUtils.validateResults(analysisResults, 2); }); test('Property12', () => { @@ -1275,7 +1281,7 @@ test('Tuple6', () => { test('Tuple7', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['tuple7.py']); - TestUtils.validateResults(analysisResults, 1); + TestUtils.validateResults(analysisResults, 2); }); test('Tuple8', () => { @@ -1589,7 +1595,7 @@ test('PseudoGeneric3', () => { test('LiteralString1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['literalString1.py']); - TestUtils.validateResults(analysisResults, 8); + TestUtils.validateResults(analysisResults, 10); }); test('LiteralString2', () => { diff --git a/packages/pyright-internal/src/tests/typeEvaluator2.test.ts b/packages/pyright-internal/src/tests/typeEvaluator2.test.ts index 5f011091a..6c1872768 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator2.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator2.test.ts @@ -75,7 +75,7 @@ test('Assignment1', () => { test('Assignment2', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['assignment2.py']); - TestUtils.validateResults(analysisResults, 2); + TestUtils.validateResults(analysisResults, 3); }); test('Assignment3', () => { @@ -164,7 +164,7 @@ test('AugmentedAssignment3', () => { test('Super1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['super1.py']); - TestUtils.validateResults(analysisResults, 4); + TestUtils.validateResults(analysisResults, 5); }); test('Super2', () => { @@ -285,11 +285,11 @@ test('isInstance3', () => { configOptions.defaultPythonVersion = PythonVersion.V3_9; const analysisResults1 = TestUtils.typeAnalyzeSampleFiles(['isinstance3.py'], configOptions); - TestUtils.validateResults(analysisResults1, 1); + TestUtils.validateResults(analysisResults1, 2); configOptions.defaultPythonVersion = PythonVersion.V3_10; const analysisResults2 = TestUtils.typeAnalyzeSampleFiles(['isinstance3.py'], configOptions); - TestUtils.validateResults(analysisResults2, 1); + TestUtils.validateResults(analysisResults2, 2); }); test('isInstance4', () => { @@ -473,7 +473,10 @@ test('ConstrainedTypeVar14', () => { }); test('ConstrainedTypeVar15', () => { - const analysisResults = TestUtils.typeAnalyzeSampleFiles(['constrainedTypeVar15.py']); + const configOptions = new ConfigOptions('.'); + configOptions.diagnosticRuleSet.disableBytesTypePromotions = true; + + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['constrainedTypeVar15.py'], configOptions); TestUtils.validateResults(analysisResults, 0); }); @@ -677,6 +680,12 @@ test('Solver29', () => { TestUtils.validateResults(analysisResults, 0); }); +test('Solver30', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solver30.py']); + + TestUtils.validateResults(analysisResults, 0); +}); + test('SolverScoring1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['solverScoring1.py']); @@ -1064,7 +1073,7 @@ test('Protocol2', () => { test('Protocol3', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['protocol3.py']); - TestUtils.validateResults(analysisResults, 4); + TestUtils.validateResults(analysisResults, 8); }); test('Protocol4', () => { @@ -1317,6 +1326,24 @@ test('Protocol44', () => { TestUtils.validateResults(analysisResults, 0); }); +test('Protocol45', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['protocol45.py']); + + TestUtils.validateResults(analysisResults, 0); +}); + +test('Protocol46', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['protocol46.py']); + + TestUtils.validateResults(analysisResults, 0); +}); + +test('Protocol47', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['protocol47.py']); + + TestUtils.validateResults(analysisResults, 0); +}); + test('TypedDict1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typedDict1.py']); @@ -1344,7 +1371,7 @@ test('TypedDict4', () => { test('TypedDict5', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typedDict5.py']); - TestUtils.validateResults(analysisResults, 3); + TestUtils.validateResults(analysisResults, 4); }); test('TypedDict6', () => { @@ -1386,7 +1413,7 @@ test('TypedDict11', () => { test('TypedDict12', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typedDict12.py']); - TestUtils.validateResults(analysisResults, 6); + TestUtils.validateResults(analysisResults, 7); }); test('TypedDict13', () => { @@ -1452,7 +1479,7 @@ test('TypedDict22', () => { test('TypedDict23', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typedDict23.py']); - TestUtils.validateResults(analysisResults, 0); + TestUtils.validateResults(analysisResults, 2); }); test('TypedDict24', () => { diff --git a/packages/pyright-internal/src/tests/typeEvaluator3.test.ts b/packages/pyright-internal/src/tests/typeEvaluator3.test.ts index 9843ce275..41654fc0a 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator3.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator3.test.ts @@ -394,6 +394,18 @@ test('Loop38', () => { TestUtils.validateResults(analysisResults, 0); }); +test('Loop39', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['loop39.py']); + + TestUtils.validateResults(analysisResults, 0); +}); + +test('Loop40', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['loop40.py']); + + TestUtils.validateResults(analysisResults, 0); +}); + test('ForLoop1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['forLoop1.py']); @@ -741,7 +753,7 @@ test('Classes1', () => { test('Classes3', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['classes3.py']); - TestUtils.validateResults(analysisResults, 4); + TestUtils.validateResults(analysisResults, 1); }); test('Classes4', () => { @@ -828,7 +840,7 @@ test('MethodOverride2', () => { // Turn on errors. configOptions.diagnosticRuleSet.reportIncompatibleMethodOverride = 'error'; analysisResults = TestUtils.typeAnalyzeSampleFiles(['methodOverride2.py'], configOptions); - TestUtils.validateResults(analysisResults, 5); + TestUtils.validateResults(analysisResults, 6); }); test('MethodOverride3', () => { @@ -977,7 +989,7 @@ test('TypePromotions1', () => { test('Index1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['index1.py']); - TestUtils.validateResults(analysisResults, 7); + TestUtils.validateResults(analysisResults, 10); }); test('ProtocolModule2', () => { @@ -1248,6 +1260,14 @@ test('MatchClass4', () => { TestUtils.validateResults(analysisResults, 0); }); +test('MatchClass5', () => { + const configOptions = new ConfigOptions('.'); + + configOptions.defaultPythonVersion = PythonVersion.V3_10; + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['matchClass5.py'], configOptions); + TestUtils.validateResults(analysisResults, 5); +}); + test('MatchValue1', () => { const configOptions = new ConfigOptions('.'); @@ -1625,7 +1645,7 @@ test('Subscript1', () => { test('Subscript2', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['subscript2.py']); - TestUtils.validateResults(analysisResults, 5); + TestUtils.validateResults(analysisResults, 8); }); test('Subscript3', () => { @@ -1634,7 +1654,7 @@ test('Subscript3', () => { // Analyze with Python 3.9 settings. configOptions.defaultPythonVersion = PythonVersion.V3_9; const analysisResults39 = TestUtils.typeAnalyzeSampleFiles(['subscript3.py'], configOptions); - TestUtils.validateResults(analysisResults39, 32); + TestUtils.validateResults(analysisResults39, 37); // Analyze with Python 3.10 settings. // These are disabled because PEP 637 was rejected. diff --git a/packages/pyright-internal/src/tests/typeEvaluator4.test.ts b/packages/pyright-internal/src/tests/typeEvaluator4.test.ts index aa3ee5857..0824c70c0 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator4.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator4.test.ts @@ -43,7 +43,7 @@ test('Required3', () => { test('Metaclass1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['metaclass1.py']); - TestUtils.validateResults(analysisResults, 2); + TestUtils.validateResults(analysisResults, 3); }); test('Metaclass2', () => { @@ -93,7 +93,7 @@ test('Metaclass10', () => { test('Metaclass11', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['metaclass11.py']); - TestUtils.validateResults(analysisResults, 1); + TestUtils.validateResults(analysisResults, 4); }); test('AssignmentExpr1', () => { @@ -311,7 +311,7 @@ test('Overload7', () => { test('Overload8', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['overload8.py']); - TestUtils.validateResults(analysisResults, 2); + TestUtils.validateResults(analysisResults, 4); }); test('Overload10', () => { @@ -326,7 +326,7 @@ test('Overload11', () => { test('Overload12', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['overload12.py']); - TestUtils.validateResults(analysisResults, 1); + TestUtils.validateResults(analysisResults, 2); }); test('Overload13', () => { @@ -341,7 +341,12 @@ test('Overload14', () => { test('Overload15', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['overload15.py']); - TestUtils.validateResults(analysisResults, 9, 1); + TestUtils.validateResults(analysisResults, 8, 1); +}); + +test('Overload16', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['overload16.py']); + TestUtils.validateResults(analysisResults, 2); }); test('Final1', () => { @@ -522,7 +527,7 @@ test('MemberAccess18', () => { test('MemberAccess19', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['memberAccess19.py']); - TestUtils.validateResults(analysisResults, 5); + TestUtils.validateResults(analysisResults, 10); }); test('MemberAccess20', () => { @@ -545,6 +550,11 @@ test('MemberAccess23', () => { TestUtils.validateResults(analysisResults, 0); }); +test('MemberAccess24', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['memberAccess24.py']); + TestUtils.validateResults(analysisResults, 0); +}); + test('DataClassNamedTuple1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['dataclassNamedTuple1.py']); @@ -779,6 +789,7 @@ test('Generic3', () => { test('Unions1', () => { const configOptions = new ConfigOptions('.'); + configOptions.diagnosticRuleSet.disableBytesTypePromotions = true; // Analyze with Python 3.9 settings. This will generate errors. configOptions.defaultPythonVersion = PythonVersion.V3_9; @@ -881,7 +892,7 @@ test('ParamSpec8', () => { test('ParamSpec9', () => { const results = TestUtils.typeAnalyzeSampleFiles(['paramSpec9.py']); - TestUtils.validateResults(results, 13); + TestUtils.validateResults(results, 14); }); test('ParamSpec10', () => { @@ -1016,7 +1027,7 @@ test('ParamSpec35', () => { test('ParamSpec36', () => { const results = TestUtils.typeAnalyzeSampleFiles(['paramSpec36.py']); - TestUtils.validateResults(results, 2); + TestUtils.validateResults(results, 3); }); test('ParamSpec37', () => { @@ -1071,7 +1082,7 @@ test('ParamSpec46', () => { test('ParamSpec47', () => { const results = TestUtils.typeAnalyzeSampleFiles(['paramSpec47.py']); - TestUtils.validateResults(results, 2); + TestUtils.validateResults(results, 3); }); test('ParamSpec48', () => { @@ -1079,6 +1090,11 @@ test('ParamSpec48', () => { TestUtils.validateResults(results, 0); }); +test('ParamSpec49', () => { + const results = TestUtils.typeAnalyzeSampleFiles(['paramSpec49.py']); + TestUtils.validateResults(results, 5); +}); + test('ClassVar1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['classVar1.py']); @@ -1281,3 +1297,9 @@ test('Del2', () => { TestUtils.validateResults(analysisResults, 2); }); + +test('Any1', () => { + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['any1.py']); + + TestUtils.validateResults(analysisResults, 4); +}); diff --git a/packages/pyright-internal/src/tests/typeEvaluator5.test.ts b/packages/pyright-internal/src/tests/typeEvaluator5.test.ts index eb1f50c61..c4e7270b6 100644 --- a/packages/pyright-internal/src/tests/typeEvaluator5.test.ts +++ b/packages/pyright-internal/src/tests/typeEvaluator5.test.ts @@ -226,6 +226,14 @@ test('TypeVarDefaultClass3', () => { TestUtils.validateResults(analysisResults, 9); }); +test('TypeVarDefaultClass4', () => { + const configOptions = new ConfigOptions('.'); + configOptions.defaultPythonVersion = PythonVersion.V3_13; + + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeVarDefaultClass4.py'], configOptions); + TestUtils.validateResults(analysisResults, 0); +}); + test('TypeVarDefaultTypeAlias1', () => { const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeVarDefaultTypeAlias1.py']); TestUtils.validateResults(analysisResults, 0); @@ -293,8 +301,11 @@ test('TypePrinter3', () => { }); test('TypeAliasType1', () => { - const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeAliasType1.py']); - TestUtils.validateResults(analysisResults, 15); + const configOptions = new ConfigOptions('.'); + configOptions.defaultPythonVersion = PythonVersion.V3_12; + + const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typeAliasType1.py'], configOptions); + TestUtils.validateResults(analysisResults, 14); }); test('TypeAliasType2', () => { @@ -307,7 +318,7 @@ test('TypedDictReadOnly1', () => { configOptions.diagnosticRuleSet.enableExperimentalFeatures = true; const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typedDictReadOnly1.py'], configOptions); - TestUtils.validateResults(analysisResults, 5); + TestUtils.validateResults(analysisResults, 2); }); test('TypedDictReadOnly2', () => { @@ -315,7 +326,7 @@ test('TypedDictReadOnly2', () => { configOptions.diagnosticRuleSet.enableExperimentalFeatures = true; const analysisResults = TestUtils.typeAnalyzeSampleFiles(['typedDictReadOnly2.py'], configOptions); - TestUtils.validateResults(analysisResults, 8); + TestUtils.validateResults(analysisResults, 15); }); test('DataclassTransform1', () => { diff --git a/packages/pyright-internal/src/tests/typePrinter.test.ts b/packages/pyright-internal/src/tests/typePrinter.test.ts index afaea020a..c7c881aad 100644 --- a/packages/pyright-internal/src/tests/typePrinter.test.ts +++ b/packages/pyright-internal/src/tests/typePrinter.test.ts @@ -18,7 +18,7 @@ import { FunctionType, FunctionTypeFlags, ModuleType, - NoneType, + NeverType, TypeVarType, UnboundType, UnknownType, @@ -45,12 +45,6 @@ test('SimpleTypes', () => { assert.strictEqual(printType(unboundType, PrintTypeFlags.None, returnTypeCallback), 'Unbound'); assert.strictEqual(printType(unboundType, PrintTypeFlags.PythonSyntax, returnTypeCallback), 'Any'); - const noneInstanceType = NoneType.createInstance(); - assert.strictEqual(printType(noneInstanceType, PrintTypeFlags.None, returnTypeCallback), 'None'); - - const noneInstantiableType = NoneType.createType(); - assert.strictEqual(printType(noneInstantiableType, PrintTypeFlags.None, returnTypeCallback), 'type[None]'); - const moduleType = ModuleType.create('Test', ''); assert.strictEqual(printType(moduleType, PrintTypeFlags.None, returnTypeCallback), 'Module("Test")'); assert.strictEqual(printType(moduleType, PrintTypeFlags.PythonSyntax, returnTypeCallback), 'Any'); @@ -122,7 +116,7 @@ test('FunctionTypes', () => { FunctionType.addParameter(funcTypeA, { category: ParameterCategory.Simple, hasDeclaredType: true, - type: NoneType.createInstance(), + type: AnyType.create(), name: 'a', }); @@ -146,39 +140,42 @@ test('FunctionTypes', () => { name: 'kwargs', }); - funcTypeA.details.declaredReturnType = NoneType.createInstance(); + funcTypeA.details.declaredReturnType = NeverType.createNoReturn(); assert.strictEqual( printType(funcTypeA, PrintTypeFlags.None, returnTypeCallback), - '(a: None, /, *args: Any, **kwargs: Any) -> None' + '(a: Any, /, *args: Any, **kwargs: Any) -> NoReturn' + ); + assert.strictEqual( + printType(funcTypeA, PrintTypeFlags.PythonSyntax, returnTypeCallback), + 'Callable[..., NoReturn]' ); - assert.strictEqual(printType(funcTypeA, PrintTypeFlags.PythonSyntax, returnTypeCallback), 'Callable[..., None]'); const funcTypeB = FunctionType.createInstance('B', '', '', FunctionTypeFlags.None); FunctionType.addParameter(funcTypeB, { category: ParameterCategory.Simple, hasDeclaredType: true, - type: NoneType.createInstance(), + type: AnyType.create(), name: 'a', }); FunctionType.addParameter(funcTypeB, { category: ParameterCategory.Simple, hasDeclaredType: true, - type: NoneType.createInstance(), + type: AnyType.create(), }); const paramSpecP = TypeVarType.createInstance('P'); paramSpecP.details.isParamSpec = true; funcTypeB.details.paramSpec = paramSpecP; - funcTypeB.details.declaredReturnType = NoneType.createInstance(); + funcTypeB.details.declaredReturnType = NeverType.createNever(); - assert.strictEqual(printType(funcTypeB, PrintTypeFlags.None, returnTypeCallback), '(a: None, /, **P) -> None'); + assert.strictEqual(printType(funcTypeB, PrintTypeFlags.None, returnTypeCallback), '(a: Any, /, **P) -> Never'); assert.strictEqual( printType(funcTypeB, PrintTypeFlags.PythonSyntax, returnTypeCallback), - 'Callable[Concatenate[None, P], None]' + 'Callable[Concatenate[Any, P], Never]' ); const funcTypeC = FunctionType.createInstance('C', '', '', FunctionTypeFlags.None); @@ -204,8 +201,8 @@ test('FunctionTypes', () => { const funcTypeD = FunctionType.createInstance('D', '', '', FunctionTypeFlags.None); funcTypeD.details.paramSpec = paramSpecP; - funcTypeD.details.declaredReturnType = NoneType.createInstance(); + funcTypeD.details.declaredReturnType = AnyType.create(); - assert.strictEqual(printType(funcTypeD, PrintTypeFlags.None, returnTypeCallback), '(**P) -> None'); - assert.strictEqual(printType(funcTypeD, PrintTypeFlags.PythonSyntax, returnTypeCallback), 'Callable[P, None]'); + assert.strictEqual(printType(funcTypeD, PrintTypeFlags.None, returnTypeCallback), '(**P) -> Any'); + assert.strictEqual(printType(funcTypeD, PrintTypeFlags.PythonSyntax, returnTypeCallback), 'Callable[P, Any]'); }); diff --git a/packages/pyright-internal/src/tests/zipfs.test.ts b/packages/pyright-internal/src/tests/zipfs.test.ts index e89267e79..439f0bcee 100644 --- a/packages/pyright-internal/src/tests/zipfs.test.ts +++ b/packages/pyright-internal/src/tests/zipfs.test.ts @@ -19,6 +19,8 @@ function runTests(p: string): void { const stats = fs.statSync(zipRoot); assert.strictEqual(stats.isDirectory(), true); assert.strictEqual(stats.isFile(), false); + assert.strictEqual((stats as any).isZipDirectory(), true); + assert.strictEqual(stats.isSymbolicLink(), false); }); test('readdirEntriesSync root', () => { diff --git a/packages/pyright-internal/src/workspaceFactory.ts b/packages/pyright-internal/src/workspaceFactory.ts index 152c9dd0f..7d5666508 100644 --- a/packages/pyright-internal/src/workspaceFactory.ts +++ b/packages/pyright-internal/src/workspaceFactory.ts @@ -105,7 +105,8 @@ export class WorkspaceFactory { kinds: string[] ) => AnalyzerService, private readonly _isPythonPathImmutable: (path: string) => boolean, - private readonly _onWorkspaceCreated: (workspace: Workspace) => void + private readonly _onWorkspaceCreated: (workspace: Workspace) => void, + private readonly _onWorkspaceRemoved: (workspace: Workspace) => void ) { this._console.log(`WorkspaceFactory ${this._id} created`); } @@ -431,6 +432,9 @@ export class WorkspaceFactory { const workspace = this._map.get(key); if (workspace) { workspace.isInitialized.resolve(); + + this._onWorkspaceRemoved(workspace); + workspace.service.dispose(); this._console.log(`WorkspaceFactory ${this._id} remove ${key}`); this._map.delete(key); diff --git a/packages/pyright-internal/typeshed-fallback/commit.txt b/packages/pyright-internal/typeshed-fallback/commit.txt index f0fb58c56..ad0398c38 100644 --- a/packages/pyright-internal/typeshed-fallback/commit.txt +++ b/packages/pyright-internal/typeshed-fallback/commit.txt @@ -1 +1 @@ -aef4fa8756d2e13972a495c69a22a20bb66043f9 +1c184fea33d50ba430410cf1b25d4aea2df2981e diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/VERSIONS b/packages/pyright-internal/typeshed-fallback/stdlib/VERSIONS index 49433e346..acaa818d6 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/VERSIONS +++ b/packages/pyright-internal/typeshed-fallback/stdlib/VERSIONS @@ -35,6 +35,7 @@ _dummy_threading: 2.7-3.8 _heapq: 2.7- _imp: 3.0- _json: 2.7- +_locale: 2.7- _markupbase: 2.7- _msi: 2.7- _operator: 3.4- @@ -151,8 +152,10 @@ imp: 2.7-3.11 importlib: 2.7- importlib.metadata: 3.8- importlib.metadata._meta: 3.10- +importlib.readers: 3.10- importlib.resources: 3.7- importlib.resources.abc: 3.11- +importlib.resources.readers: 3.11- inspect: 2.7- io: 2.7- ipaddress: 3.3- @@ -180,6 +183,7 @@ multiprocessing.shared_memory: 3.8- netrc: 2.7- nis: 2.7- nntplib: 2.7- +nt: 2.7- ntpath: 2.7- nturl2path: 2.7- numbers: 2.7- @@ -249,6 +253,7 @@ sunau: 2.7- symbol: 2.7-3.9 symtable: 2.7- sys: 2.7- +sys._monitoring: 3.12- # Doesn't actually exist. See comments in the stub. sysconfig: 2.7- syslog: 2.7- tabnanny: 2.7- diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_ast.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_ast.pyi index 05e2a08fd..402b770c0 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_ast.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_ast.pyi @@ -602,7 +602,7 @@ if sys.version_info >= (3, 12): name: _Identifier class TypeAlias(stmt): - __match_args__ = ("name", "typeparams", "value") + __match_args__ = ("name", "type_params", "value") name: Name type_params: list[type_param] value: expr diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_collections_abc.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_collections_abc.pyi index 2b57f157a..8520e9e4e 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_collections_abc.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_collections_abc.pyi @@ -81,7 +81,7 @@ class dict_values(ValuesView[_VT_co], Generic[_KT_co, _VT_co]): # undocumented def mapping(self) -> MappingProxyType[_KT_co, _VT_co]: ... @final -class dict_items(ItemsView[_KT_co, _VT_co], Generic[_KT_co, _VT_co]): # undocumented +class dict_items(ItemsView[_KT_co, _VT_co]): # undocumented def __eq__(self, __value: object) -> bool: ... if sys.version_info >= (3, 10): @property diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_ctypes.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_ctypes.pyi index 1f15ac057..495e29dfd 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_ctypes.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_ctypes.pyi @@ -44,6 +44,8 @@ if sys.platform == "win32": def FormatError(code: int = ...) -> str: ... def get_last_error() -> int: ... def set_last_error(value: int) -> int: ... + def LoadLibrary(__name: str, __load_flags: int = 0) -> int: ... + def FreeLibrary(__handle: int) -> None: ... class _CDataMeta(type): # By default mypy complains about the following two methods, because strictly speaking cls @@ -56,6 +58,12 @@ class _CData(metaclass=_CDataMeta): _b_base_: int _b_needsfree_: bool _objects: Mapping[Any, int] | None + # At runtime the following classmethods are available only on classes, not + # on instances. This can't be reflected properly in the type system: + # + # Structure.from_buffer(...) # valid at runtime + # Structure(...).from_buffer(...) # invalid at runtime + # @classmethod def from_buffer(cls, source: WriteableBuffer, offset: int = ...) -> Self: ... @classmethod diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_curses.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_curses.pyi index 61881fc09..3604f7abe 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_curses.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_curses.pyi @@ -61,7 +61,8 @@ if sys.platform != "win32": A_DIM: int A_HORIZONTAL: int A_INVIS: int - A_ITALIC: int + if sys.platform != "darwin": + A_ITALIC: int A_LEFT: int A_LOW: int A_NORMAL: int @@ -276,12 +277,7 @@ if sys.platform != "win32": def can_change_color() -> bool: ... def cbreak(__flag: bool = True) -> None: ... def color_content(__color_number: int) -> tuple[int, int, int]: ... - # Changed in Python 3.8.8 and 3.9.2 - if sys.version_info >= (3, 8): - def color_pair(pair_number: int) -> int: ... - else: - def color_pair(__color_number: int) -> int: ... - + def color_pair(__pair_number: int) -> int: ... def curs_set(__visibility: int) -> int: ... def def_prog_mode() -> None: ... def def_shell_mode() -> None: ... @@ -366,7 +362,10 @@ if sys.platform != "win32": ) -> bytes: ... def typeahead(__fd: int) -> None: ... def unctrl(__ch: _ChType) -> bytes: ... - def unget_wch(__ch: int | str) -> None: ... + if sys.version_info < (3, 12) or sys.platform != "darwin": + # The support for macos was dropped in 3.12 + def unget_wch(__ch: int | str) -> None: ... + def ungetch(__ch: _ChType) -> None: ... def ungetmouse(__id: int, __x: int, __y: int, __z: int, __bstate: int) -> None: ... def update_lines_cols() -> None: ... @@ -441,10 +440,13 @@ if sys.platform != "win32": def getch(self) -> int: ... @overload def getch(self, y: int, x: int) -> int: ... - @overload - def get_wch(self) -> int | str: ... - @overload - def get_wch(self, y: int, x: int) -> int | str: ... + if sys.version_info < (3, 12) or sys.platform != "darwin": + # The support for macos was dropped in 3.12 + @overload + def get_wch(self) -> int | str: ... + @overload + def get_wch(self, y: int, x: int) -> int | str: ... + @overload def getkey(self) -> str: ... @overload diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_locale.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_locale.pyi new file mode 100644 index 000000000..2b2fe03e4 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_locale.pyi @@ -0,0 +1,100 @@ +import sys +from _typeshed import StrPath +from collections.abc import Iterable, Mapping + +LC_CTYPE: int +LC_COLLATE: int +LC_TIME: int +LC_MONETARY: int +LC_NUMERIC: int +LC_ALL: int +CHAR_MAX: int + +def setlocale(category: int, locale: str | Iterable[str | None] | None = None) -> str: ... +def localeconv() -> Mapping[str, int | str | list[int]]: ... + +if sys.version_info >= (3, 11): + def getencoding() -> str: ... + +def strcoll(__os1: str, __os2: str) -> int: ... +def strxfrm(__string: str) -> str: ... + +# native gettext functions +# https://docs.python.org/3/library/locale.html#access-to-message-catalogs +# https://github.com/python/cpython/blob/f4c03484da59049eb62a9bf7777b963e2267d187/Modules/_localemodule.c#L626 +if sys.platform != "win32": + LC_MESSAGES: int + + ABDAY_1: int + ABDAY_2: int + ABDAY_3: int + ABDAY_4: int + ABDAY_5: int + ABDAY_6: int + ABDAY_7: int + + ABMON_1: int + ABMON_2: int + ABMON_3: int + ABMON_4: int + ABMON_5: int + ABMON_6: int + ABMON_7: int + ABMON_8: int + ABMON_9: int + ABMON_10: int + ABMON_11: int + ABMON_12: int + + DAY_1: int + DAY_2: int + DAY_3: int + DAY_4: int + DAY_5: int + DAY_6: int + DAY_7: int + + ERA: int + ERA_D_T_FMT: int + ERA_D_FMT: int + ERA_T_FMT: int + + MON_1: int + MON_2: int + MON_3: int + MON_4: int + MON_5: int + MON_6: int + MON_7: int + MON_8: int + MON_9: int + MON_10: int + MON_11: int + MON_12: int + + CODESET: int + D_T_FMT: int + D_FMT: int + T_FMT: int + T_FMT_AMPM: int + AM_STR: int + PM_STR: int + + RADIXCHAR: int + THOUSEP: int + YESEXPR: int + NOEXPR: int + CRNCYSTR: int + ALT_DIGITS: int + + def nl_langinfo(__key: int) -> str: ... + + # This is dependent on `libintl.h` which is a part of `gettext` + # system dependency. These functions might be missing. + # But, we always say that they are present. + def gettext(__msg: str) -> str: ... + def dgettext(__domain: str | None, __msg: str) -> str: ... + def dcgettext(__domain: str | None, __msg: str, __category: int) -> str: ... + def textdomain(__domain: str | None) -> str: ... + def bindtextdomain(__domain: str, __dir: StrPath | None) -> str: ... + def bind_textdomain_codeset(__domain: str, __codeset: str | None) -> str | None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_msi.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_msi.pyi index 2fdbdfd0e..160406a6d 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_msi.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_msi.pyi @@ -1,6 +1,7 @@ import sys if sys.platform == "win32": + class MSIError(Exception): ... # Actual typename View, not exposed by the implementation class _View: def Execute(self, params: _Record | None = ...) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_posixsubprocess.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_posixsubprocess.pyi index ca95336bb..170806372 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_posixsubprocess.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_posixsubprocess.pyi @@ -6,15 +6,15 @@ from typing_extensions import SupportsIndex if sys.platform != "win32": def cloexec_pipe() -> tuple[int, int]: ... def fork_exec( - __process_args: Sequence[StrOrBytesPath] | None, + __args: Sequence[StrOrBytesPath] | None, __executable_list: Sequence[bytes], __close_fds: bool, - __fds_to_keep: tuple[int, ...], - __cwd_obj: str, - __env_list: Sequence[bytes] | None, + __pass_fds: tuple[int, ...], + __cwd: str, + __env: Sequence[bytes] | None, __p2cread: int, __p2cwrite: int, - __c2pred: int, + __c2pread: int, __c2pwrite: int, __errread: int, __errwrite: int, @@ -23,9 +23,9 @@ if sys.platform != "win32": __restore_signals: int, __call_setsid: int, __pgid_to_set: int, - __gid_object: SupportsIndex | None, - __groups_list: list[int] | None, - __uid_object: SupportsIndex | None, + __gid: SupportsIndex | None, + __extra_groups: list[int] | None, + __uid: SupportsIndex | None, __child_umask: int, __preexec_fn: Callable[[], None], __allow_vfork: bool, diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_typeshed/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_typeshed/__init__.pyi index 7ae67292e..ad214a2a5 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_typeshed/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_typeshed/__init__.pyi @@ -7,8 +7,8 @@ from collections.abc import Awaitable, Callable, Iterable, Sequence, Set as Abst from dataclasses import Field from os import PathLike from types import FrameType, TracebackType -from typing import Any, AnyStr, ClassVar, Generic, Protocol, TypeVar, overload -from typing_extensions import Buffer, Final, Literal, LiteralString, TypeAlias, final +from typing import Any, AnyStr, ClassVar, Generic, Protocol, SupportsFloat, SupportsInt, TypeVar, overload +from typing_extensions import Buffer, Final, Literal, LiteralString, SupportsIndex, TypeAlias, final _KT = TypeVar("_KT") _KT_co = TypeVar("_KT_co", covariant=True) @@ -47,7 +47,7 @@ Unused: TypeAlias = object # _SentinelType = NewType("_SentinelType", object) # sentinel: _SentinelType # def foo(x: int | None | _SentinelType = ...) -> None: ... -sentinel = Any # noqa: Y026 +sentinel: Any # stable class IdentityFunction(Protocol): @@ -312,3 +312,7 @@ TraceFunction: TypeAlias = Callable[[FrameType, str, Any], TraceFunction | None] # https://github.com/microsoft/pyright/issues/4339 class DataclassInstance(Protocol): __dataclass_fields__: ClassVar[dict[str, Field[Any]]] + +# Anything that can be passed to the int/float constructors +ConvertibleToInt: TypeAlias = str | ReadableBuffer | SupportsInt | SupportsIndex | SupportsTrunc +ConvertibleToFloat: TypeAlias = str | ReadableBuffer | SupportsFloat | SupportsIndex diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_weakrefset.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_weakrefset.pyi index d73d79155..6482ade12 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_weakrefset.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_weakrefset.pyi @@ -1,6 +1,6 @@ import sys from collections.abc import Iterable, Iterator, MutableSet -from typing import Any, Generic, TypeVar, overload +from typing import Any, TypeVar, overload from typing_extensions import Self if sys.version_info >= (3, 9): @@ -11,7 +11,7 @@ __all__ = ["WeakSet"] _S = TypeVar("_S") _T = TypeVar("_T") -class WeakSet(MutableSet[_T], Generic[_T]): +class WeakSet(MutableSet[_T]): @overload def __init__(self, data: None = None) -> None: ... @overload diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/_winapi.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/_winapi.pyi index b51d84470..1aec6ce50 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/_winapi.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/_winapi.pyi @@ -54,7 +54,7 @@ if sys.platform == "win32": HIGH_PRIORITY_CLASS: Literal[0x80] INFINITE: Literal[0xFFFFFFFF] if sys.version_info >= (3, 8): - # Ignore the flake8 error -- flake8-pyi assumes + # Ignore the Flake8 error -- flake8-pyi assumes # most numbers this long will be implementation details, # but here we can see that it's a power of 2 INVALID_HANDLE_VALUE: Literal[0xFFFFFFFFFFFFFFFF] # noqa: Y054 @@ -255,3 +255,4 @@ if sys.platform == "win32": if sys.version_info >= (3, 12): def CopyFile2(existing_file_name: str, new_file_name: str, flags: int, progress_routine: int | None = None) -> int: ... + def NeedCurrentDirectoryForExePath(__exe_name: str) -> bool: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/argparse.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/argparse.pyi index 0004250b1..924cc8986 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/argparse.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/argparse.pyi @@ -342,11 +342,11 @@ if sys.version_info >= (3, 12): option_strings: Sequence[str], dest: str, default: _T | str | None = None, - type: Callable[[str], _T] | FileType | None = sentinel, # noqa: Y011 - choices: Iterable[_T] | None = sentinel, # noqa: Y011 + type: Callable[[str], _T] | FileType | None = sentinel, + choices: Iterable[_T] | None = sentinel, required: bool = False, help: str | None = None, - metavar: str | tuple[str, ...] | None = sentinel, # noqa: Y011 + metavar: str | tuple[str, ...] | None = sentinel, ) -> None: ... elif sys.version_info >= (3, 9): diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/array.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/array.pyi index b533f9240..2ef821fcf 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/array.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/array.pyi @@ -3,7 +3,7 @@ from _typeshed import ReadableBuffer, SupportsRead, SupportsWrite from collections.abc import Iterable # pytype crashes if array inherits from collections.abc.MutableSequence instead of typing.MutableSequence -from typing import Any, Generic, MutableSequence, TypeVar, overload # noqa: Y022 +from typing import Any, MutableSequence, TypeVar, overload # noqa: Y022 from typing_extensions import Literal, Self, SupportsIndex, TypeAlias if sys.version_info >= (3, 12): @@ -18,7 +18,7 @@ _T = TypeVar("_T", int, float, str) typecodes: str -class array(MutableSequence[_T], Generic[_T]): +class array(MutableSequence[_T]): @property def typecode(self) -> _TypeCode: ... @property diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/ast.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/ast.pyi index 377138141..a61b4e35f 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/ast.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/ast.pyi @@ -138,8 +138,10 @@ class NodeVisitor: def visit_withitem(self, node: withitem) -> Any: ... if sys.version_info >= (3, 10): def visit_Match(self, node: Match) -> Any: ... + def visit_match_case(self, node: match_case) -> Any: ... def visit_MatchValue(self, node: MatchValue) -> Any: ... def visit_MatchSequence(self, node: MatchSequence) -> Any: ... + def visit_MatchSingleton(self, node: MatchSingleton) -> Any: ... def visit_MatchStar(self, node: MatchStar) -> Any: ... def visit_MatchMapping(self, node: MatchMapping) -> Any: ... def visit_MatchClass(self, node: MatchClass) -> Any: ... @@ -149,6 +151,12 @@ class NodeVisitor: if sys.version_info >= (3, 11): def visit_TryStar(self, node: TryStar) -> Any: ... + if sys.version_info >= (3, 12): + def visit_TypeVar(self, node: TypeVar) -> Any: ... + def visit_ParamSpec(self, node: ParamSpec) -> Any: ... + def visit_TypeVarTuple(self, node: TypeVarTuple) -> Any: ... + def visit_TypeAlias(self, node: TypeAlias) -> Any: ... + # visit methods for deprecated nodes def visit_ExtSlice(self, node: ExtSlice) -> Any: ... def visit_Index(self, node: Index) -> Any: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/asyncio/tasks.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/asyncio/tasks.pyi index b6929deb0..cdac7d359 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/asyncio/tasks.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/asyncio/tasks.pyi @@ -2,7 +2,7 @@ import concurrent.futures import sys from collections.abc import Awaitable, Coroutine, Generator, Iterable, Iterator from types import FrameType -from typing import Any, Generic, Protocol, TextIO, TypeVar, overload +from typing import Any, Protocol, TextIO, TypeVar, overload from typing_extensions import Literal, TypeAlias from . import _CoroutineLike @@ -68,6 +68,7 @@ _T2 = TypeVar("_T2") _T3 = TypeVar("_T3") _T4 = TypeVar("_T4") _T5 = TypeVar("_T5") +_T6 = TypeVar("_T6") _FT = TypeVar("_FT", bound=Future[Any]) _FutureLike: TypeAlias = Future[_T] | Generator[Any, None, _T] | Awaitable[_T] _TaskYieldType: TypeAlias = Future[object] | None @@ -131,6 +132,19 @@ if sys.version_info >= (3, 10): return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload + def gather( # type: ignore[misc] + __coro_or_future1: _FutureLike[_T1], + __coro_or_future2: _FutureLike[_T2], + __coro_or_future3: _FutureLike[_T3], + __coro_or_future4: _FutureLike[_T4], + __coro_or_future5: _FutureLike[_T5], + __coro_or_future6: _FutureLike[_T6], + *, + return_exceptions: Literal[False] = False, + ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ... + @overload + def gather(*coros_or_futures: _FutureLike[_T], return_exceptions: Literal[False] = False) -> Future[list[_T]]: ... # type: ignore[misc] + @overload def gather(__coro_or_future1: _FutureLike[_T1], *, return_exceptions: bool) -> Future[tuple[_T1 | BaseException]]: ... # type: ignore[misc] @overload def gather( # type: ignore[misc] @@ -166,7 +180,27 @@ if sys.version_info >= (3, 10): tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException, _T5 | BaseException] ]: ... @overload - def gather(*coros_or_futures: _FutureLike[Any], return_exceptions: bool = False) -> Future[list[Any]]: ... + def gather( # type: ignore[misc] + __coro_or_future1: _FutureLike[_T1], + __coro_or_future2: _FutureLike[_T2], + __coro_or_future3: _FutureLike[_T3], + __coro_or_future4: _FutureLike[_T4], + __coro_or_future5: _FutureLike[_T5], + __coro_or_future6: _FutureLike[_T6], + *, + return_exceptions: bool, + ) -> Future[ + tuple[ + _T1 | BaseException, + _T2 | BaseException, + _T3 | BaseException, + _T4 | BaseException, + _T5 | BaseException, + _T6 | BaseException, + ] + ]: ... + @overload + def gather(*coros_or_futures: _FutureLike[_T], return_exceptions: bool) -> Future[list[_T | BaseException]]: ... else: @overload @@ -212,6 +246,22 @@ else: return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload + def gather( # type: ignore[misc] + __coro_or_future1: _FutureLike[_T1], + __coro_or_future2: _FutureLike[_T2], + __coro_or_future3: _FutureLike[_T3], + __coro_or_future4: _FutureLike[_T4], + __coro_or_future5: _FutureLike[_T5], + __coro_or_future6: _FutureLike[_T6], + *, + loop: AbstractEventLoop | None = None, + return_exceptions: Literal[False] = False, + ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ... + @overload + def gather( # type: ignore[misc] + *coros_or_futures: _FutureLike[_T], loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False + ) -> Future[list[_T]]: ... + @overload def gather( # type: ignore[misc] __coro_or_future1: _FutureLike[_T1], *, loop: AbstractEventLoop | None = None, return_exceptions: bool ) -> Future[tuple[_T1 | BaseException]]: ... @@ -249,16 +299,24 @@ else: __coro_or_future3: _FutureLike[_T3], __coro_or_future4: _FutureLike[_T4], __coro_or_future5: _FutureLike[_T5], + __coro_or_future6: _FutureLike[_T6], *, loop: AbstractEventLoop | None = None, return_exceptions: bool, ) -> Future[ - tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException, _T5 | BaseException] + tuple[ + _T1 | BaseException, + _T2 | BaseException, + _T3 | BaseException, + _T4 | BaseException, + _T5 | BaseException, + _T6 | BaseException, + ] ]: ... @overload - def gather( - *coros_or_futures: _FutureLike[Any], loop: AbstractEventLoop | None = None, return_exceptions: bool = False - ) -> Future[list[Any]]: ... + def gather( # type: ignore[misc] + *coros_or_futures: _FutureLike[_T], loop: AbstractEventLoop | None = None, return_exceptions: bool + ) -> Future[list[_T | BaseException]]: ... def run_coroutine_threadsafe(coro: _FutureLike[_T], loop: AbstractEventLoop) -> concurrent.futures.Future[_T]: ... @@ -321,7 +379,7 @@ else: # While this is true in general, here it's sort-of okay to have a covariant subclass, # since the only reason why `asyncio.Future` is invariant is the `set_result()` method, # and `asyncio.Task.set_result()` always raises. -class Task(Future[_T_co], Generic[_T_co]): # type: ignore[type-var] # pyright: ignore[reportGeneralTypeIssues] +class Task(Future[_T_co]): # type: ignore[type-var] # pyright: ignore[reportGeneralTypeIssues] if sys.version_info >= (3, 12): def __init__( self, diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/asyncio/windows_events.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/asyncio/windows_events.pyi index 2942a25c0..8e643dd4a 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/asyncio/windows_events.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/asyncio/windows_events.pyi @@ -1,6 +1,6 @@ import socket import sys -from _typeshed import Incomplete, WriteableBuffer +from _typeshed import Incomplete, ReadableBuffer, WriteableBuffer from collections.abc import Callable from typing import IO, Any, ClassVar, NoReturn from typing_extensions import Literal @@ -48,6 +48,12 @@ if sys.platform == "win32": def select(self, timeout: int | None = None) -> list[futures.Future[Any]]: ... def recv(self, conn: socket.socket, nbytes: int, flags: int = 0) -> futures.Future[bytes]: ... def recv_into(self, conn: socket.socket, buf: WriteableBuffer, flags: int = 0) -> futures.Future[Any]: ... + def recvfrom( + self, conn: socket.socket, nbytes: int, flags: int = 0 + ) -> futures.Future[tuple[bytes, socket._RetAddress]]: ... + def sendto( + self, conn: socket.socket, buf: ReadableBuffer, flags: int = 0, addr: socket._Address | None = None + ) -> futures.Future[int]: ... def send(self, conn: socket.socket, buf: WriteableBuffer, flags: int = 0) -> futures.Future[Any]: ... def accept(self, listener: socket.socket) -> futures.Future[Any]: ... def connect( @@ -60,6 +66,10 @@ if sys.platform == "win32": async def connect_pipe(self, address: str) -> windows_utils.PipeHandle: ... def wait_for_handle(self, handle: windows_utils.PipeHandle, timeout: int | None = None) -> bool: ... def close(self) -> None: ... + if sys.version_info >= (3, 11): + def recvfrom_into( + self, conn: socket.socket, buf: WriteableBuffer, flags: int = 0 + ) -> futures.Future[tuple[int, socket._RetAddress]]: ... SelectorEventLoop = _WindowsSelectorEventLoop class WindowsSelectorEventLoopPolicy(events.BaseDefaultEventLoopPolicy): diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/builtins.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/builtins.pyi index 9a1534005..b3253aa4b 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/builtins.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/builtins.pyi @@ -5,6 +5,8 @@ import types from _collections_abc import dict_items, dict_keys, dict_values from _typeshed import ( AnyStr_co, + ConvertibleToFloat, + ConvertibleToInt, FileDescriptorOrPath, OpenBinaryMode, OpenBinaryModeReading, @@ -24,7 +26,6 @@ from _typeshed import ( SupportsRDivMod, SupportsRichComparison, SupportsRichComparisonT, - SupportsTrunc, SupportsWrite, ) from collections.abc import Awaitable, Callable, Iterable, Iterator, MutableSet, Reversible, Set as AbstractSet, Sized @@ -48,7 +49,6 @@ from typing import ( # noqa: Y022 SupportsBytes, SupportsComplex, SupportsFloat, - SupportsInt, TypeVar, overload, type_check_only, @@ -221,7 +221,7 @@ _LiteralInteger = _PositiveInteger | _NegativeInteger | Literal[0] # noqa: Y026 class int: @overload - def __new__(cls, __x: str | ReadableBuffer | SupportsInt | SupportsIndex | SupportsTrunc = ...) -> Self: ... + def __new__(cls, __x: ConvertibleToInt = ...) -> Self: ... @overload def __new__(cls, __x: str | bytes | bytearray, base: SupportsIndex) -> Self: ... if sys.version_info >= (3, 8): @@ -288,7 +288,7 @@ class int: def __pow__(self, __value: _PositiveInteger, __mod: None = None) -> int: ... @overload def __pow__(self, __value: _NegativeInteger, __mod: None = None) -> float: ... - # positive x -> int; negative x -> float + # positive __value -> int; negative __value -> float # return type must be Any as `int | float` causes too many false-positive errors @overload def __pow__(self, __value: int, __mod: None = None) -> Any: ... @@ -327,7 +327,7 @@ class int: def __index__(self) -> int: ... class float: - def __new__(cls, __x: SupportsFloat | SupportsIndex | str | ReadableBuffer = ...) -> Self: ... + def __new__(cls, __x: ConvertibleToFloat = ...) -> Self: ... def as_integer_ratio(self) -> tuple[int, int]: ... def hex(self) -> str: ... def is_integer(self) -> bool: ... @@ -347,7 +347,7 @@ class float: def __divmod__(self, __value: float) -> tuple[float, float]: ... @overload def __pow__(self, __value: int, __mod: None = None) -> float: ... - # positive x -> float; negative x -> complex + # positive __value -> float; negative __value -> complex # return type must be Any as `float | complex` causes too many false-positive errors @overload def __pow__(self, __value: float, __mod: None = None) -> Any: ... @@ -867,7 +867,7 @@ class memoryview(Sequence[int]): def contiguous(self) -> bool: ... @property def nbytes(self) -> int: ... - def __init__(self, obj: ReadableBuffer) -> None: ... + def __new__(cls, obj: ReadableBuffer) -> Self: ... def __enter__(self) -> Self: ... def __exit__( self, __exc_type: type[BaseException] | None, __exc_val: BaseException | None, __exc_tb: TracebackType | None @@ -946,14 +946,14 @@ class slice: @property def stop(self) -> Any: ... @overload - def __init__(self, __stop: Any) -> None: ... + def __new__(cls, __stop: Any) -> Self: ... @overload - def __init__(self, __start: Any, __stop: Any, __step: Any = ...) -> None: ... + def __new__(cls, __start: Any, __stop: Any, __step: Any = ...) -> Self: ... def __eq__(self, __value: object) -> bool: ... __hash__: ClassVar[None] # type: ignore[assignment] def indices(self, __len: SupportsIndex) -> tuple[int, int, int]: ... -class tuple(Sequence[_T_co], Generic[_T_co]): +class tuple(Sequence[_T_co]): def __new__(cls, __iterable: Iterable[_T_co] = ...) -> Self: ... def __len__(self) -> int: ... def __contains__(self, __key: object) -> bool: ... @@ -1005,7 +1005,7 @@ class function: # mypy uses `builtins.function.__get__` to represent methods, properties, and getset_descriptors so we type the return as Any. def __get__(self, __instance: object, __owner: type | None = None) -> Any: ... -class list(MutableSequence[_T], Generic[_T]): +class list(MutableSequence[_T]): @overload def __init__(self) -> None: ... @overload @@ -1060,7 +1060,7 @@ class list(MutableSequence[_T], Generic[_T]): if sys.version_info >= (3, 9): def __class_getitem__(cls, __item: Any) -> GenericAlias: ... -class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): +class dict(MutableMapping[_KT, _VT]): # __init__ should be kept roughly in line with `collections.UserDict.__init__`, which has similar semantics # Also multiprocessing.managers.SyncManager.dict() @overload @@ -1133,7 +1133,7 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): @overload def __ior__(self, __value: Iterable[tuple[_KT, _VT]]) -> Self: ... -class set(MutableSet[_T], Generic[_T]): +class set(MutableSet[_T]): @overload def __init__(self) -> None: ... @overload @@ -1173,7 +1173,7 @@ class set(MutableSet[_T], Generic[_T]): if sys.version_info >= (3, 9): def __class_getitem__(cls, __item: Any) -> GenericAlias: ... -class frozenset(AbstractSet[_T_co], Generic[_T_co]): +class frozenset(AbstractSet[_T_co]): @overload def __new__(cls) -> Self: ... @overload @@ -1202,8 +1202,8 @@ class frozenset(AbstractSet[_T_co], Generic[_T_co]): if sys.version_info >= (3, 9): def __class_getitem__(cls, __item: Any) -> GenericAlias: ... -class enumerate(Iterator[tuple[int, _T]], Generic[_T]): - def __init__(self, iterable: Iterable[_T], start: int = ...) -> None: ... +class enumerate(Iterator[tuple[int, _T]]): + def __new__(cls, iterable: Iterable[_T], start: int = ...) -> Self: ... def __iter__(self) -> Self: ... def __next__(self) -> tuple[int, _T]: ... if sys.version_info >= (3, 9): @@ -1218,9 +1218,9 @@ class range(Sequence[int]): @property def step(self) -> int: ... @overload - def __init__(self, __stop: SupportsIndex) -> None: ... + def __new__(cls, __stop: SupportsIndex) -> Self: ... @overload - def __init__(self, __start: SupportsIndex, __stop: SupportsIndex, __step: SupportsIndex = ...) -> None: ... + def __new__(cls, __start: SupportsIndex, __stop: SupportsIndex, __step: SupportsIndex = ...) -> Self: ... def count(self, __value: int) -> int: ... def index(self, __value: int) -> int: ... # type: ignore[override] def __len__(self) -> int: ... @@ -1411,13 +1411,13 @@ else: def exit(code: sys._ExitCode = None) -> NoReturn: ... -class filter(Iterator[_T], Generic[_T]): +class filter(Iterator[_T]): @overload - def __init__(self, __function: None, __iterable: Iterable[_T | None]) -> None: ... + def __new__(cls, __function: None, __iterable: Iterable[_T | None]) -> Self: ... @overload - def __init__(self, __function: Callable[[_S], TypeGuard[_T]], __iterable: Iterable[_S]) -> None: ... + def __new__(cls, __function: Callable[[_S], TypeGuard[_T]], __iterable: Iterable[_S]) -> Self: ... @overload - def __init__(self, __function: Callable[[_T], Any], __iterable: Iterable[_T]) -> None: ... + def __new__(cls, __function: Callable[[_T], Any], __iterable: Iterable[_T]) -> Self: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... @@ -1470,37 +1470,37 @@ def len(__obj: Sized) -> int: ... def license() -> None: ... def locals() -> dict[str, Any]: ... -class map(Iterator[_S], Generic[_S]): +class map(Iterator[_S]): @overload - def __init__(self, __func: Callable[[_T1], _S], __iter1: Iterable[_T1]) -> None: ... + def __new__(cls, __func: Callable[[_T1], _S], __iter1: Iterable[_T1]) -> Self: ... @overload - def __init__(self, __func: Callable[[_T1, _T2], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> None: ... + def __new__(cls, __func: Callable[[_T1, _T2], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> Self: ... @overload - def __init__( - self, __func: Callable[[_T1, _T2, _T3], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3] - ) -> None: ... + def __new__( + cls, __func: Callable[[_T1, _T2, _T3], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3] + ) -> Self: ... @overload - def __init__( - self, + def __new__( + cls, __func: Callable[[_T1, _T2, _T3, _T4], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4], - ) -> None: ... + ) -> Self: ... @overload - def __init__( - self, + def __new__( + cls, __func: Callable[[_T1, _T2, _T3, _T4, _T5], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4], __iter5: Iterable[_T5], - ) -> None: ... + ) -> Self: ... @overload - def __init__( - self, + def __new__( + cls, __func: Callable[..., _S], __iter1: Iterable[Any], __iter2: Iterable[Any], @@ -1509,7 +1509,7 @@ class map(Iterator[_S], Generic[_S]): __iter5: Iterable[Any], __iter6: Iterable[Any], *iterables: Iterable[Any], - ) -> None: ... + ) -> Self: ... def __iter__(self) -> Self: ... def __next__(self) -> _S: ... @@ -1742,7 +1742,7 @@ else: def quit(code: sys._ExitCode = None) -> NoReturn: ... -class reversed(Iterator[_T], Generic[_T]): +class reversed(Iterator[_T]): @overload def __init__(self, __sequence: Reversible[_T]) -> None: ... @overload @@ -1816,8 +1816,10 @@ def vars(__object: type) -> types.MappingProxyType[str, Any]: ... # type: ignor @overload def vars(__object: Any = ...) -> dict[str, Any]: ... -class zip(Iterator[_T_co], Generic[_T_co]): +class zip(Iterator[_T_co]): if sys.version_info >= (3, 10): + @overload + def __new__(cls, *, strict: bool = ...) -> zip[Any]: ... @overload def __new__(cls, __iter1: Iterable[_T1], *, strict: bool = ...) -> zip[tuple[_T1]]: ... @overload @@ -1860,6 +1862,8 @@ class zip(Iterator[_T_co], Generic[_T_co]): strict: bool = ..., ) -> zip[tuple[Any, ...]]: ... else: + @overload + def __new__(cls) -> zip[Any]: ... @overload def __new__(cls, __iter1: Iterable[_T1]) -> zip[tuple[_T1]]: ... @overload diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/collections/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/collections/__init__.pyi index 3b8d92f78..bb214b5ea 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/collections/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/collections/__init__.pyi @@ -45,7 +45,7 @@ def namedtuple( defaults: Iterable[Any] | None = None, ) -> type[tuple[Any, ...]]: ... -class UserDict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): +class UserDict(MutableMapping[_KT, _VT]): data: dict[_KT, _VT] # __init__ should be kept roughly in line with `dict.__init__`, which has the same semantics @overload @@ -228,7 +228,7 @@ class UserString(Sequence[UserString]): def upper(self) -> Self: ... def zfill(self, width: int) -> Self: ... -class deque(MutableSequence[_T], Generic[_T]): +class deque(MutableSequence[_T]): @property def maxlen(self) -> int | None: ... @overload @@ -373,8 +373,17 @@ class OrderedDict(dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]): @overload def setdefault(self, key: _KT, default: _VT) -> _VT: ... def __eq__(self, __value: object) -> bool: ... + if sys.version_info >= (3, 9): + @overload + def __or__(self, __value: dict[_KT, _VT]) -> Self: ... + @overload + def __or__(self, __value: dict[_T1, _T2]) -> OrderedDict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, __value: dict[_KT, _VT]) -> Self: ... + @overload + def __ror__(self, __value: dict[_T1, _T2]) -> OrderedDict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] -class defaultdict(dict[_KT, _VT], Generic[_KT, _VT]): +class defaultdict(dict[_KT, _VT]): default_factory: Callable[[], _VT] | None @overload def __init__(self) -> None: ... @@ -415,7 +424,7 @@ class defaultdict(dict[_KT, _VT], Generic[_KT, _VT]): @overload def __ror__(self, __value: dict[_T1, _T2]) -> defaultdict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] -class ChainMap(MutableMapping[_KT, _VT], Generic[_KT, _VT]): +class ChainMap(MutableMapping[_KT, _VT]): maps: list[MutableMapping[_KT, _VT]] def __init__(self, *maps: MutableMapping[_KT, _VT]) -> None: ... def new_child(self, m: MutableMapping[_KT, _VT] | None = None) -> Self: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/contextlib.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/contextlib.pyi index dc2101dc0..c1bfedd2d 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/contextlib.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/contextlib.pyi @@ -94,7 +94,7 @@ if sys.version_info >= (3, 10): ) -> bool | None: ... else: - class _AsyncGeneratorContextManager(AbstractAsyncContextManager[_T_co], Generic[_T_co]): + class _AsyncGeneratorContextManager(AbstractAsyncContextManager[_T_co]): def __init__(self, func: Callable[..., AsyncIterator[_T_co]], args: tuple[Any, ...], kwds: dict[str, Any]) -> None: ... gen: AsyncGenerator[_T_co, Any] func: Callable[..., AsyncGenerator[_T_co, Any]] diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/fcntl.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/fcntl.pyi index 6aec7515f..56fd5679a 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/fcntl.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/fcntl.pyi @@ -101,6 +101,11 @@ if sys.platform != "win32": I_STR: int I_SWROPT: int I_UNLINK: int + + if sys.version_info >= (3, 12) and sys.platform == "linux": + FICLONE: int + FICLONERANGE: int + @overload def fcntl(__fd: FileDescriptorLike, __cmd: int, __arg: int = 0) -> int: ... @overload diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/fileinput.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/fileinput.pyi index e9f3713b4..c2fd31d1e 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/fileinput.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/fileinput.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import AnyStr_co, StrOrBytesPath from collections.abc import Callable, Iterable, Iterator from types import TracebackType -from typing import IO, Any, AnyStr, Generic, Protocol, overload +from typing import IO, Any, AnyStr, Protocol, overload from typing_extensions import Literal, Self, TypeAlias if sys.version_info >= (3, 9): @@ -158,7 +158,7 @@ def fileno() -> int: ... def isfirstline() -> bool: ... def isstdin() -> bool: ... -class FileInput(Iterator[AnyStr], Generic[AnyStr]): +class FileInput(Iterator[AnyStr]): if sys.version_info >= (3, 10): # encoding and errors are added @overload diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/http/server.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/http/server.pyi index c9700f70e..22c33bc37 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/http/server.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/http/server.pyi @@ -54,6 +54,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): extensions_map: dict[str, str] if sys.version_info >= (3, 12): index_pages: ClassVar[tuple[str, ...]] + directory: str def __init__( self, request: socketserver._RequestType, diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/importlib/abc.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/importlib/abc.pyi index 28c33205a..438dbafb4 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/importlib/abc.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/importlib/abc.pyi @@ -1,20 +1,12 @@ import _ast import sys import types -from _typeshed import ( - OpenBinaryMode, - OpenBinaryModeReading, - OpenBinaryModeUpdating, - OpenBinaryModeWriting, - OpenTextMode, - ReadableBuffer, - StrPath, -) +from _typeshed import ReadableBuffer, StrPath from abc import ABCMeta, abstractmethod from collections.abc import Iterator, Mapping, Sequence from importlib.machinery import ModuleSpec -from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper -from typing import IO, Any, BinaryIO, NoReturn, Protocol, overload, runtime_checkable +from io import BufferedReader +from typing import IO, Any, Protocol, overload, runtime_checkable from typing_extensions import Literal if sys.version_info >= (3, 11): @@ -139,72 +131,26 @@ if sys.version_info >= (3, 9): def joinpath(self, *descendants: str) -> Traversable: ... else: @abstractmethod - def joinpath(self, child: str) -> Traversable: ... - # The .open method comes from pathlib.pyi and should be kept in sync. - @overload - @abstractmethod - def open( - self, - mode: OpenTextMode = "r", - buffering: int = ..., - encoding: str | None = ..., - errors: str | None = ..., - newline: str | None = ..., - ) -> TextIOWrapper: ... - # Unbuffered binary mode: returns a FileIO - @overload - @abstractmethod - def open( - self, mode: OpenBinaryMode, buffering: Literal[0], encoding: None = None, errors: None = None, newline: None = None - ) -> FileIO: ... - # Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter - @overload - @abstractmethod - def open( - self, - mode: OpenBinaryModeUpdating, - buffering: Literal[-1, 1] = ..., - encoding: None = None, - errors: None = None, - newline: None = None, - ) -> BufferedRandom: ... - @overload - @abstractmethod - def open( - self, - mode: OpenBinaryModeWriting, - buffering: Literal[-1, 1] = ..., - encoding: None = None, - errors: None = None, - newline: None = None, - ) -> BufferedWriter: ... - @overload - @abstractmethod - def open( - self, - mode: OpenBinaryModeReading, - buffering: Literal[-1, 1] = ..., - encoding: None = None, - errors: None = None, - newline: None = None, - ) -> BufferedReader: ... - # Buffering cannot be determined: fall back to BinaryIO + def joinpath(self, __child: str) -> Traversable: ... + + # The documentation and runtime protocol allows *args, **kwargs arguments, + # but this would mean that all implementors would have to support them, + # which is not the case. @overload @abstractmethod - def open( - self, mode: OpenBinaryMode, buffering: int = ..., encoding: None = None, errors: None = None, newline: None = None - ) -> BinaryIO: ... - # Fallback if mode is not specified + def open(self, mode: Literal["r", "w"] = "r", *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ... @overload @abstractmethod - def open( - self, mode: str, buffering: int = ..., encoding: str | None = ..., errors: str | None = ..., newline: str | None = ... - ) -> IO[Any]: ... + def open(self, mode: Literal["rb", "wb"]) -> IO[bytes]: ... @property @abstractmethod def name(self) -> str: ... - @abstractmethod - def __truediv__(self, child: str) -> Traversable: ... + if sys.version_info >= (3, 10): + def __truediv__(self, __child: str) -> Traversable: ... + else: + @abstractmethod + def __truediv__(self, __child: str) -> Traversable: ... + @abstractmethod def read_bytes(self) -> bytes: ... @abstractmethod @@ -214,6 +160,6 @@ if sys.version_info >= (3, 9): @abstractmethod def files(self) -> Traversable: ... def open_resource(self, resource: str) -> BufferedReader: ... - def resource_path(self, resource: Any) -> NoReturn: ... + def resource_path(self, resource: Any) -> str: ... def is_resource(self, path: str) -> bool: ... def contents(self) -> Iterator[str]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/importlib/readers.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/importlib/readers.pyi new file mode 100644 index 000000000..ca7bd4dca --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stdlib/importlib/readers.pyi @@ -0,0 +1,61 @@ +# On py311+, things are actually defined in importlib.resources.readers, +# and re-exported here, +# but doing it this way leads to less code duplication for us + +import pathlib +import sys +from _typeshed import Incomplete, StrPath +from collections.abc import Iterable, Iterator +from io import BufferedReader +from typing import NoReturn, TypeVar +from typing_extensions import Literal, Never + +if sys.version_info >= (3, 11): + import importlib.resources.abc as abc +else: + import importlib.abc as abc + +if sys.version_info >= (3, 10): + if sys.version_info >= (3, 11): + __all__ = ["FileReader", "ZipReader", "MultiplexedPath", "NamespaceReader"] + + if sys.version_info < (3, 11): + _T = TypeVar("_T") + + def remove_duplicates(items: Iterable[_T]) -> Iterator[_T]: ... + + class FileReader(abc.TraversableResources): + path: pathlib.Path + def __init__(self, loader) -> None: ... + def resource_path(self, resource: StrPath) -> str: ... + def files(self) -> pathlib.Path: ... + + class ZipReader(abc.TraversableResources): + prefix: str + archive: Incomplete + def __init__(self, loader, module: str) -> None: ... + def open_resource(self, resource: str) -> BufferedReader: ... + def is_resource(self, path: StrPath) -> bool: ... + def files(self): ... + + class MultiplexedPath(abc.Traversable): + def __init__(self, *paths: abc.Traversable) -> None: ... + def iterdir(self) -> Iterator[abc.Traversable]: ... + def read_bytes(self) -> NoReturn: ... + def read_text(self, *args: Never, **kwargs: Never) -> NoReturn: ... # type: ignore[override] + def is_dir(self) -> Literal[True]: ... + def is_file(self) -> Literal[False]: ... + if sys.version_info >= (3, 12): + def joinpath(self, *descendants: str) -> abc.Traversable: ... + else: + def joinpath(self, child: str) -> abc.Traversable: ... # type: ignore[override] + __truediv__ = joinpath + def open(self, *args: Never, **kwargs: Never) -> NoReturn: ... # type: ignore[override] + @property + def name(self) -> str: ... + + class NamespaceReader(abc.TraversableResources): + path: MultiplexedPath + def __init__(self, namespace_path) -> None: ... + def resource_path(self, resource: str) -> str: ... + def files(self) -> MultiplexedPath: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/importlib/resources/readers.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/importlib/resources/readers.pyi new file mode 100644 index 000000000..0ab21fd29 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stdlib/importlib/resources/readers.pyi @@ -0,0 +1,14 @@ +# On py311+, things are actually defined here +# and re-exported from importlib.readers, +# but doing it this way leads to less code duplication for us + +import sys +from collections.abc import Iterable, Iterator +from typing import TypeVar + +if sys.version_info >= (3, 11): + from importlib.readers import * + + _T = TypeVar("_T") + + def remove_duplicates(items: Iterable[_T]) -> Iterator[_T]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/inspect.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/inspect.pyi index 601d23e78..6498719df 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/inspect.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/inspect.pyi @@ -294,6 +294,14 @@ _SourceObjectType: TypeAlias = ( def findsource(object: _SourceObjectType) -> tuple[list[str], int]: ... def getabsfile(object: _SourceObjectType, _filename: str | None = None) -> str: ... + +# Special-case the two most common input types here +# to avoid the annoyingly vague `Sequence[str]` return type +@overload +def getblock(lines: list[str]) -> list[str]: ... +@overload +def getblock(lines: tuple[str, ...]) -> tuple[str, ...]: ... +@overload def getblock(lines: Sequence[str]) -> Sequence[str]: ... def getdoc(object: object) -> str | None: ... def getcomments(object: object) -> str | None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/io.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/io.pyi index c114f8395..b54e0a9fd 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/io.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/io.pyi @@ -6,7 +6,7 @@ from _typeshed import FileDescriptorOrPath, ReadableBuffer, WriteableBuffer from collections.abc import Callable, Iterable, Iterator from os import _Opener from types import TracebackType -from typing import IO, Any, BinaryIO, TextIO +from typing import IO, Any, BinaryIO, TextIO, TypeVar, overload from typing_extensions import Literal, Self __all__ = [ @@ -33,6 +33,8 @@ __all__ = [ if sys.version_info >= (3, 8): __all__ += ["open_code"] +_T = TypeVar("_T") + DEFAULT_BUFFER_SIZE: Literal[8192] SEEK_SET: Literal[0] @@ -194,3 +196,9 @@ class IncrementalNewlineDecoder(codecs.IncrementalDecoder): @property def newlines(self) -> str | tuple[str, ...] | None: ... def setstate(self, __state: tuple[bytes, int]) -> None: ... + +if sys.version_info >= (3, 10): + @overload + def text_encoding(__encoding: None, __stacklevel: int = 2) -> Literal["locale", "utf-8"]: ... + @overload + def text_encoding(__encoding: _T, __stacklevel: int = 2) -> _T: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/itertools.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/itertools.pyi index 4b5d624c7..ffa8e1939 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/itertools.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/itertools.pyi @@ -23,7 +23,7 @@ _Predicate: TypeAlias = Callable[[_T], object] # Technically count can take anything that implements a number protocol and has an add method # but we can't enforce the add method -class count(Iterator[_N], Generic[_N]): +class count(Iterator[_N]): @overload def __new__(cls) -> count[int]: ... @overload @@ -33,12 +33,12 @@ class count(Iterator[_N], Generic[_N]): def __next__(self) -> _N: ... def __iter__(self) -> Self: ... -class cycle(Iterator[_T], Generic[_T]): +class cycle(Iterator[_T]): def __init__(self, __iterable: Iterable[_T]) -> None: ... def __next__(self) -> _T: ... def __iter__(self) -> Self: ... -class repeat(Iterator[_T], Generic[_T]): +class repeat(Iterator[_T]): @overload def __init__(self, object: _T) -> None: ... @overload @@ -47,7 +47,7 @@ class repeat(Iterator[_T], Generic[_T]): def __iter__(self) -> Self: ... def __length_hint__(self) -> int: ... -class accumulate(Iterator[_T], Generic[_T]): +class accumulate(Iterator[_T]): if sys.version_info >= (3, 8): @overload def __init__(self, iterable: Iterable[_T], func: None = None, *, initial: _T | None = ...) -> None: ... @@ -59,7 +59,7 @@ class accumulate(Iterator[_T], Generic[_T]): def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -class chain(Iterator[_T], Generic[_T]): +class chain(Iterator[_T]): def __init__(self, *iterables: Iterable[_T]) -> None: ... def __next__(self) -> _T: ... def __iter__(self) -> Self: ... @@ -69,17 +69,17 @@ class chain(Iterator[_T], Generic[_T]): if sys.version_info >= (3, 9): def __class_getitem__(cls, __item: Any) -> GenericAlias: ... -class compress(Iterator[_T], Generic[_T]): +class compress(Iterator[_T]): def __init__(self, data: Iterable[_T], selectors: Iterable[Any]) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -class dropwhile(Iterator[_T], Generic[_T]): +class dropwhile(Iterator[_T]): def __init__(self, __predicate: _Predicate[_T], __iterable: Iterable[_T]) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -class filterfalse(Iterator[_T], Generic[_T]): +class filterfalse(Iterator[_T]): def __init__(self, __predicate: _Predicate[_T] | None, __iterable: Iterable[_T]) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... @@ -92,7 +92,7 @@ class groupby(Iterator[tuple[_T, Iterator[_S]]], Generic[_T, _S]): def __iter__(self) -> Self: ... def __next__(self) -> tuple[_T, Iterator[_S]]: ... -class islice(Iterator[_T], Generic[_T]): +class islice(Iterator[_T]): @overload def __init__(self, __iterable: Iterable[_T], __stop: int | None) -> None: ... @overload @@ -100,19 +100,19 @@ class islice(Iterator[_T], Generic[_T]): def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -class starmap(Iterator[_T], Generic[_T]): +class starmap(Iterator[_T]): def __init__(self, __function: Callable[..., _T], __iterable: Iterable[Iterable[Any]]) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -class takewhile(Iterator[_T], Generic[_T]): +class takewhile(Iterator[_T]): def __init__(self, __predicate: _Predicate[_T], __iterable: Iterable[_T]) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... def tee(__iterable: Iterable[_T], __n: int = 2) -> tuple[Iterator[_T], ...]: ... -class zip_longest(Iterator[_T_co], Generic[_T_co]): +class zip_longest(Iterator[_T_co]): # one iterable (fillvalue doesn't matter) @overload def __new__(cls, __iter1: Iterable[_T1], *, fillvalue: object = ...) -> zip_longest[tuple[_T1]]: ... @@ -192,7 +192,7 @@ class zip_longest(Iterator[_T_co], Generic[_T_co]): def __iter__(self) -> Self: ... def __next__(self) -> _T_co: ... -class product(Iterator[_T_co], Generic[_T_co]): +class product(Iterator[_T_co]): @overload def __new__(cls, __iter1: Iterable[_T1]) -> product[tuple[_T1]]: ... @overload @@ -246,7 +246,7 @@ class permutations(Iterator[tuple[_T, ...]], Generic[_T]): def __iter__(self) -> Self: ... def __next__(self) -> tuple[_T, ...]: ... -class combinations(Iterator[_T_co], Generic[_T_co]): +class combinations(Iterator[_T_co]): @overload def __new__(cls, iterable: Iterable[_T], r: Literal[2]) -> combinations[tuple[_T, _T]]: ... @overload @@ -266,7 +266,7 @@ class combinations_with_replacement(Iterator[tuple[_T, ...]], Generic[_T]): def __next__(self) -> tuple[_T, ...]: ... if sys.version_info >= (3, 10): - class pairwise(Iterator[_T_co], Generic[_T_co]): + class pairwise(Iterator[_T_co]): def __new__(cls, __iterable: Iterable[_T]) -> pairwise[tuple[_T, _T]]: ... def __iter__(self) -> Self: ... def __next__(self) -> _T_co: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/locale.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/locale.pyi index 3753700ea..2e95c659d 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/locale.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/locale.pyi @@ -1,6 +1,95 @@ import sys -from _typeshed import StrPath -from collections.abc import Callable, Iterable, Mapping +from _locale import ( + CHAR_MAX as CHAR_MAX, + LC_ALL as LC_ALL, + LC_COLLATE as LC_COLLATE, + LC_CTYPE as LC_CTYPE, + LC_MONETARY as LC_MONETARY, + LC_NUMERIC as LC_NUMERIC, + LC_TIME as LC_TIME, + localeconv as localeconv, + setlocale as setlocale, + strcoll as strcoll, + strxfrm as strxfrm, +) + +# This module defines a function "str()", which is why "str" can't be used +# as a type annotation or type alias. +from builtins import str as _str +from collections.abc import Callable +from decimal import Decimal +from typing import Any + +if sys.version_info >= (3, 11): + from _locale import getencoding as getencoding + +# Some parts of the `_locale` module are platform-specific: +if sys.platform != "win32": + from _locale import ( + ABDAY_1 as ABDAY_1, + ABDAY_2 as ABDAY_2, + ABDAY_3 as ABDAY_3, + ABDAY_4 as ABDAY_4, + ABDAY_5 as ABDAY_5, + ABDAY_6 as ABDAY_6, + ABDAY_7 as ABDAY_7, + ABMON_1 as ABMON_1, + ABMON_2 as ABMON_2, + ABMON_3 as ABMON_3, + ABMON_4 as ABMON_4, + ABMON_5 as ABMON_5, + ABMON_6 as ABMON_6, + ABMON_7 as ABMON_7, + ABMON_8 as ABMON_8, + ABMON_9 as ABMON_9, + ABMON_10 as ABMON_10, + ABMON_11 as ABMON_11, + ABMON_12 as ABMON_12, + ALT_DIGITS as ALT_DIGITS, + AM_STR as AM_STR, + CODESET as CODESET, + CRNCYSTR as CRNCYSTR, + D_FMT as D_FMT, + D_T_FMT as D_T_FMT, + DAY_1 as DAY_1, + DAY_2 as DAY_2, + DAY_3 as DAY_3, + DAY_4 as DAY_4, + DAY_5 as DAY_5, + DAY_6 as DAY_6, + DAY_7 as DAY_7, + ERA as ERA, + ERA_D_FMT as ERA_D_FMT, + ERA_D_T_FMT as ERA_D_T_FMT, + ERA_T_FMT as ERA_T_FMT, + LC_MESSAGES as LC_MESSAGES, + MON_1 as MON_1, + MON_2 as MON_2, + MON_3 as MON_3, + MON_4 as MON_4, + MON_5 as MON_5, + MON_6 as MON_6, + MON_7 as MON_7, + MON_8 as MON_8, + MON_9 as MON_9, + MON_10 as MON_10, + MON_11 as MON_11, + MON_12 as MON_12, + NOEXPR as NOEXPR, + PM_STR as PM_STR, + RADIXCHAR as RADIXCHAR, + T_FMT as T_FMT, + T_FMT_AMPM as T_FMT_AMPM, + THOUSEP as THOUSEP, + YESEXPR as YESEXPR, + bind_textdomain_codeset as bind_textdomain_codeset, + bindtextdomain as bindtextdomain, + dcgettext as dcgettext, + dgettext as dgettext, + gettext as gettext, + nl_langinfo as nl_langinfo, + textdomain as textdomain, + ) __all__ = [ "getlocale", @@ -20,7 +109,6 @@ __all__ = [ "normalize", "LC_CTYPE", "LC_COLLATE", - "LC_MESSAGES", "LC_TIME", "LC_MONETARY", "LC_NUMERIC", @@ -34,88 +122,11 @@ if sys.version_info >= (3, 11): if sys.version_info < (3, 12): __all__ += ["format"] -# This module defines a function "str()", which is why "str" can't be used -# as a type annotation or type alias. -from builtins import str as _str -from decimal import Decimal -from typing import Any - -CODESET: int -D_T_FMT: int -D_FMT: int -T_FMT: int -T_FMT_AMPM: int -AM_STR: int -PM_STR: int - -DAY_1: int -DAY_2: int -DAY_3: int -DAY_4: int -DAY_5: int -DAY_6: int -DAY_7: int -ABDAY_1: int -ABDAY_2: int -ABDAY_3: int -ABDAY_4: int -ABDAY_5: int -ABDAY_6: int -ABDAY_7: int - -MON_1: int -MON_2: int -MON_3: int -MON_4: int -MON_5: int -MON_6: int -MON_7: int -MON_8: int -MON_9: int -MON_10: int -MON_11: int -MON_12: int -ABMON_1: int -ABMON_2: int -ABMON_3: int -ABMON_4: int -ABMON_5: int -ABMON_6: int -ABMON_7: int -ABMON_8: int -ABMON_9: int -ABMON_10: int -ABMON_11: int -ABMON_12: int - -RADIXCHAR: int -THOUSEP: int -YESEXPR: int -NOEXPR: int -CRNCYSTR: int - -ERA: int -ERA_D_T_FMT: int -ERA_D_FMT: int -ERA_T_FMT: int - -ALT_DIGITS: int - -LC_CTYPE: int -LC_COLLATE: int -LC_TIME: int -LC_MONETARY: int -LC_MESSAGES: int -LC_NUMERIC: int -LC_ALL: int - -CHAR_MAX: int +if sys.platform != "win32": + __all__ += ["LC_MESSAGES"] class Error(Exception): ... -def setlocale(category: int, locale: _str | Iterable[_str | None] | None = None) -> _str: ... -def localeconv() -> Mapping[_str, int | _str | list[int]]: ... -def nl_langinfo(__key: int) -> _str: ... def getdefaultlocale( envvars: tuple[_str, ...] = ("LC_ALL", "LC_CTYPE", "LANG", "LANGUAGE") ) -> tuple[_str | None, _str | None]: ... @@ -123,8 +134,6 @@ def getlocale(category: int = ...) -> tuple[_str | None, _str | None]: ... def getpreferredencoding(do_setlocale: bool = True) -> _str: ... def normalize(localename: _str) -> _str: ... def resetlocale(category: int = ...) -> None: ... -def strcoll(__os1: _str, __os2: _str) -> int: ... -def strxfrm(__string: _str) -> _str: ... if sys.version_info < (3, 12): def format( @@ -138,20 +147,6 @@ def atof(string: _str, func: Callable[[_str], float] = ...) -> float: ... def atoi(string: _str) -> int: ... def str(val: float) -> _str: ... -# native gettext functions -# https://docs.python.org/3/library/locale.html#access-to-message-catalogs -# https://github.com/python/cpython/blob/f4c03484da59049eb62a9bf7777b963e2267d187/Modules/_localemodule.c#L626 -if sys.platform == "linux" or sys.platform == "darwin": - def gettext(__msg: _str) -> _str: ... - def dgettext(__domain: _str | None, __msg: _str) -> _str: ... - def dcgettext(__domain: _str | None, __msg: _str, __category: int) -> _str: ... - def textdomain(__domain: _str | None) -> _str: ... - def bindtextdomain(__domain: _str, __dir: StrPath | None) -> _str: ... - def bind_textdomain_codeset(__domain: _str, __codeset: _str | None) -> _str | None: ... - -if sys.version_info >= (3, 11): - def getencoding() -> _str: ... - locale_alias: dict[_str, _str] # undocumented locale_encoding_alias: dict[_str, _str] # undocumented windows_locale: dict[int, _str] # undocumented diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/logging/handlers.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/logging/handlers.pyi index ad5bf392b..2280dbad4 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/logging/handlers.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/logging/handlers.pyi @@ -7,6 +7,7 @@ from collections.abc import Callable from logging import FileHandler, Handler, LogRecord from re import Pattern from socket import SocketKind, socket +from threading import Thread from typing import Any, ClassVar, Protocol, TypeVar _T = TypeVar("_T") @@ -264,6 +265,7 @@ class QueueListener: handlers: tuple[Handler, ...] # undocumented respect_handler_level: bool # undocumented queue: _QueueLike[Any] # undocumented + _thread: Thread | None # undocumented def __init__(self, queue: _QueueLike[Any], *handlers: Handler, respect_handler_level: bool = False) -> None: ... def dequeue(self, block: bool) -> LogRecord: ... def prepare(self, record: LogRecord) -> Any: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/mimetypes.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/mimetypes.pyi index 128a05fa5..532cc5e3c 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/mimetypes.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/mimetypes.pyi @@ -53,5 +53,4 @@ class MimeTypes: def guess_all_extensions(self, type: str, strict: bool = True) -> list[str]: ... def read(self, filename: str, strict: bool = True) -> None: ... def readfp(self, fp: IO[str], strict: bool = True) -> None: ... - if sys.platform == "win32": - def read_windows_registry(self, strict: bool = True) -> None: ... + def read_windows_registry(self, strict: bool = True) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/mmap.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/mmap.pyi index 38e192439..9a213a8b8 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/mmap.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/mmap.pyi @@ -16,6 +16,8 @@ if sys.platform == "linux": MAP_EXECUTABLE: int if sys.version_info >= (3, 10): MAP_POPULATE: int +if sys.version_info >= (3, 11) and sys.platform != "win32" and sys.platform != "darwin": + MAP_STACK: int if sys.platform != "win32": MAP_ANON: int @@ -26,7 +28,7 @@ if sys.platform != "win32": PROT_READ: int PROT_WRITE: int - PAGESIZE: int +PAGESIZE: int class mmap(Iterable[int], Sized): if sys.platform == "win32": diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/msilib/text.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/msilib/text.pyi index 1353cf8a2..441c843ca 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/msilib/text.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/msilib/text.pyi @@ -3,5 +3,5 @@ import sys if sys.platform == "win32": ActionText: list[tuple[str, str, str | None]] UIText: list[tuple[str, str | None]] - + dirname: str tables: list[str] diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/msvcrt.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/msvcrt.pyi index 5849b9b00..768edbc18 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/msvcrt.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/msvcrt.pyi @@ -1,8 +1,9 @@ import sys -from typing_extensions import Literal +from typing_extensions import Final, Literal # This module is only available on Windows if sys.platform == "win32": + CRT_ASSEMBLY_VERSION: Final[str] LK_UNLCK: Literal[0] LK_LOCK: Literal[1] LK_NBLCK: Literal[2] @@ -26,3 +27,6 @@ if sys.platform == "win32": def ungetch(__char: bytes | bytearray) -> None: ... def ungetwch(__unicode_char: str) -> None: ... def heapmin() -> None: ... + def SetErrorMode(__mode: int) -> int: ... + if sys.version_info >= (3, 10): + def GetErrorMode() -> int: ... # undocumented diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/multiprocessing/util.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/multiprocessing/util.pyi index 7ca650511..aeb46f85a 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/multiprocessing/util.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/multiprocessing/util.pyi @@ -1,9 +1,8 @@ import threading -from _typeshed import Incomplete, ReadableBuffer, SupportsTrunc, Unused +from _typeshed import ConvertibleToInt, Incomplete, Unused from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence from logging import Logger, _Level as _LoggingLevel -from typing import Any, SupportsInt -from typing_extensions import SupportsIndex +from typing import Any __all__ = [ "sub_debug", @@ -77,9 +76,4 @@ class ForkAwareLocal(threading.local): ... MAXFD: int def close_all_fds_except(fds: Iterable[int]) -> None: ... -def spawnv_passfds( - path: bytes, - # args is anything that can be passed to the int constructor - args: Sequence[str | ReadableBuffer | SupportsInt | SupportsIndex | SupportsTrunc], - passfds: Sequence[int], -) -> int: ... +def spawnv_passfds(path: bytes, args: Sequence[ConvertibleToInt], passfds: Sequence[int]) -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/os/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/os/__init__.pyi index 961858ce3..7fd04218f 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/os/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/os/__init__.pyi @@ -2,6 +2,7 @@ import sys from _typeshed import ( AnyStr_co, BytesPath, + FileDescriptor, FileDescriptorLike, FileDescriptorOrPath, GenericPath, @@ -69,9 +70,20 @@ if sys.platform != "win32": POSIX_FADV_WILLNEED: int POSIX_FADV_DONTNEED: int - SF_NODISKIO: int - SF_MNOWAIT: int - SF_SYNC: int + if sys.platform != "linux" and sys.platform != "darwin": + # In the os-module docs, these are marked as being available + # on "Unix, not Emscripten, not WASI." + # However, in the source code, a comment indicates they're "FreeBSD constants". + # sys.platform could have one of many values on a FreeBSD Python build, + # so the sys-module docs recommend doing `if sys.platform.startswith('freebsd')` + # to detect FreeBSD builds. Unfortunately that would be too dynamic + # for type checkers, however. + SF_NODISKIO: int + SF_MNOWAIT: int + SF_SYNC: int + + if sys.version_info >= (3, 11): + SF_NOCACHE: int if sys.platform == "linux": XATTR_SIZE_MAX: int @@ -121,6 +133,12 @@ if sys.platform == "linux": GRND_NONBLOCK: int GRND_RANDOM: int +if sys.platform == "darwin" and sys.version_info >= (3, 12): + PRIO_DARWIN_BG: int + PRIO_DARWIN_NONUI: int + PRIO_DARWIN_PROCESS: int + PRIO_DARWIN_THREAD: int + SEEK_SET: int SEEK_CUR: int SEEK_END: int @@ -252,12 +270,14 @@ environ: _Environ[str] if sys.platform != "win32": environb: _Environ[bytes] +if sys.version_info >= (3, 11) or sys.platform != "win32": + EX_OK: int + if sys.platform != "win32": confstr_names: dict[str, int] pathconf_names: dict[str, int] sysconf_names: dict[str, int] - EX_OK: int EX_USAGE: int EX_DATAERR: int EX_NOINPUT: int @@ -273,6 +293,8 @@ if sys.platform != "win32": EX_PROTOCOL: int EX_NOPERM: int EX_CONFIG: int + +if sys.platform != "win32" and sys.platform != "darwin": EX_NOTFOUND: int P_NOWAIT: int @@ -339,6 +361,11 @@ class stat_result(structseq[float], tuple[int, int, int, int, int, int, int, flo if sys.version_info >= (3, 8): @property def st_reparse_tag(self) -> int: ... + if sys.version_info >= (3, 12): + @property + def st_birthtime(self) -> float: ... # time of file creation in seconds + @property + def st_birthtime_ns(self) -> int: ... # time of file creation in nanoseconds else: @property def st_blocks(self) -> int: ... # number of blocks allocated for file @@ -347,13 +374,13 @@ class stat_result(structseq[float], tuple[int, int, int, int, int, int, int, flo @property def st_rdev(self) -> int: ... # type of device if an inode device if sys.platform != "linux": - # These properties are available on MacOS, but not on Windows or Ubuntu. + # These properties are available on MacOS, but not Ubuntu. # On other Unix systems (such as FreeBSD), the following attributes may be # available (but may be only filled out if root tries to use them): @property def st_gen(self) -> int: ... # file generation number @property - def st_birthtime(self) -> int: ... # time of file creation + def st_birthtime(self) -> float: ... # time of file creation in seconds if sys.platform == "darwin": @property def st_flags(self) -> int: ... # user defined flags for file @@ -484,8 +511,8 @@ if sys.platform != "win32": def setpgid(__pid: int, __pgrp: int) -> None: ... def setregid(__rgid: int, __egid: int) -> None: ... if sys.platform != "darwin": - def setresgid(rgid: int, egid: int, sgid: int) -> None: ... - def setresuid(ruid: int, euid: int, suid: int) -> None: ... + def setresgid(__rgid: int, __egid: int, __sgid: int) -> None: ... + def setresuid(__ruid: int, __euid: int, __suid: int) -> None: ... def setreuid(__ruid: int, __euid: int) -> None: ... def getsid(__pid: int) -> int: ... @@ -614,13 +641,15 @@ def open(path: StrOrBytesPath, flags: int, mode: int = 0o777, *, dir_fd: int | N def pipe() -> tuple[int, int]: ... def read(__fd: int, __length: int) -> bytes: ... +if sys.version_info >= (3, 12) or sys.platform != "win32": + def get_blocking(__fd: int) -> bool: ... + def set_blocking(__fd: int, __blocking: bool) -> None: ... + if sys.platform != "win32": def fchmod(fd: int, mode: int) -> None: ... def fchown(fd: int, uid: int, gid: int) -> None: ... def fpathconf(__fd: int, __name: str | int) -> int: ... def fstatvfs(__fd: int) -> statvfs_result: ... - def get_blocking(__fd: int) -> bool: ... - def set_blocking(__fd: int, __blocking: bool) -> None: ... def lockf(__fd: int, __command: int, __length: int) -> None: ... def openpty() -> tuple[int, int]: ... # some flavors of Unix if sys.platform != "darwin": @@ -641,18 +670,20 @@ if sys.platform != "win32": RWF_SYNC: int RWF_HIPRI: int RWF_NOWAIT: int - @overload - def sendfile(out_fd: int, in_fd: int, offset: int | None, count: int) -> int: ... - @overload - def sendfile( - out_fd: int, - in_fd: int, - offset: int, - count: int, - headers: Sequence[ReadableBuffer] = ..., - trailers: Sequence[ReadableBuffer] = ..., - flags: int = 0, - ) -> int: ... # FreeBSD and Mac OS X only + + if sys.platform == "linux": + def sendfile(out_fd: FileDescriptor, in_fd: FileDescriptor, offset: int | None, count: int) -> int: ... + else: + def sendfile( + out_fd: FileDescriptor, + in_fd: FileDescriptor, + offset: int, + count: int, + headers: Sequence[ReadableBuffer] = ..., + trailers: Sequence[ReadableBuffer] = ..., + flags: int = 0, + ) -> int: ... # FreeBSD and Mac OS X only + def readv(__fd: int, __buffers: SupportsLenAndGetItem[WriteableBuffer]) -> int: ... def writev(__fd: int, __buffers: SupportsLenAndGetItem[ReadableBuffer]) -> int: ... @@ -1042,3 +1073,45 @@ if sys.version_info >= (3, 9): if sys.platform == "linux": def pidfd_open(pid: int, flags: int = ...) -> int: ... + +if sys.version_info >= (3, 12) and sys.platform == "win32": + def listdrives() -> list[str]: ... + def listmounts(volume: str) -> list[str]: ... + def listvolumes() -> list[str]: ... + +if sys.version_info >= (3, 10) and sys.platform == "linux": + EFD_CLOEXEC: int + EFD_NONBLOCK: int + EFD_SEMAPHORE: int + SPLICE_F_MORE: int + SPLICE_F_MOVE: int + SPLICE_F_NONBLOCK: int + def eventfd(initval: int, flags: int = 524288) -> FileDescriptor: ... + def eventfd_read(fd: FileDescriptor) -> int: ... + def eventfd_write(fd: FileDescriptor, value: int) -> None: ... + def splice( + src: FileDescriptor, + dst: FileDescriptor, + count: int, + offset_src: int | None = ..., + offset_dst: int | None = ..., + flags: int = 0, + ) -> int: ... + +if sys.version_info >= (3, 12) and sys.platform == "linux": + CLONE_FILES: int + CLONE_FS: int + CLONE_NEWCGROUP: int + CLONE_NEWIPC: int + CLONE_NEWNET: int + CLONE_NEWNS: int + CLONE_NEWPID: int + CLONE_NEWTIME: int + CLONE_NEWUSER: int + CLONE_NEWUTS: int + CLONE_SIGHAND: int + CLONE_SYSVSEM: int + CLONE_THREAD: int + CLONE_VM: int + def unshare(flags: int) -> None: ... + def setns(fd: FileDescriptorLike, nstype: int = 0) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/posix.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/posix.pyi index ffd967575..81cc93c5a 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/posix.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/posix.pyi @@ -14,7 +14,6 @@ if sys.platform != "win32": EX_NOHOST as EX_NOHOST, EX_NOINPUT as EX_NOINPUT, EX_NOPERM as EX_NOPERM, - EX_NOTFOUND as EX_NOTFOUND, EX_NOUSER as EX_NOUSER, EX_OK as EX_OK, EX_OSERR as EX_OSERR, @@ -29,6 +28,7 @@ if sys.platform != "win32": F_TEST as F_TEST, F_TLOCK as F_TLOCK, F_ULOCK as F_ULOCK, + NGROUPS_MAX as NGROUPS_MAX, O_APPEND as O_APPEND, O_ASYNC as O_ASYNC, O_CREAT as O_CREAT, @@ -222,6 +222,9 @@ if sys.platform != "win32": writev as writev, ) + if sys.platform != "darwin": + from os import EX_NOTFOUND as EX_NOTFOUND + if sys.platform == "linux": from os import ( GRND_NONBLOCK as GRND_NONBLOCK, @@ -236,6 +239,20 @@ if sys.platform != "win32": removexattr as removexattr, setxattr as setxattr, ) + + if sys.version_info >= (3, 10): + from os import ( + EFD_CLOEXEC as EFD_CLOEXEC, + EFD_NONBLOCK as EFD_NONBLOCK, + EFD_SEMAPHORE as EFD_SEMAPHORE, + SPLICE_F_MORE as SPLICE_F_MORE, + SPLICE_F_MOVE as SPLICE_F_MOVE, + SPLICE_F_NONBLOCK as SPLICE_F_NONBLOCK, + eventfd as eventfd, + eventfd_read as eventfd_read, + eventfd_write as eventfd_write, + splice as splice, + ) else: from os import chflags as chflags, lchflags as lchflags, lchmod as lchmod @@ -314,6 +331,34 @@ if sys.platform != "win32": if sys.platform != "darwin": from os import RWF_DSYNC as RWF_DSYNC, RWF_HIPRI as RWF_HIPRI, RWF_NOWAIT as RWF_NOWAIT, RWF_SYNC as RWF_SYNC + if sys.version_info >= (3, 12) and sys.platform == "linux": + from os import ( + CLONE_FILES as CLONE_FILES, + CLONE_FS as CLONE_FS, + CLONE_NEWCGROUP as CLONE_NEWCGROUP, + CLONE_NEWIPC as CLONE_NEWIPC, + CLONE_NEWNET as CLONE_NEWNET, + CLONE_NEWNS as CLONE_NEWNS, + CLONE_NEWPID as CLONE_NEWPID, + CLONE_NEWTIME as CLONE_NEWTIME, + CLONE_NEWUSER as CLONE_NEWUSER, + CLONE_NEWUTS as CLONE_NEWUTS, + CLONE_SIGHAND as CLONE_SIGHAND, + CLONE_SYSVSEM as CLONE_SYSVSEM, + CLONE_THREAD as CLONE_THREAD, + CLONE_VM as CLONE_VM, + setns as setns, + unshare as unshare, + ) + + if sys.version_info >= (3, 12) and sys.platform == "darwin": + from os import ( + PRIO_DARWIN_BG as PRIO_DARWIN_BG, + PRIO_DARWIN_NONUI as PRIO_DARWIN_NONUI, + PRIO_DARWIN_PROCESS as PRIO_DARWIN_PROCESS, + PRIO_DARWIN_THREAD as PRIO_DARWIN_THREAD, + ) + # Not same as os.environ or os.environb # Because of this variable, we can't do "from posix import *" in os/__init__.pyi environ: dict[bytes, bytes] diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/resource.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/resource.pyi index f2e979ff8..57cefb468 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/resource.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/resource.pyi @@ -1,6 +1,5 @@ import sys from _typeshed import structseq -from typing import overload from typing_extensions import Final, final if sys.platform != "win32": @@ -86,8 +85,8 @@ if sys.platform != "win32": def getrusage(__who: int) -> struct_rusage: ... def setrlimit(__resource: int, __limits: tuple[int, int]) -> None: ... if sys.platform == "linux": - @overload - def prlimit(pid: int, resource: int, limits: tuple[int, int]) -> tuple[int, int]: ... - @overload - def prlimit(pid: int, resource: int) -> tuple[int, int]: ... + if sys.version_info >= (3, 12): + def prlimit(__pid: int, __resource: int, __limits: tuple[int, int] | None = None) -> tuple[int, int]: ... + else: + def prlimit(__pid: int, __resource: int, __limits: tuple[int, int] = ...) -> tuple[int, int]: ... error = OSError diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/select.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/select.pyi index c86d20c35..5e2828e42 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/select.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/select.pyi @@ -15,7 +15,8 @@ if sys.platform != "win32": POLLOUT: int POLLPRI: int POLLRDBAND: int - POLLRDHUP: int + if sys.platform == "linux": + POLLRDHUP: int POLLRDNORM: int POLLWRBAND: int POLLWRNORM: int @@ -136,7 +137,6 @@ if sys.platform == "linux": EPOLLRDNORM: int EPOLLWRBAND: int EPOLLWRNORM: int - EPOLL_RDHUP: int EPOLL_CLOEXEC: int if sys.platform != "linux" and sys.platform != "darwin" and sys.platform != "win32": diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/selectors.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/selectors.pyi index 90a923f09..043df9253 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/selectors.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/selectors.pyi @@ -59,15 +59,21 @@ class DevpollSelector(BaseSelector): def select(self, timeout: float | None = ...) -> list[tuple[SelectorKey, _EventMask]]: ... def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... -class KqueueSelector(BaseSelector): - def fileno(self) -> int: ... - def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... - def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... - def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... - def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... +if sys.platform != "win32": + class KqueueSelector(BaseSelector): + def fileno(self) -> int: ... + def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... + def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... + def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... + def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... +# Not a real class at runtime, it is just a conditional alias to other real selectors. +# The runtime logic is more fine-grained than a `sys.platform` check; +# not really expressible in the stubs class DefaultSelector(BaseSelector): def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... + if sys.platform != "win32": + def fileno(self) -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/signal.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/signal.pyi index 4c961a0c9..906a6dabe 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/signal.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/signal.pyi @@ -10,10 +10,8 @@ NSIG: int class Signals(IntEnum): SIGABRT: int - SIGEMT: int SIGFPE: int SIGILL: int - SIGINFO: int SIGINT: int SIGSEGV: int SIGTERM: int @@ -47,6 +45,9 @@ class Signals(IntEnum): SIGWINCH: int SIGXCPU: int SIGXFSZ: int + if sys.platform != "linux": + SIGEMT: int + SIGINFO: int if sys.platform != "darwin": SIGCLD: int SIGPOLL: int @@ -77,10 +78,8 @@ else: def signal(__signalnum: _SIGNUM, __handler: _HANDLER) -> _HANDLER: ... SIGABRT: Signals -SIGEMT: Signals SIGFPE: Signals SIGILL: Signals -SIGINFO: Signals SIGINT: Signals SIGSEGV: Signals SIGTERM: Signals @@ -90,6 +89,9 @@ if sys.platform == "win32": CTRL_C_EVENT: Signals CTRL_BREAK_EVENT: Signals else: + if sys.platform != "linux": + SIGINFO: Signals + SIGEMT: Signals SIGALRM: Signals SIGBUS: Signals SIGCHLD: Signals @@ -170,8 +172,12 @@ else: @property def si_band(self) -> int: ... - def sigtimedwait(sigset: Iterable[int], timeout: float) -> struct_siginfo | None: ... - def sigwaitinfo(sigset: Iterable[int]) -> struct_siginfo: ... + if sys.version_info >= (3, 10): + def sigtimedwait(__sigset: Iterable[int], __timeout: float) -> struct_siginfo | None: ... + def sigwaitinfo(__sigset: Iterable[int]) -> struct_siginfo: ... + else: + def sigtimedwait(sigset: Iterable[int], timeout: float) -> struct_siginfo | None: ... + def sigwaitinfo(sigset: Iterable[int]) -> struct_siginfo: ... if sys.version_info >= (3, 8): def strsignal(__signalnum: _SIGNUM) -> str | None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/socket.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/socket.pyi index da06ce2c2..cc0cbe370 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/socket.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/socket.pyi @@ -129,7 +129,9 @@ if sys.platform != "darwin" or sys.version_info >= (3, 9): IPV6_RTHDR as IPV6_RTHDR, ) -if sys.platform != "darwin": +if sys.platform == "darwin": + from _socket import PF_SYSTEM as PF_SYSTEM, SYSPROTO_CONTROL as SYSPROTO_CONTROL +else: from _socket import SO_EXCLUSIVEADDRUSE as SO_EXCLUSIVEADDRUSE if sys.version_info >= (3, 10): diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/ssl.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/ssl.pyi index 73762cd75..d7f256d03 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/ssl.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/ssl.pyi @@ -4,7 +4,7 @@ import sys from _typeshed import ReadableBuffer, StrOrBytesPath, WriteableBuffer from collections.abc import Callable, Iterable from typing import Any, NamedTuple, overload -from typing_extensions import Literal, Self, TypeAlias, TypedDict, final +from typing_extensions import Literal, Never, Self, TypeAlias, TypedDict, final _PCTRTT: TypeAlias = tuple[tuple[str, str], ...] _PCTRTTT: TypeAlias = tuple[_PCTRTT, ...] @@ -203,7 +203,6 @@ class Options(enum.IntFlag): OP_ENABLE_MIDDLEBOX_COMPAT: int if sys.version_info >= (3, 12): OP_LEGACY_SERVER_CONNECT: int - if sys.version_info >= (3, 12) and sys.platform != "linux": OP_ENABLE_KTLS: int if sys.version_info >= (3, 11): OP_IGNORE_UNEXPECTED_EOF: int @@ -227,7 +226,6 @@ if sys.version_info >= (3, 8): OP_ENABLE_MIDDLEBOX_COMPAT: Options if sys.version_info >= (3, 12): OP_LEGACY_SERVER_CONNECT: Options -if sys.version_info >= (3, 12) and sys.platform != "linux": OP_ENABLE_KTLS: Options if sys.version_info >= (3, 11): OP_IGNORE_UNEXPECTED_EOF: Options @@ -369,6 +367,10 @@ class SSLSocket(socket.socket): def pending(self) -> int: ... if sys.version_info >= (3, 8): def verify_client_post_handshake(self) -> None: ... + # These methods always raise `NotImplementedError`: + def recvmsg(self, *args: Never, **kwargs: Never) -> Never: ... # type: ignore[override] + def recvmsg_into(self, *args: Never, **kwargs: Never) -> Never: ... # type: ignore[override] + def sendmsg(self, *args: Never, **kwargs: Never) -> Never: ... # type: ignore[override] class TLSVersion(enum.IntEnum): MINIMUM_SUPPORTED: int diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/subprocess.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/subprocess.pyi index 346e4d551..1013db7ee 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/subprocess.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/subprocess.pyi @@ -2600,6 +2600,7 @@ if sys.platform == "win32": hStdError: Any | None wShowWindow: int lpAttributeList: Mapping[str, Any] + def copy(self) -> STARTUPINFO: ... from _winapi import ( ABOVE_NORMAL_PRIORITY_CLASS as ABOVE_NORMAL_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS as BELOW_NORMAL_PRIORITY_CLASS, diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/sys.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/sys/__init__.pyi similarity index 98% rename from packages/pyright-internal/typeshed-fallback/stdlib/sys.pyi rename to packages/pyright-internal/typeshed-fallback/stdlib/sys/__init__.pyi index ca0491240..cf3b1bc47 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/sys.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/sys/__init__.pyi @@ -225,9 +225,10 @@ class _thread_info(_UninstantiableStructseq, tuple[_ThreadInfoName, _ThreadInfoL def version(self) -> str | None: ... thread_info: _thread_info +_ReleaseLevel: TypeAlias = Literal["alpha", "beta", "candidate", "final"] @final -class _version_info(_UninstantiableStructseq, tuple[int, int, int, str, int]): +class _version_info(_UninstantiableStructseq, tuple[int, int, int, _ReleaseLevel, int]): @property def major(self) -> int: ... @property @@ -235,7 +236,7 @@ class _version_info(_UninstantiableStructseq, tuple[int, int, int, str, int]): @property def micro(self) -> int: ... @property - def releaselevel(self) -> str: ... + def releaselevel(self) -> _ReleaseLevel: ... @property def serial(self) -> int: ... @@ -369,3 +370,7 @@ if sys.version_info >= (3, 12): def activate_stack_trampoline(__backend: str) -> None: ... else: def activate_stack_trampoline(__backend: str) -> NoReturn: ... + + from . import _monitoring + + monitoring = _monitoring diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/sys/_monitoring.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/sys/_monitoring.pyi new file mode 100644 index 000000000..0137fb484 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stdlib/sys/_monitoring.pyi @@ -0,0 +1,52 @@ +# This py312+ module provides annotations for `sys.monitoring`. +# It's named `sys._monitoring` in typeshed, +# because trying to import `sys.monitoring` will fail at runtime! +# At runtime, `sys.monitoring` has the unique status +# of being a `types.ModuleType` instance that cannot be directly imported, +# and exists in the `sys`-module namespace despite `sys` not being a package. + +from collections.abc import Callable +from types import CodeType +from typing import Any + +DEBUGGER_ID: int +COVERAGE_ID: int +PROFILER_ID: int +OPTIMIZER_ID: int + +def use_tool_id(__tool_id: int, __name: str) -> None: ... +def free_tool_id(__tool_id: int) -> None: ... +def get_tool(__tool_id: int) -> str | None: ... + +events: _events + +class _events: + BRANCH: int + CALL: int + C_RAISE: int + C_RETURN: int + EXCEPTION_HANDLED: int + INSTRUCTION: int + JUMP: int + LINE: int + NO_EVENTS: int + PY_RESUME: int + PY_RETURN: int + PY_START: int + PY_THROW: int + PY_UNWIND: int + PY_YIELD: int + RAISE: int + RERAISE: int + STOP_ITERATION: int + +def get_events(__tool_id: int) -> int: ... +def set_events(__tool_id: int, __event_set: int) -> None: ... +def get_local_events(__tool_id: int, __code: CodeType) -> int: ... +def set_local_events(__tool_id: int, __code: CodeType, __event_set: int) -> int: ... +def restart_events() -> None: ... # undocumented + +DISABLE: object +MISSING: object + +def register_callback(__tool_id: int, __event: int, __func: Callable[..., Any] | None) -> Callable[..., Any] | None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/syslog.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/syslog.pyi index cfa8df887..0b769301a 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/syslog.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/syslog.pyi @@ -36,11 +36,11 @@ if sys.platform != "win32": LOG_USER: Literal[8] LOG_UUCP: Literal[64] LOG_WARNING: Literal[4] - def LOG_MASK(a: int) -> int: ... - def LOG_UPTO(a: int) -> int: ... + def LOG_MASK(__pri: int) -> int: ... + def LOG_UPTO(__pri: int) -> int: ... def closelog() -> None: ... def openlog(ident: str = ..., logoption: int = ..., facility: int = ...) -> None: ... - def setlogmask(x: int) -> int: ... + def setlogmask(__maskpri: int) -> int: ... @overload def syslog(priority: int, message: str) -> None: ... @overload diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/tempfile.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/tempfile.pyi index 61bcde242..f8dcb24c1 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/tempfile.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/tempfile.pyi @@ -321,7 +321,7 @@ else: dir: GenericPath[AnyStr] | None = None, ) -> IO[Any]: ... -class _TemporaryFileWrapper(IO[AnyStr], Generic[AnyStr]): +class _TemporaryFileWrapper(IO[AnyStr]): file: IO[AnyStr] # io.TextIOWrapper, io.BufferedReader or io.BufferedWriter name: str delete: bool diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/termios.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/termios.pyi index bf8d7bee2..776396cce 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/termios.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/termios.pyi @@ -3,10 +3,12 @@ from _typeshed import FileDescriptorLike from typing import Any from typing_extensions import TypeAlias -if sys.platform != "win32": - # Must be a list of length 7, containing 6 ints and a list of NCCS 1-character bytes or ints. - _Attr: TypeAlias = list[int | list[bytes | int]] +# Must be a list of length 7, containing 6 ints and a list of NCCS 1-character bytes or ints. +_Attr: TypeAlias = list[int | list[bytes | int]] | list[int | list[bytes]] | list[int | list[int]] +# Same as _Attr for return types; we use Any to avoid a union. +_AttrReturn: TypeAlias = list[Any] +if sys.platform != "win32": B0: int B1000000: int B110: int @@ -252,7 +254,7 @@ if sys.platform != "win32": XCASE: int XTABS: int - def tcgetattr(__fd: FileDescriptorLike) -> list[Any]: ... # Returns _Attr; we use Any to avoid a union in the return type + def tcgetattr(__fd: FileDescriptorLike) -> _AttrReturn: ... def tcsetattr(__fd: FileDescriptorLike, __when: int, __attributes: _Attr) -> None: ... def tcsendbreak(__fd: FileDescriptorLike, __duration: int) -> None: ... def tcdrain(__fd: FileDescriptorLike) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/tkinter/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/tkinter/__init__.pyi index a0a88a8ac..51ed55db8 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/tkinter/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/tkinter/__init__.pyi @@ -2888,7 +2888,7 @@ class Scrollbar(Widget): def fraction(self, x: int, y: int) -> float: ... def identify(self, x: int, y: int) -> Literal["arrow1", "arrow2", "slider", "trough1", "trough2", ""]: ... def get(self) -> tuple[float, float, float, float] | tuple[float, float]: ... - def set(self, first: float, last: float) -> None: ... + def set(self, first: float | str, last: float | str) -> None: ... _TextIndex: TypeAlias = _tkinter.Tcl_Obj | str | float | Misc diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/tty.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/tty.pyi index 43f2e1cf9..add0d57a8 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/tty.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/tty.pyi @@ -1,9 +1,16 @@ import sys +import termios from typing import IO from typing_extensions import TypeAlias if sys.platform != "win32": __all__ = ["setraw", "setcbreak"] + if sys.version_info >= (3, 12): + __all__ += ["cfmakeraw", "cfmakecbreak"] + + _ModeSetterReturn: TypeAlias = termios._AttrReturn + else: + _ModeSetterReturn: TypeAlias = None _FD: TypeAlias = int | IO[str] @@ -15,5 +22,9 @@ if sys.platform != "win32": ISPEED: int OSPEED: int CC: int - def setraw(fd: _FD, when: int = 2) -> None: ... - def setcbreak(fd: _FD, when: int = 2) -> None: ... + def setraw(fd: _FD, when: int = 2) -> _ModeSetterReturn: ... + def setcbreak(fd: _FD, when: int = 2) -> _ModeSetterReturn: ... + + if sys.version_info >= (3, 12): + def cfmakeraw(mode: termios._Attr) -> None: ... + def cfmakecbreak(mode: termios._Attr) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/types.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/types.pyi index 2f4bd1a88..a50bbf145 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/types.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/types.pyi @@ -16,7 +16,7 @@ from collections.abc import ( from importlib.machinery import ModuleSpec # pytype crashes if types.MappingProxyType inherits from collections.abc.Mapping instead of typing.Mapping -from typing import Any, ClassVar, Generic, Mapping, Protocol, TypeVar, overload # noqa: Y022 +from typing import Any, ClassVar, Mapping, Protocol, TypeVar, overload # noqa: Y022 from typing_extensions import Literal, ParamSpec, Self, TypeVarTuple, final __all__ = [ @@ -69,7 +69,7 @@ _VT_co = TypeVar("_VT_co", covariant=True) @final class _Cell: if sys.version_info >= (3, 8): - def __init__(self, __contents: object = ...) -> None: ... + def __new__(cls, __contents: object = ...) -> Self: ... def __eq__(self, __value: object) -> bool: ... __hash__: ClassVar[None] # type: ignore[assignment] @@ -96,14 +96,14 @@ class FunctionType: __type_params__: tuple[TypeVar | ParamSpec | TypeVarTuple, ...] __module__: str - def __init__( - self, + def __new__( + cls, code: CodeType, globals: dict[str, Any], name: str | None = ..., argdefs: tuple[object, ...] | None = ..., closure: tuple[_Cell, ...] | None = ..., - ) -> None: ... + ) -> Self: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... @overload def __get__(self, __instance: None, __owner: type) -> FunctionType: ... @@ -162,8 +162,8 @@ class CodeType: def co_positions(self) -> Iterable[tuple[int | None, int | None, int | None, int | None]]: ... if sys.version_info >= (3, 11): - def __init__( - self, + def __new__( + cls, __argcount: int, __posonlyargcount: int, __kwonlyargcount: int, @@ -182,10 +182,10 @@ class CodeType: __exceptiontable: bytes, __freevars: tuple[str, ...] = ..., __cellvars: tuple[str, ...] = ..., - ) -> None: ... + ) -> Self: ... elif sys.version_info >= (3, 10): - def __init__( - self, + def __new__( + cls, __argcount: int, __posonlyargcount: int, __kwonlyargcount: int, @@ -202,10 +202,10 @@ class CodeType: __linetable: bytes, __freevars: tuple[str, ...] = ..., __cellvars: tuple[str, ...] = ..., - ) -> None: ... + ) -> Self: ... elif sys.version_info >= (3, 8): - def __init__( - self, + def __new__( + cls, __argcount: int, __posonlyargcount: int, __kwonlyargcount: int, @@ -222,10 +222,10 @@ class CodeType: __lnotab: bytes, __freevars: tuple[str, ...] = ..., __cellvars: tuple[str, ...] = ..., - ) -> None: ... + ) -> Self: ... else: - def __init__( - self, + def __new__( + cls, __argcount: int, __kwonlyargcount: int, __nlocals: int, @@ -241,7 +241,7 @@ class CodeType: __lnotab: bytes, __freevars: tuple[str, ...] = ..., __cellvars: tuple[str, ...] = ..., - ) -> None: ... + ) -> Self: ... if sys.version_info >= (3, 11): def replace( self, @@ -309,9 +309,9 @@ class CodeType: ) -> CodeType: ... @final -class MappingProxyType(Mapping[_KT, _VT_co], Generic[_KT, _VT_co]): +class MappingProxyType(Mapping[_KT, _VT_co]): __hash__: ClassVar[None] # type: ignore[assignment] - def __init__(self, mapping: SupportsKeysAndGetItem[_KT, _VT_co]) -> None: ... + def __new__(cls, mapping: SupportsKeysAndGetItem[_KT, _VT_co]) -> Self: ... def __getitem__(self, __key: _KT) -> _VT_co: ... def __iter__(self) -> Iterator[_KT]: ... def __len__(self) -> int: ... @@ -444,7 +444,7 @@ class MethodType: def __name__(self) -> str: ... # inherited from the added function @property def __qualname__(self) -> str: ... # inherited from the added function - def __init__(self, __func: Callable[..., Any], __obj: object) -> None: ... + def __new__(cls, __func: Callable[..., Any], __obj: object) -> Self: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... def __eq__(self, __value: object) -> bool: ... def __hash__(self) -> int: ... @@ -513,7 +513,7 @@ class ClassMethodDescriptorType: @final class TracebackType: - def __init__(self, tb_next: TracebackType | None, tb_frame: FrameType, tb_lasti: int, tb_lineno: int) -> None: ... + def __new__(cls, tb_next: TracebackType | None, tb_frame: FrameType, tb_lasti: int, tb_lineno: int) -> Self: ... tb_next: TracebackType | None # the rest are read-only even in 3.7 @property @@ -610,7 +610,7 @@ if sys.version_info >= (3, 9): def __args__(self) -> tuple[Any, ...]: ... @property def __parameters__(self) -> tuple[Any, ...]: ... - def __init__(self, origin: type, args: Any) -> None: ... + def __new__(cls, origin: type, args: Any) -> Self: ... def __getitem__(self, __typeargs: Any) -> GenericAlias: ... def __eq__(self, __value: object) -> bool: ... def __hash__(self) -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/typing.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/typing.pyi index 2c1ebe6d7..ad5719ca9 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/typing.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/typing.pyi @@ -527,7 +527,7 @@ class Sequence(Collection[_T_co], Reversible[_T_co], Generic[_T_co]): def __iter__(self) -> Iterator[_T_co]: ... def __reversed__(self) -> Iterator[_T_co]: ... -class MutableSequence(Sequence[_T], Generic[_T]): +class MutableSequence(Sequence[_T]): @abstractmethod def insert(self, index: int, value: _T) -> None: ... @overload @@ -557,7 +557,7 @@ class MutableSequence(Sequence[_T], Generic[_T]): def remove(self, value: _T) -> None: ... def __iadd__(self, values: Iterable[_T]) -> typing_extensions.Self: ... -class AbstractSet(Collection[_T_co], Generic[_T_co]): +class AbstractSet(Collection[_T_co]): @abstractmethod def __contains__(self, x: object) -> bool: ... def _hash(self) -> int: ... @@ -573,7 +573,7 @@ class AbstractSet(Collection[_T_co], Generic[_T_co]): def __eq__(self, other: object) -> bool: ... def isdisjoint(self, other: Iterable[Any]) -> bool: ... -class MutableSet(AbstractSet[_T], Generic[_T]): +class MutableSet(AbstractSet[_T]): @abstractmethod def add(self, value: _T) -> None: ... @abstractmethod @@ -646,7 +646,7 @@ class Mapping(Collection[_KT], Generic[_KT, _VT_co]): def __contains__(self, __key: object) -> bool: ... def __eq__(self, __other: object) -> bool: ... -class MutableMapping(Mapping[_KT, _VT], Generic[_KT, _VT]): +class MutableMapping(Mapping[_KT, _VT]): @abstractmethod def __setitem__(self, __key: _KT, __value: _VT) -> None: ... @abstractmethod @@ -703,14 +703,16 @@ TYPE_CHECKING: bool # In stubs, the arguments of the IO class are marked as positional-only. # This differs from runtime, but better reflects the fact that in reality # classes deriving from IO use different names for the arguments. -class IO(Iterator[AnyStr], Generic[AnyStr]): +class IO(Iterator[AnyStr]): # At runtime these are all abstract properties, # but making them abstract in the stub is hugely disruptive, for not much gain. # See #8726 @property def mode(self) -> str: ... + # Usually str, but may be bytes if a bytes path was passed to open(). See #10737. + # If PEP 696 becomes available, we may want to use a defaulted TypeVar here. @property - def name(self) -> str: ... + def name(self) -> str | Any: ... @abstractmethod def close(self) -> None: ... @property diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/unittest/case.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/unittest/case.pyi index 1f58f266e..aa04e16d6 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/unittest/case.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/unittest/case.pyi @@ -126,9 +126,9 @@ class TestCase: @overload def assertLess(self, a: _T, b: SupportsDunderGT[_T], msg: Any = None) -> None: ... @overload - def assertLessEqual(self, a: SupportsDunderLT[_T], b: _T, msg: Any = None) -> None: ... + def assertLessEqual(self, a: SupportsDunderLE[_T], b: _T, msg: Any = None) -> None: ... @overload - def assertLessEqual(self, a: _T, b: SupportsDunderGT[_T], msg: Any = None) -> None: ... + def assertLessEqual(self, a: _T, b: SupportsDunderGE[_T], msg: Any = None) -> None: ... # `assertRaises`, `assertRaisesRegex`, and `assertRaisesRegexp` # are not using `ParamSpec` intentionally, # because they might be used with explicitly wrong arg types to raise some error in tests. diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/weakref.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/weakref.pyi index ca5366602..ae88f3a31 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/weakref.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/weakref.pyi @@ -40,7 +40,7 @@ _P = ParamSpec("_P") ProxyTypes: tuple[type[Any], ...] -class WeakMethod(ref[_CallableT], Generic[_CallableT]): +class WeakMethod(ref[_CallableT]): def __new__(cls, meth: _CallableT, callback: Callable[[Self], object] | None = None) -> Self: ... def __call__(self) -> _CallableT | None: ... def __eq__(self, other: object) -> bool: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/winreg.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/winreg.pyi index 337bd9706..613b239ff 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/winreg.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/winreg.pyi @@ -99,3 +99,5 @@ if sys.platform == "win32": def Close(self) -> None: ... def Detach(self) -> int: ... def __hash__(self) -> int: ... + @property + def handle(self) -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/winsound.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/winsound.pyi index 9b2b57a38..aa04fdc27 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/winsound.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/winsound.pyi @@ -4,6 +4,7 @@ from typing import overload from typing_extensions import Literal if sys.platform == "win32": + SND_APPLICATION: Literal[128] SND_FILENAME: Literal[131072] SND_ALIAS: Literal[65536] SND_LOOP: Literal[8] diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/__init__.pyi index 8bcf902df..f726eae05 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/__init__.pyi @@ -2,12 +2,18 @@ import sys from _typeshed import ReadableBuffer, StrPath, SupportsRead, _T_co from collections.abc import Iterable from typing import Any, NoReturn, Protocol +from typing_extensions import TypeAlias from xml.sax.handler import ContentHandler as ContentHandler, ErrorHandler as ErrorHandler from xml.sax.xmlreader import Locator, XMLReader class _SupportsReadClose(SupportsRead[_T_co], Protocol[_T_co]): def close(self) -> None: ... +if sys.version_info >= (3, 8): + _Source: TypeAlias = StrPath | _SupportsReadClose[bytes] | _SupportsReadClose[str] +else: + _Source: TypeAlias = str | _SupportsReadClose[bytes] | _SupportsReadClose[str] + class SAXException(Exception): def __init__(self, msg: str, exception: Exception | None = None) -> None: ... def getMessage(self) -> str: ... @@ -28,20 +34,13 @@ class SAXReaderNotAvailable(SAXNotSupportedException): ... default_parser_list: list[str] if sys.version_info >= (3, 8): + def make_parser(parser_list: Iterable[str] = ()) -> XMLReader: ... - def parse( - source: StrPath | _SupportsReadClose[bytes] | _SupportsReadClose[str], - handler: ContentHandler, - errorHandler: ErrorHandler = ..., - ) -> None: ... else: + def make_parser(parser_list: list[str] = []) -> XMLReader: ... - def parse( - source: str | _SupportsReadClose[bytes] | _SupportsReadClose[str], - handler: ContentHandler, - errorHandler: ErrorHandler = ..., - ) -> None: ... +def parse(source: _Source, handler: ContentHandler, errorHandler: ErrorHandler = ...) -> None: ... def parseString(string: ReadableBuffer | str, handler: ContentHandler, errorHandler: ErrorHandler | None = ...) -> None: ... def _create_parser(parser_name: str) -> XMLReader: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/handler.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/handler.pyi index 63b725bd6..30fe31d51 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/handler.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/handler.pyi @@ -1,5 +1,6 @@ import sys from typing import NoReturn +from xml.sax import xmlreader version: str @@ -9,19 +10,19 @@ class ErrorHandler: def warning(self, exception: BaseException) -> None: ... class ContentHandler: - def setDocumentLocator(self, locator): ... - def startDocument(self): ... - def endDocument(self): ... - def startPrefixMapping(self, prefix, uri): ... - def endPrefixMapping(self, prefix): ... - def startElement(self, name, attrs): ... - def endElement(self, name): ... - def startElementNS(self, name, qname, attrs): ... - def endElementNS(self, name, qname): ... - def characters(self, content): ... - def ignorableWhitespace(self, whitespace): ... - def processingInstruction(self, target, data): ... - def skippedEntity(self, name): ... + def setDocumentLocator(self, locator: xmlreader.Locator) -> None: ... + def startDocument(self) -> None: ... + def endDocument(self) -> None: ... + def startPrefixMapping(self, prefix: str | None, uri: str) -> None: ... + def endPrefixMapping(self, prefix) -> None: ... + def startElement(self, name: str, attrs: xmlreader.AttributesImpl) -> None: ... + def endElement(self, name: str) -> None: ... + def startElementNS(self, name: tuple[str, str], qname: str, attrs: xmlreader.AttributesNSImpl) -> None: ... + def endElementNS(self, name: tuple[str, str], qname: str) -> None: ... + def characters(self, content: str) -> None: ... + def ignorableWhitespace(self, whitespace: str) -> None: ... + def processingInstruction(self, target: str, data: str) -> None: ... + def skippedEntity(self, name: str) -> None: ... class DTDHandler: def notationDecl(self, name, publicId, systemId): ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/saxutils.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/saxutils.pyi index 0d9223770..06e03a1e4 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/saxutils.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/saxutils.pyi @@ -2,7 +2,7 @@ from _typeshed import SupportsWrite from codecs import StreamReaderWriter, StreamWriter from collections.abc import Mapping from io import RawIOBase, TextIOBase -from xml.sax import handler, xmlreader +from xml.sax import _Source, handler, xmlreader def escape(data: str, entities: Mapping[str, str] = {}) -> str: ... def unescape(data: str, entities: Mapping[str, str] = {}) -> str: ... @@ -15,46 +15,46 @@ class XMLGenerator(handler.ContentHandler): encoding: str = "iso-8859-1", short_empty_elements: bool = False, ) -> None: ... - def startDocument(self): ... - def endDocument(self): ... - def startPrefixMapping(self, prefix, uri): ... - def endPrefixMapping(self, prefix): ... - def startElement(self, name, attrs): ... - def endElement(self, name): ... - def startElementNS(self, name, qname, attrs): ... - def endElementNS(self, name, qname): ... - def characters(self, content): ... - def ignorableWhitespace(self, content): ... - def processingInstruction(self, target, data): ... + def startDocument(self) -> None: ... + def endDocument(self) -> None: ... + def startPrefixMapping(self, prefix: str | None, uri: str) -> None: ... + def endPrefixMapping(self, prefix: str | None) -> None: ... + def startElement(self, name: str, attrs: xmlreader.AttributesImpl) -> None: ... + def endElement(self, name: str) -> None: ... + def startElementNS(self, name: tuple[str, str], qname: str, attrs: xmlreader.AttributesNSImpl) -> None: ... + def endElementNS(self, name: tuple[str, str], qname: str) -> None: ... + def characters(self, content: str) -> None: ... + def ignorableWhitespace(self, content: str) -> None: ... + def processingInstruction(self, target: str, data: str) -> None: ... class XMLFilterBase(xmlreader.XMLReader): def __init__(self, parent: xmlreader.XMLReader | None = None) -> None: ... def error(self, exception): ... def fatalError(self, exception): ... def warning(self, exception): ... - def setDocumentLocator(self, locator): ... - def startDocument(self): ... - def endDocument(self): ... - def startPrefixMapping(self, prefix, uri): ... - def endPrefixMapping(self, prefix): ... - def startElement(self, name, attrs): ... - def endElement(self, name): ... - def startElementNS(self, name, qname, attrs): ... - def endElementNS(self, name, qname): ... - def characters(self, content): ... - def ignorableWhitespace(self, chars): ... - def processingInstruction(self, target, data): ... - def skippedEntity(self, name): ... + def setDocumentLocator(self, locator: xmlreader.Locator) -> None: ... + def startDocument(self) -> None: ... + def endDocument(self) -> None: ... + def startPrefixMapping(self, prefix: str | None, uri: str) -> None: ... + def endPrefixMapping(self, prefix: str | None) -> None: ... + def startElement(self, name: str, attrs: xmlreader.AttributesImpl) -> None: ... + def endElement(self, name: str) -> None: ... + def startElementNS(self, name: tuple[str, str], qname: str, attrs: xmlreader.AttributesNSImpl) -> None: ... + def endElementNS(self, name: tuple[str, str], qname: str) -> None: ... + def characters(self, content: str) -> None: ... + def ignorableWhitespace(self, chars: str) -> None: ... + def processingInstruction(self, target: str, data: str) -> None: ... + def skippedEntity(self, name: str) -> None: ... def notationDecl(self, name, publicId, systemId): ... def unparsedEntityDecl(self, name, publicId, systemId, ndata): ... def resolveEntity(self, publicId, systemId): ... - def parse(self, source): ... + def parse(self, source: _Source) -> None: ... def setLocale(self, locale): ... - def getFeature(self, name): ... - def setFeature(self, name, state): ... - def getProperty(self, name): ... - def setProperty(self, name, value): ... - def getParent(self): ... - def setParent(self, parent): ... + def getFeature(self, name: str) -> object: ... + def setFeature(self, name: str, state: object) -> None: ... + def getProperty(self, name: str) -> object: ... + def setProperty(self, name: str, value: object) -> None: ... + def getParent(self) -> xmlreader.XMLReader: ... + def setParent(self, parent: xmlreader.XMLReader) -> None: ... def prepare_input_source(source, base=""): ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/xmlreader.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/xmlreader.pyi index 0bf167b04..74d2efb01 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/xmlreader.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/xml/sax/xmlreader.pyi @@ -1,20 +1,23 @@ from collections.abc import Mapping +from typing import overload +from typing_extensions import Self, TypeAlias +from xml.sax.handler import ContentHandler, DTDHandler, EntityResolver, ErrorHandler class XMLReader: def parse(self, source): ... - def getContentHandler(self): ... - def setContentHandler(self, handler): ... - def getDTDHandler(self): ... - def setDTDHandler(self, handler): ... - def getEntityResolver(self): ... - def setEntityResolver(self, resolver): ... - def getErrorHandler(self): ... - def setErrorHandler(self, handler): ... + def getContentHandler(self) -> ContentHandler: ... + def setContentHandler(self, handler: ContentHandler) -> None: ... + def getDTDHandler(self) -> DTDHandler: ... + def setDTDHandler(self, handler: DTDHandler) -> None: ... + def getEntityResolver(self) -> EntityResolver: ... + def setEntityResolver(self, resolver: EntityResolver) -> None: ... + def getErrorHandler(self) -> ErrorHandler: ... + def setErrorHandler(self, handler: ErrorHandler) -> None: ... def setLocale(self, locale): ... - def getFeature(self, name): ... - def setFeature(self, name, state): ... - def getProperty(self, name): ... - def setProperty(self, name, value): ... + def getFeature(self, name: str) -> object: ... + def setFeature(self, name: str, state: object) -> None: ... + def getProperty(self, name: str) -> object: ... + def setProperty(self, name: str, value: object) -> None: ... class IncrementalParser(XMLReader): def __init__(self, bufsize: int = 65536) -> None: ... @@ -45,27 +48,40 @@ class InputSource: class AttributesImpl: def __init__(self, attrs: Mapping[str, str]) -> None: ... - def getLength(self): ... - def getType(self, name): ... - def getValue(self, name): ... - def getValueByQName(self, name): ... - def getNameByQName(self, name): ... - def getQNameByName(self, name): ... - def getNames(self): ... - def getQNames(self): ... + def getLength(self) -> int: ... + def getType(self, name: str) -> str: ... + def getValue(self, name: str) -> str: ... + def getValueByQName(self, name: str) -> str: ... + def getNameByQName(self, name: str) -> str: ... + def getQNameByName(self, name: str) -> str: ... + def getNames(self) -> list[str]: ... + def getQNames(self) -> list[str]: ... def __len__(self) -> int: ... - def __getitem__(self, name): ... - def keys(self): ... - def __contains__(self, name): ... - def get(self, name, alternative=None): ... - def copy(self): ... - def items(self): ... - def values(self): ... + def __getitem__(self, name: str) -> str: ... + def keys(self) -> list[str]: ... + def __contains__(self, name: str) -> bool: ... + @overload + def get(self, name: str, alternative: None = None) -> str | None: ... + @overload + def get(self, name: str, alternative: str) -> str: ... + def copy(self) -> Self: ... + def items(self) -> list[tuple[str, str]]: ... + def values(self) -> list[str]: ... + +_NSName: TypeAlias = tuple[str | None, str] class AttributesNSImpl(AttributesImpl): - def __init__(self, attrs: Mapping[tuple[str, str], str], qnames: Mapping[tuple[str, str], str]) -> None: ... - def getValueByQName(self, name): ... - def getNameByQName(self, name): ... - def getQNameByName(self, name): ... - def getQNames(self): ... - def copy(self): ... + def __init__(self, attrs: Mapping[_NSName, str], qnames: Mapping[_NSName, str]) -> None: ... + def getType(self, name: _NSName) -> str: ... # type: ignore[override] + def getValue(self, name: _NSName) -> str: ... # type: ignore[override] + def getNameByQName(self, name: str) -> _NSName: ... # type: ignore[override] + def getQNameByName(self, name: _NSName) -> str: ... # type: ignore[override] + def getNames(self) -> list[_NSName]: ... # type: ignore[override] + def __getitem__(self, name: _NSName) -> str: ... # type: ignore[override] + def keys(self) -> list[_NSName]: ... # type: ignore[override] + def __contains__(self, name: _NSName) -> bool: ... # type: ignore[override] + @overload # type: ignore[override] + def get(self, name: _NSName, alternative: None = None) -> str | None: ... + @overload # type: ignore[override] + def get(self, name: _NSName, alternative: str) -> str: ... + def items(self) -> list[tuple[_NSName, str]]: ... # type: ignore[override] diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/xxlimited.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/xxlimited.pyi index b2fb72ad2..d4f41bbaf 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/xxlimited.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/xxlimited.pyi @@ -7,6 +7,8 @@ class Str: ... @final class Xxo: def demo(self) -> None: ... + if sys.version_info >= (3, 11) and sys.platform != "win32": + x_exports: int def foo(__i: int, __j: int) -> Any: ... def new() -> Xxo: ... diff --git a/packages/pyright-internal/typeshed-fallback/stdlib/zipfile.pyi b/packages/pyright-internal/typeshed-fallback/stdlib/zipfile.pyi index dc07eb3f2..b7144f3ab 100644 --- a/packages/pyright-internal/typeshed-fallback/stdlib/zipfile.pyi +++ b/packages/pyright-internal/typeshed-fallback/stdlib/zipfile.pyi @@ -2,9 +2,10 @@ import io import sys from _typeshed import SizedBuffer, StrOrBytesPath, StrPath from collections.abc import Callable, Iterable, Iterator +from io import TextIOWrapper from os import PathLike from types import TracebackType -from typing import IO, Any, Protocol, overload +from typing import IO, Protocol, overload from typing_extensions import Literal, Self, TypeAlias __all__ = [ @@ -223,11 +224,18 @@ class ZipInfo: def FileHeader(self, zip64: bool | None = None) -> bytes: ... if sys.version_info >= (3, 8): - if sys.version_info < (3, 9): - class _PathOpenProtocol(Protocol): - def __call__(self, mode: _ReadWriteMode = "r", pwd: bytes | None = ..., *, force_zip64: bool = ...) -> IO[bytes]: ... + class CompleteDirs(ZipFile): + def resolve_dir(self, name: str) -> str: ... + @overload + @classmethod + def make(cls, source: ZipFile) -> CompleteDirs: ... + @overload + @classmethod + def make(cls: type[Self], source: StrPath | IO[bytes]) -> Self: ... class Path: + root: CompleteDirs + def __init__(self, root: ZipFile | StrPath | IO[bytes], at: str = "") -> None: ... @property def name(self) -> str: ... @property @@ -243,19 +251,25 @@ if sys.version_info >= (3, 8): @property def stem(self) -> str: ... - def __init__(self, root: ZipFile | StrPath | IO[bytes], at: str = "") -> None: ... if sys.version_info >= (3, 9): + @overload def open( self, - mode: _ReadWriteBinaryMode = "r", + mode: Literal["r", "w"] = "r", encoding: str | None = None, - *args: Any, + errors: str | None = None, + newline: str | None = None, + line_buffering: bool = ..., + write_through: bool = ..., + *, pwd: bytes | None = None, - **kwargs: Any, - ) -> IO[bytes]: ... + ) -> TextIOWrapper: ... + @overload + def open(self, mode: Literal["rb", "wb"], *, pwd: bytes | None = None) -> IO[bytes]: ... else: - @property - def open(self) -> _PathOpenProtocol: ... + def open( + self, mode: _ReadWriteBinaryMode = "r", pwd: bytes | None = None, *, force_zip64: bool = False + ) -> IO[bytes]: ... if sys.version_info >= (3, 10): def iterdir(self) -> Iterator[Self]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/METADATA.toml new file mode 100644 index 000000000..19f709209 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/METADATA.toml @@ -0,0 +1,3 @@ +version = "5.3.*" +requires = ["Flask>=0.9"] +upstream_repository = "https://github.com/miguelgrinberg/flask-socketio" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/__init__.pyi new file mode 100644 index 000000000..093762f3b --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/__init__.pyi @@ -0,0 +1,133 @@ +from _typeshed import Incomplete +from collections.abc import Callable +from threading import Thread +from typing import Any, Protocol, TypeVar, overload +from typing_extensions import ParamSpec, TypeAlias + +from flask import Flask +from flask.testing import FlaskClient + +from .namespace import Namespace +from .test_client import SocketIOTestClient + +_P = ParamSpec("_P") +_R_co = TypeVar("_R_co", covariant=True) +_ExceptionHandler: TypeAlias = Callable[[BaseException], _R_co] +_Handler: TypeAlias = Callable[_P, _R_co] + +class _HandlerDecorator(Protocol): + def __call__(self, handler: _Handler[_P, _R_co]) -> _Handler[_P, _R_co]: ... + +class _ExceptionHandlerDecorator(Protocol): + def __call__(self, exception_handler: _ExceptionHandler[_R_co]) -> _ExceptionHandler[_R_co]: ... + +class SocketIO: + # Many instance attributes are deliberately not included here, + # as the maintainer of Flask-SocketIO considers them private, internal details: + # https://github.com/python/typeshed/pull/10735#discussion_r1330768869 + def __init__( + self, + app: Flask | None = None, + *, + # SocketIO options + manage_session: bool = True, + message_queue: str | None = None, + channel: str = "flask-socketio", + path: str = "socket.io", + resource: str = "socket.io", + **kwargs, # TODO: Socket.IO server options, Engine.IO server config + ) -> None: ... + def init_app( + self, + app: Flask, + *, + # SocketIO options + manage_session: bool = True, + message_queue: str | None = None, + channel: str = "flask-socketio", + path: str = "socket.io", + resource: str = "socket.io", + **kwargs, # TODO: Socket.IO server options, Engine.IO server config: ... + ) -> None: ... + def on(self, message: str, namespace: str | None = None) -> _HandlerDecorator: ... + def on_error(self, namespace: str | None = None) -> _ExceptionHandlerDecorator: ... + def on_error_default(self, exception_handler: _ExceptionHandler[_R_co]) -> _ExceptionHandler[_R_co]: ... + def on_event(self, message: str, handler: _Handler[[Incomplete], object], namespace: str | None = None) -> None: ... + @overload + def event(self, __event_handler: _Handler[_P, _R_co]) -> _Handler[_P, _R_co]: ... + @overload + def event(self, namespace: str | None = None, *args, **kwargs) -> _HandlerDecorator: ... + def on_namespace(self, namespace_handler: Namespace) -> None: ... + def emit( + self, + event: str, + *args, + namespace: str = "/", # / is the default (global) namespace + to: str | None = None, + include_self: bool = True, + skip_sid: str | list[str] | None = None, + callback: Callable[..., Incomplete] | None = None, + ) -> None: ... + def call( + self, + event: str, + *args, + namespace: str = "/", # / is the default (global) namespace + to: str | None = None, + timeout: int = 60, # seconds + ignore_queue: bool = False, + ): ... + def send( + self, + data: Any, + json: bool = False, + namespace: str | None = None, + to: str | None = None, + callback: Callable[..., Incomplete] | None = None, + include_self: bool = True, + skip_sid: list[str] | str | None = None, + **kwargs, + ) -> None: ... + def close_room(self, room: str, namespace: str | None = None) -> None: ... + def run( + self, + app, + host: str | None = None, + port: int | None = None, + *, + debug: bool = True, + use_reloader: bool, + reloader_options: dict[str, Incomplete] = {}, + log_output: bool, + allow_unsafe_werkzeug: bool = False, + **kwargs, + ) -> None: ... + def stop(self) -> None: ... + def start_background_task(self, target: Callable[_P, None], *args: _P.args, **kwargs: _P.kwargs) -> Thread: ... + def sleep(self, seconds: int = 0): ... + def test_client( + self, + app: Flask, + namespace: str | None = None, + query_string: str | None = None, + headers: dict[str, Incomplete] | None = None, + auth: dict[str, Incomplete] | None = None, + flask_test_client: FlaskClient | None = None, + ) -> SocketIOTestClient: ... + +def emit( + event, + *args, + namespace: str = "/", # / is the default (global) namespace + to: str | None = None, + include_self: bool = True, + skip_sid: str | list[str] | None = None, + callback: Callable[..., Incomplete] | None = None, + broadcast: bool = False, +) -> None: ... +def send(message: str, **kwargs) -> None: ... +def join_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... +def leave_room(room, sid: str | None = None, namespace: str | None = None) -> None: ... +def close_room(room, namespace: str | None = None) -> None: ... +def rooms(sid: str | None = None, namespace: str | None = None) -> list[str]: ... +def disconnect(sid: str | None = None, namespace: str | None = None, silent: bool = False) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/namespace.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/namespace.pyi new file mode 100644 index 000000000..1886d2306 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/namespace.pyi @@ -0,0 +1,74 @@ +from _typeshed import Incomplete +from collections.abc import Callable +from typing import Any, Protocol, TypeVar + +_T = TypeVar("_T") + +# at runtime, socketio.namespace.BaseNamespace, but socketio isn't py.typed +class _BaseNamespace(Protocol): + def is_asyncio_based(self) -> bool: ... + def trigger_event(self, event: str, *args): ... + +# at runtime, socketio.namespace.BaseNamespace, but socketio isn't py.typed +class _Namespace(_BaseNamespace, Protocol): + def emit( + self, + event: str, + data: Incomplete | None = None, + to=None, + room: str | None = None, + skip_sid=None, + namespace: str | None = None, + callback: Callable[..., Incomplete] | None = None, + ignore_queue: bool = False, + ): ... + def send( + self, + data: Incomplete, + to=None, + room: str | None = None, + skip_sid=None, + namespace: str | None = None, + callback: Callable[..., Incomplete] | None = None, + ignore_queue: bool = False, + ) -> None: ... + def call( + self, + event: str, + data: Incomplete | None = None, + to=None, + sid=None, + namespace: str | None = None, + timeout=None, + ignore_queue: bool = False, + ): ... + def enter_room(self, sid, room: str, namespace: str | None = None): ... + def leave_room(self, sid, room: str, namespace: str | None = None): ... + def close_room(self, room: str, namespace: str | None = None): ... + def rooms(self, sid, namespace: str | None = None): ... + def get_session(self, sid, namespace: str | None = None): ... + def save_session(self, sid, session, namespace: str | None = None): ... + def session(self, sid, namespace: str | None = None): ... + def disconnect(self, sid, namespace: str | None = None): ... + +class Namespace(_Namespace): + def __init__(self, namespace: str | None = None) -> None: ... + def trigger_event(self, event: str, *args): ... + def emit( # type: ignore[override] + self, + event: str, + data: Incomplete | None = None, + room: str | None = None, + include_self: bool = True, + namespace: str | None = None, + callback: Callable[..., _T] | None = None, + ) -> _T | tuple[str, int]: ... + def send( # type: ignore[override] + self, + data: Incomplete, + room: str | None = None, + include_self: bool = True, + namespace: str | None = None, + callback: Callable[..., Any] | None = None, + ) -> None: ... + def close_room(self, room: str, namespace: str | None = None) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/test_client.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/test_client.pyi new file mode 100644 index 000000000..977aa361c --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/Flask-SocketIO/flask_socketio/test_client.pyi @@ -0,0 +1,41 @@ +from _typeshed import Incomplete +from typing import Any +from typing_extensions import TypedDict + +from flask import Flask +from flask.testing import FlaskClient + +class _Packet(TypedDict): + name: str + args: Any + namespace: str + +class SocketIOTestClient: + def __init__( + self, + app: Flask, + socketio, + namespace: str | None = None, + query_string: str | None = None, + headers: dict[str, Incomplete] | None = None, + auth: dict[str, Incomplete] | None = None, + flask_test_client: FlaskClient | None = None, + ) -> None: ... + def is_connected(self, namespace: str | None = None) -> bool: ... + def connect( + self, + namespace: str | None = None, + query_string: str | None = None, + headers: dict[str, Incomplete] | None = None, + auth: dict[str, Incomplete] | None = None, + ) -> None: ... + def disconnect(self, namespace: str | None = None) -> None: ... + def emit(self, event: str, *args, callback: bool = True, namespace: str | None = None) -> Incomplete | None: ... + def send( + self, + data: str | dict[str, Incomplete] | list[Incomplete], + json: bool = False, + callback: bool = False, + namespace: str | None = None, + ): ... + def get_received(self, namespace: str | None = None) -> list[_Packet]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Markdown/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/Markdown/METADATA.toml index baa9a2192..a84da2a3e 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Markdown/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/Markdown/METADATA.toml @@ -1,4 +1,4 @@ -version = "3.4.*" +version = "3.5.*" upstream_repository = "https://github.com/Python-Markdown/markdown" partial_stub = true diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/METADATA.toml index 9dc403e84..4e9663bc3 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/METADATA.toml @@ -1,6 +1,5 @@ -version = "10.0.*" +version = "10.1.*" upstream_repository = "https://github.com/python-pillow/Pillow" -partial_stub = true [tool.stubtest] stubtest_requirements = ["olefile"] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/EpsImagePlugin.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/EpsImagePlugin.pyi index c480388c9..8f62e26f1 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/EpsImagePlugin.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/EpsImagePlugin.pyi @@ -9,8 +9,10 @@ from .ImageFile import ImageFile split: Incomplete field: Incomplete if sys.platform == "win32": - gs_windows_binary: Literal["gswin32c", "gswin64c", "gs", False] + gs_binary: Literal["gswin32c", "gswin64c", "gs", False, None] + gs_windows_binary: Literal["gswin32c", "gswin64c", "gs", False, None] else: + gs_binary: Literal["gs", False, None] gs_windows_binary: None def has_ghostscript(): ... @@ -28,7 +30,6 @@ class EpsImageFile(ImageFile): format_description: ClassVar[str] mode_map: Incomplete im: Incomplete - mode: Incomplete tile: Incomplete def load(self, scale: int = 1, transparency: bool = False) -> _PixelAccessor: ... def load_seek(self, *args, **kwargs) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/IcnsImagePlugin.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/IcnsImagePlugin.pyi index 95650a31c..f7218692e 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/IcnsImagePlugin.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/IcnsImagePlugin.pyi @@ -34,5 +34,4 @@ class IcnsImageFile(ImageFile): def size(self, value) -> None: ... best_size: Incomplete im: Incomplete - mode: Incomplete def load(self) -> _PixelAccessor: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/IcoImagePlugin.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/IcoImagePlugin.pyi index 2a0b92fa2..a8a61e4bb 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/IcoImagePlugin.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/IcoImagePlugin.pyi @@ -23,6 +23,5 @@ class IcoImageFile(ImageFile): @size.setter def size(self, value) -> None: ... im: Incomplete - mode: Incomplete def load(self) -> _PixelAccessor: ... def load_seek(self) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/Image.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/Image.pyi index 14c95dad8..8e03aeef2 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/Image.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/Image.pyi @@ -124,6 +124,12 @@ class Quantize(IntEnum): FASTOCTREE: Literal[2] LIBIMAGEQUANT: Literal[3] +# All Quantize items +MEDIANCUT: Literal[0] +MAXCOVERAGE: Literal[1] +FASTOCTREE: Literal[2] +LIBIMAGEQUANT: Literal[3] + ID: list[str] OPEN: dict[str, Any] MIME: dict[str, str] @@ -161,7 +167,6 @@ class Image: format: ClassVar[str | None] format_description: ClassVar[str | None] im: Incomplete - mode: _Mode palette: Incomplete info: dict[Incomplete, Incomplete] readonly: int @@ -176,6 +181,8 @@ class Image: def height(self) -> int: ... @property def size(self) -> tuple[int, int]: ... + @property + def mode(self) -> _Mode: ... def __enter__(self) -> Self: ... def __exit__(self, *args: Unused) -> None: ... def close(self) -> None: ... @@ -219,6 +226,8 @@ class Image: def get_child_images(self) -> list[Image]: ... def getim(self): ... def getpalette(self, rawmode: str | None = "RGB") -> list[int] | None: ... + @property + def has_transparency_data(self) -> bool: ... def apply_transparency(self) -> None: ... def getpixel(self, xy: tuple[int, int]): ... def getprojection(self) -> tuple[list[int], list[int]]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageDraw.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageDraw.pyi index fd5f4c74c..d28771900 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageDraw.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageDraw.pyi @@ -99,6 +99,8 @@ class ImageDraw: stroke_width: int = 0, stroke_fill: _Ink | None = None, embedded_color: bool = False, + *, + font_size: int | None = None, ) -> None: ... def textlength( self, @@ -108,6 +110,8 @@ class ImageDraw: features: Sequence[str] | None = None, language: str | None = None, embedded_color: bool = False, + *, + font_size: int | None = None, ) -> float: ... def textbbox( self, @@ -122,6 +126,8 @@ class ImageDraw: language: str | None = None, stroke_width: int = 0, embedded_color: bool = False, + *, + font_size: int | None = None, ) -> tuple[int, int, int, int]: ... def multiline_textbbox( self, @@ -136,6 +142,8 @@ class ImageDraw: language: str | None = None, stroke_width: int = 0, embedded_color: bool = False, + *, + font_size: int | None = None, ) -> tuple[int, int, int, int]: ... def Draw(im: Image, mode: str | None = None) -> ImageDraw: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageFont.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageFont.pyi index 08b987e50..605f4f4cb 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageFont.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageFont.pyi @@ -111,4 +111,4 @@ def truetype( layout_engine: Layout | None = None, ) -> FreeTypeFont: ... def load_path(filename: str | bytes) -> ImageFont: ... -def load_default() -> ImageFont: ... +def load_default(size: int | None = None) -> ImageFont: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageOps.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageOps.pyi index e02190f65..c9f4f0275 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageOps.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/ImageOps.pyi @@ -24,6 +24,7 @@ def colorize( midpoint: int = 127, ) -> Image: ... def contain(image: Image, size: _Size, method: Resampling | _Resample = ...) -> Image: ... +def cover(image: Image, size: _Size, method: Resampling | _Resample = ...) -> Image: ... def pad( image: Image, size: _Size, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/JpegImagePlugin.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/JpegImagePlugin.pyi index 0b74b1070..bb938eab4 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/JpegImagePlugin.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/JpegImagePlugin.pyi @@ -16,7 +16,6 @@ class JpegImageFile(ImageFile): format: ClassVar[Literal["JPEG", "MPO"]] format_description: ClassVar[str] def load_read(self, read_bytes): ... - mode: Incomplete tile: Incomplete decoderconfig: Incomplete def draft(self, mode, size): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/PsdImagePlugin.pyi b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/PsdImagePlugin.pyi index f6e620b93..452f087de 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/PsdImagePlugin.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/Pillow/PIL/PsdImagePlugin.pyi @@ -9,7 +9,6 @@ MODES: Incomplete class PsdImageFile(ImageFile): format: ClassVar[Literal["PSD"]] format_description: ClassVar[str] - mode: Incomplete tile: Incomplete frame: Incomplete fp: Incomplete diff --git a/packages/pyright-internal/typeshed-fallback/stubs/PyScreeze/pyscreeze/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/PyScreeze/pyscreeze/__init__.pyi index be6db8189..97b730bf5 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/PyScreeze/pyscreeze/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/PyScreeze/pyscreeze/__init__.pyi @@ -1,4 +1,4 @@ -from _typeshed import Incomplete, StrOrBytesPath, Unused +from _typeshed import Incomplete, ReadableBuffer, StrOrBytesPath, Unused from collections.abc import Callable, Generator from typing import NamedTuple, SupportsFloat, TypeVar, overload from typing_extensions import Final, ParamSpec, SupportsIndex, TypeAlias @@ -7,13 +7,9 @@ from PIL import Image _P = ParamSpec("_P") _R = TypeVar("_R") -# TODO: cv2.Mat is not available as a type yet: -# https://github.com/microsoft/python-type-stubs/issues/211 -# https://github.com/microsoft/python-type-stubs/tree/main/cv2 -# https://github.com/opencv/opencv/pull/20370 -# cv2.Mat is just an alias for a numpy NDArray, but can't import that either. -# Because pyscreeze does not declare it as a dependency, stub_uploader won't let it. -_Mat: TypeAlias = Incomplete +# cv2.typing.MatLike: is an alias for `numpy.ndarray | cv2.mat_wrapper.Mat`, Mat extends ndarray. +# But can't import either, because pyscreeze does not declare them as dependencies, stub_uploader won't let it. +_MatLike: TypeAlias = Incomplete useOpenCV: Final[bool] RUNNING_PYTHON_2: Final = False @@ -40,21 +36,22 @@ class RGB(NamedTuple): class PyScreezeException(Exception): ... class ImageNotFoundException(PyScreezeException): ... -# _locateAll_opencv def requiresPyGetWindow(wrappedFunction: Callable[_P, _R]) -> Callable[_P, _R]: ... + +# _locateAll_opencv @overload def locate( - needleImage: str | Image.Image | _Mat, - haystackImage: str | Image.Image | _Mat, + needleImage: str | Image.Image | _MatLike, + haystackImage: str | Image.Image | _MatLike, *, grayscale: bool | None = None, limit: Unused = 1, region: tuple[int, int, int, int] | None = None, step: int = 1, - confidence: SupportsFloat | SupportsIndex | str = 0.999, + confidence: SupportsFloat | SupportsIndex | str | ReadableBuffer = 0.999, ) -> Box | None: ... -# _locateAll_python / _locateAll_pillow +# _locateAll_pillow @overload def locate( needleImage: str | Image.Image, @@ -70,17 +67,17 @@ def locate( # _locateAll_opencv @overload def locateOnScreen( - image: str | Image.Image | _Mat, + image: str | Image.Image | _MatLike, minSearchTime: float = 0, *, grayscale: bool | None = None, limit: Unused = 1, region: tuple[int, int, int, int] | None = None, step: int = 1, - confidence: SupportsFloat | SupportsIndex | str = 0.999, + confidence: SupportsFloat | SupportsIndex | str | ReadableBuffer = 0.999, ) -> Box | None: ... -# _locateAll_python / _locateAll_pillow +# _locateAll_pillow @overload def locateOnScreen( image: str | Image.Image, @@ -96,16 +93,16 @@ def locateOnScreen( # _locateAll_opencv @overload def locateAllOnScreen( - image: str | Image.Image | _Mat, + image: str | Image.Image | _MatLike, *, grayscale: bool | None = None, limit: int = 1000, region: tuple[int, int, int, int] | None = None, step: int = 1, - confidence: SupportsFloat | SupportsIndex | str = 0.999, + confidence: SupportsFloat | SupportsIndex | str | ReadableBuffer = 0.999, ) -> Generator[Box, None, None]: ... -# _locateAll_python / _locateAll_pillow +# _locateAll_pillow @overload def locateAllOnScreen( image: str | Image.Image, @@ -120,17 +117,17 @@ def locateAllOnScreen( # _locateAll_opencv @overload def locateCenterOnScreen( - image: str | Image.Image | _Mat, + image: str | Image.Image | _MatLike, *, minSearchTime: float, grayscale: bool | None = None, limit: Unused = 1, region: tuple[int, int, int, int] | None = None, step: int = 1, - confidence: SupportsFloat | SupportsIndex | str = 0.999, + confidence: SupportsFloat | SupportsIndex | str | ReadableBuffer = 0.999, ) -> Point | None: ... -# _locateAll_python / _locateAll_pillow +# _locateAll_pillow @overload def locateCenterOnScreen( image: str | Image.Image, @@ -142,22 +139,22 @@ def locateCenterOnScreen( step: int = 1, confidence: None = None, ) -> Point | None: ... -def locateOnScreenNear(image: str | Image.Image | _Mat, x: int, y: int) -> Box: ... -def locateCenterOnScreenNear(image: str | Image.Image | _Mat, x: int, y: int) -> Point | None: ... +def locateOnScreenNear(image: str | Image.Image | _MatLike, x: int, y: int) -> Box: ... +def locateCenterOnScreenNear(image: str | Image.Image | _MatLike, x: int, y: int) -> Point | None: ... # _locateAll_opencv @overload def locateOnWindow( - image: str | Image.Image | _Mat, + image: str | Image.Image | _MatLike, title: str, *, grayscale: bool | None = None, limit: Unused = 1, step: int = 1, - confidence: SupportsFloat | SupportsIndex | str = 0.999, + confidence: SupportsFloat | SupportsIndex | str | ReadableBuffer = 0.999, ) -> Box | None: ... -# _locateAll_python / _locateAll_pillow +# _locateAll_pillow @overload def locateOnWindow( image: str | Image.Image, @@ -181,16 +178,16 @@ def screenshot(imageFilename: StrOrBytesPath | None = None, region: tuple[int, i # _locateAll_opencv @overload def locateAll( - needleImage: str | Image.Image | _Mat, - haystackImage: str | Image.Image | _Mat, + needleImage: str | Image.Image | _MatLike, + haystackImage: str | Image.Image | _MatLike, grayscale: bool | None = None, limit: int = 1000, region: tuple[int, int, int, int] | None = None, step: int = 1, - confidence: SupportsFloat | SupportsIndex | str = 0.999, + confidence: SupportsFloat | SupportsIndex | str | ReadableBuffer = 0.999, ) -> Generator[Box, None, None]: ... -# _locateAll_python / _locateAll_pillow +# _locateAll_pillow @overload def locateAll( needleImage: str | Image.Image, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/PyYAML/yaml/emitter.pyi b/packages/pyright-internal/typeshed-fallback/stubs/PyYAML/yaml/emitter.pyi index 7b5245de4..62fd9d07a 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/PyYAML/yaml/emitter.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/PyYAML/yaml/emitter.pyi @@ -1,7 +1,10 @@ -from typing import Any, Protocol, TypeVar +from collections.abc import Callable +from typing import Any, NoReturn, Protocol, TypeVar from yaml.error import YAMLError +from .events import Event + _T_contra = TypeVar("_T_contra", str, bytes, contravariant=True) class _WriteStream(Protocol[_T_contra]): @@ -26,94 +29,100 @@ class ScalarAnalysis: ) -> None: ... class Emitter: - DEFAULT_TAG_PREFIXES: Any + DEFAULT_TAG_PREFIXES: dict[str, str] stream: _WriteStream[Any] - encoding: Any - states: Any - state: Any - events: Any - event: Any - indents: Any - indent: Any - flow_level: Any - root_context: Any - sequence_context: Any - mapping_context: Any - simple_key_context: Any - line: Any - column: Any - whitespace: Any - indention: Any - open_ended: Any - canonical: Any - allow_unicode: Any - best_indent: Any - best_width: Any - best_line_break: Any - tag_prefixes: Any - prepared_anchor: Any - prepared_tag: Any - analysis: Any - style: Any + encoding: str | None + states: list[Callable[[], None]] + state: Callable[[], None] | None + events: list[Event] + event: Event | None + indents: list[int | None] + indent: int | None + flow_level: int + root_context: bool + sequence_context: bool + mapping_context: bool + simple_key_context: bool + line: int + column: int + whitespace: bool + indention: bool + open_ended: bool + canonical: bool | None + allow_unicode: bool | None + best_indent: int + best_width: int + best_line_break: str + tag_prefixes: dict[str, str] | None + prepared_anchor: str | None + prepared_tag: str | None + analysis: ScalarAnalysis | None + style: str | None def __init__( - self, stream: _WriteStream[Any], canonical=None, indent=None, width=None, allow_unicode=None, line_break=None + self, + stream: _WriteStream[Any], + canonical: bool | None = ..., + indent: int | None = ..., + width: int | None = ..., + allow_unicode: bool | None = ..., + line_break: str | None = ..., ) -> None: ... - def dispose(self): ... - def emit(self, event): ... - def need_more_events(self): ... - def need_events(self, count): ... - def increase_indent(self, flow=False, indentless=False): ... - def expect_stream_start(self): ... - def expect_nothing(self): ... - def expect_first_document_start(self): ... - def expect_document_start(self, first=False): ... - def expect_document_end(self): ... - def expect_document_root(self): ... - def expect_node(self, root=False, sequence=False, mapping=False, simple_key=False): ... - def expect_alias(self): ... - def expect_scalar(self): ... - def expect_flow_sequence(self): ... - def expect_first_flow_sequence_item(self): ... - def expect_flow_sequence_item(self): ... - def expect_flow_mapping(self): ... - def expect_first_flow_mapping_key(self): ... - def expect_flow_mapping_key(self): ... - def expect_flow_mapping_simple_value(self): ... - def expect_flow_mapping_value(self): ... - def expect_block_sequence(self): ... - def expect_first_block_sequence_item(self): ... - def expect_block_sequence_item(self, first=False): ... - def expect_block_mapping(self): ... - def expect_first_block_mapping_key(self): ... - def expect_block_mapping_key(self, first=False): ... - def expect_block_mapping_simple_value(self): ... - def expect_block_mapping_value(self): ... - def check_empty_sequence(self): ... - def check_empty_mapping(self): ... - def check_empty_document(self): ... - def check_simple_key(self): ... - def process_anchor(self, indicator): ... - def process_tag(self): ... - def choose_scalar_style(self): ... - def process_scalar(self): ... - def prepare_version(self, version): ... - def prepare_tag_handle(self, handle): ... - def prepare_tag_prefix(self, prefix): ... - def prepare_tag(self, tag): ... - def prepare_anchor(self, anchor): ... - def analyze_scalar(self, scalar): ... - def flush_stream(self): ... - def write_stream_start(self): ... - def write_stream_end(self): ... - def write_indicator(self, indicator, need_whitespace, whitespace=False, indention=False): ... - def write_indent(self): ... - def write_line_break(self, data=None): ... - def write_version_directive(self, version_text): ... - def write_tag_directive(self, handle_text, prefix_text): ... - def write_single_quoted(self, text, split=True): ... - ESCAPE_REPLACEMENTS: Any - def write_double_quoted(self, text, split=True): ... - def determine_block_hints(self, text): ... - def write_folded(self, text): ... - def write_literal(self, text): ... - def write_plain(self, text, split=True): ... + def dispose(self) -> None: ... + def emit(self, event: Event) -> None: ... + def need_more_events(self) -> bool: ... + def need_events(self, count: int) -> bool: ... + def increase_indent(self, flow: bool = ..., indentless: bool = ...) -> None: ... + def expect_stream_start(self) -> None: ... + def expect_nothing(self) -> NoReturn: ... + def expect_first_document_start(self) -> None: ... + def expect_document_start(self, first: bool = False) -> None: ... + def expect_document_end(self) -> None: ... + def expect_document_root(self) -> None: ... + def expect_node(self, root: bool = ..., sequence: bool = ..., mapping: bool = ..., simple_key: bool = ...) -> None: ... + def expect_alias(self) -> None: ... + def expect_scalar(self) -> None: ... + def expect_flow_sequence(self) -> None: ... + def expect_first_flow_sequence_item(self) -> None: ... + def expect_flow_sequence_item(self) -> None: ... + def expect_flow_mapping(self) -> None: ... + def expect_first_flow_mapping_key(self) -> None: ... + def expect_flow_mapping_key(self) -> None: ... + def expect_flow_mapping_simple_value(self) -> None: ... + def expect_flow_mapping_value(self) -> None: ... + def expect_block_sequence(self) -> None: ... + def expect_first_block_sequence_item(self) -> None: ... + def expect_block_sequence_item(self, first: bool = ...) -> None: ... + def expect_block_mapping(self) -> None: ... + def expect_first_block_mapping_key(self) -> None: ... + def expect_block_mapping_key(self, first: bool = ...) -> None: ... + def expect_block_mapping_simple_value(self) -> None: ... + def expect_block_mapping_value(self) -> None: ... + def check_empty_sequence(self) -> bool: ... + def check_empty_mapping(self) -> bool: ... + def check_empty_document(self) -> bool: ... + def check_simple_key(self) -> bool: ... + def process_anchor(self, indicator: str) -> None: ... + def process_tag(self) -> None: ... + def choose_scalar_style(self) -> str: ... + def process_scalar(self) -> None: ... + def prepare_version(self, version) -> str: ... + def prepare_tag_handle(self, handle: str) -> str: ... + def prepare_tag_prefix(self, prefix: str) -> str: ... + def prepare_tag(self, tag: str) -> str: ... + def prepare_anchor(self, anchor: str) -> str: ... + def analyze_scalar(self, scalar: str) -> ScalarAnalysis: ... + def flush_stream(self) -> None: ... + def write_stream_start(self) -> None: ... + def write_stream_end(self) -> None: ... + def write_indicator(self, indicator: str, need_whitespace: bool, whitespace: bool = ..., indention: bool = ...) -> None: ... + def write_indent(self) -> None: ... + def write_line_break(self, data: str | None = ...) -> None: ... + def write_version_directive(self, version_text: str) -> None: ... + def write_tag_directive(self, handle_text: str, prefix_text: str) -> None: ... + def write_single_quoted(self, text: str, split: bool = ...) -> None: ... + ESCAPE_REPLACEMENTS: dict[str, str] + def write_double_quoted(self, text: str, split: bool = ...) -> None: ... + def determine_block_hints(self, text: str) -> str: ... + def write_folded(self, text: str) -> None: ... + def write_literal(self, text: str) -> None: ... + def write_plain(self, text: str, split: bool = ...) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/METADATA.toml new file mode 100644 index 000000000..d9080fa07 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/METADATA.toml @@ -0,0 +1,3 @@ +version = "3.1.*" +upstream_repository = "https://github.com/wtforms/wtforms" +requires = ["MarkupSafe"] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/__init__.pyi new file mode 100644 index 000000000..e440ec792 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/__init__.pyi @@ -0,0 +1,4 @@ +from wtforms import validators as validators, widgets as widgets +from wtforms.fields import * +from wtforms.form import Form as Form +from wtforms.validators import ValidationError as ValidationError diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/contrib/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/csrf/__init__.pyi similarity index 100% rename from packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/contrib/__init__.pyi rename to packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/csrf/__init__.pyi diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/csrf/core.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/csrf/core.pyi new file mode 100644 index 000000000..785f34a98 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/csrf/core.pyi @@ -0,0 +1,39 @@ +from abc import abstractmethod +from collections.abc import Callable, Sequence +from typing import Any +from typing_extensions import Self + +from wtforms.fields import HiddenField +from wtforms.fields.core import UnboundField, _Filter, _FormT, _Validator, _Widget +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext + +class CSRFTokenField(HiddenField): + current_token: str | None + csrf_impl: CSRF + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: str | Callable[[], str] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + *, + csrf_impl: CSRF, + ) -> None: ... + +class CSRF: + field_class: type[CSRFTokenField] + def setup_form(self, form: BaseForm) -> list[tuple[str, UnboundField[Any]]]: ... + @abstractmethod + def generate_csrf_token(self, csrf_token_field: CSRFTokenField) -> str: ... + @abstractmethod + def validate_csrf_token(self, form: BaseForm, field: CSRFTokenField) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/csrf/session.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/csrf/session.pyi new file mode 100644 index 000000000..6b2ccd98e --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/csrf/session.pyi @@ -0,0 +1,18 @@ +from _typeshed import SupportsItemAccess +from datetime import datetime, timedelta +from typing import Any + +from wtforms.csrf.core import CSRF, CSRFTokenField +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta + +class SessionCSRF(CSRF): + TIME_FORMAT: str + form_meta: DefaultMeta + def generate_csrf_token(self, csrf_token_field: CSRFTokenField) -> str: ... + def validate_csrf_token(self, form: BaseForm, field: CSRFTokenField) -> None: ... + def now(self) -> datetime: ... + @property + def time_limit(self) -> timedelta: ... + @property + def session(self) -> SupportsItemAccess[str, Any]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/__init__.pyi new file mode 100644 index 000000000..d96ee0b4a --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/__init__.pyi @@ -0,0 +1,8 @@ +from wtforms.fields.choices import * +from wtforms.fields.choices import SelectFieldBase as SelectFieldBase +from wtforms.fields.core import Field as Field, Flags as Flags, Label as Label +from wtforms.fields.datetime import * +from wtforms.fields.form import * +from wtforms.fields.list import * +from wtforms.fields.numeric import * +from wtforms.fields.simple import * diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/choices.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/choices.pyi new file mode 100644 index 000000000..5a2eff87a --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/choices.pyi @@ -0,0 +1,77 @@ +from collections.abc import Callable, Iterable, Iterator, Sequence +from typing import Any +from typing_extensions import Self, TypeAlias + +from wtforms.fields.core import Field, _Filter, _FormT, _Validator, _Widget +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext + +# technically this allows a list, but we're more strict for type safety +_Choice: TypeAlias = tuple[Any, str] | tuple[Any, str, dict[str, Any]] +# it's too difficult to get type safety here due to to nested partially invariant collections +_GroupedChoices: TypeAlias = dict[str, Any] # Any should be Collection[_Choice] +_FullChoice: TypeAlias = tuple[Any, str, bool, dict[str, Any]] # value, label, selected, render_kw +_FullGroupedChoices: TypeAlias = tuple[str, Iterable[_FullChoice]] +_Option: TypeAlias = SelectFieldBase._Option + +class SelectFieldBase(Field): + option_widget: _Widget[_Option] + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + option_widget: _Widget[_Option] | None = None, + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: object | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + def iter_choices(self) -> Iterator[_FullChoice]: ... + def has_groups(self) -> bool: ... + def iter_groups(self) -> Iterator[_FullGroupedChoices]: ... + def __iter__(self) -> Iterator[_Option]: ... + + class _Option(Field): + checked: bool + +class SelectField(SelectFieldBase): + coerce: Callable[[Any], Any] + choices: list[_Choice] | _GroupedChoices + validate_choice: bool + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + coerce: Callable[[Any], Any] = ..., + choices: Iterable[_Choice] | _GroupedChoices | Callable[[], Iterable[_Choice] | _GroupedChoices] | None = None, + validate_choice: bool = True, + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: object | None = None, + widget: _Widget[Self] | None = None, + option_widget: _Widget[_Option] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + def iter_choices(self) -> Iterator[_FullChoice]: ... + def has_groups(self) -> bool: ... + def iter_groups(self) -> Iterator[_FullGroupedChoices]: ... + +class SelectMultipleField(SelectField): + data: list[Any] | None + +class RadioField(SelectField): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/core.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/core.pyi new file mode 100644 index 000000000..614f93a9c --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/core.pyi @@ -0,0 +1,132 @@ +from builtins import type as _type # type is being shadowed in Field +from collections.abc import Callable, Iterable, Sequence +from typing import Any, Generic, Protocol, TypeVar, overload +from typing_extensions import Self, TypeAlias + +from markupsafe import Markup +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta, _MultiDictLikeWithGetlist, _SupportsGettextAndNgettext + +_FormT = TypeVar("_FormT", bound=BaseForm) +_FieldT = TypeVar("_FieldT", bound=Field) +_FormT_contra = TypeVar("_FormT_contra", bound=BaseForm, contravariant=True) +_FieldT_contra = TypeVar("_FieldT_contra", bound=Field, contravariant=True) +# It would be nice to annotate this as invariant, i.e. input type and output type +# needs to be the same, but it will probably be too annoying to use, for now we +# trust, that people won't use it to change the type of data in a field... +_Filter: TypeAlias = Callable[[Any], Any] + +class _Validator(Protocol[_FormT_contra, _FieldT_contra]): + def __call__(self, __form: _FormT_contra, __field: _FieldT_contra) -> object: ... + +class _Widget(Protocol[_FieldT_contra]): + def __call__(self, field: _FieldT_contra, **kwargs: Any) -> Markup: ... + +class Field: + errors: Sequence[str] + process_errors: Sequence[str] + raw_data: list[Any] | None + object_data: Any + data: Any + validators: Sequence[_Validator[Any, Self]] + # even though this could be None on the base class, this should + # never actually be None in a real field + widget: _Widget[Self] + do_not_call_in_templates: bool + meta: DefaultMeta + default: Any | None + description: str + render_kw: dict[str, Any] + filters: Sequence[_Filter] + flags: Flags + name: str + short_name: str + id: str + type: str + label: Label + # technically this can return UnboundField, but that is not allowed + # by type checkers, so we use a descriptor hack to get around this + # limitation instead + def __new__(cls, *args: Any, **kwargs: Any) -> Self: ... + def __init__( + self, + label: str | None = None, + # for tuple we can be a bit more type safe and only accept validators + # that would work on this or a less specific field, but in general it + # would be too annoying to restrict to Sequence[_Validator], since mypy + # will infer a list of mixed validators as list[object], since that is + # the common base class between all validators + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: object | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + def __html__(self) -> str: ... + def __call__(self, **kwargs: object) -> Markup: ... + @classmethod + def check_validators(cls, validators: Iterable[_Validator[_FormT, Self]] | None) -> None: ... + def gettext(self, string: str) -> str: ... + def ngettext(self, singular: str, plural: str, n: int) -> str: ... + def validate(self, form: BaseForm, extra_validators: tuple[_Validator[_FormT, Self], ...] | list[Any] = ()) -> bool: ... + def pre_validate(self, form: BaseForm) -> None: ... + def post_validate(self, form: BaseForm, validation_stopped: bool) -> None: ... + def process( + self, formdata: _MultiDictLikeWithGetlist | None, data: Any = ..., extra_filters: Sequence[_Filter] | None = None + ) -> None: ... + def process_data(self, value: Any) -> None: ... + def process_formdata(self, valuelist: list[Any]) -> None: ... + def populate_obj(self, obj: object, name: str) -> None: ... + + # this is a workaround for what is essentialy illegal in static type checking + # Field.__new__ would return an UnboundField, unless the _form parameter is + # specified. We can't really work around it by making UnboundField a subclass + # of Field, since all subclasses of Field still need to return an UnboundField + # and we can't expect third parties to add a __new__ method to every field + # they define... + # This workaround only works for Form, not BaseForm, but we take what we can get + # BaseForm shouldn't really be used anyways + @overload + def __get__(self, obj: None, owner: _type[object] | None = None) -> UnboundField[Self]: ... + @overload + def __get__(self, obj: object, owner: _type[object] | None = None) -> Self: ... + +class UnboundField(Generic[_FieldT]): + creation_counter: int + field_class: type[_FieldT] + name: str | None + args: tuple[Any, ...] + kwargs: dict[str, Any] + def __init__(self, field_class: type[_FieldT], *args: object, name: str | None = None, **kwargs: object) -> None: ... + def bind( + self, + form: BaseForm, + name: str, + prefix: str = "", + translations: _SupportsGettextAndNgettext | None = None, + **kwargs: object, + ) -> _FieldT: ... + +class Flags: + # the API for this is a bit loosey goosey, the intention probably + # was that the values should always be boolean, but __contains__ + # just returns the same thing as __getattr__ and in the widgets + # there are fields that could accept numeric values from Flags + def __getattr__(self, name: str) -> Any | None: ... + def __setattr__(self, name: str, value: object) -> None: ... + def __delattr__(self, name: str) -> None: ... + def __contains__(self, name: str) -> Any | None: ... + +class Label: + field_id: str + text: str + def __init__(self, field_id: str, text: str) -> None: ... + def __html__(self) -> str: ... + def __call__(self, text: str | None = None, **kwargs: Any) -> Markup: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/datetime.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/datetime.pyi new file mode 100644 index 000000000..4b181bc15 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/datetime.pyi @@ -0,0 +1,136 @@ +from collections.abc import Callable, Sequence +from datetime import date, datetime, time +from typing import Any +from typing_extensions import Self + +from wtforms.fields.core import Field, _Filter, _FormT, _Validator, _Widget +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext + +class DateTimeField(Field): + format: list[str] + strptime_format: list[str] + data: datetime | None + default: datetime | Callable[[], datetime] | None + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + format: str | list[str] = "%Y-%m-%d %H:%M:%S", + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: datetime | Callable[[], datetime] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class DateField(DateTimeField): + data: date | None # type: ignore[assignment] + default: date | Callable[[], date] | None # type: ignore[assignment] + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + format: str | list[str] = "%Y-%m-%d", + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: date | Callable[[], date] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class TimeField(DateTimeField): + data: time | None # type: ignore[assignment] + default: time | Callable[[], time] | None # type: ignore[assignment] + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + format: str | list[str] = "%H:%M", + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: time | Callable[[], time] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class MonthField(DateField): + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + format: str | list[str] = "%Y-%m", + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: time | Callable[[], time] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class WeekField(DateField): + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + format: str | list[str] = "%Y-W%W", # only difference is the default value + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: time | Callable[[], time] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class DateTimeLocalField(DateTimeField): + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + format: str | list[str] = ..., + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: time | Callable[[], time] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/form.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/form.pyi new file mode 100644 index 000000000..fe9c694d1 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/form.pyi @@ -0,0 +1,38 @@ +from collections.abc import Iterator, Sequence +from typing import Any, Generic, TypeVar + +from wtforms.fields.core import Field, _Widget +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext + +_BoundFormT = TypeVar("_BoundFormT", bound=BaseForm) + +class FormField(Field, Generic[_BoundFormT]): + form_class: type[_BoundFormT] + form: _BoundFormT + separator: str + def __init__( + self: FormField[_BoundFormT], + form_class: type[_BoundFormT], + label: str | None = None, + validators: None = None, + separator: str = "-", + *, + description: str = "", + id: str | None = None, + default: object | None = None, + widget: _Widget[FormField[_BoundFormT]] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + def __iter__(self) -> Iterator[Field]: ... + def __getitem__(self, name: str) -> Field: ... + def __getattr__(self, name: str) -> Field: ... + @property + def data(self) -> dict[str, Any]: ... + @property + def errors(self) -> dict[str | None, Sequence[str]]: ... # type: ignore[override] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/list.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/list.pyi new file mode 100644 index 000000000..4ce857d67 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/list.pyi @@ -0,0 +1,44 @@ +from collections.abc import Callable, Iterable, Iterator +from typing import Any, Generic, TypeVar + +from wtforms.fields.core import Field, UnboundField, _FormT, _Validator, _Widget +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext + +_BoundFieldT = TypeVar("_BoundFieldT", bound=Field) + +class FieldList(Field, Generic[_BoundFieldT]): + unbound_field: UnboundField[_BoundFieldT] + min_entries: int + max_entries: int | None + last_index: int + entries: list[_BoundFieldT] + object_data: Iterable[Any] + def __init__( + self: FieldList[_BoundFieldT], + # because of our workaround we need to accept Field as well + unbound_field: UnboundField[_BoundFieldT] | _BoundFieldT, + label: str | None = None, + validators: tuple[_Validator[_FormT, _BoundFieldT], ...] | list[Any] | None = None, + min_entries: int = 0, + max_entries: int | None = None, + separator: str = "-", + default: Iterable[Any] | Callable[[], Iterable[Any]] = (), + *, + description: str = "", + id: str | None = None, + widget: _Widget[FieldList[Any]] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + def append_entry(self, data: Any = ...) -> _BoundFieldT: ... + def pop_entry(self) -> _BoundFieldT: ... + def __iter__(self) -> Iterator[_BoundFieldT]: ... + def __len__(self) -> int: ... + def __getitem__(self, index: int) -> _BoundFieldT: ... + @property + def data(self) -> list[Any]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/numeric.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/numeric.pyi new file mode 100644 index 000000000..7288369c0 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/numeric.pyi @@ -0,0 +1,145 @@ +from collections.abc import Callable, Sequence +from decimal import Decimal +from typing import Any, overload +from typing_extensions import Literal, Self + +from wtforms.fields.core import Field, _Filter, _FormT, _Validator, _Widget +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext +from wtforms.utils import UnsetValue + +__all__ = ("IntegerField", "DecimalField", "FloatField", "IntegerRangeField", "DecimalRangeField") + +class LocaleAwareNumberField(Field): + use_locale: bool + number_format: Any | None + locale: str + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + use_locale: bool = False, + # this accepts a babel.numbers.NumberPattern, but since it + # is an optional dependency we don't want to depend on it + # for annotating this one argument + number_format: str | Any | None = None, + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: object | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class IntegerField(Field): + data: int | None + # technically this is not as strict and will accept anything + # that can be passed into int(), but we might as well be + default: int | Callable[[], int] | None + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: int | Callable[[], int] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class DecimalField(LocaleAwareNumberField): + data: Decimal | None + # technically this is not as strict and will accept anything + # that can be passed into Decimal(), but we might as well be + default: Decimal | Callable[[], Decimal] | None + places: int | None + rounding: str | None + @overload + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + *, + places: UnsetValue = ..., + rounding: None = None, + use_locale: Literal[True], + # this accepts a babel.numbers.NumberPattern, but since it + # is an optional dependency we don't want to depend on it + # for annotation this one argument + number_format: str | Any | None = None, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: Decimal | Callable[[], Decimal] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + @overload + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + places: int | UnsetValue | None = ..., + rounding: str | None = None, + *, + use_locale: Literal[False] = False, + # this accepts a babel.numbers.NumberPattern, but since it + # is an optional dependency we don't want to depend on it + # for annotation this one argument + number_format: str | Any | None = None, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: Decimal | Callable[[], Decimal] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class FloatField(Field): + data: float | None + # technically this is not as strict and will accept anything + # that can be passed into float(), but we might as well be + default: float | Callable[[], float] | None + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: float | Callable[[], float] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class IntegerRangeField(IntegerField): ... +class DecimalRangeField(DecimalField): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/simple.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/simple.pyi new file mode 100644 index 000000000..0fa58d5fe --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/fields/simple.pyi @@ -0,0 +1,65 @@ +from collections.abc import Callable, Collection, Sequence +from typing import Any +from typing_extensions import Self + +from wtforms.fields.core import Field, _Filter, _FormT, _Validator, _Widget +from wtforms.form import BaseForm +from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext + +class BooleanField(Field): + data: bool + default: bool | Callable[[], bool] | None + false_values: Collection[Any] + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + false_values: Collection[Any] | None = None, + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: bool | Callable[[], bool] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class StringField(Field): + data: str | None + default: str | Callable[[], str] | None + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: str | Callable[[], str] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + +class TextAreaField(StringField): ... +class PasswordField(StringField): ... +class FileField(Field): ... + +class MultipleFileField(FileField): + data: list[Any] + +class HiddenField(StringField): ... +class SubmitField(BooleanField): ... +class SearchField(StringField): ... +class TelField(StringField): ... +class URLField(StringField): ... +class EmailField(StringField): ... +class ColorField(StringField): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/form.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/form.pyi new file mode 100644 index 000000000..bfb81c72b --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/form.pyi @@ -0,0 +1,84 @@ +from _typeshed import SupportsItems +from collections.abc import Iterable, Iterator, Mapping, Sequence +from typing import Any, ClassVar, Protocol, overload +from typing_extensions import TypeAlias + +from wtforms.fields.core import Field, UnboundField +from wtforms.meta import DefaultMeta, _MultiDictLike + +_FormErrors: TypeAlias = dict[str | None, Sequence[str] | _FormErrors] + +# _unbound_fields will always be a list on an instance, but on a +# class it might be None, if it never has been instantiated, or +# not instantianted after a new field had been added/removed +class _UnboundFields(Protocol): + @overload + def __get__(self, obj: None, owner: type[object] | None = None) -> list[tuple[str, UnboundField[Any]]] | None: ... + @overload + def __get__(self, obj: object, owner: type[object] | None = None) -> list[tuple[str, UnboundField[Any]]]: ... + +class BaseForm: + meta: DefaultMeta + form_errors: list[str] + # we document this, because it's the only efficient way to introspect + # the field names of the form, it also seems to be stable API-wise + _fields: dict[str, Field] + def __init__( + self, + fields: SupportsItems[str, UnboundField[Any]] | Iterable[tuple[str, UnboundField[Any]]], + prefix: str = "", + meta: DefaultMeta = ..., + ) -> None: ... + def __iter__(self) -> Iterator[Field]: ... + def __contains__(self, name: str) -> bool: ... + def __getitem__(self, name: str) -> Field: ... + def __setitem__(self, name: str, value: UnboundField[Any]) -> None: ... + def __delitem__(self, name: str) -> None: ... + def populate_obj(self, obj: object) -> None: ... + # while we would like to be more strict on extra_filters, we can't easily do that + # without it being annoying in most situations + def process( + self, + formdata: _MultiDictLike | None = None, + obj: object | None = None, + data: Mapping[str, Any] | None = None, + extra_filters: Mapping[str, Sequence[Any]] | None = None, + **kwargs: object, + ) -> None: ... + # same thing here with extra_validators + def validate(self, extra_validators: Mapping[str, Sequence[Any]] | None = None) -> bool: ... + @property + def data(self) -> dict[str, Any]: ... + # because of the Liskov violation in FormField.errors we need to make errors a recursive type + @property + def errors(self) -> _FormErrors: ... + +class FormMeta(type): + def __init__(cls, name: str, bases: Sequence[type[object]], attrs: Mapping[str, Any]) -> None: ... + def __call__(cls, *args: Any, **kwargs: Any) -> Any: ... + def __setattr__(cls, name: str, value: object) -> None: ... + def __delattr__(cls, name: str) -> None: ... + +class Form(BaseForm, metaclass=FormMeta): + # due to the metaclass this should always be a subclass of DefaultMeta + # but if we annotate this as such, then subclasses cannot use it in the + # intended way + Meta: ClassVar[type[Any]] + # this attribute is documented, so we annotate it + _unbound_fields: _UnboundFields + def __init__( + self, + formdata: _MultiDictLike | None = None, + obj: object | None = None, + prefix: str = "", + data: Mapping[str, Any] | None = None, + meta: Mapping[str, Any] | None = None, + *, + # same issue as with process + extra_filters: Mapping[str, Sequence[Any]] | None = None, + **kwargs: object, + ) -> None: ... + # this should emit a type_error, since it's not allowed to be called + def __setitem__(self, name: str, value: None) -> None: ... # type: ignore[override] + def __delitem__(self, name: str) -> None: ... + def __delattr__(self, name: str) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/i18n.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/i18n.pyi new file mode 100644 index 000000000..39cd5f697 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/i18n.pyi @@ -0,0 +1,30 @@ +from collections.abc import Callable, Iterable +from gettext import GNUTranslations +from typing import Protocol, TypeVar, overload + +_T = TypeVar("_T") + +class _SupportsUgettextAndUngettext(Protocol): + def ugettext(self, __string: str) -> str: ... + def ungettext(self, __singular: str, __plural: str, __n: int) -> str: ... + +def messages_path() -> str: ... +def get_builtin_gnu_translations(languages: Iterable[str] | None = None) -> GNUTranslations: ... +@overload +def get_translations( + languages: Iterable[str] | None = None, getter: Callable[[Iterable[str]], GNUTranslations] = ... +) -> GNUTranslations: ... +@overload +def get_translations(languages: Iterable[str] | None = None, *, getter: Callable[[Iterable[str]], _T]) -> _T: ... +@overload +def get_translations(languages: Iterable[str] | None, getter: Callable[[Iterable[str]], _T]) -> _T: ... + +class DefaultTranslations: + translations: _SupportsUgettextAndUngettext + def __init__(self, translations: _SupportsUgettextAndUngettext) -> None: ... + def gettext(self, string: str) -> str: ... + def ngettext(self, singular: str, plural: str, n: int) -> str: ... + +class DummyTranslations: + def gettext(self, string: str) -> str: ... + def ngettext(self, singular: str, plural: str, n: int) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/meta.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/meta.pyi new file mode 100644 index 000000000..aa67be71c --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/meta.pyi @@ -0,0 +1,55 @@ +from _typeshed import SupportsItems +from collections.abc import Collection, Iterator, MutableMapping +from typing import Any, Protocol, TypeVar, overload +from typing_extensions import Literal, TypeAlias + +from markupsafe import Markup +from wtforms.fields.core import Field, UnboundField +from wtforms.form import BaseForm + +_FieldT = TypeVar("_FieldT", bound=Field) + +class _SupportsGettextAndNgettext(Protocol): + def gettext(self, __string: str) -> str: ... + def ngettext(self, __singular: str, __plural: str, __n: int) -> str: ... + +# these are the methods WTForms depends on, the dict can either provide +# a getlist or getall, if it only provies getall, it will wrapped, to +# provide getlist instead +class _MultiDictLikeBase(Protocol): + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... + def __contains__(self, __key: Any) -> bool: ... + +# since how file uploads are represented in formdata is implementation-specific +# we have to be generous in what we accept in the return of getlist/getall +# we can make this generic if we ever want to be more specific +class _MultiDictLikeWithGetlist(_MultiDictLikeBase, Protocol): + def getlist(self, __key: str) -> list[Any]: ... + +class _MultiDictLikeWithGetall(_MultiDictLikeBase, Protocol): + def getall(self, __key: str) -> list[Any]: ... + +_MultiDictLike: TypeAlias = _MultiDictLikeWithGetall | _MultiDictLikeWithGetlist + +class DefaultMeta: + def bind_field(self, form: BaseForm, unbound_field: UnboundField[_FieldT], options: MutableMapping[str, Any]) -> _FieldT: ... + @overload + def wrap_formdata(self, form: BaseForm, formdata: None) -> None: ... + @overload + def wrap_formdata(self, form: BaseForm, formdata: _MultiDictLike) -> _MultiDictLikeWithGetlist: ... + def render_field(self, field: Field, render_kw: SupportsItems[str, Any]) -> Markup: ... + csrf: bool + csrf_field_name: str + csrf_secret: Any | None + csrf_context: Any | None + csrf_class: type[Any] | None + def build_csrf(self, form: BaseForm) -> Any: ... + locales: Literal[False] | Collection[str] + cache_translations: bool + translations_cache: dict[str, _SupportsGettextAndNgettext] + def get_translations(self, form: BaseForm) -> _SupportsGettextAndNgettext: ... + def update_values(self, values: SupportsItems[str, Any]) -> None: ... + # since meta can be extended with arbitary data we add a __getattr__ + # method that returns Any + def __getattr__(self, name: str) -> Any: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/utils.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/utils.pyi new file mode 100644 index 000000000..ea7408985 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/utils.pyi @@ -0,0 +1,19 @@ +from collections.abc import Iterable, Iterator +from typing import Any +from typing_extensions import Literal + +from wtforms.meta import _MultiDictLikeWithGetall + +def clean_datetime_format_for_strptime(formats: Iterable[str]) -> list[str]: ... + +class UnsetValue: + def __bool__(self) -> Literal[False]: ... + +unset_value: UnsetValue + +class WebobInputWrapper: + def __init__(self, multidict: _MultiDictLikeWithGetall) -> None: ... + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... + def __contains__(self, name: str) -> bool: ... + def getlist(self, name: str) -> list[Any]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/validators.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/validators.pyi new file mode 100644 index 000000000..e6d22833c --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/validators.pyi @@ -0,0 +1,166 @@ +from collections.abc import Callable, Collection, Iterable +from decimal import Decimal +from re import Match, Pattern +from typing import Any, TypeVar, overload + +from wtforms.fields import Field, StringField +from wtforms.form import BaseForm + +_ValuesT = TypeVar("_ValuesT", bound=Collection[Any], contravariant=True) + +class ValidationError(ValueError): + def __init__(self, message: str = "", *args: object) -> None: ... + +class StopValidation(Exception): + def __init__(self, message: str = "", *args: object) -> None: ... + +class EqualTo: + fieldname: str + message: str | None + def __init__(self, fieldname: str, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: Field) -> None: ... + +class Length: + min: int + max: int + message: str | None + field_flags: dict[str, Any] + def __init__(self, min: int = -1, max: int = -1, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: StringField) -> None: ... + +class NumberRange: + min: float | Decimal | None + max: float | Decimal | None + message: str | None + field_flags: dict[str, Any] + def __init__( + self, min: float | Decimal | None = None, max: float | Decimal | None = None, message: str | None = None + ) -> None: ... + # any numeric field will work, for now we don't try to use a union + # to restrict to the defined numeric fields, since user-defined fields + # will likely not use a common base class, just like the existing + # numeric fields + def __call__(self, form: BaseForm, field: Field) -> None: ... + +class Optional: + string_check: Callable[[str], bool] + field_flags: dict[str, Any] + def __init__(self, strip_whitespace: bool = True) -> None: ... + def __call__(self, form: BaseForm, field: Field) -> None: ... + +class DataRequired: + message: str | None + field_flags: dict[str, Any] + def __init__(self, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: Field) -> None: ... + +class InputRequired: + message: str | None + field_flags: dict[str, Any] + def __init__(self, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: Field) -> None: ... + +class Regexp: + regex: Pattern[str] + message: str | None + def __init__(self, regex: str | Pattern[str], flags: int = 0, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: StringField, message: str | None = None) -> Match[str]: ... + +class Email: + message: str | None + granular_message: bool + check_deliverability: bool + allow_smtputf8: bool + allow_empty_local: bool + def __init__( + self, + message: str | None = None, + granular_message: bool = False, + check_deliverability: bool = False, + allow_smtputf8: bool = True, + allow_empty_local: bool = False, + ) -> None: ... + def __call__(self, form: BaseForm, field: StringField) -> None: ... + +class IPAddress: + ipv4: bool + ipv6: bool + message: str | None + def __init__(self, ipv4: bool = True, ipv6: bool = False, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: StringField) -> None: ... + @classmethod + def check_ipv4(cls, value: str | None) -> bool: ... + @classmethod + def check_ipv6(cls, value: str | None) -> bool: ... + +class MacAddress(Regexp): + def __init__(self, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: StringField) -> None: ... # type: ignore[override] + +class URL(Regexp): + validate_hostname: HostnameValidation + def __init__(self, require_tld: bool = True, allow_ip: bool = True, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: StringField) -> None: ... # type: ignore[override] + +class UUID: + message: str | None + def __init__(self, message: str | None = None) -> None: ... + def __call__(self, form: BaseForm, field: StringField) -> None: ... + +class AnyOf: + values: Collection[Any] + message: str | None + values_formatter: Callable[[Any], str] + @overload + def __init__(self, values: Collection[Any], message: str | None = None, values_formatter: None = None) -> None: ... + @overload + def __init__(self, values: _ValuesT, message: str | None, values_formatter: Callable[[_ValuesT], str]) -> None: ... + @overload + def __init__(self, values: _ValuesT, message: str | None = None, *, values_formatter: Callable[[_ValuesT], str]) -> None: ... + def __call__(self, form: BaseForm, field: Field) -> None: ... + @staticmethod + def default_values_formatter(values: Iterable[object]) -> str: ... + +class NoneOf: + values: Collection[Any] + message: str | None + values_formatter: Callable[[Any], str] + @overload + def __init__(self, values: Collection[Any], message: str | None = None, values_formatter: None = None) -> None: ... + @overload + def __init__(self, values: _ValuesT, message: str | None, values_formatter: Callable[[_ValuesT], str]) -> None: ... + @overload + def __init__(self, values: _ValuesT, message: str | None = None, *, values_formatter: Callable[[_ValuesT], str]) -> None: ... + def __call__(self, form: BaseForm, field: Field) -> None: ... + @staticmethod + def default_values_formatter(v: Iterable[object]) -> str: ... + +class HostnameValidation: + hostname_part: Pattern[str] + tld_part: Pattern[str] + require_tld: bool + allow_ip: bool + def __init__(self, require_tld: bool = True, allow_ip: bool = False) -> None: ... + def __call__(self, hostname: str) -> bool: ... + +class ReadOnly: + def __call__(self, form: BaseForm, field: Field) -> None: ... + +class Disabled: + def __call__(self, form: BaseForm, field: Field) -> None: ... + +email = Email +equal_to = EqualTo +ip_address = IPAddress +mac_address = MacAddress +length = Length +number_range = NumberRange +optional = Optional +input_required = InputRequired +data_required = DataRequired +regexp = Regexp +url = URL +any_of = AnyOf +none_of = NoneOf +readonly = ReadOnly +disabled = Disabled diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/widgets/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/widgets/__init__.pyi new file mode 100644 index 000000000..89e4b0488 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/widgets/__init__.pyi @@ -0,0 +1,2 @@ +from wtforms.widgets.core import * +from wtforms.widgets.core import Input as Input, html_params as html_params diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/widgets/core.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/widgets/core.pyi new file mode 100644 index 000000000..90d13e764 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/WTForms/wtforms/widgets/core.pyi @@ -0,0 +1,121 @@ +from decimal import Decimal +from typing import Any +from typing_extensions import Literal + +from markupsafe import Markup +from wtforms.fields import Field, FormField, SelectFieldBase, StringField +from wtforms.fields.choices import _Option + +__all__ = ( + "CheckboxInput", + "ColorInput", + "DateInput", + "DateTimeInput", + "DateTimeLocalInput", + "EmailInput", + "FileInput", + "HiddenInput", + "ListWidget", + "MonthInput", + "NumberInput", + "Option", + "PasswordInput", + "RadioInput", + "RangeInput", + "SearchInput", + "Select", + "SubmitInput", + "TableWidget", + "TextArea", + "TextInput", + "TelInput", + "TimeInput", + "URLInput", + "WeekInput", +) + +def html_params(**kwargs: object) -> str: ... + +class ListWidget: + html_tag: Literal["ul", "ol"] + prefix_label: bool + def __init__(self, html_tag: Literal["ul", "ol"] = "ul", prefix_label: bool = True) -> None: ... + # any iterable field is fine, since people might define iterable fields + # that are not derived from FieldList, we just punt and accept any field + # with Intersection we could be more specific + def __call__(self, field: Field, **kwargs: object) -> Markup: ... + +class TableWidget: + with_table_tag: bool + def __init__(self, with_table_tag: bool = True) -> None: ... + def __call__(self, field: FormField[Any], **kwargs: object) -> Markup: ... + +class Input: + validation_attrs: list[str] + input_type: str + def __init__(self, input_type: str | None = None) -> None: ... + def __call__(self, field: Field, **kwargs: object) -> Markup: ... + @staticmethod + def html_params(**kwargs: object) -> str: ... + +class TextInput(Input): ... + +class PasswordInput(Input): + hide_value: bool + def __init__(self, hide_value: bool = True) -> None: ... + +class HiddenInput(Input): + field_flags: dict[str, Any] + +class CheckboxInput(Input): ... +class RadioInput(Input): ... + +class FileInput(Input): + multiple: bool + def __init__(self, multiple: bool = False) -> None: ... + +class SubmitInput(Input): ... + +class TextArea: + validation_attrs: list[str] + def __call__(self, field: StringField, **kwargs: object) -> Markup: ... + +class Select: + validation_attrs: list[str] + multiple: bool + def __init__(self, multiple: bool = False) -> None: ... + def __call__(self, field: SelectFieldBase, **kwargs: object) -> Markup: ... + @classmethod + def render_option(cls, value: object, label: str, selected: bool, **kwargs: object) -> Markup: ... + +class Option: + def __call__(self, field: _Option, **kwargs: object) -> Markup: ... + +class SearchInput(Input): ... +class TelInput(Input): ... +class URLInput(Input): ... +class EmailInput(Input): ... +class DateTimeInput(Input): ... +class DateInput(Input): ... +class MonthInput(Input): ... +class WeekInput(Input): ... +class TimeInput(Input): ... +class DateTimeLocalInput(Input): ... + +class NumberInput(Input): + step: Decimal | float | str | None + min: Decimal | float | str | None + max: Decimal | float | str | None + def __init__( + self, + step: Decimal | float | str | None = None, + min: Decimal | float | str | None = None, + max: Decimal | float | str | None = None, + ) -> None: ... + +class RangeInput(Input): + # maybe we should allow any str for this + step: Decimal | float | str | None + def __init__(self, step: Decimal | float | str | None = None) -> None: ... + +class ColorInput(Input): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WebOb/webob/cookies.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WebOb/webob/cookies.pyi index f0bfb5830..7104a281d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/WebOb/webob/cookies.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/WebOb/webob/cookies.pyi @@ -1,13 +1,24 @@ -from _typeshed import Incomplete +from _typeshed import sentinel from _typeshed.wsgi import WSGIEnvironment -from collections.abc import ItemsView, Iterator, KeysView, MutableMapping, ValuesView +from collections.abc import Callable, Collection, ItemsView, Iterator, KeysView, MutableMapping, ValuesView from datetime import date, datetime, timedelta -from typing import TypeVar, overload -from typing_extensions import Literal +from hashlib import _Hash +from typing import Any, Protocol, TypeVar, overload +from typing_extensions import Literal, TypeAlias from webob.descriptors import _AsymmetricProperty +from webob.request import Request +from webob.response import Response _T = TypeVar("_T") +# we accept both the official spelling and the one used in the WebOb docs +# the implementation compares after lower() so technically there are more +# valid spellings, but it seems mor natural to support these two spellings +_SameSitePolicy: TypeAlias = Literal["Strict", "Lax", "None", "strict", "lax", "none"] + +class _Serializer(Protocol): + def loads(self, __appstruct: Any) -> bytes: ... + def dumps(self, __bstruct: bytes) -> Any: ... class RequestCookies(MutableMapping[str, str]): def __init__(self, environ: WSGIEnvironment) -> None: ... @@ -61,7 +72,7 @@ class Morsel(dict[bytes, bytes | bool | None]): def secure(self) -> bool | None: ... @secure.setter def secure(self, v: bool) -> None: ... - samesite: _AsymmetricProperty[bytes | None, Literal["strict", "lax", "none"] | None] + samesite: _AsymmetricProperty[bytes | None, _SameSitePolicy | None] def serialize(self, full: bool = True) -> str: ... def __str__(self, full: bool = True) -> str: ... @@ -74,75 +85,98 @@ def make_cookie( secure: bool = False, httponly: bool = False, comment: str | None = None, - samesite: Literal["strict", "lax", "none"] | None = None, + samesite: _SameSitePolicy | None = None, ) -> str: ... class JSONSerializer: - def dumps(self, appstruct): ... - def loads(self, bstruct): ... + def dumps(self, appstruct: Any) -> bytes: ... + def loads(self, bstruct: bytes | str) -> Any: ... class Base64Serializer: - serializer: Incomplete - def __init__(self, serializer: Incomplete | None = None) -> None: ... - def dumps(self, appstruct): ... - def loads(self, bstruct): ... + serializer: _Serializer + def __init__(self, serializer: _Serializer | None = None) -> None: ... + def dumps(self, appstruct: Any) -> bytes: ... + def loads(self, bstruct: bytes) -> Any: ... class SignedSerializer: - salt: Incomplete - secret: Incomplete - hashalg: Incomplete - salted_secret: Incomplete - digestmod: Incomplete - digest_size: Incomplete - serializer: Incomplete - def __init__(self, secret, salt, hashalg: str = "sha512", serializer: Incomplete | None = None) -> None: ... - def dumps(self, appstruct): ... - def loads(self, bstruct): ... + salt: str + secret: str + hashalg: str + salted_secret: bytes + digestmod: Callable[[bytes], _Hash] + digest_size: int + serializer: _Serializer + def __init__(self, secret: str, salt: str, hashalg: str = "sha512", serializer: _Serializer | None = None) -> None: ... + def dumps(self, appstruct: Any) -> bytes: ... + def loads(self, bstruct: bytes) -> Any: ... class CookieProfile: - cookie_name: Incomplete - secure: Incomplete - max_age: Incomplete - httponly: Incomplete - samesite: Incomplete - path: Incomplete - domains: Incomplete - serializer: Incomplete - request: Incomplete + cookie_name: str + secure: bool + max_age: int | timedelta | None + httponly: bool | None + samesite: _SameSitePolicy | None + path: str + domains: Collection[str] | None + serializer: _Serializer + request: Request | None def __init__( self, - cookie_name, + cookie_name: str, secure: bool = False, - max_age: Incomplete | None = None, - httponly: Incomplete | None = None, - samesite: Incomplete | None = None, + max_age: int | timedelta | None = None, + httponly: bool | None = None, + samesite: _SameSitePolicy | None = None, path: str = "/", - domains: Incomplete | None = None, - serializer: Incomplete | None = None, + # even though the docs claim any iterable is fine, that is + # clearly not the case judging by the implementation + domains: Collection[str] | None = None, + serializer: _Serializer | None = None, ) -> None: ... - def __call__(self, request): ... - def bind(self, request): ... - def get_value(self): ... - def set_cookies(self, response, value, domains=..., max_age=..., path=..., secure=..., httponly=..., samesite=...): ... - def get_headers(self, value, domains=..., max_age=..., path=..., secure=..., httponly=..., samesite=...): ... + def __call__(self, request: Request) -> CookieProfile: ... + def bind(self, request: Request) -> CookieProfile: ... + def get_value(self) -> Any | None: ... + def set_cookies( + self, + response: Response, + value: Any, + domains: Collection[str] = sentinel, + max_age: int | timedelta | None = sentinel, + path: str = sentinel, + secure: bool = sentinel, + httponly: bool = sentinel, + samesite: _SameSitePolicy | None = sentinel, + ) -> Response: ... + def get_headers( + self, + value: Any, + domains: Collection[str] = sentinel, + max_age: int | timedelta | None = sentinel, + path: str = sentinel, + secure: bool = sentinel, + httponly: bool = sentinel, + samesite: _SameSitePolicy | None = sentinel, + ) -> list[tuple[str, str]]: ... class SignedCookieProfile(CookieProfile): - secret: Incomplete - salt: Incomplete - hashalg: Incomplete - original_serializer: Incomplete + secret: str + salt: str + hashalg: str + serializer: SignedSerializer + original_serializer: _Serializer def __init__( self, - secret, - salt, - cookie_name, + secret: str, + salt: str, + cookie_name: str, secure: bool = False, - max_age: Incomplete | None = None, + max_age: int | timedelta | None = None, httponly: bool = False, - samesite: Incomplete | None = None, + samesite: _SameSitePolicy | None = None, path: str = "/", - domains: Incomplete | None = None, + domains: Collection[str] | None = None, hashalg: str = "sha512", - serializer: Incomplete | None = None, + serializer: _Serializer | None = None, ) -> None: ... - def bind(self, request): ... + def __call__(self, request: Request) -> SignedCookieProfile: ... + def bind(self, request: Request) -> SignedCookieProfile: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/WebOb/webob/response.pyi b/packages/pyright-internal/typeshed-fallback/stubs/WebOb/webob/response.pyi index 7b0ed4d98..ebd11adba 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/WebOb/webob/response.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/WebOb/webob/response.pyi @@ -7,6 +7,7 @@ from typing_extensions import Literal, TypeAlias, TypedDict from webob.byterange import ContentRange from webob.cachecontrol import _ResponseCacheControl +from webob.cookies import _SameSitePolicy from webob.descriptors import _AsymmetricProperty, _AsymmetricPropertyWithDelete, _authorization, _DateProperty, _ListProperty from webob.headers import ResponseHeaders from webob.request import Request @@ -134,7 +135,7 @@ class Response: httponly: bool = False, comment: str | None = None, overwrite: bool = False, - samesite: Literal["strict", "lax", "none"] | None = None, + samesite: _SameSitePolicy | None = None, ) -> None: ... def delete_cookie(self, name: str, path: str = "/", domain: str | None = None) -> None: ... def unset_cookie(self, name: str, strict: bool = True) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/async_recorder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/async_recorder.pyi index 146a71fc7..41138e427 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/async_recorder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/async_recorder.pyi @@ -1,14 +1,9 @@ from _typeshed import Incomplete from types import TracebackType -from .models.segment import SegmentContextManager as SegmentContextManager -from .models.subsegment import ( - SubsegmentContextManager as SubsegmentContextManager, - is_already_recording as is_already_recording, - subsegment_decorator as subsegment_decorator, -) -from .recorder import AWSXRayRecorder as AWSXRayRecorder -from .utils import stacktrace as stacktrace +from .models.segment import SegmentContextManager +from .models.subsegment import SubsegmentContextManager +from .recorder import AWSXRayRecorder class AsyncSegmentContextManager(SegmentContextManager): async def __aenter__(self): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/context.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/context.pyi index d5f0806b6..3b389b303 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/context.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/context.pyi @@ -2,9 +2,6 @@ import time from logging import Logger from typing import Any -from .. import global_sdk_config as global_sdk_config -from .exceptions.exceptions import SegmentNotFoundException as SegmentNotFoundException -from .models.dummy_entities import DummySegment as DummySegment from .models.entity import Entity from .models.segment import Segment from .models.subsegment import Subsegment diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/daemon_config.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/daemon_config.pyi index 3ac5aa77f..e5c4b9609 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/daemon_config.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/daemon_config.pyi @@ -1,5 +1,3 @@ -from .exceptions.exceptions import InvalidDaemonAddressException as InvalidDaemonAddressException - DAEMON_ADDRESS_KEY: str DEFAULT_ADDRESS: str diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/lambda_launcher.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/lambda_launcher.pyi index 622213441..2ff1a6d6c 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/lambda_launcher.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/lambda_launcher.pyi @@ -1,11 +1,7 @@ from _typeshed import Incomplete from logging import Logger -from aws_xray_sdk import global_sdk_config as global_sdk_config - -from .context import Context as Context -from .models.facade_segment import FacadeSegment as FacadeSegment -from .models.trace_header import TraceHeader as TraceHeader +from .context import Context log: Logger LAMBDA_TRACE_HEADER_KEY: str diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/entity.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/entity.pyi index b07998812..91260a83d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/entity.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/entity.pyi @@ -3,12 +3,6 @@ from logging import Logger from traceback import StackSummary from typing import Any -from ..exceptions.exceptions import AlreadyEndedException as AlreadyEndedException -from ..utils.compat import annotation_value_types as annotation_value_types, string_types as string_types -from ..utils.conversion import metadata_to_dict as metadata_to_dict -from . import http as http -from .throwable import Throwable as Throwable - log: Logger ORIGIN_TRACE_HEADER_ATTR_KEY: str diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/facade_segment.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/facade_segment.pyi index e8b054ac2..44623545f 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/facade_segment.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/facade_segment.pyi @@ -1,8 +1,7 @@ from _typeshed import Incomplete from typing import Any -from ..exceptions.exceptions import FacadeSegmentMutationException as FacadeSegmentMutationException -from .segment import Segment as Segment +from .segment import Segment MUTATION_UNSUPPORTED_MESSAGE: str diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/segment.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/segment.pyi index 7c90e37a6..507832b24 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/segment.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/segment.pyi @@ -1,12 +1,10 @@ from types import TracebackType from typing import Any -from ..exceptions.exceptions import SegmentNameMissingException as SegmentNameMissingException from ..recorder import AWSXRayRecorder -from ..utils.atomic_counter import AtomicCounter as AtomicCounter -from .entity import Entity as Entity +from ..utils.atomic_counter import AtomicCounter +from .entity import Entity from .subsegment import Subsegment -from .traceid import TraceId as TraceId ORIGIN_TRACE_HEADER_ATTR_KEY: str diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/subsegment.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/subsegment.pyi index 45a6ae889..ad398ae98 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/subsegment.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/subsegment.pyi @@ -4,8 +4,7 @@ from types import TracebackType from typing import Any from ...core import AWSXRayRecorder -from ..exceptions.exceptions import SegmentNotFoundException as SegmentNotFoundException -from .entity import Entity as Entity +from .entity import Entity from .segment import Segment SUBSEGMENT_RECORDING_ATTRIBUTE: str diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/throwable.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/throwable.pyi index a7be6d684..a990c488d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/throwable.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/models/throwable.pyi @@ -1,7 +1,5 @@ from typing import Any -from ..utils.compat import string_types as string_types - log: Any class Throwable: diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/patcher.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/patcher.pyi index b33041f3f..3557c26c3 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/patcher.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/patcher.pyi @@ -2,10 +2,6 @@ from collections.abc import Iterable from logging import Logger from typing import Any -from aws_xray_sdk import global_sdk_config as global_sdk_config - -from .utils.compat import PY2 as PY2, is_classmethod as is_classmethod, is_instance_method as is_instance_method - log: Logger SUPPORTED_MODULES: Any NO_DOUBLE_PATCH: Any diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/plugins/utils.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/plugins/utils.pyi index 9d521e651..f3ef252e2 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/plugins/utils.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/plugins/utils.pyi @@ -1,7 +1,5 @@ from typing import Any -from ..exceptions.exceptions import MissingPluginNames as MissingPluginNames - module_prefix: str PLUGIN_MAPPING: Any diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/recorder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/recorder.pyi index 88f90f4ae..eb91d70c4 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/recorder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/recorder.pyi @@ -3,27 +3,15 @@ from collections.abc import Callable, Iterable from logging import Logger from typing import Any -from aws_xray_sdk import global_sdk_config as global_sdk_config -from aws_xray_sdk.version import VERSION as VERSION - -from .context import Context as Context -from .daemon_config import DaemonConfig as DaemonConfig -from .emitters.udp_emitter import UDPEmitter as UDPEmitter -from .exceptions.exceptions import ( - SegmentNameMissingException as SegmentNameMissingException, - SegmentNotFoundException as SegmentNotFoundException, -) -from .lambda_launcher import check_in_lambda as check_in_lambda -from .models.default_dynamic_naming import DefaultDynamicNaming as DefaultDynamicNaming -from .models.dummy_entities import DummySegment as DummySegment, DummySubsegment as DummySubsegment -from .models.segment import Segment as Segment, SegmentContextManager as SegmentContextManager -from .models.subsegment import Subsegment as Subsegment, SubsegmentContextManager as SubsegmentContextManager -from .plugins.utils import get_plugin_modules as get_plugin_modules +from .context import Context +from .emitters.udp_emitter import UDPEmitter +from .models.default_dynamic_naming import DefaultDynamicNaming +from .models.dummy_entities import DummySegment, DummySubsegment +from .models.segment import Segment, SegmentContextManager +from .models.subsegment import Subsegment, SubsegmentContextManager from .sampling.local.sampler import LocalSampler from .sampling.sampler import DefaultSampler -from .streaming.default_streaming import DefaultStreaming as DefaultStreaming -from .utils import stacktrace as stacktrace -from .utils.compat import string_types as string_types +from .streaming.default_streaming import DefaultStreaming log: Logger TRACING_NAME_KEY: str diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/sampling/connector.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/sampling/connector.pyi index 8edea3c58..3ae19b8da 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/sampling/connector.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/sampling/connector.pyi @@ -1,11 +1,3 @@ -from datetime import datetime as datetime - -from aws_xray_sdk.core.context import Context as Context -from aws_xray_sdk.core.models.dummy_entities import DummySegment as DummySegment -from aws_xray_sdk.core.utils.compat import PY2 as PY2 - -from .sampling_rule import SamplingRule as SamplingRule - class ServiceConnector: def __init__(self) -> None: ... def fetch_sampling_rules(self): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/sampling/sampling_rule.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/sampling/sampling_rule.pyi index 268fc401c..17b6ee99d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/sampling/sampling_rule.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/sampling/sampling_rule.pyi @@ -1,8 +1,5 @@ from _typeshed import Incomplete -from ..utils.search_pattern import wildcard_match as wildcard_match -from .reservoir import Reservoir as Reservoir - class SamplingRule: def __init__( self, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/utils/compat.pyi b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/utils/compat.pyi index 32562d540..799c00ba0 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/utils/compat.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/aws-xray-sdk/aws_xray_sdk/core/utils/compat.pyi @@ -1,10 +1,6 @@ from typing import Any -from typing_extensions import Literal -PY2: Literal[False] -PY35: Literal[True] annotation_value_types: Any -string_types = str def is_classmethod(func): ... def is_instance_method(parent_class, func_name, func): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/beautifulsoup4/bs4/element.pyi b/packages/pyright-internal/typeshed-fallback/stubs/beautifulsoup4/bs4/element.pyi index aa1e01015..94d13a11f 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/beautifulsoup4/bs4/element.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/beautifulsoup4/bs4/element.pyi @@ -1,7 +1,7 @@ from _typeshed import Incomplete, ReadableBuffer from collections.abc import Callable, Iterable, Iterator from re import Pattern -from typing import Any, Generic, TypeVar, overload +from typing import Any, TypeVar, overload from typing_extensions import Self, TypeAlias from . import BeautifulSoup @@ -372,7 +372,7 @@ class SoupStrainer: searchTag = search_tag def search(self, markup: PageElement | Iterable[PageElement]): ... -class ResultSet(list[_PageElementT], Generic[_PageElementT]): +class ResultSet(list[_PageElementT]): source: SoupStrainer @overload def __init__(self, source: SoupStrainer) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/bleach/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/bleach/METADATA.toml index 58f084566..43e630933 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/bleach/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/bleach/METADATA.toml @@ -1,4 +1,4 @@ -version = "6.0.*" +version = "6.1.*" upstream_repository = "https://github.com/mozilla/bleach" partial_stub = true diff --git a/packages/pyright-internal/typeshed-fallback/stubs/bleach/bleach/html5lib_shim.pyi b/packages/pyright-internal/typeshed-fallback/stubs/bleach/bleach/html5lib_shim.pyi index ee35bc62d..dbcde6f14 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/bleach/bleach/html5lib_shim.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/bleach/bleach/html5lib_shim.pyi @@ -1,11 +1,14 @@ from _typeshed import Incomplete -from collections.abc import Generator, Iterable +from collections.abc import Generator, Iterable, Iterator class HTMLParser: # actually html5lib.HTMLParser def __getattr__(self, __name: str) -> Incomplete: ... class Filter: # actually html5lib.filters.base.Filter - def __getattr__(self, __name: str) -> Incomplete: ... + source: Incomplete + def __init__(self, source) -> None: ... + def __iter__(self) -> Iterator[Incomplete]: ... + def __getattr__(self, name: str) -> Incomplete: ... # copy attributes from source class SanitizerFilter: # actually html5lib.filters.sanitizer.Filter def __getattr__(self, __name: str) -> Incomplete: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/braintree/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/braintree/METADATA.toml index 464274f4a..36c07e34d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/braintree/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/braintree/METADATA.toml @@ -1,4 +1,4 @@ -version = "4.22.*" +version = "4.23.*" upstream_repository = "https://github.com/braintree/braintree_python" partial_stub = true diff --git a/packages/pyright-internal/typeshed-fallback/stubs/braintree/braintree/environment.pyi b/packages/pyright-internal/typeshed-fallback/stubs/braintree/braintree/environment.pyi index a778ab4fa..1228c7f28 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/braintree/braintree/environment.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/braintree/braintree/environment.pyi @@ -1,33 +1,47 @@ -from typing import Any +from _typeshed import Incomplete +from typing import ClassVar from braintree.exceptions.configuration_error import ConfigurationError as ConfigurationError class Environment: - __name__: Any - is_ssl: Any - ssl_certificate: Any + Development: ClassVar[Environment] + QA: ClassVar[Environment] + Sandbox: ClassVar[Environment] + Production: ClassVar[Environment] + All: ClassVar[dict[str, Environment]] + __name__: str + is_ssl: bool + ssl_certificate: Incomplete def __init__( - self, name, server, port, auth_url, is_ssl, ssl_certificate, graphql_server: str = "", graphql_port: str = "" + self, + name, + server: str, + port, + auth_url: str, + is_ssl: bool, + ssl_certificate, + graphql_server: str = "", + graphql_port: str = "", ) -> None: ... @property - def base_url(self): ... + def base_url(self) -> str: ... @property - def port(self): ... + def port(self) -> int: ... @property - def auth_url(self): ... + def auth_url(self) -> str: ... @property - def protocol(self): ... + def protocol(self) -> str: ... @property - def server(self): ... + def server(self) -> str: ... @property - def server_and_port(self): ... + def server_and_port(self) -> str: ... @property - def graphql_server(self): ... + def graphql_server(self) -> str: ... @property - def graphql_port(self): ... + def graphql_port(self) -> str: ... @property - def graphql_server_and_port(self): ... + def graphql_server_and_port(self) -> str: ... @staticmethod - def parse_environment(environment): ... + def parse_environment(environment: Environment | str | None) -> Environment | None: ... @staticmethod - def braintree_root(): ... + def braintree_root() -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/cachetools/cachetools/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/cachetools/cachetools/__init__.pyi index 5cac854c8..3513d7664 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/cachetools/cachetools/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/cachetools/cachetools/__init__.pyi @@ -1,7 +1,7 @@ from _typeshed import IdentityFunction, Unused from collections.abc import Callable, Iterator, MutableMapping, Sequence from contextlib import AbstractContextManager -from typing import Any, Generic, TypeVar, overload +from typing import Any, TypeVar, overload __all__ = ("Cache", "FIFOCache", "LFUCache", "LRUCache", "MRUCache", "RRCache", "TLRUCache", "TTLCache", "cached", "cachedmethod") __version__: str @@ -10,7 +10,7 @@ _KT = TypeVar("_KT") _VT = TypeVar("_VT") _T = TypeVar("_T") -class Cache(MutableMapping[_KT, _VT], Generic[_KT, _VT]): +class Cache(MutableMapping[_KT, _VT]): @overload def __init__(self, maxsize: float, getsizeof: Callable[[_VT], float]) -> None: ... @overload diff --git a/packages/pyright-internal/typeshed-fallback/stubs/cffi/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/cffi/METADATA.toml index 6bd875a85..f1607a4d9 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/cffi/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/cffi/METADATA.toml @@ -1,4 +1,4 @@ -version = "1.15.*" +version = "1.16.*" upstream_repository = "https://foss.heptapod.net/pypy/cffi" requires = ["types-setuptools"] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/croniter/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/croniter/METADATA.toml index e2699fe30..882feb99b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/croniter/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/croniter/METADATA.toml @@ -1,2 +1,2 @@ -version = "1.4.*" +version = "2.0.*" upstream_repository = "https://github.com/kiorky/croniter" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/@tests/stubtest_allowlist.txt b/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/@tests/stubtest_allowlist.txt deleted file mode 100644 index 9a3c06c24..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/@tests/stubtest_allowlist.txt +++ /dev/null @@ -1,2 +0,0 @@ -# Loop variable that leaks into the global namespace -dj_database_url.key diff --git a/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/METADATA.toml deleted file mode 100644 index 7064924e3..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/METADATA.toml +++ /dev/null @@ -1,3 +0,0 @@ -version = "1.3.*" -upstream_repository = "https://github.com/jazzband/dj-database-url" -obsolete_since = "2.0.0" # Released on 2023-04-27 diff --git a/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/dj_database_url.pyi b/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/dj_database_url.pyi deleted file mode 100644 index 99e9ef076..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/dj-database-url/dj_database_url.pyi +++ /dev/null @@ -1,40 +0,0 @@ -from _typeshed import Incomplete -from typing import Any -from typing_extensions import TypedDict - -DEFAULT_ENV: str -SCHEMES: dict[str, str] - -# From https://docs.djangoproject.com/en/4.0/ref/settings/#databases -class DBConfig(TypedDict, total=False): - ATOMIC_REQUESTS: bool - AUTOCOMMIT: bool - CONN_MAX_AGE: int | None - DISABLE_SERVER_SIDE_CURSORS: bool - ENGINE: str - HOST: str - NAME: str - OPTIONS: dict[str, Any] | None - PASSWORD: str - PORT: str - TEST: dict[str, Any] - TIME_ZONE: str - USER: str - -def parse( - url: str, - engine: str | None = ..., - conn_max_age: int = ..., - conn_health_checks: bool = ..., - ssl_require: bool = ..., - test_options: dict[Incomplete, Incomplete] | None = ..., -) -> DBConfig: ... -def config( - env: str = ..., - default: str | None = ..., - engine: str | None = ..., - conn_max_age: int | None = ..., - conn_health_checks: bool = ..., - ssl_require: bool = ..., - test_options: dict[Incomplete, Incomplete] | None = ..., -) -> DBConfig: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/flake8-simplify/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/flake8-simplify/METADATA.toml index 1971ff585..975ef0a56 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/flake8-simplify/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/flake8-simplify/METADATA.toml @@ -1,4 +1,4 @@ -version = "0.20.*" +version = "0.21.*" upstream_repository = "https://github.com/MartinThoma/flake8-simplify" partial_stub = true diff --git a/packages/pyright-internal/typeshed-fallback/stubs/flake8-typing-imports/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/flake8-typing-imports/METADATA.toml index 6ac5c40b7..313048cd7 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/flake8-typing-imports/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/flake8-typing-imports/METADATA.toml @@ -1,4 +1,4 @@ -version = "1.14.*" +version = "1.15.*" upstream_repository = "https://github.com/asottile/flake8-typing-imports" partial_stub = true diff --git a/packages/pyright-internal/typeshed-fallback/stubs/fpdf2/fpdf/syntax.pyi b/packages/pyright-internal/typeshed-fallback/stubs/fpdf2/fpdf/syntax.pyi index 3671c05ae..e2ca70cdd 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/fpdf2/fpdf/syntax.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/fpdf2/fpdf/syntax.pyi @@ -2,7 +2,7 @@ import datetime from _typeshed import Incomplete, SupportsItems from abc import ABC, abstractmethod from re import Pattern -from typing import ClassVar, Generic, TypeVar +from typing import ClassVar, TypeVar from typing_extensions import Literal, Self from .encryption import StandardSecurityHandler @@ -62,7 +62,7 @@ class PDFDate: def __init__(self, date: datetime.datetime, with_tz: bool = False, encrypt: bool = False) -> None: ... def serialize(self) -> str: ... -class PDFArray(list[_T], Generic[_T]): +class PDFArray(list[_T]): def serialize(self) -> str: ... class Destination(ABC): diff --git a/packages/pyright-internal/typeshed-fallback/stubs/greenlet/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/greenlet/METADATA.toml index 3e0cb4f94..7b7346c3e 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/greenlet/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/greenlet/METADATA.toml @@ -1,2 +1,2 @@ -version = "2.0.*" +version = "3.0.*" upstream_repository = "https://github.com/python-greenlet/greenlet" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/greenlet/greenlet/_greenlet.pyi b/packages/pyright-internal/typeshed-fallback/stubs/greenlet/greenlet/_greenlet.pyi index e3ec8a53c..e873b1083 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/greenlet/greenlet/_greenlet.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/greenlet/greenlet/_greenlet.pyi @@ -63,6 +63,10 @@ class greenlet: @staticmethod def settrace(__callback: _TraceCallback | None) -> _TraceCallback | None: ... +class UnswitchableGreenlet(greenlet): # undocumented + force_switch_error: bool + force_slp_switch_error: bool + def enable_optional_cleanup(__enabled: bool) -> None: ... def get_clocks_used_doing_optional_cleanup() -> int: ... def get_pending_cleanup_count() -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/humanfriendly/humanfriendly/case.pyi b/packages/pyright-internal/typeshed-fallback/stubs/humanfriendly/humanfriendly/case.pyi index 4240cf2ab..d54838f75 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/humanfriendly/humanfriendly/case.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/humanfriendly/humanfriendly/case.pyi @@ -1,13 +1,13 @@ from _typeshed import Incomplete from collections import OrderedDict -from typing import Generic, TypeVar +from typing import TypeVar from humanfriendly.compat import unicode _KT = TypeVar("_KT") _VT = TypeVar("_VT") -class CaseInsensitiveDict(OrderedDict[_KT, _VT], Generic[_KT, _VT]): +class CaseInsensitiveDict(OrderedDict[_KT, _VT]): def __init__(self, other: Incomplete | None = None, **kw) -> None: ... def coerce_key(self, key): ... @classmethod diff --git a/packages/pyright-internal/typeshed-fallback/stubs/influxdb-client/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/influxdb-client/METADATA.toml index 3357b027b..7537f2307 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/influxdb-client/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/influxdb-client/METADATA.toml @@ -1,6 +1,14 @@ -version = "1.37.*" +version = "1.38.*" upstream_repository = "https://github.com/influxdata/influxdb-client-python" -requires = ["types-urllib3"] +# requires a version of urllib3 with a py.typed file +requires = ["urllib3>=2"] + +extra_description = """\ + Note: `types-influxdb-client` has required `urllib3>=2` since v1.37.0.1. \ + If you need to install `types-influxdb-client` into an environment \ + that must also have `urllib3<2` installed into it, \ + you will have to use `types-influxdb-client<1.37.0.1`.\ + """ [tool.stubtest] extras = ["extra"] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/invoke/invoke/tasks.pyi b/packages/pyright-internal/typeshed-fallback/stubs/invoke/invoke/tasks.pyi index 7a1188a4e..72a212644 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/invoke/invoke/tasks.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/invoke/invoke/tasks.pyi @@ -57,7 +57,7 @@ class Task(Generic[_P, _R_co]): def get_arguments(self, ignore_unknown_help: bool | None = None) -> list[Argument]: ... @overload -def task( +def task( # type: ignore[misc] *args: Task[..., Any] | Call, name: str | None = ..., aliases: tuple[str, ...] = ..., diff --git a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/METADATA.toml index 8586b7fa0..85ad912c0 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/METADATA.toml @@ -1,6 +1,8 @@ -version = "4.17.*" +version = "4.19.*" upstream_repository = "https://github.com/python-jsonschema/jsonschema" +requires = ["referencing"] partial_stub = true +requires_python = ">=3.8" [tool.stubtest] ignore_missing_stub = true diff --git a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_validators.pyi b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_keywords.pyi similarity index 100% rename from packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_validators.pyi rename to packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_keywords.pyi diff --git a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_legacy_validators.pyi b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_legacy_keywords.pyi similarity index 100% rename from packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_legacy_validators.pyi rename to packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_legacy_keywords.pyi diff --git a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_typing.pyi b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_typing.pyi new file mode 100644 index 000000000..bf096c3fa --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_typing.pyi @@ -0,0 +1,13 @@ +from collections.abc import Callable, Iterable +from typing import Any, Protocol +from typing_extensions import TypeAlias + +from jsonschema.protocols import Validator +from referencing.jsonschema import Schema + +class SchemaKeywordValidator(Protocol): + def __call__(self, validator: Validator, value: Any, instance: Any, schema: Schema) -> None: ... + +id_of: TypeAlias = Callable[[Schema], str | None] # noqa: Y042 + +ApplicableValidators: TypeAlias = Callable[[Schema], Iterable[tuple[str, Any]]] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_utils.pyi b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_utils.pyi index e00eb7c25..fd0207bd9 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_utils.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/_utils.pyi @@ -13,7 +13,6 @@ class URIDict(MutableMapping[str, str]): class Unset: ... -def load_schema(name): ... def format_as_index(container: str, indices) -> str: ... def find_additional_properties( instance: Iterable[Incomplete], schema: Mapping[Incomplete, Incomplete] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/validators.pyi b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/validators.pyi index 47ace89da..72ef1f6cf 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/validators.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/jsonschema/jsonschema/validators.pyi @@ -4,6 +4,9 @@ from contextlib import contextmanager from typing import Any, ClassVar from typing_extensions import TypeAlias +from referencing.jsonschema import Schema, SchemaRegistry +from referencing.typing import URI + from ._format import FormatChecker from ._types import TypeChecker from ._utils import Unset, URIDict @@ -14,8 +17,6 @@ _JsonObject: TypeAlias = Mapping[str, Any] _JsonValue: TypeAlias = _JsonObject | list[Any] | str | int | float | bool | None _ValidatorCallback: TypeAlias = Callable[[Any, Any, _JsonValue, _JsonObject], Iterator[ValidationError]] -_Schema: TypeAlias = Mapping[str, Any] - # This class does not exist at runtime. Compatible classes are created at # runtime by create(). class _Validator: @@ -24,31 +25,45 @@ class _Validator: TYPE_CHECKER: ClassVar[Incomplete] FORMAT_CHECKER: ClassVar[Incomplete] @staticmethod - def ID_OF(schema: _Schema) -> str: ... - schema: _Schema - resolver: Incomplete - format_checker: Incomplete - evolve: Incomplete - def __init__(self, schema: _Schema, resolver: Incomplete | None = ..., format_checker: Incomplete | None = ...) -> None: ... + def ID_OF(contents: Schema) -> URI | None: ... + schema: Schema + format_checker: FormatChecker | None + def __init__( + self, + schema: Schema, + resolver: Incomplete | None = None, + format_checker: FormatChecker | None = None, + *, + registry: SchemaRegistry = ..., + _resolver: Incomplete | None = None, + ) -> None: ... @classmethod - def check_schema(cls, schema: _Schema, format_checker: FormatChecker | Unset = ...) -> None: ... - def iter_errors(self, instance, _schema: _Schema | None = ...) -> Generator[Incomplete, None, None]: ... + def check_schema(cls, schema: Schema, format_checker: FormatChecker | Unset = ...) -> None: ... + @property + def resolver(self): ... + def evolve(self, **changes) -> _Validator: ... + def iter_errors(self, instance, _schema: Schema | None = ...) -> Generator[Incomplete, None, None]: ... def descend( - self, instance, schema: _Schema, path: Incomplete | None = ..., schema_path: Incomplete | None = ... + self, + instance, + schema: Schema, + path: Incomplete | None = ..., + schema_path: Incomplete | None = ..., + resolver: Incomplete | None = None, ) -> Generator[Incomplete, None, None]: ... def validate(self, *args, **kwargs) -> None: ... def is_type(self, instance, type): ... - def is_valid(self, instance, _schema: _Schema | None = ...) -> bool: ... + def is_valid(self, instance, _schema: Schema | None = ...) -> bool: ... def validates(version: str) -> Callable[..., Incomplete]: ... def create( - meta_schema: _Schema, + meta_schema: Schema, validators: Mapping[str, _ValidatorCallback] | tuple[()] = (), version: Incomplete | None = None, type_checker: TypeChecker = ..., format_checker: FormatChecker = ..., - id_of: Callable[[_Schema], str] = ..., - applicable_validators: Callable[[_Schema], Iterable[tuple[str, _ValidatorCallback]]] = ..., + id_of: Callable[[Schema], str] = ..., + applicable_validators: Callable[[Schema], Iterable[tuple[str, _ValidatorCallback]]] = ..., ) -> type[_Validator]: ... def extend( validator, @@ -84,7 +99,7 @@ class RefResolver: remote_cache: Incomplete | None = None, ) -> None: ... @classmethod - def from_schema(cls, schema: _Schema, id_of=..., *args, **kwargs): ... + def from_schema(cls, schema: Schema, id_of=..., *args, **kwargs): ... def push_scope(self, scope) -> None: ... def pop_scope(self) -> None: ... @property @@ -100,5 +115,5 @@ class RefResolver: def resolve_fragment(self, document, fragment): ... def resolve_remote(self, uri): ... -def validate(instance: object, schema: _Schema, cls: type[_Validator] | None = None, *args: Any, **kwargs: Any) -> None: ... -def validator_for(schema: _Schema | bool, default=...): ... +def validate(instance: object, schema: Schema, cls: type[_Validator] | None = None, *args: Any, **kwargs: Any) -> None: ... +def validator_for(schema: Schema | bool, default=...): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/ldap3/ldap3/utils/ciDict.pyi b/packages/pyright-internal/typeshed-fallback/stubs/ldap3/ldap3/utils/ciDict.pyi index 828dcece0..333dac598 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/ldap3/ldap3/utils/ciDict.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/ldap3/ldap3/utils/ciDict.pyi @@ -1,11 +1,11 @@ from _typeshed import Incomplete from collections.abc import MutableMapping -from typing import Generic, TypeVar +from typing import TypeVar _KT = TypeVar("_KT") _VT = TypeVar("_VT") -class CaseInsensitiveDict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): +class CaseInsensitiveDict(MutableMapping[_KT, _VT]): def __init__(self, other: Incomplete | None = None, **kwargs) -> None: ... def __contains__(self, item): ... def __delitem__(self, key) -> None: ... @@ -19,7 +19,7 @@ class CaseInsensitiveDict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): def __eq__(self, other): ... def copy(self): ... -class CaseInsensitiveWithAliasDict(CaseInsensitiveDict[_KT, _VT], Generic[_KT, _VT]): +class CaseInsensitiveWithAliasDict(CaseInsensitiveDict[_KT, _VT]): def __init__(self, other: Incomplete | None = None, **kwargs) -> None: ... def aliases(self): ... def __setitem__(self, key, value) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/netaddr/netaddr/ip/iana.pyi b/packages/pyright-internal/typeshed-fallback/stubs/netaddr/netaddr/ip/iana.pyi index 268023950..76e5f9990 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/netaddr/netaddr/ip/iana.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/netaddr/netaddr/ip/iana.pyi @@ -3,7 +3,7 @@ from collections.abc import Callable, Mapping, MutableMapping from typing import Any from typing_extensions import TypeAlias from xml.sax import handler -from xml.sax.xmlreader import XMLReader +from xml.sax.xmlreader import AttributesImpl, XMLReader from netaddr.core import Publisher, Subscriber from netaddr.ip import IPAddress, IPNetwork, IPRange @@ -14,7 +14,7 @@ IANA_INFO: dict[str, dict[_IanaInfoKey, dict[str, str]]] class SaxRecordParser(handler.ContentHandler): def __init__(self, callback: Callable[[Mapping[str, object] | None], object] | None = None) -> None: ... - def startElement(self, name: str, attrs: Mapping[str, object]) -> None: ... + def startElement(self, name: str, attrs: AttributesImpl) -> None: ... def endElement(self, name: str) -> None: ... def characters(self, content: str) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/__init__.pyi index cc5d82bfe..92212f351 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/__init__.pyi @@ -1,2 +1,22 @@ +from datetime import date, datetime, time, timedelta +from decimal import Decimal +from typing_extensions import TypeAlias + +from openpyxl.cell.rich_text import CellRichText +from openpyxl.worksheet.formula import ArrayFormula, DataTableFormula + from .cell import Cell as Cell, MergedCell as MergedCell, WriteOnlyCell as WriteOnlyCell from .read_only import ReadOnlyCell as ReadOnlyCell + +_TimeTypes: TypeAlias = datetime | date | time | timedelta +_CellValue: TypeAlias = ( # noqa: Y047 # Used in other modules + # if numpy is installed also numpy bool and number types + bool + | float + | Decimal + | str + | CellRichText + | _TimeTypes + | DataTableFormula + | ArrayFormula +) diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/cell.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/cell.pyi index 1f4ee9568..6ac9c68e3 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/cell.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/cell.pyi @@ -1,22 +1,17 @@ -from datetime import date, datetime, time, timedelta -from decimal import Decimal +from _typeshed import ReadableBuffer +from datetime import datetime from re import Pattern from typing import overload -from typing_extensions import Final, TypeAlias +from typing_extensions import Final, Literal -from openpyxl.cell.rich_text import CellRichText +from openpyxl.cell import _CellValue, _TimeTypes from openpyxl.comments.comments import Comment +from openpyxl.compat.numbers import NUMERIC_TYPES as NUMERIC_TYPES # cell numeric types from openpyxl.styles.cell_style import StyleArray from openpyxl.styles.styleable import StyleableObject -from openpyxl.worksheet.formula import ArrayFormula, DataTableFormula from openpyxl.worksheet.hyperlink import Hyperlink from openpyxl.worksheet.worksheet import Worksheet -_TimeTypes: TypeAlias = datetime | date | time | timedelta -_CellValue: TypeAlias = ( # if numpy is installed also numpy bool and number types - bool | float | Decimal | str | CellRichText | _TimeTypes | DataTableFormula | ArrayFormula -) - __docformat__: Final = "restructuredtext en" TIME_TYPES: Final[tuple[type, ...]] TIME_FORMATS: Final[dict[type[_TimeTypes], str]] @@ -37,8 +32,8 @@ TYPE_FORMULA_CACHE_STRING: Final = "str" VALID_TYPES: Final[tuple[str, ...]] -def get_type(t: type, value: object) -> str | None: ... -def get_time_format(t: datetime) -> str: ... +def get_type(t: type, value: object) -> Literal["n", "s", "d", "f", None]: ... +def get_time_format(t: _TimeTypes) -> str: ... class Cell(StyleableObject): row: int @@ -65,14 +60,14 @@ class Cell(StyleableObject): @overload def check_string(self, value: None) -> None: ... @overload - def check_string(self, value: str | bytes) -> str: ... + def check_string(self, value: str | ReadableBuffer) -> str: ... def check_error(self, value: object) -> str: ... @property - def value(self) -> _CellValue: ... + def value(self) -> _CellValue | None: ... @value.setter def value(self, value: _CellValue | bytes | None) -> None: ... @property - def internal_value(self) -> _CellValue: ... + def internal_value(self) -> _CellValue | None: ... @property def hyperlink(self) -> Hyperlink | None: ... @hyperlink.setter @@ -92,6 +87,7 @@ class MergedCell(StyleableObject): row: int column: int def __init__(self, worksheet: Worksheet, row: int | None = None, column: int | None = None) -> None: ... + # Same as Cell.coordinate @property def coordinate(self) -> str: ... value: str | float | int | datetime | None diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/read_only.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/read_only.pyi index 71e54e185..b465734c9 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/read_only.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/read_only.pyi @@ -1,6 +1,14 @@ from _typeshed import Incomplete from typing_extensions import Final +from openpyxl.cell import _CellValue +from openpyxl.styles.alignment import Alignment +from openpyxl.styles.borders import Border +from openpyxl.styles.cell_style import StyleArray +from openpyxl.styles.fills import Fill +from openpyxl.styles.fonts import Font +from openpyxl.styles.protection import Protection + class ReadOnlyCell: parent: Incomplete row: Incomplete @@ -9,35 +17,38 @@ class ReadOnlyCell: def __init__(self, sheet, row, column, value, data_type: str = "n", style_id: int = 0) -> None: ... def __eq__(self, other): ... def __ne__(self, other): ... - # defined twice in the implementation + # Same as Cell.coordinate + # Defined twice in the implementation @property - def coordinate(self): ... + def coordinate(self) -> str: ... + # Same as Cell.column_letter @property - def column_letter(self): ... + def column_letter(self) -> str: ... @property - def style_array(self): ... + def style_array(self) -> StyleArray: ... @property - def has_style(self): ... + def has_style(self) -> bool: ... @property - def number_format(self): ... + def number_format(self) -> str: ... @property - def font(self): ... + def font(self) -> Font: ... @property - def fill(self): ... + def fill(self) -> Fill: ... @property - def border(self): ... + def border(self) -> Border: ... @property - def alignment(self): ... + def alignment(self) -> Alignment: ... @property - def protection(self): ... + def protection(self) -> Protection: ... + # Same as Cell.is_date @property - def is_date(self): ... + def is_date(self) -> bool: ... @property - def internal_value(self): ... + def internal_value(self) -> _CellValue | None: ... @property - def value(self): ... + def value(self) -> _CellValue | None: ... @value.setter - def value(self, value) -> None: ... + def value(self, value: None) -> None: ... class EmptyCell: value: Incomplete diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/text.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/text.pyi index 24a59d210..56ee76b30 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/text.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/cell/text.pyi @@ -95,4 +95,4 @@ class Text(Serialisable): __elements__: ClassVar[tuple[str, ...]] def __init__(self, t: object = None, r=(), rPh=(), phoneticPr: _PhoneticProperties | None = None) -> None: ... @property - def content(self): ... + def content(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/_chart.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/_chart.pyi index d59f5e108..816919bdd 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/_chart.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/_chart.pyi @@ -46,4 +46,4 @@ class ChartBase(Serialisable): def add_data(self, data, from_rows: bool = False, titles_from_data: bool = False) -> None: ... def append(self, value) -> None: ... @property - def path(self): ... + def path(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/label.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/label.pyi index de3cfd45f..243ab1a5b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/label.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/label.pyi @@ -7,7 +7,7 @@ from openpyxl.chart.text import RichText from openpyxl.descriptors.base import Alias, Typed, _ConvertibleToBool, _ConvertibleToInt from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import NestedBool, NestedInteger, NestedNoneSet, NestedString, _NestedNoneSetParam -from openpyxl.descriptors.serialisable import Serialisable as Serialisable +from openpyxl.descriptors.serialisable import Serialisable from ..xml._functions_overloads import _HasTagAndGet diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/reference.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/reference.pyi index 72d0a106f..71eaf66b6 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/reference.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/reference.pyi @@ -41,9 +41,9 @@ class Reference(Strict): def __len__(self) -> int: ... def __eq__(self, other): ... @property - def rows(self) -> Generator[Incomplete, None, None]: ... + def rows(self) -> Generator[Reference, None, None]: ... @property - def cols(self) -> Generator[Incomplete, None, None]: ... + def cols(self) -> Generator[Reference, None, None]: ... def pop(self): ... @property - def sheetname(self): ... + def sheetname(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/shapes.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/shapes.pyi index 94da38a6b..ab7de9d1a 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/shapes.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chart/shapes.pyi @@ -5,6 +5,7 @@ from typing_extensions import Literal, TypeAlias from openpyxl.descriptors.base import Alias, NoneSet, Typed, _ConvertibleToBool from openpyxl.descriptors.nested import EmptyTag from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.drawing.colors import ColorChoice, ColorChoiceDescriptor from openpyxl.drawing.fill import GradientFillProperties, PatternFillProperties from openpyxl.drawing.geometry import CustomGeometry2D, PresetGeometry2D, Scene3D, Shape3D, Transform2D from openpyxl.drawing.line import LineProperties @@ -23,7 +24,7 @@ class GraphicalProperties(Serialisable): custGeom: Typed[CustomGeometry2D, Literal[True]] prstGeom: Typed[PresetGeometry2D, Literal[True]] noFill: EmptyTag[Literal[False]] - solidFill: Incomplete + solidFill: ColorChoiceDescriptor gradFill: Typed[GradientFillProperties, Literal[True]] pattFill: Typed[PatternFillProperties, Literal[True]] ln: Typed[LineProperties, Literal[True]] @@ -38,7 +39,7 @@ class GraphicalProperties(Serialisable): bwMode: _GraphicalPropertiesBwMode | Literal["none"] | None = None, xfrm: Transform2D | None = None, noFill: _HasTagAndGet[_ConvertibleToBool] | _ConvertibleToBool = None, - solidFill: Incomplete | None = None, + solidFill: str | ColorChoice | None = None, gradFill: GradientFillProperties | None = None, pattFill: PatternFillProperties | None = None, ln: Incomplete | None = None, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chartsheet/properties.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chartsheet/properties.pyi index 9c0eec5b6..973b86374 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chartsheet/properties.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/chartsheet/properties.pyi @@ -2,7 +2,7 @@ from typing import ClassVar from typing_extensions import Literal from openpyxl.descriptors.base import Bool, String, Typed, _ConvertibleToBool -from openpyxl.descriptors.serialisable import Serialisable as Serialisable +from openpyxl.descriptors.serialisable import Serialisable from openpyxl.styles.colors import Color class ChartsheetProperties(Serialisable): diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/comments/comment_sheet.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/comments/comment_sheet.pyi index 4d10664d0..f15829346 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/comments/comment_sheet.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/comments/comment_sheet.pyi @@ -5,6 +5,7 @@ from typing_extensions import Literal, TypeAlias from openpyxl.cell.text import Text from openpyxl.comments.author import AuthorList +from openpyxl.comments.comments import Comment from openpyxl.descriptors.base import Bool, Integer, Set, String, Typed, _ConvertibleToBool, _ConvertibleToInt from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.serialisable import Serialisable @@ -101,7 +102,7 @@ class CommentRecord(Serialisable): @classmethod def from_cell(cls, cell): ... @property - def content(self): ... + def content(self) -> str: ... class CommentSheet(Serialisable): tagname: ClassVar[str] @@ -113,9 +114,9 @@ class CommentSheet(Serialisable): def __init__(self, authors: AuthorList, commentList: Incomplete | None = None, extLst: Unused = None) -> None: ... def to_tree(self): ... @property - def comments(self) -> Generator[Incomplete, None, None]: ... + def comments(self) -> Generator[tuple[str, Comment], None, None]: ... @classmethod def from_comments(cls, comments): ... def write_shapes(self, vml: Incomplete | None = None): ... @property - def path(self): ... + def path(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/comments/comments.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/comments/comments.pyi index e529f78da..a735081bf 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/comments/comments.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/comments/comments.pyi @@ -1,4 +1,5 @@ from _typeshed import Incomplete +from typing import Any class Comment: content: Incomplete @@ -7,12 +8,12 @@ class Comment: width: Incomplete def __init__(self, text, author, height: int = 79, width: int = 144) -> None: ... @property - def parent(self): ... + def parent(self) -> Any: ... # AnyOf[Cell, MergedCell, ReadOnlyCell] def __eq__(self, other): ... def __copy__(self): ... def bind(self, cell) -> None: ... def unbind(self) -> None: ... @property - def text(self): ... + def text(self) -> str: ... @text.setter - def text(self, value) -> None: ... + def text(self, value: str) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/compat/singleton.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/compat/singleton.pyi index 65403a663..859a30110 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/compat/singleton.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/compat/singleton.pyi @@ -1,7 +1,15 @@ +from typing import Any, overload + class Singleton(type): - def __init__(self, *args, **kw) -> None: ... - def __call__(self, *args, **kw): ... + @overload + def __init__(self, __o: object) -> None: ... + @overload + def __init__(self, __name: str, __bases: tuple[type, ...], __dict: dict[str, Any], **kwds: Any) -> None: ... + def __call__(self, *args: Any, **kwds: Any) -> Any: ... class Cached(type): - def __init__(self, *args, **kw) -> None: ... - def __call__(self, *args): ... + @overload + def __init__(self, __o: object) -> None: ... + @overload + def __init__(self, __name: str, __bases: tuple[type, ...], __dict: dict[str, Any], **kwds: Any) -> None: ... + def __call__(self, *args: Any) -> Any: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/__init__.pyi index 5817c55b8..18097e820 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/__init__.pyi @@ -1,10 +1,12 @@ +from _typeshed import Incomplete, Self + from .base import * from .sequence import Sequence as Sequence class MetaStrict(type): - def __new__(cls, clsname, bases, methods): ... + def __new__(cls: type[Self], clsname: str, bases: tuple[type, ...], methods: dict[str, Descriptor[Incomplete]]) -> Self: ... class MetaSerialisable(type): - def __new__(cls, clsname, bases, methods): ... + def __new__(cls: type[Self], clsname: str, bases: tuple[type, ...], methods: dict[str, Descriptor[Incomplete]]) -> Self: ... class Strict(metaclass=MetaStrict): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/sequence.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/sequence.pyi index ef3d3096f..5776357a6 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/sequence.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/sequence.pyi @@ -1,7 +1,7 @@ from _typeshed import Incomplete, Unused from collections.abc import Generator, Iterable -from typing import Any, Protocol -from typing_extensions import Self, TypeVar +from typing import Any, Protocol, TypeVar +from typing_extensions import Self from openpyxl.descriptors import Strict from openpyxl.descriptors.serialisable import Serialisable, _SerialisableTreeElement diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/serialisable.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/serialisable.pyi index 7da292d88..5319a1f6e 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/serialisable.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/serialisable.pyi @@ -1,5 +1,6 @@ from _typeshed import Incomplete, SupportsIter -from typing import Any, ClassVar, NoReturn, Protocol +from collections.abc import Iterator +from typing import Any, ClassVar, Protocol from typing_extensions import Final, Self from openpyxl.descriptors import MetaSerialisable @@ -21,8 +22,10 @@ class Serialisable(metaclass=MetaSerialisable): __namespaced__: ClassVar[tuple[tuple[str, str], ...]] idx_base: int # Needs overrides in many sub-classes. But a lot of subclasses are instanciated without overriding it, so can't be abstract + # Subclasses "overrides" this property with a ClassVar, and Serialisable is too widely used, + # so it can't be typed as NoReturn either without introducing many false-positives. @property - def tagname(self) -> str | NoReturn: ... + def tagname(self) -> str: ... namespace: ClassVar[str | None] # Note: To respect the Liskov substitution principle, the protocol for node includes all child class requirements. # Same with the return type to avoid override issues. @@ -32,7 +35,7 @@ class Serialisable(metaclass=MetaSerialisable): @classmethod def from_tree(cls, node: _SerialisableTreeElement) -> Self | None: ... def to_tree(self, tagname: str | None = None, idx: Incomplete | None = None, namespace: str | None = None): ... - def __iter__(self): ... + def __iter__(self) -> Iterator[tuple[str, str]]: ... def __eq__(self, other): ... def __ne__(self, other): ... def __hash__(self) -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/slots.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/slots.pyi index ebfc3090e..f74e59307 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/slots.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/descriptors/slots.pyi @@ -1,2 +1,4 @@ +from _typeshed import Incomplete, Self + class AutoSlotProperties(type): - def __new__(mcl, classname, bases, dictionary): ... + def __new__(mcl: type[Self], classname: str, bases: tuple[type, ...], dictionary: dict[str, Incomplete]) -> Self: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/colors.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/colors.pyi index 889d7de2a..24cce5f4d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/colors.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/colors.pyi @@ -503,7 +503,8 @@ class ColorMapping(Serialisable): extLst: ExtensionList | None = None, ) -> None: ... -class ColorChoiceDescriptor(Typed[ColorChoice, Incomplete]): +class ColorChoiceDescriptor(Typed[ColorChoice, Literal[True]]): expected_type: type[ColorChoice] allow_none: Literal[True] - def __set__(self, instance: Serialisable | Strict, value) -> None: ... + def __init__(self, name: str | None = None) -> None: ... + def __set__(self, instance: Serialisable | Strict, value: str | ColorChoice | None) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/drawing.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/drawing.pyi index 0637334da..2dddc1300 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/drawing.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/drawing.pyi @@ -1,5 +1,7 @@ from _typeshed import Incomplete +from .spreadsheet_drawing import AbsoluteAnchor, OneCellAnchor + class Drawing: count: int name: str @@ -14,13 +16,13 @@ class Drawing: anchorrow: int def __init__(self) -> None: ... @property - def width(self): ... + def width(self) -> int: ... @width.setter - def width(self, w) -> None: ... + def width(self, w: int) -> None: ... @property - def height(self): ... + def height(self) -> int: ... @height.setter - def height(self, h) -> None: ... + def height(self, h: int) -> None: ... def set_dimension(self, w: int = 0, h: int = 0) -> None: ... @property - def anchor(self): ... + def anchor(self) -> AbsoluteAnchor | OneCellAnchor: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/image.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/image.pyi index 3864d30df..b275596fd 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/image.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/image.pyi @@ -6,4 +6,4 @@ class Image: format: Incomplete def __init__(self, img) -> None: ... @property - def path(self): ... + def path(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/line.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/line.pyi index 8a7aba534..70ff2585a 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/line.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/line.pyi @@ -15,6 +15,7 @@ from openpyxl.descriptors.base import ( from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import EmptyTag, NestedInteger, NestedNoneSet, _NestedNoneSetParam from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.drawing.colors import ColorChoice, ColorChoiceDescriptor from openpyxl.drawing.fill import GradientFillProperties, PatternFillProperties from ..xml._functions_overloads import _HasTagAndGet @@ -63,7 +64,7 @@ class LineProperties(Serialisable): cmpd: NoneSet[_LinePropertiesCmpd] algn: NoneSet[_LinePropertiesAlgn] noFill: EmptyTag[Literal[False]] - solidFill: Incomplete + solidFill: ColorChoiceDescriptor gradFill: Typed[GradientFillProperties, Literal[True]] pattFill: Typed[PatternFillProperties, Literal[True]] prstDash: NestedNoneSet[_LinePropertiesPrstDash] @@ -83,7 +84,7 @@ class LineProperties(Serialisable): cmpd: _LinePropertiesCmpd | Literal["none"] | None = None, algn: _LinePropertiesAlgn | Literal["none"] | None = None, noFill: _HasTagAndGet[_ConvertibleToBool] | _ConvertibleToBool = None, - solidFill: Incomplete | None = None, + solidFill: str | ColorChoice | None = None, gradFill: GradientFillProperties | None = None, pattFill: PatternFillProperties | None = None, prstDash: _NestedNoneSetParam[_LinePropertiesPrstDash] = None, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/spreadsheet_drawing.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/spreadsheet_drawing.pyi index cb0f7762a..d516ce6a0 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/spreadsheet_drawing.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/spreadsheet_drawing.pyi @@ -118,4 +118,4 @@ class SpreadsheetDrawing(Serialisable): def __hash__(self) -> int: ... def __bool__(self) -> bool: ... @property - def path(self): ... + def path(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/text.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/text.pyi index 672b0d26f..e18fa6dab 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/text.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/drawing/text.pyi @@ -18,6 +18,7 @@ from openpyxl.descriptors.base import ( from openpyxl.descriptors.excel import Coordinate, ExtensionList from openpyxl.descriptors.nested import EmptyTag, NestedBool, NestedInteger, NestedText, NestedValue from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.drawing.colors import ColorChoice, ColorChoiceDescriptor from openpyxl.drawing.effect import Color, EffectContainer, EffectList from openpyxl.drawing.fill import Blip, BlipFillProperties, GradientFillProperties, PatternFillProperties from openpyxl.drawing.geometry import Scene3D @@ -223,7 +224,7 @@ class CharacterProperties(Serialisable): rtl: NestedBool[Literal[True]] extLst: Typed[ExtensionList, Literal[True]] noFill: EmptyTag[Literal[False]] - solidFill: Incomplete + solidFill: ColorChoiceDescriptor gradFill: Typed[GradientFillProperties, Literal[True]] blipFill: Typed[BlipFillProperties, Literal[True]] pattFill: Typed[PatternFillProperties, Literal[True]] @@ -265,9 +266,9 @@ class CharacterProperties(Serialisable): hlinkClick: Hyperlink | None = None, hlinkMouseOver: Hyperlink | None = None, rtl: _HasTagAndGet[_ConvertibleToBool | None] | _ConvertibleToBool | None = None, - extLst: ExtensionList | None = None, + extLst: Unused = None, noFill: _HasTagAndGet[_ConvertibleToBool] | _ConvertibleToBool = None, - solidFill: Incomplete | None = None, + solidFill: str | ColorChoice | None = None, gradFill: GradientFillProperties | None = None, blipFill: BlipFillProperties | None = None, pattFill: PatternFillProperties | None = None, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formatting/formatting.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formatting/formatting.pyi index a828d3c08..adec95048 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formatting/formatting.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formatting/formatting.pyi @@ -1,4 +1,5 @@ from _typeshed import Incomplete, Unused +from collections.abc import Iterator from typing import ClassVar from typing_extensions import Literal @@ -26,7 +27,7 @@ class ConditionalFormattingList: def add(self, range_string, cfRule) -> None: ... def __bool__(self) -> bool: ... def __len__(self) -> int: ... - def __iter__(self): ... + def __iter__(self) -> Iterator[ConditionalFormatting]: ... def __getitem__(self, key): ... def __delitem__(self, key) -> None: ... def __setitem__(self, key, rule) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formatting/rule.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formatting/rule.pyi index b9e99931d..2ccd4f9f0 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formatting/rule.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formatting/rule.pyi @@ -1,11 +1,12 @@ from _typeshed import Incomplete, Unused -from typing import ClassVar +from typing import ClassVar, overload from typing_extensions import Literal, TypeAlias from openpyxl.descriptors import Float, Strict from openpyxl.descriptors.base import Bool, Integer, NoneSet, Set, String, Typed, _ConvertibleToBool, _ConvertibleToInt from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.styles.colors import Color, ColorDescriptor from openpyxl.styles.differential import DifferentialStyle _IconSetIconSet: TypeAlias = Literal[ @@ -106,16 +107,27 @@ class DataBar(RuleType): minLength: Integer[Literal[True]] maxLength: Integer[Literal[True]] showValue: Bool[Literal[True]] - color: Incomplete + color: ColorDescriptor[Literal[False]] __elements__: ClassVar[tuple[str, ...]] cfvo: Incomplete + @overload def __init__( self, minLength: _ConvertibleToInt | None = None, maxLength: _ConvertibleToInt | None = None, showValue: _ConvertibleToBool | None = None, cfvo: Incomplete | None = None, - color: Incomplete | None = None, + *, + color: str | Color, + ) -> None: ... + @overload + def __init__( + self, + minLength: _ConvertibleToInt | None, + maxLength: _ConvertibleToInt | None, + showValue: _ConvertibleToBool | None, + cfvo: Incomplete | None, + color: str | Color, ) -> None: ... class ColorScale(RuleType): diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formula/tokenizer.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formula/tokenizer.pyi index 6b7d97431..acf53bcb9 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formula/tokenizer.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/formula/tokenizer.pyi @@ -1,6 +1,13 @@ from _typeshed import Incomplete from re import Pattern -from typing_extensions import Final +from typing_extensions import Final, Literal, TypeAlias + +_TokenTypesNotOperand: TypeAlias = Literal[ + "LITERAL", "FUNC", "ARRAY", "PAREN", "SEP", "OPERATOR-PREFIX", "OPERATOR-INFIX", "OPERATOR-POSTFIX", "WHITE-SPACE" +] +_TokenTypes: TypeAlias = Literal["OPERAND", _TokenTypesNotOperand] +_TokenOperandSubtypes: TypeAlias = Literal["TEXT", "NUMBER", "LOGICAL", "ERROR", "RANGE"] +_TokenSubtypes: TypeAlias = Literal["", _TokenOperandSubtypes, "OPEN", "CLOSE", "ARG", "ROW"] class TokenizerError(Exception): ... @@ -33,9 +40,9 @@ class Token: OP_POST: Final = "OPERATOR-POSTFIX" WSPACE: Final = "WHITE-SPACE" value: Incomplete - type: Incomplete - subtype: Incomplete - def __init__(self, value, type_, subtype: str = "") -> None: ... + type: _TokenTypes + subtype: _TokenSubtypes + def __init__(self, value, type_: _TokenTypes, subtype: _TokenSubtypes = "") -> None: ... TEXT: Final = "TEXT" NUMBER: Final = "NUMBER" LOGICAL: Final = "LOGICAL" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/custom.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/custom.pyi index 048329b94..0aa754643 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/custom.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/custom.pyi @@ -54,7 +54,7 @@ _MappingPropertyType: TypeAlias = StringProperty | IntProperty | FloatProperty | CLASS_MAPPING: Final[dict[type[_MappingPropertyType], str]] XML_MAPPING: Final[dict[str, type[_MappingPropertyType]]] -class CustomPropertyList(Strict): +class CustomPropertyList(Strict, Generic[_T]): props: Sequence def __init__(self) -> None: ... @classmethod @@ -66,4 +66,4 @@ class CustomPropertyList(Strict): def names(self) -> list[str]: ... def __getitem__(self, name): ... def __delitem__(self, name) -> None: ... - def __iter__(self) -> Iterator[Incomplete]: ... + def __iter__(self) -> Iterator[_TypedProperty[_T]]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/interface.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/interface.pyi index d000905f4..45a7da111 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/interface.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/interface.pyi @@ -1,6 +1,8 @@ -from abc import ABC, ABCMeta, abstractmethod +from abc import ABC, abstractmethod -class ISerialisableFile(ABC, metaclass=ABCMeta): +# This interface is unused. Nothing implements `id` as property either. +# IDs can be ints, strings, None, or a Descriptor returning those throughout the codebase. +class ISerialisableFile(ABC): @property @abstractmethod - def id(self): ... + def id(self) -> str | int | None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/manifest.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/manifest.pyi index e0b8b8430..62a51a728 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/manifest.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/manifest.pyi @@ -31,9 +31,9 @@ class Manifest(Serialisable): __elements__: ClassVar[tuple[str, ...]] def __init__(self, Default=(), Override=()) -> None: ... @property - def filenames(self): ... + def filenames(self) -> list[str]: ... @property - def extensions(self): ... + def extensions(self) -> list[tuple[str, str]]: ... def to_tree(self): ... def __contains__(self, content_type): ... def find(self, content_type): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/workbook.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/workbook.pyi index 7f7b8117c..288d93c72 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/workbook.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/packaging/workbook.pyi @@ -101,4 +101,4 @@ class WorkbookPackage(Serialisable): ) -> None: ... def to_tree(self): ... @property - def active(self): ... + def active(self) -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/cache.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/cache.pyi index c900dbf96..c07c9e3a7 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/cache.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/cache.pyi @@ -101,7 +101,7 @@ class ServerFormatList(Serialisable): __attrs__: ClassVar[tuple[str, ...]] def __init__(self, count: Incomplete | None = None, serverFormat: Incomplete | None = None) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class Query(Serialisable): tagname: ClassVar[str] @@ -384,7 +384,7 @@ class GroupItems(Serialisable): __attrs__: ClassVar[tuple[str, ...]] def __init__(self, count: Incomplete | None = None, m=(), n=(), b=(), e=(), s=(), d=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class DiscretePr(Serialisable): tagname: ClassVar[str] @@ -475,7 +475,7 @@ class SharedItems(Serialisable): longText: _ConvertibleToBool | None = None, ) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class CacheField(Serialisable): tagname: ClassVar[str] @@ -585,7 +585,7 @@ class Page(Serialisable): __elements__: ClassVar[tuple[str, ...]] def __init__(self, count: Incomplete | None = None, pageItem: Incomplete | None = None) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class Consolidation(Serialisable): tagname: ClassVar[str] @@ -723,4 +723,4 @@ class CacheDefinition(Serialisable): ) -> None: ... def to_tree(self): ... @property - def path(self): ... + def path(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/record.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/record.pyi index 7e90dac95..234d02a97 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/record.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/record.pyi @@ -37,7 +37,7 @@ class RecordList(Serialisable): __attrs__: ClassVar[tuple[str, ...]] def __init__(self, count: Unused = None, r=(), extLst: ExtensionList | None = None) -> None: ... @property - def count(self): ... + def count(self) -> int: ... def to_tree(self): ... @property - def path(self): ... + def path(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/table.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/table.pyi index 6f27a7a32..b7f89dbd1 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/table.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/pivot/table.pyi @@ -117,7 +117,7 @@ class ColHierarchiesUsage(Serialisable): __attrs__: ClassVar[tuple[str, ...]] def __init__(self, count: Incomplete | None = None, colHierarchyUsage=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class RowHierarchiesUsage(Serialisable): tagname: ClassVar[str] @@ -126,7 +126,7 @@ class RowHierarchiesUsage(Serialisable): __attrs__: ClassVar[tuple[str, ...]] def __init__(self, count: Incomplete | None = None, rowHierarchyUsage=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class PivotFilter(Serialisable): tagname: ClassVar[str] @@ -211,7 +211,7 @@ class MemberList(Serialisable): __elements__: ClassVar[tuple[str, ...]] def __init__(self, count: Incomplete | None = None, level: _ConvertibleToInt | None = None, member=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class MemberProperty(Serialisable): tagname: ClassVar[str] @@ -331,7 +331,7 @@ class Reference(Serialisable): extLst: ExtensionList | None = None, ) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class PivotArea(Serialisable): tagname: ClassVar[str] @@ -419,7 +419,7 @@ class ConditionalFormatList(Serialisable): def __init__(self, conditionalFormat=..., count: Incomplete | None = ...) -> None: ... def by_priority(self): ... @property - def count(self): ... + def count(self) -> int: ... def to_tree(self, tagname: str | None = None): ... # type: ignore[override] class Format(Serialisable): @@ -952,7 +952,7 @@ class TableDefinition(Serialisable): ) -> None: ... def to_tree(self): ... @property - def path(self): ... + def path(self) -> str: ... def formatted_fields(self) -> dict[Incomplete, list[Incomplete]]: ... @property def summary(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/reader/workbook.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/reader/workbook.pyi index 7ef1b85e4..b016ceebe 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/reader/workbook.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/reader/workbook.pyi @@ -1,6 +1,8 @@ from _typeshed import Incomplete from collections.abc import Generator +from openpyxl.packaging.relationship import RelationshipList +from openpyxl.pivot.cache import CacheDefinition from openpyxl.workbook import Workbook class WorkbookParser: @@ -11,10 +13,10 @@ class WorkbookParser: sheets: Incomplete def __init__(self, archive, workbook_part_name, keep_links: bool = True) -> None: ... @property - def rels(self): ... + def rels(self) -> RelationshipList: ... caches: Incomplete def parse(self) -> None: ... def find_sheets(self) -> Generator[Incomplete, None, None]: ... def assign_names(self) -> None: ... @property - def pivot_caches(self): ... + def pivot_caches(self) -> dict[int, CacheDefinition]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/alignment.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/alignment.pyi index 752312b98..1b413e249 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/alignment.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/alignment.pyi @@ -1,6 +1,7 @@ from _typeshed import Incomplete +from collections.abc import Iterator from typing import ClassVar -from typing_extensions import Literal, TypeAlias +from typing_extensions import Final, Literal, TypeAlias from openpyxl.descriptors.base import Alias, Bool, Min, MinMax, NoneSet, _ConvertibleToBool, _ConvertibleToFloat from openpyxl.descriptors.serialisable import Serialisable @@ -10,8 +11,8 @@ _HorizontalAlignmentsType: TypeAlias = Literal[ ] _VerticalAlignmentsType: TypeAlias = Literal["top", "center", "bottom", "justify", "distributed"] -horizontal_alignments: tuple[_HorizontalAlignmentsType, ...] -vertical_aligments: tuple[_VerticalAlignmentsType, ...] +horizontal_alignments: Final[tuple[_HorizontalAlignmentsType, ...]] +vertical_aligments: Final[tuple[_VerticalAlignmentsType, ...]] class Alignment(Serialisable): tagname: ClassVar[str] @@ -44,4 +45,4 @@ class Alignment(Serialisable): shrink_to_fit: Incomplete | None = None, mergeCell: Incomplete | None = None, ) -> None: ... - def __iter__(self): ... + def __iter__(self) -> Iterator[tuple[str, str]]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/borders.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/borders.pyi index 3a9607925..5e9c0ebf6 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/borders.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/borders.pyi @@ -1,9 +1,11 @@ from _typeshed import Incomplete +from collections.abc import Iterator from typing import ClassVar from typing_extensions import Final, Literal, TypeAlias from openpyxl.descriptors.base import Alias, Bool, NoneSet, Typed, _ConvertibleToBool from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.styles.colors import Color, ColorDescriptor _SideStyle: TypeAlias = Literal[ "dashDot", @@ -38,13 +40,13 @@ BORDER_THIN: Final = "thin" class Side(Serialisable): __fields__: ClassVar[tuple[str, ...]] - color: Incomplete + color: ColorDescriptor[Literal[True]] style: NoneSet[_SideStyle] border_style: Alias def __init__( self, style: _SideStyle | Literal["none"] | None = None, - color: Incomplete | None = None, + color: str | Color | None = None, border_style: Incomplete | None = None, ) -> None: ... @@ -81,6 +83,6 @@ class Border(Serialisable): start: Side | None = None, end: Side | None = None, ) -> None: ... - def __iter__(self): ... + def __iter__(self) -> Iterator[tuple[str, str]]: ... DEFAULT_BORDER: Final[Border] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/cell_style.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/cell_style.pyi index 22362cf54..0640927d4 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/cell_style.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/cell_style.pyi @@ -1,7 +1,8 @@ from _typeshed import Incomplete, Unused from array import array +from collections.abc import Iterable from typing import ClassVar -from typing_extensions import Literal +from typing_extensions import Literal, Self from openpyxl.descriptors import Strict from openpyxl.descriptors.base import Bool, Integer, Typed, _ConvertibleToBool, _ConvertibleToInt @@ -16,21 +17,21 @@ class ArrayDescriptor: def __get__(self, instance: Serialisable | Strict, cls: Unused): ... def __set__(self, instance: Serialisable | Strict, value) -> None: ... -class StyleArray(array[Incomplete]): +class StyleArray(array[int]): tagname: ClassVar[str] - fontId: Incomplete - fillId: Incomplete - borderId: Incomplete - numFmtId: Incomplete - protectionId: Incomplete - alignmentId: Incomplete - pivotButton: Incomplete - quotePrefix: Incomplete - xfId: Incomplete - def __new__(cls, args=[0, 0, 0, 0, 0, 0, 0, 0, 0]): ... + fontId: ArrayDescriptor + fillId: ArrayDescriptor + borderId: ArrayDescriptor + numFmtId: ArrayDescriptor + protectionId: ArrayDescriptor + alignmentId: ArrayDescriptor + pivotButton: ArrayDescriptor + quotePrefix: ArrayDescriptor + xfId: ArrayDescriptor + def __new__(cls, args: bytes | bytearray | Iterable[int] = [0, 0, 0, 0, 0, 0, 0, 0, 0]) -> Self: ... def __hash__(self) -> int: ... - def __copy__(self): ... - def __deepcopy__(self, memo): ... + def __copy__(self) -> StyleArray: ... + def __deepcopy__(self, memo: Unused) -> StyleArray: ... class CellStyle(Serialisable): tagname: ClassVar[str] @@ -76,9 +77,9 @@ class CellStyle(Serialisable): @classmethod def from_array(cls, style): ... @property - def applyProtection(self): ... + def applyProtection(self) -> Literal[True] | None: ... @property - def applyAlignment(self): ... + def applyAlignment(self) -> Literal[True] | None: ... class CellStyleList(Serialisable): tagname: ClassVar[str] @@ -91,5 +92,5 @@ class CellStyleList(Serialisable): __elements__: ClassVar[tuple[str, ...]] def __init__(self, count: Unused = None, xf=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... def __getitem__(self, idx): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/colors.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/colors.pyi index 3b69fc271..c7f0c095e 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/colors.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/colors.pyi @@ -1,25 +1,44 @@ from _typeshed import Incomplete, Unused +from collections.abc import Iterator from re import Pattern -from typing import ClassVar -from typing_extensions import Final, Literal +from typing import ClassVar, TypeVar, overload +from typing_extensions import Final, Literal, Self from openpyxl.descriptors import Strict, Typed -from openpyxl.descriptors.base import Bool, Integer, MinMax, String, _ConvertibleToBool, _ConvertibleToFloat, _ConvertibleToInt +from openpyxl.descriptors.base import ( + _N, + Bool, + Integer, + MinMax, + String, + _ConvertibleToBool, + _ConvertibleToFloat, + _ConvertibleToInt, +) from openpyxl.descriptors.serialisable import Serialisable +_S = TypeVar("_S", bound=Serialisable) + COLOR_INDEX: Final[tuple[str, ...]] BLACK: Final = "00000000" WHITE: Final = "00FFFFFF" BLUE: Final = "00FFFFFF" aRGB_REGEX: Final[Pattern[str]] -class RGB(Typed[str, Incomplete]): +class RGB(Typed[str, _N]): expected_type: type[str] - def __set__(self, instance: Serialisable | Strict, value) -> None: ... + @overload + def __init__(self: RGB[Literal[True]], name: str | None = None, *, allow_none: Literal[True]) -> None: ... + @overload + def __init__(self: RGB[Literal[False]], name: str | None = None, *, allow_none: Literal[False] = False) -> None: ... + @overload + def __set__(self: RGB[Literal[True]], instance: Serialisable | Strict, value: str | None) -> None: ... + @overload + def __set__(self: RGB[Literal[False]], instance: Serialisable | Strict, value: str) -> None: ... class Color(Serialisable): tagname: ClassVar[str] - rgb: Incomplete + rgb: RGB[Literal[False]] indexed: Integer[Literal[False]] auto: Bool[Literal[False]] theme: Integer[Literal[False]] @@ -36,29 +55,45 @@ class Color(Serialisable): type: Unused = "rgb", ) -> None: ... @property - def value(self): ... + def value(self) -> str | int | bool: ... @value.setter - def value(self, value) -> None: ... - def __iter__(self): ... + def value(self, value: str | _ConvertibleToInt | _ConvertibleToBool) -> None: ... + def __iter__(self) -> Iterator[tuple[str, str]]: ... @property - def index(self): ... - def __add__(self, other): ... + def index(self) -> str | int | bool: ... + @overload + def __add__(self, other: Color) -> Self: ... + @overload + def __add__(self, other: _S) -> _S: ... -class ColorDescriptor(Typed[Color, Incomplete]): +class ColorDescriptor(Typed[Color, _N]): expected_type: type[Color] - def __set__(self, instance: Serialisable | Strict, value) -> None: ... + @overload + def __init__(self: ColorDescriptor[Literal[True]], name: str | None = None, *, allow_none: Literal[True]) -> None: ... + @overload + def __init__( + self: ColorDescriptor[Literal[False]], name: str | None = None, *, allow_none: Literal[False] = False + ) -> None: ... + @overload + def __set__(self: ColorDescriptor[_N], instance: Serialisable | Strict, value: str) -> None: ... + @overload + def __set__(self: ColorDescriptor[Literal[True]], instance: Serialisable | Strict, value: Color | None) -> None: ... + @overload + def __set__(self: ColorDescriptor[Literal[False]], instance: Serialisable | Strict, value: Color) -> None: ... class RgbColor(Serialisable): tagname: ClassVar[str] - rgb: Incomplete - def __init__(self, rgb: Incomplete | None = None) -> None: ... + rgb: RGB[Literal[False]] + def __init__(self, rgb: str) -> None: ... class ColorList(Serialisable): tagname: ClassVar[str] indexedColors: Incomplete mruColors: Incomplete __elements__: ClassVar[tuple[str, ...]] - def __init__(self, indexedColors=(), mruColors=()) -> None: ... + def __init__( + self, indexedColors: list[RgbColor] | tuple[RgbColor, ...] = (), mruColors: list[Color] | tuple[Color, ...] = () + ) -> None: ... def __bool__(self) -> bool: ... @property - def index(self): ... + def index(self) -> list[str]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/differential.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/differential.pyi index 508463dd5..7fac40e0f 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/differential.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/differential.pyi @@ -40,4 +40,4 @@ class DifferentialStyleList(Serialisable): def __bool__(self) -> bool: ... def __getitem__(self, idx): ... @property - def count(self): ... + def count(self) -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/fills.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/fills.pyi index f8bf1b486..749797c8f 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/fills.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/fills.pyi @@ -1,11 +1,12 @@ from _typeshed import Incomplete -from collections.abc import Iterable, Sequence as ABCSequence +from collections.abc import Iterable, Iterator, Sequence as ABCSequence from typing import ClassVar from typing_extensions import Final, Literal, TypeAlias -from openpyxl.descriptors import Sequence +from openpyxl.descriptors import Sequence, Strict from openpyxl.descriptors.base import Alias, Float, MinMax, NoneSet, Set, _ConvertibleToFloat from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.styles.colors import Color, ColorDescriptor from ..xml._functions_overloads import _SupportsIterAndAttribAndTextAndTag @@ -31,7 +32,6 @@ FILL_PATTERN_MEDIUMGRAY: Final = "mediumGray" _GradientFillType: TypeAlias = Literal["linear", "path"] _FillsType: TypeAlias = Literal[ - "none", "solid", "darkDown", "darkGray", @@ -51,7 +51,7 @@ _FillsType: TypeAlias = Literal[ "lightVertical", "mediumGray", ] -fills: tuple[_FillsType, ...] +fills: Final[tuple[_FillsType, ...]] class Fill(Serialisable): tagname: ClassVar[str] @@ -63,18 +63,18 @@ class PatternFill(Fill): __elements__: ClassVar[tuple[str, ...]] patternType: NoneSet[_FillsType] fill_type: Alias - fgColor: Incomplete + fgColor: ColorDescriptor[Literal[False]] start_color: Alias - bgColor: Incomplete + bgColor: ColorDescriptor[Literal[False]] end_color: Alias def __init__( self, - patternType: Incomplete | None = None, - fgColor=..., - bgColor=..., - fill_type: Incomplete | None = None, - start_color: Incomplete | None = None, - end_color: Incomplete | None = None, + patternType: _FillsType | Literal["none"] | None = None, + fgColor: str | Color = ..., + bgColor: str | Color = ..., + fill_type: _FillsType | Literal["none"] | None = None, + start_color: str | Color | None = None, + end_color: str | Color | None = None, ) -> None: ... def to_tree(self, tagname: str | None = None, idx: Incomplete | None = None): ... # type: ignore[override] @@ -89,7 +89,7 @@ class Stop(Serialisable): class StopList(Sequence): expected_type: type[Incomplete] - def __set__(self, obj, values) -> None: ... + def __set__(self, obj: Serialisable | Strict, values) -> None: ... class GradientFill(Fill): tagname: ClassVar[str] @@ -111,5 +111,5 @@ class GradientFill(Fill): bottom: _ConvertibleToFloat = 0, stop=(), ) -> None: ... - def __iter__(self): ... + def __iter__(self) -> Iterator[tuple[str, str]]: ... def to_tree(self, tagname: str | None = None, namespace: str | None = None, idx: Incomplete | None = None): ... # type: ignore[override] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/fonts.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/fonts.pyi index d8ab9e06d..1972fa612 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/fonts.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/fonts.pyi @@ -1,4 +1,3 @@ -from _typeshed import Incomplete from typing import ClassVar from typing_extensions import Final, Literal, Self, TypeAlias @@ -13,6 +12,7 @@ from openpyxl.descriptors.nested import ( _NestedNoneSetParam, ) from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.styles.colors import Color, ColorDescriptor from ..xml._functions_overloads import _HasTagAndGet, _SupportsFindAndIterAndAttribAndText @@ -43,7 +43,7 @@ class Font(Serialisable): u: NestedNoneSet[_FontU] underline: Alias vertAlign: NestedNoneSet[_FontVertAlign] - color: Incomplete + color: ColorDescriptor[Literal[True]] scheme: NestedNoneSet[_FontScheme] tagname: ClassVar[str] __elements__: ClassVar[tuple[str, ...]] @@ -56,7 +56,7 @@ class Font(Serialisable): charset: _HasTagAndGet[_ConvertibleToInt | None] | _ConvertibleToInt | None = None, u: _NestedNoneSetParam[_FontU] = None, strike: _HasTagAndGet[_ConvertibleToBool | None] | _ConvertibleToBool | None = None, - color: Incomplete | None = None, + color: str | Color | None = None, scheme: _NestedNoneSetParam[_FontScheme] = None, family: _HasTagAndGet[_ConvertibleToFloat | None] | _ConvertibleToFloat | None = None, size: _HasTagAndGet[_ConvertibleToFloat] | _ConvertibleToFloat | None = None, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/named_styles.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/named_styles.pyi index aa858f0a7..ed20b5d7a 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/named_styles.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/named_styles.pyi @@ -1,4 +1,5 @@ from _typeshed import Incomplete, Unused +from collections.abc import Iterator from typing import ClassVar from typing_extensions import Literal @@ -37,9 +38,9 @@ class NamedStyle(Serialisable): xfId: Unused = None, ) -> None: ... def __setattr__(self, attr: str, value) -> None: ... - def __iter__(self): ... + def __iter__(self) -> Iterator[tuple[str, str]]: ... @property - def xfId(self): ... + def xfId(self) -> int | None: ... def bind(self, wb) -> None: ... def as_tuple(self): ... def as_xf(self): ... @@ -47,7 +48,7 @@ class NamedStyle(Serialisable): class NamedStyleList(list[Incomplete]): @property - def names(self): ... + def names(self) -> list[str]: ... def __getitem__(self, key): ... def append(self, style) -> None: ... @@ -80,6 +81,6 @@ class _NamedCellStyleList(Serialisable): __attrs__: ClassVar[tuple[str, ...]] def __init__(self, count: Unused = None, cellStyle=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... @property - def names(self): ... + def names(self) -> NamedStyleList: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/numbers.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/numbers.pyi index d23d987c8..746ac403a 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/numbers.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/numbers.pyi @@ -51,7 +51,7 @@ LOCALE_GROUP: Final = r"\[(?!hh?\]|mm?\]|ss?\])[^\]]*\]" STRIP_RE: Final[Pattern[str]] TIMEDELTA_RE: Final[Pattern[str]] -def is_date_format(fmt): ... +def is_date_format(fmt) -> bool: ... def is_timedelta_format(fmt): ... def is_datetime(fmt): ... def is_builtin(fmt): ... @@ -74,5 +74,5 @@ class NumberFormatList(Serialisable): __attrs__: ClassVar[tuple[str, ...]] def __init__(self, count: Unused = None, numFmt=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... def __getitem__(self, idx): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/protection.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/protection.pyi index 7295cbf23..d317a5d46 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/protection.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/protection.pyi @@ -1,10 +1,11 @@ -from _typeshed import Incomplete from typing import ClassVar +from typing_extensions import Literal +from openpyxl.descriptors.base import Bool, _ConvertibleToBool from openpyxl.descriptors.serialisable import Serialisable class Protection(Serialisable): tagname: ClassVar[str] - locked: Incomplete - hidden: Incomplete - def __init__(self, locked: bool = True, hidden: bool = False) -> None: ... + locked: Bool[Literal[False]] + hidden: Bool[Literal[False]] + def __init__(self, locked: _ConvertibleToBool = True, hidden: _ConvertibleToBool = False) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/styleable.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/styleable.pyi index 6753a0222..4dfe4d235 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/styleable.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/styleable.pyi @@ -42,6 +42,6 @@ class StyleableObject: parent: Incomplete def __init__(self, sheet, style_array: Incomplete | None = None) -> None: ... @property - def style_id(self): ... + def style_id(self) -> int: ... @property - def has_style(self): ... + def has_style(self) -> bool: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/stylesheet.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/stylesheet.pyi index b3c1465ad..3d7b94d33 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/stylesheet.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/stylesheet.pyi @@ -47,7 +47,7 @@ class Stylesheet(Serialisable): @classmethod def from_tree(cls, node: _ChildSerialisableTreeElement) -> Self: ... @property - def custom_formats(self): ... + def custom_formats(self) -> dict[int, str]: ... def to_tree(self, tagname: str | None = None, idx: Incomplete | None = None, namespace: str | None = None): ... def apply_stylesheet(archive, wb): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/table.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/table.pyi index e9853be0f..48875a293 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/table.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/styles/table.pyi @@ -77,4 +77,4 @@ class TableStyleList(Serialisable): tableStyle=(), ) -> None: ... @property - def count(self): ... + def count(self) -> int: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/utils/protection.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/utils/protection.pyi index f2b3f73e3..4bcddbe2b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/utils/protection.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/utils/protection.pyi @@ -1 +1 @@ -def hash_password(plaintext_password: str = ""): ... +def hash_password(plaintext_password: str = "") -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/child.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/child.pyi index 827361215..678dcbb1a 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/child.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/child.pyi @@ -3,6 +3,8 @@ from re import Pattern from typing_extensions import Final from openpyxl import _Decodable +from openpyxl.workbook.workbook import Workbook +from openpyxl.worksheet.header_footer import HeaderFooterItem INVALID_TITLE_REGEX: Final[Pattern[str]] @@ -10,38 +12,38 @@ def avoid_duplicate_name(names, value): ... class _WorkbookChild: HeaderFooter: Incomplete - def __init__(self, parent: Incomplete | None = None, title: str | _Decodable | None = None) -> None: ... + def __init__(self, parent: Workbook | None = None, title: str | _Decodable | None = None) -> None: ... @property - def parent(self): ... + def parent(self) -> Workbook | None: ... @property - def encoding(self): ... + def encoding(self) -> str: ... # Will error without a parent. @property def title(self) -> str: ... @title.setter def title(self, value: str | _Decodable) -> None: ... @property - def oddHeader(self): ... + def oddHeader(self) -> HeaderFooterItem | None: ... @oddHeader.setter - def oddHeader(self, value) -> None: ... + def oddHeader(self, value: HeaderFooterItem | None) -> None: ... @property - def oddFooter(self): ... + def oddFooter(self) -> HeaderFooterItem | None: ... @oddFooter.setter - def oddFooter(self, value) -> None: ... + def oddFooter(self, value: HeaderFooterItem | None) -> None: ... @property - def evenHeader(self): ... + def evenHeader(self) -> HeaderFooterItem | None: ... @evenHeader.setter - def evenHeader(self, value) -> None: ... + def evenHeader(self, value: HeaderFooterItem | None) -> None: ... @property - def evenFooter(self): ... + def evenFooter(self) -> HeaderFooterItem | None: ... @evenFooter.setter - def evenFooter(self, value) -> None: ... + def evenFooter(self, value: HeaderFooterItem | None) -> None: ... @property - def firstHeader(self): ... + def firstHeader(self) -> HeaderFooterItem | None: ... @firstHeader.setter - def firstHeader(self, value) -> None: ... + def firstHeader(self, value: HeaderFooterItem | None) -> None: ... @property - def firstFooter(self): ... + def firstFooter(self) -> HeaderFooterItem | None: ... @firstFooter.setter - def firstFooter(self, value) -> None: ... + def firstFooter(self, value: HeaderFooterItem | None) -> None: ... @property - def path(self): ... + def path(self) -> str: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/defined_name.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/defined_name.pyi index 7d3b95867..7ebc83961 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/defined_name.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/defined_name.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete from collections import defaultdict -from collections.abc import Generator +from collections.abc import Generator, Iterator from re import Pattern from typing import ClassVar from typing_extensions import Final, Literal @@ -8,6 +8,7 @@ from typing_extensions import Final, Literal from openpyxl.descriptors import Sequence from openpyxl.descriptors.base import Alias, Bool, Integer, String, _ConvertibleToBool, _ConvertibleToInt from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.formula.tokenizer import _TokenOperandSubtypes, _TokenTypesNotOperand RESERVED: Final[frozenset[str]] RESERVED_REGEX: Final[Pattern[str]] @@ -51,14 +52,14 @@ class DefinedName(Serialisable): attr_text: Incomplete | None = None, ) -> None: ... @property - def type(self): ... + def type(self) -> _TokenTypesNotOperand | _TokenOperandSubtypes: ... @property - def destinations(self) -> Generator[Incomplete, None, None]: ... + def destinations(self) -> Generator[tuple[str, str], None, None]: ... @property - def is_reserved(self): ... + def is_reserved(self) -> str | None: ... @property - def is_external(self): ... - def __iter__(self): ... + def is_external(self) -> bool: ... + def __iter__(self) -> Iterator[tuple[str, str]]: ... class DefinedNameDict(dict[str, DefinedName]): def add(self, value: DefinedName) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/external_link/external.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/external_link/external.pyi index fcd66e68b..ef1f1d578 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/external_link/external.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/external_link/external.pyi @@ -74,6 +74,6 @@ class ExternalLink(Serialisable): ) -> None: ... def to_tree(self): ... @property - def path(self): ... + def path(self) -> str: ... def read_external_link(archive, book_path): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/protection.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/protection.pyi index 236dfceb6..21e3ceeb6 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/protection.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/protection.pyi @@ -1,5 +1,5 @@ from _typeshed import Incomplete -from typing import ClassVar +from typing import ClassVar, overload from typing_extensions import Literal, Self from openpyxl.descriptors.base import Alias, Bool, Integer, String, _ConvertibleToBool, _ConvertibleToInt @@ -46,16 +46,26 @@ class WorkbookProtection(Serialisable): workbookSaltValue: Incomplete | None = None, workbookSpinCount: _ConvertibleToInt | None = None, ) -> None: ... - def set_workbook_password(self, value: str = "", already_hashed: bool = False) -> None: ... + @overload + def set_workbook_password(self, value: str = "", already_hashed: Literal[False] = False) -> None: ... + @overload + def set_workbook_password(self, value: str | None, already_hashed: Literal[True]) -> None: ... + @overload + def set_workbook_password(self, value: str | None = "", *, already_hashed: Literal[True]) -> None: ... @property - def workbookPassword(self): ... + def workbookPassword(self) -> str | None: ... @workbookPassword.setter - def workbookPassword(self, value) -> None: ... - def set_revisions_password(self, value: str = "", already_hashed: bool = False) -> None: ... + def workbookPassword(self, value: str) -> None: ... + @overload + def set_revisions_password(self, value: str = "", already_hashed: Literal[False] = False) -> None: ... + @overload + def set_revisions_password(self, value: str | None, already_hashed: Literal[True]) -> None: ... + @overload + def set_revisions_password(self, value: str | None = "", *, already_hashed: Literal[True]) -> None: ... @property - def revisionsPassword(self): ... + def revisionsPassword(self) -> str | None: ... @revisionsPassword.setter - def revisionsPassword(self, value) -> None: ... + def revisionsPassword(self, value: str) -> None: ... @classmethod def from_tree(cls, node: _SupportsIterAndAttribAndTextAndGet) -> Self: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/web.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/web.pyi index a5c184bc4..a00cd9f55 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/web.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/workbook/web.pyi @@ -57,7 +57,7 @@ class WebPublishObjectList(Serialisable): __elements__: ClassVar[tuple[str, ...]] def __init__(self, count: Unused = None, webPublishObject=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class WebPublishing(Serialisable): tagname: ClassVar[str] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_read_only.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_read_only.pyi index 489cae116..8eba59e18 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_read_only.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_read_only.pyi @@ -1,6 +1,9 @@ from _typeshed import Incomplete +from collections.abc import Generator from openpyxl import _VisibilityType +from openpyxl.cell import _CellValue +from openpyxl.cell.cell import Cell from openpyxl.worksheet.worksheet import Worksheet def read_dimension(source): ... @@ -10,10 +13,10 @@ class ReadOnlyWorksheet: iter_rows = Worksheet.iter_rows # Same as Worksheet.values @property - def values(self): ... + def values(self) -> Generator[tuple[_CellValue, ...], None, None]: ... # Same as Worksheet.rows @property - def rows(self): ... + def rows(self) -> Generator[tuple[Cell, ...], None, None]: ... __getitem__ = Worksheet.__getitem__ __iter__ = Worksheet.__iter__ parent: Incomplete @@ -23,10 +26,10 @@ class ReadOnlyWorksheet: def calculate_dimension(self, force: bool = False): ... def reset_dimensions(self) -> None: ... @property - def min_row(self): ... + def min_row(self) -> int: ... @property - def max_row(self): ... + def max_row(self) -> int | None: ... @property - def min_column(self): ... + def min_column(self) -> int: ... @property - def max_column(self): ... + def max_column(self) -> int | None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_reader.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_reader.pyi index 4d3cf8f0c..d5e0d4169 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_reader.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_reader.pyi @@ -1,6 +1,6 @@ -import datetime from _typeshed import Incomplete from collections.abc import Container, Generator +from datetime import datetime from typing_extensions import Final from openpyxl.cell.rich_text import CellRichText @@ -45,7 +45,7 @@ def parse_richtext_string(element: _ChildSerialisableTreeElement) -> CellRichTex class WorkSheetParser: min_row: Incomplete | None min_col: Incomplete | None - epoch: datetime.datetime + epoch: datetime source: Incomplete shared_strings: Incomplete data_only: bool @@ -73,7 +73,7 @@ class WorkSheetParser: src, shared_strings, data_only: bool = False, - epoch: datetime.datetime = ..., + epoch: datetime = ..., date_formats: Container[Incomplete] = ..., timedelta_formats: Container[Incomplete] = ..., rich_text: bool = False, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_write_only.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_write_only.pyi index 9aec689ac..ffecf3337 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_write_only.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/_write_only.pyi @@ -1,7 +1,7 @@ -from _typeshed import Incomplete from collections.abc import Iterable from openpyxl import _Decodable +from openpyxl.cell.cell import Cell from openpyxl.workbook.child import _WorkbookChild from openpyxl.worksheet.table import TableList from openpyxl.worksheet.worksheet import Worksheet @@ -16,7 +16,7 @@ class WriteOnlyWorksheet(_WorkbookChild): @property def tables(self) -> TableList: ... @property - def print_titles(self) -> str | None: ... + def print_titles(self) -> str: ... @property def print_title_cols(self) -> str | None: ... @print_title_cols.setter @@ -28,15 +28,15 @@ class WriteOnlyWorksheet(_WorkbookChild): @property def freeze_panes(self) -> str | None: ... @freeze_panes.setter - def freeze_panes(self, topLeftCell: Incomplete | None = ...) -> None: ... + def freeze_panes(self, topLeftCell: str | Cell | None = ...) -> None: ... @property - def print_area(self) -> list[str]: ... + def print_area(self) -> str: ... @print_area.setter - def print_area(self, value: str | Iterable[str]) -> None: ... + def print_area(self, value: str | Iterable[str] | None) -> None: ... @property def sheet_view(self): ... def __init__(self, parent, title: str | _Decodable | None) -> None: ... @property - def closed(self): ... + def closed(self) -> bool: ... def close(self) -> None: ... def append(self, row) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/cell_range.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/cell_range.pyi index 0ef744d1b..f54fc91bc 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/cell_range.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/cell_range.pyi @@ -1,6 +1,7 @@ from _typeshed import Incomplete, Unused -from collections.abc import Generator -from typing import overload +from collections.abc import Generator, Iterator +from itertools import product +from typing import Any, overload from typing_extensions import Literal from openpyxl.descriptors import Strict @@ -36,15 +37,15 @@ class CellRange(Serialisable): title: str | None = None, ) -> None: ... @property - def bounds(self): ... + def bounds(self) -> tuple[int, int, int, int]: ... @property - def coord(self): ... + def coord(self) -> str: ... @property - def rows(self) -> Generator[Incomplete, None, None]: ... + def rows(self) -> Generator[list[tuple[int, int]], None, None]: ... @property - def cols(self) -> Generator[Incomplete, None, None]: ... + def cols(self) -> Generator[list[tuple[int, int]], None, None]: ... @property - def cells(self): ... + def cells(self) -> product[tuple[int, int]]: ... def __copy__(self): ... def shift(self, col_shift: int = 0, row_shift: int = 0) -> None: ... def __ne__(self, other): ... @@ -61,19 +62,20 @@ class CellRange(Serialisable): __and__ = intersection def union(self, other): ... __or__ = union - def __iter__(self): ... + # Iterates over class attributes. Value could be anything. + def __iter__(self) -> Iterator[tuple[str, Any]]: ... def expand(self, right: int = 0, down: int = 0, left: int = 0, up: int = 0) -> None: ... def shrink(self, right: int = 0, bottom: int = 0, left: int = 0, top: int = 0) -> None: ... @property - def size(self): ... + def size(self) -> dict[str, int]: ... @property - def top(self): ... + def top(self) -> list[tuple[int, int]]: ... @property - def bottom(self): ... + def bottom(self) -> list[tuple[int, int]]: ... @property - def left(self): ... + def left(self) -> list[tuple[int, int]]: ... @property - def right(self): ... + def right(self) -> list[tuple[int, int]]: ... class MultiCellRange(Strict): ranges: Incomplete @@ -86,5 +88,5 @@ class MultiCellRange(Strict): def __ne__(self, other): ... def __bool__(self) -> bool: ... def remove(self, coord) -> None: ... - def __iter__(self): ... + def __iter__(self) -> Iterator[CellRange]: ... def __copy__(self): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/datavalidation.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/datavalidation.pyi index 157a3bad2..be101133b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/datavalidation.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/datavalidation.pyi @@ -100,7 +100,7 @@ class DataValidationList(Serialisable): dataValidation=(), ) -> None: ... @property - def count(self): ... + def count(self) -> int: ... def __len__(self) -> int: ... def append(self, dv) -> None: ... def to_tree(self, tagname: str | None = None): ... # type: ignore[override] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/dimensions.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/dimensions.pyi index 290a1b926..b33b68b42 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/dimensions.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/dimensions.pyi @@ -148,4 +148,4 @@ class SheetDimension(Serialisable): ref: String[Literal[False]] def __init__(self, ref: str) -> None: ... @property - def boundaries(self): ... + def boundaries(self) -> tuple[int, int, int, int]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/merge.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/merge.pyi index 491fb7d10..8f2120a02 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/merge.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/merge.pyi @@ -9,7 +9,7 @@ class MergeCell(CellRange): tagname: ClassVar[str] # Same as CellRange.coord @property - def ref(self): ... + def ref(self) -> str: ... __attrs__: ClassVar[tuple[str, ...]] def __init__(self, ref: Incomplete | None = None) -> None: ... def __copy__(self): ... @@ -23,7 +23,7 @@ class MergeCells(Serialisable): __attrs__: ClassVar[tuple[str, ...]] def __init__(self, count: Unused = None, mergeCell=()) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class MergedCellRange(CellRange): ws: Incomplete diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/page.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/page.pyi index 2538cabf0..9fe49afa4 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/page.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/page.pyi @@ -4,6 +4,7 @@ from typing_extensions import Literal, Self, TypeAlias from openpyxl.descriptors.base import Bool, Float, Integer, NoneSet, _ConvertibleToBool, _ConvertibleToFloat, _ConvertibleToInt from openpyxl.descriptors.serialisable import Serialisable, _ChildSerialisableTreeElement +from openpyxl.worksheet.properties import PageSetupProperties _PrintPageSetupOrientation: TypeAlias = Literal["default", "portrait", "landscape"] _PrintPageSetupPageOrder: TypeAlias = Literal["downThenOver", "overThenDown"] @@ -56,15 +57,15 @@ class PrintPageSetup(Serialisable): ) -> None: ... def __bool__(self) -> bool: ... @property - def sheet_properties(self): ... + def sheet_properties(self) -> PageSetupProperties | None: ... @property - def fitToPage(self): ... + def fitToPage(self) -> bool | None: ... @fitToPage.setter - def fitToPage(self, value) -> None: ... + def fitToPage(self, value: _ConvertibleToBool | None) -> None: ... @property - def autoPageBreaks(self): ... + def autoPageBreaks(self) -> bool | None: ... @autoPageBreaks.setter - def autoPageBreaks(self, value) -> None: ... + def autoPageBreaks(self, value: _ConvertibleToBool | None) -> None: ... @classmethod def from_tree(cls, node: _ChildSerialisableTreeElement) -> Self: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/pagebreak.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/pagebreak.pyi index aaa8b55d4..7b6a1f6da 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/pagebreak.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/pagebreak.pyi @@ -33,9 +33,9 @@ class RowBreak(Serialisable): def __bool__(self) -> bool: ... def __len__(self) -> int: ... @property - def count(self): ... + def count(self) -> int: ... @property - def manualBreakCount(self): ... + def manualBreakCount(self) -> int: ... def append(self, brk: Incomplete | None = None) -> None: ... PageBreak = RowBreak diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/properties.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/properties.pyi index dcc4fdef2..3a2195906 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/properties.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/properties.pyi @@ -1,9 +1,9 @@ -from _typeshed import Incomplete from typing import ClassVar from typing_extensions import Literal from openpyxl.descriptors.base import Bool, String, Typed, _ConvertibleToBool from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.styles.colors import Color, ColorDescriptor class Outline(Serialisable): tagname: ClassVar[str] @@ -36,7 +36,7 @@ class WorksheetProperties(Serialisable): syncVertical: Bool[Literal[True]] transitionEvaluation: Bool[Literal[True]] transitionEntry: Bool[Literal[True]] - tabColor: Incomplete + tabColor: ColorDescriptor[Literal[True]] outlinePr: Typed[Outline, Literal[True]] pageSetUpPr: Typed[PageSetupProperties, Literal[True]] __elements__: ClassVar[tuple[str, ...]] @@ -51,7 +51,7 @@ class WorksheetProperties(Serialisable): syncVertical: _ConvertibleToBool | None = None, transitionEvaluation: _ConvertibleToBool | None = None, transitionEntry: _ConvertibleToBool | None = None, - tabColor: Incomplete | None = None, + tabColor: str | Color | None = None, outlinePr: Outline | None = None, pageSetUpPr: PageSetupProperties | None = None, ) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/protection.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/protection.pyi index 90ddad654..bac5c14af 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/protection.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/protection.pyi @@ -1,16 +1,21 @@ from _typeshed import Incomplete -from typing import ClassVar +from typing import ClassVar, overload from typing_extensions import Literal from openpyxl.descriptors.base import Alias, Bool, Integer, String, _ConvertibleToBool, _ConvertibleToInt from openpyxl.descriptors.serialisable import Serialisable class _Protected: - def set_password(self, value: str = "", already_hashed: bool = False) -> None: ... + @overload + def set_password(self, value: str = "", already_hashed: Literal[False] = False) -> None: ... + @overload + def set_password(self, value: str | None, already_hashed: Literal[True]) -> None: ... + @overload + def set_password(self, value: str | None = "", *, already_hashed: Literal[True]) -> None: ... @property - def password(self): ... + def password(self) -> str | None: ... @password.setter - def password(self, value) -> None: ... + def password(self, value: str) -> None: ... class SheetProtection(Serialisable, _Protected): tagname: ClassVar[str] @@ -61,7 +66,12 @@ class SheetProtection(Serialisable, _Protected): spinCount: _ConvertibleToInt | None = None, hashValue: Incomplete | None = None, ) -> None: ... - def set_password(self, value: str = "", already_hashed: bool = False) -> None: ... + @overload + def set_password(self, value: str = "", already_hashed: Literal[False] = False) -> None: ... + @overload + def set_password(self, value: str | None, already_hashed: Literal[True]) -> None: ... + @overload + def set_password(self, value: str | None = "", *, already_hashed: Literal[True]) -> None: ... def enable(self) -> None: ... def disable(self) -> None: ... def __bool__(self) -> bool: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/scenario.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/scenario.pyi index cb5c04e46..6229287a5 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/scenario.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/scenario.pyi @@ -76,7 +76,7 @@ class Scenario(Serialisable): comment: str | None = None, ) -> None: ... @property - def count(self): ... + def count(self) -> int: ... class ScenarioList(Serialisable): tagname: ClassVar[str] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/table.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/table.pyi index 03f0e0ffb..f87ba4031 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/table.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/table.pyi @@ -1,4 +1,5 @@ from _typeshed import Incomplete, Unused +from collections.abc import Iterator from typing import ClassVar, overload from typing_extensions import Final, Literal, Self, TypeAlias @@ -127,7 +128,7 @@ class TableColumn(Serialisable): xmlColumnPr: XMLColumnProps | None = None, extLst: ExtensionList | None = None, ) -> None: ... - def __iter__(self): ... + def __iter__(self) -> Iterator[tuple[str, str]]: ... @classmethod def from_tree(cls, node: _ChildSerialisableTreeElement) -> Self: ... @@ -197,9 +198,9 @@ class Table(Serialisable): ) -> None: ... def to_tree(self): ... @property - def path(self): ... + def path(self) -> str: ... @property - def column_names(self): ... + def column_names(self) -> list[str]: ... class TablePartList(Serialisable): tagname: ClassVar[str] @@ -211,7 +212,7 @@ class TablePartList(Serialisable): def __init__(self, count: Unused = None, tablePart=()) -> None: ... def append(self, part) -> None: ... @property - def count(self): ... + def count(self) -> int: ... def __bool__(self) -> bool: ... class TableList(dict[Incomplete, Incomplete]): diff --git a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi index b0216d0ca..3ce24862b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi @@ -1,11 +1,12 @@ from _typeshed import Incomplete from collections.abc import Generator, Iterable, Iterator from datetime import datetime -from typing import Any, overload +from typing import Any, NoReturn, overload from typing_extensions import Final, Literal from openpyxl import _Decodable, _VisibilityType -from openpyxl.cell.cell import Cell, _CellValue +from openpyxl.cell import _CellValue +from openpyxl.cell.cell import Cell from openpyxl.formatting.formatting import ConditionalFormattingList from openpyxl.workbook.child import _WorkbookChild from openpyxl.workbook.defined_name import DefinedNameDict @@ -71,24 +72,24 @@ class Worksheet(_WorkbookChild): @property def sheet_view(self) -> SheetView: ... @property - def selected_cell(self) -> Cell: ... + def selected_cell(self) -> str | None: ... @property - def active_cell(self) -> Cell: ... + def active_cell(self) -> str | None: ... @property - def array_formulae(self) -> dict[Incomplete, Incomplete]: ... + def array_formulae(self) -> dict[str, str]: ... @property - def show_gridlines(self) -> bool: ... + def show_gridlines(self) -> bool | None: ... @property def freeze_panes(self) -> str | None: ... @freeze_panes.setter - def freeze_panes(self, topLeftCell: Incomplete | None = ...) -> None: ... + def freeze_panes(self, topLeftCell: str | Cell | None = ...) -> None: ... def cell(self, row: int, column: int, value: str | None = None) -> Cell: ... @overload def __getitem__(self, key: int | slice) -> tuple[Cell, ...]: ... @overload - def __getitem__(self, key: str) -> Any: ... # Cell | tuple[Cell, ...] + def __getitem__(self, key: str) -> Any: ... # AnyOf[Cell, tuple[Cell, ...]] def __setitem__(self, key: str, value: str) -> None: ... - def __iter__(self) -> Iterator[Cell]: ... + def __iter__(self) -> Iterator[tuple[Cell, ...]]: ... def __delitem__(self, key: str) -> None: ... @property def min_row(self) -> int: ... @@ -180,7 +181,7 @@ class Worksheet(_WorkbookChild): values_only: bool, ) -> Generator[tuple[Cell | str | float | datetime | None, ...], None, None]: ... @property - def columns(self) -> Generator[Cell, None, None]: ... + def columns(self) -> Generator[tuple[Cell, ...], None, None]: ... def set_printer_settings( self, paper_size: int | None, orientation: None | Literal["default", "portrait", "landscape"] ) -> None: ... @@ -199,8 +200,9 @@ class Worksheet(_WorkbookChild): end_row: int | None = None, end_column: int | None = None, ) -> None: ... + # deprecated: Will always raise: TypeError: 'set' object is not subscriptable @property - def merged_cell_ranges(self) -> list[CellRange]: ... + def merged_cell_ranges(self) -> NoReturn: ... def unmerge_cells( self, range_string: str | None = None, @@ -224,8 +226,8 @@ class Worksheet(_WorkbookChild): @print_title_cols.setter def print_title_cols(self, cols: str | None) -> None: ... @property - def print_titles(self) -> str | None: ... + def print_titles(self) -> str: ... @property - def print_area(self) -> list[str]: ... + def print_area(self) -> str: ... @print_area.setter - def print_area(self, value: str | Iterable[str]) -> None: ... + def print_area(self, value: str | Iterable[str] | None) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/peewee/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/peewee/METADATA.toml index 5adfe58b8..cabd85fab 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/peewee/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/peewee/METADATA.toml @@ -1,2 +1,2 @@ -version = "3.16.*" +version = "3.17.*" upstream_repository = "https://github.com/coleifer/peewee" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/peewee/peewee.pyi b/packages/pyright-internal/typeshed-fallback/stubs/peewee/peewee.pyi index a59530702..8f2b35474 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/peewee/peewee.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/peewee/peewee.pyi @@ -2,9 +2,9 @@ import itertools import logging import threading from _typeshed import Incomplete, SupportsKeysAndGetItem -from collections.abc import Generator, Iterable +from collections.abc import Callable, Generator, Iterable from types import TracebackType -from typing import ClassVar, NamedTuple, TypeVar +from typing import Any, ClassVar, NamedTuple, TypeVar from typing_extensions import Self class NullHandler(logging.Handler): @@ -18,6 +18,7 @@ long = int izip_longest = itertools.zip_longest _VT = TypeVar("_VT") +_F = TypeVar("_F", bound=Callable[..., Any]) class attrdict(dict[str, _VT]): def __getattr__(self, attr: str) -> _VT: ... @@ -116,9 +117,10 @@ class Node: def unwrap(self): ... class ColumnFactory: - node: Incomplete - def __init__(self, node) -> None: ... - def __getattr__(self, attr: str): ... + node: Node + def __init__(self, node: Node) -> None: ... + def __getattr__(self, attr: str) -> Column: ... + def __getitem__(self, attr: str) -> Column: ... class _DynamicColumn: def __get__(self, instance, instance_type: Incomplete | None = ...): ... @@ -880,8 +882,8 @@ class SqliteDatabase(Database): def aggregate(self, name: Incomplete | None = ..., num_params: int = ...): ... def register_collation(self, fn, name: Incomplete | None = ...): ... def collation(self, name: Incomplete | None = ...): ... - def register_function(self, fn, name: Incomplete | None = ..., num_params: int = ...) -> None: ... - def func(self, name: Incomplete | None = ..., num_params: int = ...): ... + def register_function(self, fn, name: str | None = None, num_params: int = -1, deterministic: bool | None = None) -> None: ... + def func(self, name: str | None = None, num_params: int = -1, deterministic: bool | None = None) -> Callable[[_F], _F]: ... def register_window_function(self, klass, name: Incomplete | None = ..., num_params: int = ...) -> None: ... def window_function(self, name: Incomplete | None = ..., num_params: int = ...): ... def register_table_function(self, klass, name: Incomplete | None = ...) -> None: ... @@ -934,6 +936,7 @@ class PostgresqlDatabase(Database): def is_connection_usable(self): ... def last_insert_id(self, cursor, query_type: Incomplete | None = ...): ... def rows_affected(self, cursor): ... + def begin(self, isolation_level: str | None = None) -> None: ... def get_tables(self, schema: Incomplete | None = ...): ... def get_views(self, schema: Incomplete | None = ...): ... def get_indexes(self, table, schema: Incomplete | None = ...): ... @@ -967,6 +970,7 @@ class MySQLDatabase(Database): def init(self, database, **kwargs) -> None: ... def is_connection_usable(self): ... def default_values_insert(self, ctx): ... + def begin(self, isolation_level: str | None = None) -> None: ... def get_tables(self, schema: Incomplete | None = ...): ... def get_views(self, schema: Incomplete | None = ...): ... def get_indexes(self, table, schema: Incomplete | None = ...): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/protobuf/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/protobuf/METADATA.toml index 01c72968f..7ee1107f0 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/protobuf/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/protobuf/METADATA.toml @@ -1,6 +1,6 @@ version = "4.24.*" upstream_repository = "https://github.com/protocolbuffers/protobuf" -extra_description = "Generated with aid from [mypy-protobuf](https://github.com/nipunn1313/mypy-protobuf) v3.4.0" +extra_description = "Generated using [mypy-protobuf==3.5.0](https://github.com/nipunn1313/mypy-protobuf/tree/v3.5.0) on protobuf==4.21.8" partial_stub = true [tool.stubtest] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/compiler/plugin_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/compiler/plugin_pb2.pyi index 2c54ee220..a2e15b129 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/compiler/plugin_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/compiler/plugin_pb2.pyi @@ -125,7 +125,7 @@ class CodeGeneratorResponse(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _FeatureEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[CodeGeneratorResponse._Feature.ValueType], builtins.type): # noqa: F821 + class _FeatureEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[CodeGeneratorResponse._Feature.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor FEATURE_NONE: CodeGeneratorResponse._Feature.ValueType # 0 FEATURE_PROTO3_OPTIONAL: CodeGeneratorResponse._Feature.ValueType # 1 diff --git a/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/descriptor_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/descriptor_pb2.pyi index e37479b5c..bda40e15e 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/descriptor_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/descriptor_pb2.pyi @@ -252,7 +252,7 @@ class FieldDescriptorProto(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FieldDescriptorProto._Type.ValueType], builtins.type): # noqa: F821 + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FieldDescriptorProto._Type.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor TYPE_DOUBLE: FieldDescriptorProto._Type.ValueType # 1 """0 is reserved for errors. @@ -333,7 +333,7 @@ class FieldDescriptorProto(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _LabelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FieldDescriptorProto._Label.ValueType], builtins.type): # noqa: F821 + class _LabelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FieldDescriptorProto._Label.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor LABEL_OPTIONAL: FieldDescriptorProto._Label.ValueType # 1 """0 is reserved for errors""" @@ -654,7 +654,7 @@ class FileOptions(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _OptimizeModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FileOptions._OptimizeMode.ValueType], builtins.type): # noqa: F821 + class _OptimizeModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FileOptions._OptimizeMode.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor SPEED: FileOptions._OptimizeMode.ValueType # 1 """Generate complete code for parsing, serialization,""" @@ -916,7 +916,7 @@ class FieldOptions(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _CTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FieldOptions._CType.ValueType], builtins.type): # noqa: F821 + class _CTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FieldOptions._CType.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor STRING: FieldOptions._CType.ValueType # 0 """Default mode.""" @@ -933,7 +933,7 @@ class FieldOptions(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _JSTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FieldOptions._JSType.ValueType], builtins.type): # noqa: F821 + class _JSTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FieldOptions._JSType.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor JS_NORMAL: FieldOptions._JSType.ValueType # 0 """Use the default type.""" @@ -1167,7 +1167,7 @@ class MethodOptions(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _IdempotencyLevelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[MethodOptions._IdempotencyLevel.ValueType], builtins.type): # noqa: F821 + class _IdempotencyLevelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[MethodOptions._IdempotencyLevel.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor IDEMPOTENCY_UNKNOWN: MethodOptions._IdempotencyLevel.ValueType # 0 NO_SIDE_EFFECTS: MethodOptions._IdempotencyLevel.ValueType # 1 diff --git a/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/type_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/type_pb2.pyi index 5071cdf65..c66cd6311 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/type_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/protobuf/google/protobuf/type_pb2.pyi @@ -122,7 +122,7 @@ class Field(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _KindEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Field._Kind.ValueType], builtins.type): # noqa: F821 + class _KindEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Field._Kind.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor TYPE_UNKNOWN: Field._Kind.ValueType # 0 """Field type unknown.""" @@ -209,7 +209,7 @@ class Field(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _CardinalityEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Field._Cardinality.ValueType], builtins.type): # noqa: F821 + class _CardinalityEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Field._Cardinality.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor CARDINALITY_UNKNOWN: Field._Cardinality.ValueType # 0 """For fields with unknown cardinality.""" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_linux.pyi b/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_linux.pyi index d204ef7ae..72c51e0de 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_linux.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_linux.pyi @@ -5,6 +5,7 @@ DUPLEX_HALF: int DUPLEX_UNKNOWN: int version: int +def check_pid_range(__pid: int) -> None: ... def disk_partitions(*args, **kwargs) -> Any: ... def linux_sysinfo(*args, **kwargs) -> Any: ... def net_if_duplex_speed(*args, **kwargs) -> Any: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_osx.pyi b/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_osx.pyi index 2578efca4..c027e4394 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_osx.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_osx.pyi @@ -19,9 +19,8 @@ TCPS_SYN_SENT: int TCPS_TIME_WAIT: int version: int -class ZombieProcessError(Exception): ... - def boot_time(*args, **kwargs) -> Any: ... +def check_pid_range(__pid: int) -> None: ... def cpu_count_cores(*args, **kwargs) -> Any: ... def cpu_count_logical(*args, **kwargs) -> Any: ... def cpu_freq(*args, **kwargs) -> Any: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_windows.pyi b/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_windows.pyi index 0ce552766..3f3245d45 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_windows.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/psutil/psutil/_psutil_windows.pyi @@ -35,6 +35,7 @@ class TimeoutExpired(Exception): ... def QueryDosDevice(*args, **kwargs): ... # incomplete def boot_time(*args, **kwargs): ... # incomplete +def check_pid_range(__pid: int) -> None: ... def cpu_count_cores(*args, **kwargs): ... # incomplete def cpu_count_logical(*args, **kwargs): ... # incomplete def cpu_freq(*args, **kwargs): ... # incomplete diff --git a/packages/pyright-internal/typeshed-fallback/stubs/psycopg2/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/psycopg2/METADATA.toml index a49a94bb3..017299847 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/psycopg2/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/psycopg2/METADATA.toml @@ -1,6 +1,3 @@ version = "2.9.*" upstream_repository = "https://github.com/psycopg/psycopg2" -partial_stub = true - -[tool.stubtest] -ignore_missing_stub = false +partial_stub = false diff --git a/packages/pyright-internal/typeshed-fallback/stubs/psycopg2/psycopg2/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/psycopg2/psycopg2/__init__.pyi index da21d947b..2d3cb10f1 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/psycopg2/psycopg2/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/psycopg2/psycopg2/__init__.pyi @@ -1,7 +1,7 @@ from collections.abc import Callable from typing import Any, TypeVar, overload -# connection and cursor not available at runtime +from psycopg2 import errors as errors, extensions as extensions from psycopg2._psycopg import ( BINARY as BINARY, DATETIME as DATETIME, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/METADATA.toml index 3effa864a..c1210224d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/METADATA.toml @@ -1,2 +1,2 @@ -version = "0.4.*" +version = "0.5.*" upstream_repository = "https://github.com/pyasn1/pyasn1" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/__init__.pyi index e69de29bb..a578d2b81 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/__init__.pyi @@ -0,0 +1,3 @@ +from typing_extensions import Final + +__version__: Final[str] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/decoder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/decoder.pyi index 3e5e0eb6a..32149c41b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/decoder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/decoder.pyi @@ -6,7 +6,9 @@ from pyasn1.type import base, char, univ, useful from pyasn1.type.base import Asn1Type from pyasn1.type.tag import TagSet -class AbstractDecoder: +__all__ = ["StreamingDecoder", "Decoder", "decode"] + +class AbstractPayloadDecoder: protoComponent: Asn1Type | None @abstractmethod def valueDecoder( @@ -33,11 +35,11 @@ class AbstractDecoder: **options, ) -> None: ... -class AbstractSimpleDecoder(AbstractDecoder, metaclass=ABCMeta): +class AbstractSimplePayloadDecoder(AbstractPayloadDecoder, metaclass=ABCMeta): @staticmethod - def substrateCollector(asn1Object, substrate, length): ... + def substrateCollector(asn1Object, substrate, length, options): ... -class ExplicitTagDecoder(AbstractSimpleDecoder): +class RawPayloadDecoder(AbstractSimplePayloadDecoder): protoComponent: univ.Any def valueDecoder( self, @@ -62,7 +64,7 @@ class ExplicitTagDecoder(AbstractSimpleDecoder): **options, ): ... -class IntegerDecoder(AbstractSimpleDecoder): +class IntegerPayloadDecoder(AbstractSimplePayloadDecoder): protoComponent: univ.Integer def valueDecoder( self, @@ -76,10 +78,10 @@ class IntegerDecoder(AbstractSimpleDecoder): **options, ): ... -class BooleanDecoder(IntegerDecoder): +class BooleanPayloadDecoder(IntegerPayloadDecoder): protoComponent: univ.Boolean -class BitStringDecoder(AbstractSimpleDecoder): +class BitStringPayloadDecoder(AbstractSimplePayloadDecoder): protoComponent: univ.BitString supportConstructedForm: bool def valueDecoder( @@ -105,7 +107,7 @@ class BitStringDecoder(AbstractSimpleDecoder): **options, ): ... -class OctetStringDecoder(AbstractSimpleDecoder): +class OctetStringPayloadDecoder(AbstractSimplePayloadDecoder): protoComponent: univ.OctetString supportConstructedForm: bool def valueDecoder( @@ -131,7 +133,7 @@ class OctetStringDecoder(AbstractSimpleDecoder): **options, ): ... -class NullDecoder(AbstractSimpleDecoder): +class NullPayloadDecoder(AbstractSimplePayloadDecoder): protoComponent: univ.Null def valueDecoder( self, @@ -145,7 +147,7 @@ class NullDecoder(AbstractSimpleDecoder): **options, ): ... -class ObjectIdentifierDecoder(AbstractSimpleDecoder): +class ObjectIdentifierPayloadDecoder(AbstractSimplePayloadDecoder): protoComponent: univ.ObjectIdentifier def valueDecoder( self, @@ -159,7 +161,7 @@ class ObjectIdentifierDecoder(AbstractSimpleDecoder): **options, ): ... -class RealDecoder(AbstractSimpleDecoder): +class RealPayloadDecoder(AbstractSimplePayloadDecoder): protoComponent: univ.Real def valueDecoder( self, @@ -173,10 +175,10 @@ class RealDecoder(AbstractSimpleDecoder): **options, ): ... -class AbstractConstructedDecoder(AbstractDecoder, metaclass=ABCMeta): +class AbstractConstructedPayloadDecoder(AbstractPayloadDecoder, metaclass=ABCMeta): protoComponent: base.ConstructedAsn1Type | None -class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): +class ConstructedPayloadDecoderBase(AbstractConstructedPayloadDecoder): protoRecordComponent: univ.SequenceAndSetBase | None protoSequenceComponent: univ.SequenceOfAndSetOfBase | None def valueDecoder( @@ -202,27 +204,27 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): **options, ): ... -class SequenceOrSequenceOfDecoder(UniversalConstructedTypeDecoder): +class SequenceOrSequenceOfPayloadDecoder(ConstructedPayloadDecoderBase): protoRecordComponent: univ.Sequence protoSequenceComponent: univ.SequenceOf -class SequenceDecoder(SequenceOrSequenceOfDecoder): +class SequencePayloadDecoder(SequenceOrSequenceOfPayloadDecoder): protoComponent: univ.Sequence -class SequenceOfDecoder(SequenceOrSequenceOfDecoder): +class SequenceOfPayloadDecoder(SequenceOrSequenceOfPayloadDecoder): protoComponent: univ.SequenceOf -class SetOrSetOfDecoder(UniversalConstructedTypeDecoder): +class SetOrSetOfPayloadDecoder(ConstructedPayloadDecoderBase): protoRecordComponent: univ.Set protoSequenceComponent: univ.SetOf -class SetDecoder(SetOrSetOfDecoder): +class SetPayloadDecoder(SetOrSetOfPayloadDecoder): protoComponent: univ.Set -class SetOfDecoder(SetOrSetOfDecoder): +class SetOfPayloadDecoder(SetOrSetOfPayloadDecoder): protoComponent: univ.SetOf -class ChoiceDecoder(AbstractConstructedDecoder): +class ChoicePayloadDecoder(AbstractConstructedPayloadDecoder): protoComponent: univ.Choice def valueDecoder( self, @@ -247,7 +249,7 @@ class ChoiceDecoder(AbstractConstructedDecoder): **options, ): ... -class AnyDecoder(AbstractSimpleDecoder): +class AnyPayloadDecoder(AbstractSimplePayloadDecoder): protoComponent: univ.Any def valueDecoder( self, @@ -272,53 +274,61 @@ class AnyDecoder(AbstractSimpleDecoder): **options, ): ... -class UTF8StringDecoder(OctetStringDecoder): +class UTF8StringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.UTF8String -class NumericStringDecoder(OctetStringDecoder): +class NumericStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.NumericString -class PrintableStringDecoder(OctetStringDecoder): +class PrintableStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.PrintableString -class TeletexStringDecoder(OctetStringDecoder): +class TeletexStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.TeletexString -class VideotexStringDecoder(OctetStringDecoder): +class VideotexStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.VideotexString -class IA5StringDecoder(OctetStringDecoder): +class IA5StringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.IA5String -class GraphicStringDecoder(OctetStringDecoder): +class GraphicStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.GraphicString -class VisibleStringDecoder(OctetStringDecoder): +class VisibleStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.VisibleString -class GeneralStringDecoder(OctetStringDecoder): +class GeneralStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.GeneralString -class UniversalStringDecoder(OctetStringDecoder): +class UniversalStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.UniversalString -class BMPStringDecoder(OctetStringDecoder): +class BMPStringPayloadDecoder(OctetStringPayloadDecoder): protoComponent: char.BMPString -class ObjectDescriptorDecoder(OctetStringDecoder): +class ObjectDescriptorPayloadDecoder(OctetStringPayloadDecoder): protoComponent: useful.ObjectDescriptor -class GeneralizedTimeDecoder(OctetStringDecoder): +class GeneralizedTimePayloadDecoder(OctetStringPayloadDecoder): protoComponent: useful.GeneralizedTime -class UTCTimeDecoder(OctetStringDecoder): +class UTCTimePayloadDecoder(OctetStringPayloadDecoder): protoComponent: useful.UTCTime -class Decoder: +TAG_MAP: dict[TagSet, AbstractPayloadDecoder] +TYPE_MAP: dict[int, AbstractPayloadDecoder] +# deprecated aliases +tagMap = TAG_MAP +typeMap = TYPE_MAP + +class SingleItemDecoder: defaultErrorState: int - defaultRawDecoder: AnyDecoder + defaultRawDecoder: AnyPayloadDecoder supportIndefLength: bool - def __init__(self, tagMap, typeMap={}) -> None: ... + TAG_MAP: dict[TagSet, AbstractPayloadDecoder] + TYPE_MAP: dict[int, AbstractPayloadDecoder] + def __init__(self, tagMap=..., typeMap=..., **ignored: Unused) -> None: ... def __call__( self, substrate, @@ -332,3 +342,15 @@ class Decoder: ): ... decode: Decoder + +class StreamingDecoder: + SINGLE_ITEM_DECODER: type[SingleItemDecoder] + + def __init__(self, substrate, asn1Spec=None, tagMap=..., typeMap=..., **ignored: Unused) -> None: ... + def __iter__(self): ... + +class Decoder: + STREAMING_DECODER: type[StreamingDecoder] + + @classmethod + def __call__(cls, substrate, asn1Spec=None, tagMap=..., typeMap=..., **ignored: Unused): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/encoder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/encoder.pyi index d9ed6218d..8a78123b4 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/encoder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/encoder.pyi @@ -1,7 +1,10 @@ -from _typeshed import Incomplete +from _typeshed import Incomplete, Unused from abc import abstractmethod from pyasn1.type.base import Asn1Type +from pyasn1.type.tag import TagSet + +__all__ = ["Encoder", "encode"] class AbstractItemEncoder: supportIndefLenMode: bool @@ -58,10 +61,25 @@ class ChoiceEncoder(AbstractItemEncoder): class AnyEncoder(OctetStringEncoder): def encodeValue(self, value, asn1Spec, encodeFun, **options): ... -class Encoder: +TAG_MAP: dict[TagSet, AbstractItemEncoder] +TYPE_MAP: dict[int, AbstractItemEncoder] +# deprecated aliases +tagMap = TAG_MAP +typeMap = TYPE_MAP + +class SingleItemEncoder: fixedDefLengthMode: bool | None fixedChunkSize: int | None - def __init__(self, tagMap, typeMap={}) -> None: ... + TAG_MAP: dict[TagSet, AbstractItemEncoder] + TYPE_MAP: dict[int, AbstractItemEncoder] + + def __init__(self, tagMap=..., typeMap=..., **ignored: Unused) -> None: ... def __call__(self, value, asn1Spec: Asn1Type | None = None, **options): ... +class Encoder: + SINGLE_ITEM_ENCODER: type[SingleItemEncoder] + + def __init__(self, tagMap=..., typeMap=..., **options: Unused) -> None: ... + def __call__(self, pyObject, asn1Spec: Asn1Type | None = None, **options): ... + encode: Encoder diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/eoo.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/eoo.pyi index b34fb621f..00375f576 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/eoo.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/ber/eoo.pyi @@ -1,6 +1,8 @@ from pyasn1.type import base from pyasn1.type.tag import TagSet +__all__ = ["endOfOctets"] + class EndOfOctets(base.SimpleAsn1Type): defaultValue: int tagSet: TagSet diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/cer/decoder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/cer/decoder.pyi index 024d3509e..f847313ad 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/cer/decoder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/cer/decoder.pyi @@ -4,7 +4,9 @@ from pyasn1.codec.ber import decoder from pyasn1.type import univ from pyasn1.type.tag import TagSet -class BooleanDecoder(decoder.AbstractSimpleDecoder): +__all__ = ["decode", "StreamingDecoder"] + +class BooleanPayloadDecoder(decoder.AbstractSimplePayloadDecoder): protoComponent: univ.Boolean def valueDecoder( self, @@ -18,10 +20,24 @@ class BooleanDecoder(decoder.AbstractSimpleDecoder): **options, ): ... -BitStringDecoder = decoder.BitStringDecoder -OctetStringDecoder = decoder.OctetStringDecoder -RealDecoder = decoder.RealDecoder +BitStringPayloadDecoder = decoder.BitStringPayloadDecoder +OctetStringPayloadDecoder = decoder.OctetStringPayloadDecoder +RealPayloadDecoder = decoder.RealPayloadDecoder + +TAG_MAP: dict[TagSet, decoder.AbstractPayloadDecoder] +TYPE_MAP: dict[int, decoder.AbstractPayloadDecoder] +# deprecated aliases +tagMap = TAG_MAP +typeMap = TYPE_MAP + +class SingleItemDecoder(decoder.SingleItemDecoder): + TAG_MAP: dict[TagSet, decoder.AbstractPayloadDecoder] + TYPE_MAP: dict[int, decoder.AbstractPayloadDecoder] + +class StreamingDecoder(decoder.StreamingDecoder): + SINGLE_ITEM_DECODER: type[SingleItemDecoder] -class Decoder(decoder.Decoder): ... +class Decoder(decoder.Decoder): + STREAMING_DECODER: type[StreamingDecoder] decode: Decoder diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/cer/encoder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/cer/encoder.pyi index 3b01db7d4..25552d917 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/cer/encoder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/cer/encoder.pyi @@ -1,6 +1,9 @@ from typing import ClassVar from pyasn1.codec.ber import encoder +from pyasn1.type.tag import TagSet + +__all__ = ["Encoder", "encode"] class BooleanEncoder(encoder.IntegerEncoder): def encodeValue(self, value, asn1Spec, encodeFun, **options): ... @@ -33,8 +36,20 @@ class SetEncoder(encoder.SequenceEncoder): class SequenceEncoder(encoder.SequenceEncoder): omitEmptyOptionals: bool -class Encoder(encoder.Encoder): +TAG_MAP: dict[TagSet, encoder.AbstractItemEncoder] +TYPE_MAP: dict[int, encoder.AbstractItemEncoder] +# deprecated aliases +tagMap = TAG_MAP +typeMap = TYPE_MAP + +class SingleItemEncoder(encoder.SingleItemEncoder): fixedDefLengthMode: bool fixedChunkSize: int + TAG_MAP: dict[TagSet, encoder.AbstractItemEncoder] + TYPE_MAP: dict[int, encoder.AbstractItemEncoder] + +class Encoder(encoder.Encoder): + SINGLE_ITEM_ENCODER: type[SingleItemEncoder] + encode: Encoder diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/der/decoder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/der/decoder.pyi index 68aeb5993..042470f21 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/der/decoder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/der/decoder.pyi @@ -1,12 +1,33 @@ +from pyasn1.codec.ber.decoder import AbstractPayloadDecoder from pyasn1.codec.cer import decoder +from pyasn1.type.tag import TagSet -class BitStringDecoder(decoder.BitStringDecoder): +__all__ = ["decode", "StreamingDecoder"] + +class BitStringPayloadDecoder(decoder.BitStringPayloadDecoder): supportConstructedForm: bool -class OctetStringDecoder(decoder.OctetStringDecoder): +class OctetStringPayloadDecoder(decoder.OctetStringPayloadDecoder): supportConstructedForm: bool -class Decoder(decoder.Decoder): +RealPayloadDecoder = decoder.RealPayloadDecoder + +TAG_MAP: dict[TagSet, AbstractPayloadDecoder] +TYPE_MAP: dict[int, AbstractPayloadDecoder] +# deprecated aliases +tagMap = TAG_MAP +typeMap = TYPE_MAP + +class SingleItemDecoder(decoder.SingleItemDecoder): + TAG_MAP: dict[TagSet, AbstractPayloadDecoder] + TYPE_MAP: dict[int, AbstractPayloadDecoder] + supportIndefLength: bool +class StreamingDecoder(decoder.StreamingDecoder): + SINGLE_ITEM_DECODER: type[SingleItemDecoder] + +class Decoder(decoder.Decoder): + STREAMING_DECODER: type[StreamingDecoder] + decode: Decoder diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/der/encoder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/der/encoder.pyi index 55c024e6c..3b1b5a4a6 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/der/encoder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/der/encoder.pyi @@ -1,9 +1,25 @@ +from pyasn1.codec.ber.encoder import AbstractItemEncoder from pyasn1.codec.cer import encoder +from pyasn1.type.tag import TagSet + +__all__ = ["Encoder", "encode"] class SetEncoder(encoder.SetEncoder): ... -class Encoder(encoder.Encoder): +TAG_MAP: dict[TagSet, AbstractItemEncoder] +TYPE_MAP: dict[int, AbstractItemEncoder] +# deprecated aliases +tagMap = TAG_MAP +typeMap = TYPE_MAP + +class SingleItemEncoder(encoder.SingleItemEncoder): fixedDefLengthMode: bool fixedChunkSize: int + TAG_MAP: dict[TagSet, AbstractItemEncoder] + TYPE_MAP: dict[int, AbstractItemEncoder] + +class Encoder(encoder.Encoder): + SINGLE_ITEM_ENCODER: type[SingleItemEncoder] + encode: Encoder diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/native/decoder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/native/decoder.pyi index e25ef738a..a1bbb983b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/native/decoder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/native/decoder.pyi @@ -1,23 +1,42 @@ from _typeshed import Incomplete, Unused from collections.abc import Callable -class AbstractScalarDecoder: +from pyasn1.type.tag import TagSet + +__all__ = ["decode"] + +class AbstractScalarPayloadDecoder: def __call__(self, pyObject, asn1Spec, decodeFun: Unused = None, **options): ... -class BitStringDecoder(AbstractScalarDecoder): +class BitStringPayloadDecoder(AbstractScalarPayloadDecoder): def __call__(self, pyObject, asn1Spec, decodeFun: Unused = None, **options): ... -class SequenceOrSetDecoder: +class SequenceOrSetPayloadDecoder: def __call__(self, pyObject, asn1Spec, decodeFun: Callable[..., Incomplete] | None = None, **options): ... -class SequenceOfOrSetOfDecoder: +class SequenceOfOrSetOfPayloadDecoder: def __call__(self, pyObject, asn1Spec, decodeFun: Callable[..., Incomplete] | None = None, **options): ... -class ChoiceDecoder: +class ChoicePayloadDecoder: def __call__(self, pyObject, asn1Spec, decodeFun: Callable[..., Incomplete] | None = None, **options): ... -class Decoder: - def __init__(self, tagMap, typeMap) -> None: ... +TAG_MAP: dict[TagSet, AbstractScalarPayloadDecoder | SequenceOrSetPayloadDecoder | ChoicePayloadDecoder] +TYPE_MAP: dict[int, AbstractScalarPayloadDecoder | SequenceOrSetPayloadDecoder | ChoicePayloadDecoder] +# deprecated aliases +tagMap = TAG_MAP +typeMap = TYPE_MAP + +class SingleItemDecoder: + TAG_MAP: dict[TagSet, AbstractScalarPayloadDecoder | SequenceOrSetPayloadDecoder | ChoicePayloadDecoder] + TYPE_MAP: dict[int, AbstractScalarPayloadDecoder | SequenceOrSetPayloadDecoder | ChoicePayloadDecoder] + + def __init__(self, tagMap=..., typeMap=..., **ignored: Unused) -> None: ... def __call__(self, pyObject, asn1Spec, **options): ... +class Decoder: + SINGLE_ITEM_DECODER: type[SingleItemDecoder] + + def __init__(self, tagMap=..., typeMap=..., **options: Unused) -> None: ... + def __call__(self, pyObject, asn1Spec=None, **kwargs): ... + decode: Decoder diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/native/encoder.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/native/encoder.pyi index 337ab2329..a69a11346 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/native/encoder.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/native/encoder.pyi @@ -1,6 +1,11 @@ +from _typeshed import Unused from abc import abstractmethod from collections import OrderedDict +from pyasn1.type.tag import TagSet + +__all__ = ["encode"] + class AbstractItemEncoder: @abstractmethod def encode(self, value, encodeFun, **options) -> None: ... @@ -44,8 +49,23 @@ class ChoiceEncoder(SequenceEncoder): ... class AnyEncoder(AbstractItemEncoder): def encode(self, value, encodeFun, **options): ... -class Encoder: - def __init__(self, tagMap, typeMap={}) -> None: ... +TAG_MAP: dict[TagSet, AbstractItemEncoder] +TYPE_MAP: dict[int, AbstractItemEncoder] +# deprecated aliases +tagMap = TAG_MAP +typeMap = TYPE_MAP + +class SingleItemEncoder: + TAG_MAP: dict[TagSet, AbstractItemEncoder] + TYPE_MAP: dict[int, AbstractItemEncoder] + + def __init__(self, tagMap=..., typeMap=..., **ignored: Unused) -> None: ... def __call__(self, value, **options): ... -encode: Encoder +class Encoder: + SINGLE_ITEM_ENCODER: type[SingleItemEncoder] + + def __init__(self, tagMap=..., typeMap=..., **options: Unused): ... + def __call__(self, pyObject, asn1Spec=None, **options): ... + +encode: SingleItemEncoder diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/streaming.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/streaming.pyi new file mode 100644 index 000000000..9c90e7e06 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/codec/streaming.pyi @@ -0,0 +1,21 @@ +import io +from _typeshed import Incomplete +from collections.abc import Generator + +from pyasn1 import error as error +from pyasn1.type import univ as univ + +class CachingStreamWrapper(io.IOBase): + def __init__(self, raw) -> None: ... + def peek(self, n): ... + def seekable(self): ... + def seek(self, n: int = -1, whence=0): ... + def read(self, n: int = -1): ... + @property + def markedPosition(self): ... + def tell(self): ... + +def asSeekableStream(substrate): ... +def isEndOfStream(substrate) -> Generator[Incomplete, None, None]: ... +def peekIntoStream(substrate, size: int = -1) -> Generator[Incomplete, None, None]: ... +def readFromStream(substrate, size: int = -1, context: Incomplete | None = None) -> Generator[Incomplete, None, None]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/binary.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/binary.pyi deleted file mode 100644 index d034c5045..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/binary.pyi +++ /dev/null @@ -1 +0,0 @@ -from builtins import bin as bin diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/calling.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/calling.pyi deleted file mode 100644 index 9b1d682f3..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/calling.pyi +++ /dev/null @@ -1 +0,0 @@ -from builtins import callable as callable diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/dateandtime.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/dateandtime.pyi deleted file mode 100644 index 739dbe57c..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/dateandtime.pyi +++ /dev/null @@ -1,3 +0,0 @@ -from datetime import datetime - -strptime = datetime.strptime diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/string.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/string.pyi deleted file mode 100644 index c88881c11..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/compat/string.pyi +++ /dev/null @@ -1,2 +0,0 @@ -# Same as string.partition(sep) -def partition(string: str, sep: str) -> tuple[str, str, str]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/debug.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/debug.pyi index 5af57249f..b0060f42b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/debug.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/debug.pyi @@ -1,6 +1,8 @@ import logging from typing import TextIO +__all__ = ["Debug", "setLogger", "hexdump"] + class Printer: def __init__( self, @@ -10,8 +12,6 @@ class Printer: ) -> None: ... def __call__(self, msg) -> None: ... -NullHandler = logging.NullHandler - class Debug: defaultPrinter: Printer def __init__(self, *flags, **options) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/error.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/error.pyi index 892e6e2c5..2625bb2cd 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/error.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/error.pyi @@ -1,6 +1,12 @@ -class PyAsn1Error(Exception): ... +class PyAsn1Error(Exception): + def __init__(self, *args, **kwargs) -> None: ... + @property + def context(self): ... + class ValueConstraintError(PyAsn1Error): ... class SubstrateUnderrunError(PyAsn1Error): ... +class EndOfStreamError(SubstrateUnderrunError): ... +class UnsupportedSubstrateError(PyAsn1Error): ... class PyAsn1UnicodeError(PyAsn1Error, UnicodeError): def __init__(self, message, unicode_error: UnicodeError | None = None) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/base.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/base.pyi index 808cff5f1..a5f60f50e 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/base.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/base.pyi @@ -5,6 +5,8 @@ from typing_extensions import final from pyasn1.type import constraint, namedtype from pyasn1.type.tag import TagSet +__all__ = ["Asn1Item", "Asn1Type", "SimpleAsn1Type", "ConstructedAsn1Type"] + class Asn1Item: @classmethod def getTypeId(cls, increment: int = 1): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/char.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/char.pyi index 61a43f6fc..8791c07ab 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/char.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/char.pyi @@ -1,6 +1,22 @@ from pyasn1.type import univ from pyasn1.type.tag import TagSet +__all__ = [ + "NumericString", + "PrintableString", + "TeletexString", + "T61String", + "VideotexString", + "IA5String", + "GraphicString", + "VisibleString", + "ISO646String", + "GeneralString", + "UniversalString", + "BMPString", + "UTF8String", +] + class AbstractCharacterString(univ.OctetString): def __bytes__(self) -> bytes: ... def prettyIn(self, value): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/constraint.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/constraint.pyi index 21728b81f..df8d2c558 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/constraint.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/constraint.pyi @@ -1,3 +1,15 @@ +__all__ = [ + "SingleValueConstraint", + "ContainedSubtypeConstraint", + "ValueRangeConstraint", + "ValueSizeConstraint", + "PermittedAlphabetConstraint", + "InnerTypeConstraint", + "ConstraintsExclusion", + "ConstraintsIntersection", + "ConstraintsUnion", +] + class AbstractConstraint: def __init__(self, *values) -> None: ... def __call__(self, value, idx: int | None = None) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/namedtype.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/namedtype.pyi index 5c4eadf30..c8d12b5de 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/namedtype.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/namedtype.pyi @@ -1,3 +1,5 @@ +__all__ = ["NamedType", "OptionalNamedType", "DefaultedNamedType", "NamedTypes"] + class NamedType: isOptional: bool isDefaulted: bool diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/namedval.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/namedval.pyi index 348fb9174..20c190470 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/namedval.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/namedval.pyi @@ -1,6 +1,8 @@ from _typeshed import Incomplete from collections.abc import Generator +__all__ = ["NamedValues"] + class NamedValues: def __init__(self, *args, **kwargs) -> None: ... def __eq__(self, other): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/opentype.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/opentype.pyi index 919055315..8317aa0db 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/opentype.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/opentype.pyi @@ -3,6 +3,8 @@ from collections.abc import Mapping from pyasn1.type.base import Asn1Type +__all__ = ["OpenType"] + class OpenType: def __init__(self, name, typeMap: Mapping[Incomplete, Asn1Type] | None = None) -> None: ... @property diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/tag.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/tag.pyi index 732916513..15d26de05 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/tag.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/tag.pyi @@ -1,3 +1,16 @@ +__all__ = [ + "tagClassUniversal", + "tagClassApplication", + "tagClassContext", + "tagClassPrivate", + "tagFormatSimple", + "tagFormatConstructed", + "tagCategoryImplicit", + "tagCategoryExplicit", + "tagCategoryUntagged", + "Tag", + "TagSet", +] tagClassUniversal: int tagClassApplication: int tagClassContext: int diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/tagmap.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/tagmap.pyi index 175da1faa..b842e0a4a 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/tagmap.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/tagmap.pyi @@ -2,6 +2,8 @@ from collections.abc import Container, Mapping from pyasn1.type.base import Asn1Type +__all__ = ["TagMap"] + class TagMap: def __init__( self, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/univ.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/univ.pyi index 6330ba5d4..f48d1bdf6 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/univ.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/univ.pyi @@ -6,6 +6,26 @@ from typing_extensions import Self, SupportsIndex, TypeAlias from pyasn1.type import base, constraint, namedtype, namedval from pyasn1.type.tag import TagSet +__all__ = [ + "Integer", + "Boolean", + "BitString", + "OctetString", + "Null", + "ObjectIdentifier", + "Real", + "Enumerated", + "SequenceOfAndSetOfBase", + "SequenceOf", + "SetOf", + "SequenceAndSetBase", + "Sequence", + "Set", + "Choice", + "Any", + "NoValue", + "noValue", +] _SizedIntegerable: TypeAlias = ReadableBuffer | str | SupportsInt | SupportsIndex | SupportsTrunc NoValue = base.NoValue diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/useful.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/useful.pyi index 76a80aefe..5d2ad64b3 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/useful.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyasn1/pyasn1/type/useful.pyi @@ -3,6 +3,8 @@ import datetime from pyasn1.type import char from pyasn1.type.tag import TagSet +__all__ = ["ObjectDescriptor", "GeneralizedTime", "UTCTime"] + class ObjectDescriptor(char.GraphicString): tagSet: TagSet typeId: int diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/METADATA.toml index 66f637e9c..671a85b0d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/METADATA.toml @@ -1,3 +1,4 @@ -version = "5.13.*" +version = "6.1.*" upstream_repository = "https://github.com/pyinstaller/pyinstaller" requires = ["types-setuptools"] +requires_python = ">=3.8" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/building/api.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/building/api.pyi index 2a3dc4fc2..936c68dbc 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/building/api.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/building/api.pyi @@ -13,7 +13,6 @@ from PyInstaller.building.build_main import Analysis from PyInstaller.building.datastruct import Target, _TOCTuple from PyInstaller.building.splash import Splash from PyInstaller.utils.win32.versioninfo import VSVersionInfo -from PyInstaller.utils.win32.winmanifest import Manifest if sys.platform == "darwin": _TargetArch: TypeAlias = Literal["x86_64", "arm64", "universal2"] @@ -22,9 +21,9 @@ if sys.platform == "darwin": _CodesignIdentityParam: TypeAlias = str | None else: _TargetArch: TypeAlias = None - _SuportedTargetArchParam: TypeAlias = object + _SuportedTargetArchParam: TypeAlias = Unused _CodesignIdentity: TypeAlias = None - _CodesignIdentityParam: TypeAlias = object + _CodesignIdentityParam: TypeAlias = Unused if sys.platform == "win32": _Icon: TypeAlias = list[StrPath] | str @@ -34,18 +33,18 @@ elif sys.platform == "darwin": _IconParam: TypeAlias = StrPath | list[StrPath] | None else: _Icon: TypeAlias = None - _IconParam: TypeAlias = object + _IconParam: TypeAlias = Unused if sys.platform == "win32": _VersionSrc: TypeAlias = VSVersionInfo | None _VersionParam: TypeAlias = VSVersionInfo | StrOrBytesPath | None - _Manifest: TypeAlias = Manifest - _ManifestParam: TypeAlias = Manifest | None + _Manifest: TypeAlias = bytes + _ManifestParam: TypeAlias = str | None else: _VersionSrc: TypeAlias = None - _VersionParam: TypeAlias = object + _VersionParam: TypeAlias = Unused _Manifest: TypeAlias = None - _ManifestParam: TypeAlias = object + _ManifestParam: TypeAlias = Unused class PYZ(Target): name: str @@ -60,6 +59,7 @@ class PKG(Target): xformdict: ClassVar[dict[str, str]] toc: list[_TOCTuple] cdict: Mapping[str, bool] + python_lib_name: str name: str exclude_binaries: bool strip_binaries: bool @@ -71,6 +71,7 @@ class PKG(Target): def __init__( self, toc: Iterable[_TOCTuple], + python_lib_name: str, name: str | None = None, cdict: Mapping[str, bool] | None = None, exclude_binaries: bool = False, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/building/datastruct.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/building/datastruct.pyi index 2adfb61e7..8db3cd5e7 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/building/datastruct.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/building/datastruct.pyi @@ -3,7 +3,7 @@ from collections.abc import Iterable, Sequence from typing import ClassVar from typing_extensions import Literal, LiteralString, Self, SupportsIndex, TypeAlias -_TypeCode: TypeAlias = Literal["DATA", "BINARY", "EXTENSION", "OPTION"] +_TypeCode: TypeAlias = Literal["DEPENDENCY", "SYMLINK", "DATA", "BINARY", "EXECUTABLE", "EXTENSION", "OPTION"] _TOCTuple: TypeAlias = tuple[str, str | None, _TypeCode | None] class TOC(list[_TOCTuple]): @@ -44,3 +44,4 @@ class Tree(Target, list[_TOCTuple]): def normalize_toc(toc: Iterable[_TOCTuple]) -> list[_TOCTuple]: ... def normalize_pyz_toc(toc: Iterable[_TOCTuple]) -> list[_TOCTuple]: ... +def toc_process_symbolic_links(toc: Iterable[_TOCTuple]) -> list[_TOCTuple]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/compat.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/compat.pyi index b06ad3bd0..7e9ed00c5 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/compat.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/compat.pyi @@ -9,8 +9,8 @@ strict_collect_mode: bool is_64bits: Final[bool] is_py35: Final = True is_py36: Final = True -is_py37: Final[bool] -is_py38: Final[bool] +is_py37: Final = True +is_py38: Final = True is_py39: Final[bool] is_py310: Final[bool] is_py311: Final[bool] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/hooks/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/hooks/__init__.pyi index 8929d4165..b24363581 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/hooks/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/hooks/__init__.pyi @@ -5,11 +5,9 @@ from collections.abc import Callable, Iterable from typing import Any from typing_extensions import Final, Literal -import pkg_resources from PyInstaller import HOMEPATH as HOMEPATH from PyInstaller.depend.imphookapi import PostGraphAPI from PyInstaller.utils.hooks import conda -from PyInstaller.utils.hooks.win32 import get_pywin32_module_file_attribute as get_pywin32_module_file_attribute conda_support = conda @@ -27,11 +25,9 @@ def remove_file_extension(filename: str) -> str: ... def can_import_module(module_name: str) -> bool: ... def get_module_attribute(module_name: str, attr_name: str) -> Any: ... def get_module_file_attribute(package: str) -> str | None: ... -def is_module_satisfies( - requirements: Iterable[str] | pkg_resources.Requirement, - version: str | pkg_resources.Distribution | None = None, - version_attr: str = "__version__", -) -> bool: ... +def get_pywin32_module_file_attribute(module_name: str) -> str | None: ... +def check_requirement(requirement: str) -> bool: ... +def is_module_satisfies(requirements: str, version: None = None, version_attr: None = None) -> bool: ... def is_package(module_name: str) -> bool: ... def get_all_package_paths(package: str) -> list[str]: ... def package_base_path(package_path: str, package: str) -> str: ... @@ -58,11 +54,10 @@ def collect_system_data_files( ) -> list[tuple[str, str]]: ... def copy_metadata(package_name: str, recursive: bool = False) -> list[tuple[str, str]]: ... def get_installer(module: str) -> str | None: ... -def requirements_for_package(package_name: str) -> list[str]: ... def collect_all( package_name: str, include_py_files: bool = True, - filter_submodules: Callable[[str], bool] | None = None, + filter_submodules: Callable[[str], bool] = ..., exclude_datas: Iterable[str] | None = None, include_datas: Iterable[str] | None = None, on_error: Literal["ignore", "warn once", "warn", "raise"] = "warn once", diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/hooks/win32.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/hooks/win32.pyi deleted file mode 100644 index ac5efe75a..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/hooks/win32.pyi +++ /dev/null @@ -1 +0,0 @@ -def get_pywin32_module_file_attribute(module_name: str) -> str | None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/win32/winmanifest.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/win32/winmanifest.pyi deleted file mode 100644 index 9ec38f6b2..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/pyinstaller/PyInstaller/utils/win32/winmanifest.pyi +++ /dev/null @@ -1,127 +0,0 @@ -from _typeshed import Incomplete, ReadableBuffer, Unused -from typing import IO, AnyStr, overload -from typing_extensions import Literal -from xml.dom.minidom import Document as _Document, Element as _Element, Node - -def getChildElementsByTagName(self: Node, tagName: str) -> list[Element]: ... -def getFirstChildElementByTagName(self: Node, tagName: str) -> Element | None: ... - -class Document(_Document): - cE = _Document.createElement - cT = _Document.createTextNode - aChild = _Document.appendChild - getEByTN = _Document.getElementsByTagName - getCEByTN = getChildElementsByTagName - getFCEByTN = getFirstChildElementByTagName - -class Element(_Element): - getA = _Element.getAttribute - remA = _Element.removeAttribute - setA = _Element.setAttribute - aChild = _Element.appendChild - getEByTN = _Element.getElementsByTagName - getCEByTN = getChildElementsByTagName - getFCEByTN = getFirstChildElementByTagName - -# Used by other types referenced in https://pyinstaller.org/en/stable/spec-files.html#spec-file-operation -class Manifest: - filename: Incomplete - optional: Incomplete - manifestType: Incomplete - manifestVersion: Incomplete - noInheritable: Incomplete - noInherit: Incomplete - type: Incomplete - name: Incomplete - language: str | None - processorArchitecture: Incomplete - version: Incomplete - publicKeyToken: Incomplete - applyPublisherPolicy: Incomplete - description: Incomplete - requestedExecutionLevel: Incomplete - uiAccess: Incomplete - dependentAssemblies: Incomplete - bindingRedirects: Incomplete - files: Incomplete - comInterfaceExternalProxyStubs: Incomplete - def __init__( - self, - manifestType: str = "assembly", - manifestVersion: Incomplete | None = None, - noInheritable: bool = False, - noInherit: bool = False, - type_: Incomplete | None = None, - name: Incomplete | None = None, - language: str | None = None, - processorArchitecture: Incomplete | None = None, - version: Incomplete | None = None, - publicKeyToken: Incomplete | None = None, - description: Unused = None, - requestedExecutionLevel: Incomplete | None = None, - uiAccess: Incomplete | None = None, - dependentAssemblies: Incomplete | None = None, - files: Incomplete | None = None, - comInterfaceExternalProxyStubs: Incomplete | None = None, - ) -> None: ... - @overload - def __eq__(self, other: Manifest | str) -> bool: ... # type: ignore[misc] - @overload - def __eq__(self, other: object) -> Literal[False]: ... - @overload - def __ne__(self, other: Manifest | str) -> bool: ... # type: ignore[misc] - @overload - def __ne__(self, other: object) -> Literal[True]: ... - def add_dependent_assembly( - self, - manifestVersion: Incomplete | None = None, - noInheritable: bool = False, - noInherit: bool = False, - type_: Incomplete | None = None, - name: Incomplete | None = None, - language: str | None = None, - processorArchitecture: Incomplete | None = None, - version: Incomplete | None = None, - publicKeyToken: Incomplete | None = None, - description: Incomplete | None = None, - requestedExecutionLevel: Incomplete | None = None, - uiAccess: Incomplete | None = None, - dependentAssemblies: Incomplete | None = None, - files: Incomplete | None = None, - comInterfaceExternalProxyStubs: Incomplete | None = None, - ) -> None: ... - def add_file( - self, - name: str = "", - hashalg: str = "", - hash: str = "", - comClasses: Incomplete | None = None, - typelibs: Incomplete | None = None, - comInterfaceProxyStubs: Incomplete | None = None, - windowClasses: Incomplete | None = None, - ) -> None: ... - @classmethod - def get_winsxs_dir(cls) -> str: ... - @classmethod - def get_manifest_dir(cls) -> str: ... - @classmethod - def get_policy_dir(cls) -> str: ... - def get_policy_redirect(self, language: str | None = None, version: Incomplete | None = None) -> Incomplete: ... - def find_files(self, ignore_policies: bool = True) -> list[Incomplete]: ... - def getid(self, language: str | None = None, version: Incomplete | None = None) -> str: ... - def getlanguage(self, language: str | None = None, windowsversion: Incomplete | None = None) -> str: ... - def getpolicyid(self, fuzzy: bool = True, language: str | None = None, windowsversion: Incomplete | None = None) -> str: ... - def load_dom(self, domtree: Document | Element, initialize: bool = True) -> None: ... - def parse(self, filename_or_file: str | IO[AnyStr], initialize: bool = True) -> None: ... - def parse_string(self, xmlstr: ReadableBuffer | str, initialize: bool = True) -> None: ... - def same_id(self, manifest: Manifest, skip_version_check: bool = False) -> bool: ... - def todom(self) -> Document: ... - def toprettyxml(self, indent: str = " ", newl: str = ..., encoding: str = "UTF-8") -> str: ... - def toxml(self, encoding: str = "UTF-8") -> str: ... - def update_resources(self, dstpath: str, names: Incomplete | None = None, languages: Incomplete | None = None) -> None: ... - def writeprettyxml( - self, filename_or_file: str | IO[AnyStr] | None = None, indent: str = " ", newl: str = ..., encoding: str = "UTF-8" - ) -> None: ... - def writexml( - self, filename_or_file: str | IO[AnyStr] | None = None, indent: Unused = " ", newl: Unused = ..., encoding: str = "UTF-8" - ) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyjks/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/METADATA.toml new file mode 100644 index 000000000..ccc64c3d6 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/METADATA.toml @@ -0,0 +1,3 @@ +version = "20.0.*" +upstream_repository = "https://github.com/kurtbrose/pyjks" +requires = ["types-pyasn1"] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/__init__.pyi new file mode 100644 index 000000000..26eee4cd2 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/__init__.pyi @@ -0,0 +1,48 @@ +# pyjks exports lots of junk such as jks.jks.SIGNATURE_WHITENING, jks.util.b8 etc. +# We don't mark those as re-exported as those don't seem like intended part of the public API. +from .bks import ( + AbstractBksEntry as AbstractBksEntry, + BksKeyEntry as BksKeyEntry, + BksKeyStore as BksKeyStore, + BksSealedKeyEntry as BksSealedKeyEntry, + BksSecretKeyEntry as BksSecretKeyEntry, + BksTrustedCertEntry as BksTrustedCertEntry, + UberKeyStore as UberKeyStore, +) +from .jks import ( + KeyStore as KeyStore, + PrivateKeyEntry as PrivateKeyEntry, + SecretKeyEntry as SecretKeyEntry, + TrustedCertEntry as TrustedCertEntry, + __version__ as __version__, + __version_info__ as __version_info__, +) +from .util import ( + AbstractKeystore as AbstractKeystore, + AbstractKeystoreEntry as AbstractKeystoreEntry, + BadDataLengthException as BadDataLengthException, + BadHashCheckException as BadHashCheckException, + BadKeystoreFormatException as BadKeystoreFormatException, + BadPaddingException as BadPaddingException, + DecryptionFailureException as DecryptionFailureException, + DuplicateAliasException as DuplicateAliasException, + KeystoreException as KeystoreException, + KeystoreSignatureException as KeystoreSignatureException, + NotYetDecryptedException as NotYetDecryptedException, + UnexpectedAlgorithmException as UnexpectedAlgorithmException, + UnexpectedJavaTypeException as UnexpectedJavaTypeException, + UnexpectedKeyEncodingException as UnexpectedKeyEncodingException, + UnsupportedKeyFormatException as UnsupportedKeyFormatException, + UnsupportedKeystoreEntryTypeException as UnsupportedKeystoreEntryTypeException, + UnsupportedKeystoreTypeException as UnsupportedKeystoreTypeException, + UnsupportedKeystoreVersionException as UnsupportedKeystoreVersionException, + add_pkcs7_padding as add_pkcs7_padding, + as_hex as as_hex, + as_pem as as_pem, + bitstring_to_bytes as bitstring_to_bytes, + pkey_as_pem as pkey_as_pem, + print_pem as print_pem, + strip_pkcs5_padding as strip_pkcs5_padding, + strip_pkcs7_padding as strip_pkcs7_padding, + xor_bytearrays as xor_bytearrays, +) diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/bks.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/bks.pyi new file mode 100644 index 000000000..3d01f4a7b --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/bks.pyi @@ -0,0 +1,124 @@ +from _typeshed import SupportsKeysAndGetItem, Unused +from typing_extensions import Final, Literal, Self, TypeAlias + +from .jks import TrustedCertEntry +from .util import AbstractKeystore, AbstractKeystoreEntry + +_BksType: TypeAlias = Literal["bks", "uber"] +_CertType: TypeAlias = Literal["X.509"] +_EntryFormat: TypeAlias = Literal["PKCS8", "PKCS#8", "X.509", "X509", "RAW"] +_BksVersion: TypeAlias = Literal[1, 2] + +ENTRY_TYPE_CERTIFICATE: Final = 1 +ENTRY_TYPE_KEY: Final = 2 +ENTRY_TYPE_SECRET: Final = 3 +ENTRY_TYPE_SEALED: Final = 4 + +KEY_TYPE_PRIVATE: Final = 0 +KEY_TYPE_PUBLIC: Final = 1 +KEY_TYPE_SECRET: Final = 2 +_KeyType: TypeAlias = Literal[0, 1, 2] + +class AbstractBksEntry(AbstractKeystoreEntry): + store_type: _BksType | None + cert_chain: list[tuple[_CertType, bytes]] + def __init__( + self, + *, + cert_chain: list[tuple[_CertType, bytes]] = ..., + encrypted: bytes | None = None, + store_type: _BksType | None = None, + alias: str, + timestamp: int, + **kwargs: Unused, + ) -> None: ... + +class BksTrustedCertEntry(TrustedCertEntry): + store_type: _BksType | None # type: ignore[assignment] + +class BksKeyEntry(AbstractBksEntry): + type: _KeyType + format: _EntryFormat + algorithm: str + encoded: bytes + # type == KEY_TYPE_PRIVATE + pkey_pkcs8: bytes + pkey: bytes + algorithm_oid: tuple[int, ...] + # type == KEY_TYPE_PUBLIC + public_key_info: bytes + public_key: bytes + # type == KEY_TYPE_SECRET + key: bytes + key_size: int + def __init__( + self, + type: _KeyType, + format: _EntryFormat, + algorithm: str, + encoded: bytes, + *, + cert_chain: list[tuple[_CertType, bytes]] = ..., + encrypted: bytes | None = None, + store_type: _BksType | None = None, + alias: str, + timestamp: int, + **kwargs: Unused, + ) -> None: ... + @classmethod + def type2str(cls, t: _KeyType) -> Literal["PRIVATE", "PUBLIC", "SECRET"]: ... + def is_decrypted(self) -> Literal[True]: ... + +class BksSecretKeyEntry(AbstractBksEntry): + key: bytes + def is_decrypted(self) -> Literal[True]: ... + +class BksSealedKeyEntry(AbstractBksEntry): + # Properties provided by __getattr__ + nested: BksKeyEntry | None + # __getattr__ proxies all attributes of nested BksKeyEntry after decrypting + type: _KeyType + format: _EntryFormat + algorithm: str + encoded: bytes + # if type == KEY_TYPE_PRIVATE + pkey_pkcs8: bytes + pkey: bytes + algorithm_oid: tuple[int, ...] + # if type == KEY_TYPE_PUBLIC + public_key_info: bytes + public_key: bytes + # if type == KEY_TYPE_SECRET + key: bytes + key_size: int + +class BksKeyStore(AbstractKeystore): + store_type: Literal["bks"] + entries: dict[str, BksTrustedCertEntry | BksKeyEntry | BksSealedKeyEntry | BksSecretKeyEntry] # type: ignore[assignment] + version: _BksVersion + def __init__( + self, + store_type: Literal["bks"], + entries: SupportsKeysAndGetItem[str, BksTrustedCertEntry | BksKeyEntry | BksSealedKeyEntry | BksSecretKeyEntry], + version: _BksVersion = 2, + ) -> None: ... + @property + def certs(self) -> dict[str, BksTrustedCertEntry]: ... + @property + def plain_keys(self) -> dict[str, BksKeyEntry]: ... + @property + def sealed_keys(self) -> dict[str, BksSealedKeyEntry]: ... + @property + def secret_keys(self) -> dict[str, BksSecretKeyEntry]: ... + @classmethod + def loads(cls, data: bytes, store_password: str, try_decrypt_keys: bool = True) -> Self: ... + +class UberKeyStore(BksKeyStore): + store_type: Literal["uber"] # type: ignore[assignment] + version: Literal[1] + def __init__( + self, + store_type: Literal["uber"], + entries: SupportsKeysAndGetItem[str, BksTrustedCertEntry | BksKeyEntry | BksSealedKeyEntry | BksSecretKeyEntry], + version: Literal[1] = 1, + ) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/jks.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/jks.pyi new file mode 100644 index 000000000..1275b7fa2 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/jks.pyi @@ -0,0 +1,129 @@ +from _typeshed import SupportsKeysAndGetItem, Unused +from collections.abc import Iterable +from typing import NoReturn, overload +from typing_extensions import Final, Literal, Self, TypeAlias + +from .util import AbstractKeystore, AbstractKeystoreEntry + +__version_info__: Final[tuple[int, int, int] | tuple[int, int, int, str]] +__version__: Final[str] +MAGIC_NUMBER_JKS: Final[bytes] +MAGIC_NUMBER_JCEKS: Final[bytes] +SIGNATURE_WHITENING: Final[bytes] + +_JksType: TypeAlias = Literal["jks", "jceks"] +_CertType: TypeAlias = Literal["X.509"] +_KeyFormat: TypeAlias = Literal["pkcs8", "rsa_raw"] + +class TrustedCertEntry(AbstractKeystoreEntry): + store_type: _JksType | None + type: _CertType | None + cert: bytes + # NB! For most use cases, use TrustedCertEntry.new() classmethod. + def __init__( + self, + *, + type: _CertType | None = None, + cert: bytes, + store_type: _JksType | None = None, + alias: str, + timestamp: int, + **kwargs: Unused, + ) -> None: ... + @classmethod + def new(cls, alias: str, cert: bytes) -> Self: ... # type: ignore[override] + def is_decrypted(self) -> Literal[True]: ... + +class PrivateKeyEntry(AbstractKeystoreEntry): + store_type: _JksType | None + cert_chain: list[tuple[_CertType, bytes]] + # Properties provided by __getattr__ after decryption + @property + def pkey(self) -> bytes: ... + @property + def pkey_pkcs8(self) -> bytes: ... + @property + def algorithm_oid(self) -> tuple[int, ...]: ... + # NB! For most use cases, use PrivateKeyEntry.new() classmethod. + # Overloaded: must provide `encrypted` OR `pkey`, `pkey_pkcs8`, `algorithm_oid` + @overload + def __init__( + self, + *, + cert_chain: list[tuple[_CertType, bytes]], + encrypted: bytes, + store_type: _JksType | None = None, + alias: str, + timestamp: int, + **kwargs: Unused, + ) -> None: ... + @overload + def __init__( + self, + *, + cert_chain: list[tuple[_CertType, bytes]], + pkey: bytes, + pkey_pkcs8: bytes, + algorithm_oid: tuple[int, ...], + store_type: _JksType | None = None, + alias: str, + timestamp: int, + **kwargs: Unused, + ) -> None: ... + @classmethod + def new( # type: ignore[override] + cls, alias: str, certs: Iterable[bytes], key: bytes, key_format: _KeyFormat = "pkcs8" + ) -> Self: ... + +class SecretKeyEntry(AbstractKeystoreEntry): + store_type: _JksType | None + # Properties provided by __getattr__ + @property + def algorithm(self) -> str: ... + @property + def key(self) -> bytes: ... + @property + def key_size(self) -> int: ... + # Overloaded: must provide `sealed_obj` OR `algorithm`, `key`, `key_size` + @overload + def __init__( + self, *, sealed_obj: bytes, store_type: _JksType | None = None, alias: str, timestamp: int, **kwargs: Unused + ) -> None: ... + @overload + def __init__( + self, + *, + algorithm: str, + key: bytes, + key_size: int, + store_type: _JksType | None = None, + alias: str, + timestamp: int, + **kwargs: Unused, + ) -> None: ... + # Not implemented by pyjks + @classmethod + def new( # type: ignore[override] + cls, alias: str, sealed_obj: bool, algorithm: str, key: bytes, key_size: int + ) -> NoReturn: ... + # Not implemented by pyjks + def encrypt(self, key_password: str) -> NoReturn: ... + +class KeyStore(AbstractKeystore): + entries: dict[str, TrustedCertEntry | PrivateKeyEntry | SecretKeyEntry] # type: ignore[assignment] + store_type: _JksType + @classmethod + def new(cls, store_type: _JksType, store_entries: Iterable[TrustedCertEntry | PrivateKeyEntry | SecretKeyEntry]) -> Self: ... + @classmethod + def loads(cls, data: bytes, store_password: str | None, try_decrypt_keys: bool = True) -> Self: ... + def saves(self, store_password: str) -> bytes: ... + # NB! For most use cases, use KeyStore.new() classmethod. + def __init__( + self, store_type: _JksType, entries: SupportsKeysAndGetItem[str, TrustedCertEntry | PrivateKeyEntry | SecretKeyEntry] + ) -> None: ... + @property + def certs(self) -> dict[str, TrustedCertEntry]: ... + @property + def secret_keys(self) -> dict[str, SecretKeyEntry]: ... + @property + def private_keys(self) -> dict[str, PrivateKeyEntry]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/rfc2898.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/rfc2898.pyi new file mode 100644 index 000000000..b6711c502 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/rfc2898.pyi @@ -0,0 +1,5 @@ +from pyasn1.type.namedtype import NamedTypes +from pyasn1.type.univ import Sequence + +class PBEParameter(Sequence): + componentType: NamedTypes diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/rfc7292.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/rfc7292.pyi new file mode 100644 index 000000000..a411e794e --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/rfc7292.pyi @@ -0,0 +1,28 @@ +from hashlib import _Hash +from typing_extensions import Final, Literal, TypeAlias + +from pyasn1.type.namedtype import NamedTypes +from pyasn1.type.univ import Sequence + +PBE_WITH_SHA1_AND_TRIPLE_DES_CBC_OID: Final[tuple[int, ...]] +PURPOSE_KEY_MATERIAL: Final = 1 +PURPOSE_IV_MATERIAL: Final = 2 +PURPOSE_MAC_MATERIAL: Final = 3 + +_Purpose: TypeAlias = Literal[1, 2, 3] + +class Pkcs12PBEParams(Sequence): + componentType: NamedTypes + +def derive_key( + hashfn: _Hash, purpose_byte: _Purpose, password_str: str, salt: bytes, iteration_count: int, desired_key_size: int +) -> bytes: ... +def decrypt_PBEWithSHAAnd3KeyTripleDESCBC( + data: bytes | bytearray, password_str: str, salt: bytes, iteration_count: int +) -> bytes: ... +def decrypt_PBEWithSHAAndTwofishCBC( + encrypted_data: bytes | bytearray, password: str, salt: bytes, iteration_count: int +) -> bytes: ... +def encrypt_PBEWithSHAAndTwofishCBC( + plaintext_data: bytes | bytearray, password: str, salt: bytes, iteration_count: int +) -> bytes: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/sun_crypto.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/sun_crypto.pyi new file mode 100644 index 000000000..822892b55 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/sun_crypto.pyi @@ -0,0 +1,8 @@ +from typing_extensions import Final + +SUN_JKS_ALGO_ID: Final[tuple[int, ...]] +SUN_JCE_ALGO_ID: Final[tuple[int, ...]] + +def jks_pkey_encrypt(key: bytes | bytearray, password_str: str) -> bytes: ... +def jks_pkey_decrypt(data: bytes | bytearray, password_str: str) -> bytes: ... +def jce_pbe_decrypt(data: bytes | bytearray, password: str, salt: bytes, iteration_count: int) -> bytes: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/util.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/util.pyi new file mode 100644 index 000000000..2eff180d2 --- /dev/null +++ b/packages/pyright-internal/typeshed-fallback/stubs/pyjks/jks/util.pyi @@ -0,0 +1,65 @@ +from _typeshed import FileDescriptorOrPath, SupportsKeysAndGetItem, Unused +from collections.abc import Iterable +from struct import Struct +from typing_extensions import Final, Literal, Self, TypeAlias + +from .bks import BksKeyEntry +from .jks import PrivateKeyEntry + +b8: Final[Struct] +b4: Final[Struct] +b2: Final[Struct] +b1: Final[Struct] +py23basestring: Final[tuple[type[str], type[str]]] +RSA_ENCRYPTION_OID: Final[tuple[int, ...]] +DSA_OID: Final[tuple[int, ...]] +DSA_WITH_SHA1_OID: Final[tuple[int, ...]] + +_KeystoreType: TypeAlias = Literal["jks", "jceks", "bks", "uber"] +_PemType: TypeAlias = Literal["CERTIFICATE", "PUBLIC KEY", "PRIVATE KEY", "RSA PRIVATE KEY"] + +class KeystoreException(Exception): ... +class KeystoreSignatureException(KeystoreException): ... +class DuplicateAliasException(KeystoreException): ... +class NotYetDecryptedException(KeystoreException): ... +class BadKeystoreFormatException(KeystoreException): ... +class BadDataLengthException(KeystoreException): ... +class BadPaddingException(KeystoreException): ... +class BadHashCheckException(KeystoreException): ... +class DecryptionFailureException(KeystoreException): ... +class UnsupportedKeystoreVersionException(KeystoreException): ... +class UnexpectedJavaTypeException(KeystoreException): ... +class UnexpectedAlgorithmException(KeystoreException): ... +class UnexpectedKeyEncodingException(KeystoreException): ... +class UnsupportedKeystoreTypeException(KeystoreException): ... +class UnsupportedKeystoreEntryTypeException(KeystoreException): ... +class UnsupportedKeyFormatException(KeystoreException): ... + +class AbstractKeystore: + store_type: _KeystoreType + entries: dict[str, AbstractKeystoreEntry] + def __init__(self, store_type: _KeystoreType, entries: SupportsKeysAndGetItem[str, AbstractKeystoreEntry]) -> None: ... + @classmethod + def load(cls, filename: FileDescriptorOrPath, store_password: str | None, try_decrypt_keys: bool = True) -> Self: ... + def save(self, filename: FileDescriptorOrPath, store_password: str) -> None: ... + +class AbstractKeystoreEntry: + store_type: _KeystoreType | None + alias: str + timestamp: int + def __init__(self, *, store_type: _KeystoreType | None = None, alias: str, timestamp: int, **kwargs: Unused) -> None: ... + @classmethod + def new(cls, alias: str) -> Self: ... + def is_decrypted(self) -> bool: ... + def decrypt(self, key_password: str) -> None: ... + def encrypt(self, key_password: str) -> None: ... + +def as_hex(ba: bytes | bytearray) -> str: ... +def as_pem(der_bytes: bytes, type: _PemType) -> str: ... +def bitstring_to_bytes(bitstr: Iterable[int]) -> bytes: ... +def xor_bytearrays(a: bytes | bytearray, b: bytes | bytearray) -> bytearray: ... +def print_pem(der_bytes: bytes, type: _PemType) -> None: ... +def pkey_as_pem(pk: PrivateKeyEntry | BksKeyEntry) -> str: ... +def strip_pkcs5_padding(m: bytes | bytearray) -> bytes: ... +def strip_pkcs7_padding(m: bytes | bytearray, block_size: int) -> bytes: ... +def add_pkcs7_padding(m: bytes | bytearray, block_size: int) -> bytes: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pytz/pytz/tzinfo.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pytz/pytz/tzinfo.pyi index ddbe54a11..b1d0386bc 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pytz/pytz/tzinfo.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pytz/pytz/tzinfo.pyi @@ -3,6 +3,8 @@ from abc import abstractmethod from typing import Any, overload class BaseTzInfo(datetime.tzinfo): + _utcoffset: datetime.timedelta | None + _tzname: str | None zone: str | None # Actually None but should be set on concrete subclasses # The following abstract methods don't exist in the implementation, but # are implemented by all sub-classes. diff --git a/packages/pyright-internal/typeshed-fallback/stubs/pywin32/win32com/client/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/pywin32/win32com/client/__init__.pyi index f87b379fc..feb41f060 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/pywin32/win32com/client/__init__.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/pywin32/win32com/client/__init__.pyi @@ -1,5 +1,5 @@ from _typeshed import Incomplete -from typing_extensions import TypeAlias +from typing_extensions import Final, TypeAlias import _win32typing from win32com.client import dynamic as dynamic, gencache as gencache @@ -36,7 +36,7 @@ class Constants: __dicts__: Incomplete def __getattr__(self, a: str): ... -constants: Incomplete +constants: Final[Constants] class EventsProxy: def __init__(self, ob) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/asyncio/client.pyi b/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/asyncio/client.pyi index 2c8b4235a..e58f75d2b 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/asyncio/client.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/asyncio/client.pyi @@ -30,10 +30,121 @@ class Redis(AbstractRedis, RedisModuleCommands, AsyncCoreCommands[_StrType], Asy connection_pool: Any single_connection_client: Any connection: Any + @overload @classmethod - def from_url(cls, url: str, **kwargs) -> Redis[Any]: ... + def from_url( + cls, + url: str, + *, + host: str = "localhost", + port: int = 6379, + db: str | int = 0, + password: str | None = None, + socket_timeout: float | None = None, + socket_connect_timeout: float | None = None, + socket_keepalive: bool | None = None, + socket_keepalive_options: Mapping[int, int | bytes] | None = None, + connection_pool: ConnectionPool | None = None, + unix_socket_path: str | None = None, + encoding: str = "utf-8", + encoding_errors: str = "strict", + decode_responses: Literal[True], + retry_on_timeout: bool = False, + retry_on_error: list[type[RedisError]] | None = None, + ssl: bool = False, + ssl_keyfile: str | None = None, + ssl_certfile: str | None = None, + ssl_cert_reqs: str = "required", + ssl_ca_certs: str | None = None, + ssl_ca_data: str | None = None, + ssl_check_hostname: bool = False, + max_connections: int | None = None, + single_connection_client: bool = False, + health_check_interval: int = 0, + client_name: str | None = None, + username: str | None = None, + retry: Retry | None = None, + auto_close_connection_pool: bool = True, + redis_connect_func: ConnectCallbackT | None = None, + credential_provider: CredentialProvider | None = None, + ) -> Redis[str]: ... + @overload + @classmethod + def from_url( + cls, + url: str, + *, + host: str = "localhost", + port: int = 6379, + db: str | int = 0, + password: str | None = None, + socket_timeout: float | None = None, + socket_connect_timeout: float | None = None, + socket_keepalive: bool | None = None, + socket_keepalive_options: Mapping[int, int | bytes] | None = None, + connection_pool: ConnectionPool | None = None, + unix_socket_path: str | None = None, + encoding: str = "utf-8", + encoding_errors: str = "strict", + decode_responses: Literal[False] = False, + retry_on_timeout: bool = False, + retry_on_error: list[type[RedisError]] | None = None, + ssl: bool = False, + ssl_keyfile: str | None = None, + ssl_certfile: str | None = None, + ssl_cert_reqs: str = "required", + ssl_ca_certs: str | None = None, + ssl_ca_data: str | None = None, + ssl_check_hostname: bool = False, + max_connections: int | None = None, + single_connection_client: bool = False, + health_check_interval: int = 0, + client_name: str | None = None, + username: str | None = None, + retry: Retry | None = None, + auto_close_connection_pool: bool = True, + redis_connect_func: ConnectCallbackT | None = None, + credential_provider: CredentialProvider | None = None, + ) -> Redis[bytes]: ... + @overload def __init__( - self, + self: Redis[str], + *, + host: str = "localhost", + port: int = 6379, + db: str | int = 0, + password: str | None = None, + socket_timeout: float | None = None, + socket_connect_timeout: float | None = None, + socket_keepalive: bool | None = None, + socket_keepalive_options: Mapping[int, int | bytes] | None = None, + connection_pool: ConnectionPool | None = None, + unix_socket_path: str | None = None, + encoding: str = "utf-8", + encoding_errors: str = "strict", + decode_responses: Literal[True], + retry_on_timeout: bool = False, + retry_on_error: list[type[RedisError]] | None = None, + ssl: bool = False, + ssl_keyfile: str | None = None, + ssl_certfile: str | None = None, + ssl_cert_reqs: str = "required", + ssl_ca_certs: str | None = None, + ssl_ca_data: str | None = None, + ssl_check_hostname: bool = False, + max_connections: int | None = None, + single_connection_client: bool = False, + health_check_interval: int = 0, + client_name: str | None = None, + username: str | None = None, + retry: Retry | None = None, + auto_close_connection_pool: bool = True, + redis_connect_func: ConnectCallbackT | None = None, + credential_provider: CredentialProvider | None = None, + ) -> None: ... + @overload + def __init__( + self: Redis[bytes], *, host: str = "localhost", port: int = 6379, @@ -47,7 +158,7 @@ class Redis(AbstractRedis, RedisModuleCommands, AsyncCoreCommands[_StrType], Asy unix_socket_path: str | None = None, encoding: str = "utf-8", encoding_errors: str = "strict", - decode_responses: bool = False, + decode_responses: Literal[False] = False, retry_on_timeout: bool = False, retry_on_error: list[type[RedisError]] | None = None, ssl: bool = False, @@ -178,7 +289,7 @@ PSWorkerThreadExcHandlerT: TypeAlias = PubsubWorkerExceptionHandler | AsyncPubsu CommandT: TypeAlias = tuple[tuple[str | bytes, ...], Mapping[str, Any]] CommandStackT: TypeAlias = list[CommandT] -class Pipeline(Redis[_StrType], Generic[_StrType]): +class Pipeline(Redis[_StrType]): UNWATCH_COMMANDS: ClassVar[set[str]] connection_pool: Any connection: Any diff --git a/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/client.pyi b/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/client.pyi index b8079fa3d..5c2e4a1ac 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/client.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/client.pyi @@ -382,7 +382,7 @@ class PubSubWorkerThread(threading.Thread): def run(self) -> None: ... def stop(self) -> None: ... -class Pipeline(Redis[_StrType], Generic[_StrType]): +class Pipeline(Redis[_StrType]): UNWATCH_COMMANDS: Any connection_pool: Any connection: Any diff --git a/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/cluster.pyi b/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/cluster.pyi index ba515942a..7cca70103 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/cluster.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/cluster.pyi @@ -188,7 +188,7 @@ class ClusterPubSub(PubSub): def execute_command(self, *args, **kwargs) -> None: ... def get_redis_connection(self) -> Redis[Any] | None: ... -class ClusterPipeline(RedisCluster[_StrType], Generic[_StrType]): +class ClusterPipeline(RedisCluster[_StrType]): command_stack: list[Incomplete] nodes_manager: Incomplete refresh_table_asap: bool diff --git a/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/commands/cluster.pyi b/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/commands/cluster.pyi index 28789988b..a6b329e9f 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/commands/cluster.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/redis/redis/commands/cluster.pyi @@ -16,7 +16,7 @@ class ClusterManagementCommands(ManagementCommands): def replicaof(self, *args, **kwargs) -> None: ... def swapdb(self, *args, **kwargs) -> None: ... -class ClusterDataAccessCommands(DataAccessCommands[_StrType], Generic[_StrType]): +class ClusterDataAccessCommands(DataAccessCommands[_StrType]): def stralgo( self, algo, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/regex/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/regex/METADATA.toml index 9f95df0df..43018d8b7 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/regex/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/regex/METADATA.toml @@ -1,2 +1,2 @@ -version = "2023.8.8" +version = "2023.10.3" upstream_repository = "https://github.com/mrabarnett/mrab-regex" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/requests-oauthlib/requests_oauthlib/oauth2_session.pyi b/packages/pyright-internal/typeshed-fallback/stubs/requests-oauthlib/requests_oauthlib/oauth2_session.pyi index b9317cad3..c170c9f06 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/requests-oauthlib/requests_oauthlib/oauth2_session.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/requests-oauthlib/requests_oauthlib/oauth2_session.pyi @@ -71,7 +71,7 @@ class OAuth2Session(requests.Session): def access_token(self) -> None: ... @property def authorized(self) -> bool: ... - def authorization_url(self, url: str, state: Incomplete | None = None, **kwargs) -> str: ... + def authorization_url(self, url: str, state: Incomplete | None = None, **kwargs) -> tuple[str, str]: ... def fetch_token( self, token_url: str, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/requests/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/requests/METADATA.toml index 39371b90e..bd69d2dfc 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/requests/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/requests/METADATA.toml @@ -1,6 +1,13 @@ version = "2.31.*" upstream_repository = "https://github.com/psf/requests" -requires = ["types-urllib3"] +# requires a version of urllib3 with a py.typed file +requires = ["urllib3>=2"] +extra_description = """\ + Note: `types-requests` has required `urllib3>=2` since v2.31.0.7. \ + If you need to install `types-requests` into an environment \ + that must also have `urllib3<2` installed into it, \ + you will have to use `types-requests<2.31.0.7`.\ + """ [tool.stubtest] extras = ["socks"] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/requests/requests/exceptions.pyi b/packages/pyright-internal/typeshed-fallback/stubs/requests/requests/exceptions.pyi index b642d5ad3..99f4448d9 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/requests/requests/exceptions.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/requests/requests/exceptions.pyi @@ -1,11 +1,14 @@ -from typing import Any - from urllib3.exceptions import HTTPError as BaseHTTPError +from .models import Request, Response +from .sessions import PreparedRequest + class RequestException(OSError): - response: Any - request: Any - def __init__(self, *args, **kwargs) -> None: ... + response: Response | None + request: Request | PreparedRequest | None + def __init__( + self, *args: object, request: Request | PreparedRequest | None = ..., response: Response | None = ... + ) -> None: ... class InvalidJSONError(RequestException): ... class JSONDecodeError(InvalidJSONError): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/requests/requests/utils.pyi b/packages/pyright-internal/typeshed-fallback/stubs/requests/requests/utils.pyi index 20dd0e0e8..f5805d81d 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/requests/requests/utils.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/requests/requests/utils.pyi @@ -34,7 +34,7 @@ def unquote_header_value(value, is_filename: bool = False): ... def dict_from_cookiejar(cj): ... def add_dict_to_cookiejar(cj, cookie_dict): ... def get_encodings_from_content(content): ... -def get_encoding_from_headers(headers): ... +def get_encoding_from_headers(headers: Mapping[str, str]) -> str | None: ... def stream_decode_response_unicode(iterator, r): ... def iter_slices(string: str, slice_length: int | None) -> Generator[str, None, None]: ... def get_unicode_from_response(r): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/data_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/data_pb2.pyi index cd9ded47d..d53937df2 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/data_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/data_pb2.pyi @@ -66,7 +66,7 @@ class AbilityData(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TargetEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[AbilityData._Target.ValueType], builtins.type): # noqa: F821 + class _TargetEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[AbilityData._Target.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Point: AbilityData._Target.ValueType # 2 """Requires a target position.""" @@ -183,7 +183,7 @@ class Weapon(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TargetTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Weapon._TargetType.ValueType], builtins.type): # noqa: F821 + class _TargetTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Weapon._TargetType.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Ground: Weapon._TargetType.ValueType # 1 Air: Weapon._TargetType.ValueType # 2 diff --git a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/debug_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/debug_pb2.pyi index 77441ec37..5f605f930 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/debug_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/debug_pb2.pyi @@ -337,7 +337,7 @@ class DebugTestProcess(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TestEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DebugTestProcess._Test.ValueType], builtins.type): # noqa: F821 + class _TestEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DebugTestProcess._Test.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor hang: DebugTestProcess._Test.ValueType # 1 crash: DebugTestProcess._Test.ValueType # 2 @@ -387,7 +387,7 @@ class DebugEndGame(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _EndResultEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DebugEndGame._EndResult.ValueType], builtins.type): # noqa: F821 + class _EndResultEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DebugEndGame._EndResult.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Surrender: DebugEndGame._EndResult.ValueType # 1 """Default if nothing is set. The current player admits defeat.""" @@ -418,7 +418,7 @@ class DebugSetUnitValue(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _UnitValueEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DebugSetUnitValue._UnitValue.ValueType], builtins.type): # noqa: F821 + class _UnitValueEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DebugSetUnitValue._UnitValue.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Energy: DebugSetUnitValue._UnitValue.ValueType # 1 Life: DebugSetUnitValue._UnitValue.ValueType # 2 diff --git a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/sc2api_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/sc2api_pb2.pyi index 23c69ca1f..c3b879600 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/sc2api_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/sc2api_pb2.pyi @@ -542,7 +542,7 @@ class ResponseCreateGame(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseCreateGame._Error.ValueType], builtins.type): # noqa: F821 + class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseCreateGame._Error.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor MissingMap: ResponseCreateGame._Error.ValueType # 1 InvalidMapPath: ResponseCreateGame._Error.ValueType # 2 @@ -664,7 +664,7 @@ class ResponseJoinGame(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseJoinGame._Error.ValueType], builtins.type): # noqa: F821 + class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseJoinGame._Error.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor MissingParticipation: ResponseJoinGame._Error.ValueType # 1 InvalidObservedPlayerId: ResponseJoinGame._Error.ValueType # 2 @@ -741,7 +741,7 @@ class ResponseRestartGame(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseRestartGame._Error.ValueType], builtins.type): # noqa: F821 + class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseRestartGame._Error.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor LaunchError: ResponseRestartGame._Error.ValueType # 1 @@ -818,7 +818,7 @@ class ResponseStartReplay(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseStartReplay._Error.ValueType], builtins.type): # noqa: F821 + class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseStartReplay._Error.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor MissingReplay: ResponseStartReplay._Error.ValueType # 1 InvalidReplayPath: ResponseStartReplay._Error.ValueType # 2 @@ -878,7 +878,7 @@ class ResponseMapCommand(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseMapCommand._Error.ValueType], builtins.type): # noqa: F821 + class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseMapCommand._Error.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor NoTriggerError: ResponseMapCommand._Error.ValueType # 1 @@ -1371,7 +1371,7 @@ class ResponseReplayInfo(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseReplayInfo._Error.ValueType], builtins.type): # noqa: F821 + class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseReplayInfo._Error.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor MissingReplay: ResponseReplayInfo._Error.ValueType # 1 InvalidReplayPath: ResponseReplayInfo._Error.ValueType # 2 @@ -1501,7 +1501,7 @@ class ResponseSaveMap(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseSaveMap._Error.ValueType], builtins.type): # noqa: F821 + class _ErrorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ResponseSaveMap._Error.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor InvalidMapData: ResponseSaveMap._Error.ValueType # 1 @@ -1897,7 +1897,7 @@ class ActionChat(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ChannelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionChat._Channel.ValueType], builtins.type): # noqa: F821 + class _ChannelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionChat._Channel.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Broadcast: ActionChat._Channel.ValueType # 1 Team: ActionChat._Channel.ValueType # 2 diff --git a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/score_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/score_pb2.pyi index 78549038d..a1c5360f3 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/score_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/score_pb2.pyi @@ -24,7 +24,7 @@ class Score(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ScoreTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Score._ScoreType.ValueType], builtins.type): # noqa: F821 + class _ScoreTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Score._ScoreType.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Curriculum: Score._ScoreType.ValueType # 1 """map generated score (from curriculum maps with special scoring)""" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/spatial_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/spatial_pb2.pyi index 1e2559038..5105e79a6 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/spatial_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/spatial_pb2.pyi @@ -376,7 +376,7 @@ class ActionSpatialUnitSelectionPoint(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionSpatialUnitSelectionPoint._Type.ValueType], builtins.type): # noqa: F821 + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionSpatialUnitSelectionPoint._Type.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Select: ActionSpatialUnitSelectionPoint._Type.ValueType # 1 """Equivalent to normal click. Changes selection to unit.""" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/ui_pb2.pyi b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/ui_pb2.pyi index 9490cde97..480c49603 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/ui_pb2.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/s2clientprotocol/s2clientprotocol/ui_pb2.pyi @@ -307,7 +307,7 @@ class ActionControlGroup(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _ControlGroupActionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionControlGroup._ControlGroupAction.ValueType], builtins.type): # noqa: F821 + class _ControlGroupActionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionControlGroup._ControlGroupAction.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Recall: ActionControlGroup._ControlGroupAction.ValueType # 1 """Equivalent to number hotkey. Replaces current selection with control group.""" @@ -397,7 +397,7 @@ class ActionSelectIdleWorker(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionSelectIdleWorker._Type.ValueType], builtins.type): # noqa: F821 + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionSelectIdleWorker._Type.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor Set: ActionSelectIdleWorker._Type.ValueType # 1 """Equivalent to click with no modifiers. Replaces selection with single idle worker.""" @@ -438,7 +438,7 @@ class ActionMultiPanel(google.protobuf.message.Message): ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType - class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionMultiPanel._Type.ValueType], builtins.type): # noqa: F821 + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ActionMultiPanel._Type.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor SingleSelect: ActionMultiPanel._Type.ValueType # 1 """Click on icon""" diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/asyncio.pyi b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/asyncio.pyi index 3f9558419..bef9dc177 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/asyncio.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/asyncio.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete, SupportsWrite from collections.abc import Awaitable, Callable, Generator, Iterable, Iterator, Mapping -from typing import Generic, NoReturn, TypeVar, overload +from typing import NoReturn, TypeVar, overload from typing_extensions import Self from .std import tqdm as std_tqdm @@ -9,7 +9,7 @@ __all__ = ["tqdm_asyncio", "tarange", "tqdm", "trange"] _T = TypeVar("_T") -class tqdm_asyncio(std_tqdm[_T], Generic[_T]): +class tqdm_asyncio(std_tqdm[_T]): iterable_awaitable: bool iterable_next: Callable[[], _T | Awaitable[_T]] iterable_iterator: Iterator[_T] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/discord.pyi b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/discord.pyi index 9ab90e8b8..638683940 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/discord.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/discord.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete, SupportsWrite from collections.abc import Iterable, Mapping -from typing import Generic, NoReturn, TypeVar, overload +from typing import NoReturn, TypeVar, overload from ..auto import tqdm as tqdm_auto from .utils_worker import MonoWorker @@ -15,7 +15,7 @@ class DiscordIO(MonoWorker): _T = TypeVar("_T") -class tqdm_discord(tqdm_auto[_T], Generic[_T]): +class tqdm_discord(tqdm_auto[_T]): dio: Incomplete @overload def __init__( diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/slack.pyi b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/slack.pyi index 97b3a3f6d..bcf98f326 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/slack.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/slack.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete, SupportsWrite from collections.abc import Iterable, Mapping -from typing import Generic, NoReturn, TypeVar, overload +from typing import NoReturn, TypeVar, overload from ..auto import tqdm as tqdm_auto from .utils_worker import MonoWorker @@ -16,7 +16,7 @@ class SlackIO(MonoWorker): _T = TypeVar("_T") -class tqdm_slack(tqdm_auto[_T], Generic[_T]): +class tqdm_slack(tqdm_auto[_T]): sio: Incomplete @overload def __init__( diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/telegram.pyi b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/telegram.pyi index eb0fc7a4a..fd0225d80 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/telegram.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/contrib/telegram.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete, SupportsWrite from collections.abc import Iterable, Mapping -from typing import Generic, NoReturn, TypeVar, overload +from typing import NoReturn, TypeVar, overload from ..auto import tqdm as tqdm_auto from .utils_worker import MonoWorker @@ -21,7 +21,7 @@ class TelegramIO(MonoWorker): _T = TypeVar("_T") -class tqdm_telegram(tqdm_auto[_T], Generic[_T]): +class tqdm_telegram(tqdm_auto[_T]): tgio: Incomplete @overload def __init__( diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/gui.pyi b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/gui.pyi index a8a1844ef..7156e55cb 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/gui.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/gui.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete, SupportsWrite from collections.abc import Iterable, Mapping -from typing import Generic, NoReturn, TypeVar, overload +from typing import NoReturn, TypeVar, overload from .std import tqdm as std_tqdm @@ -8,7 +8,7 @@ __all__ = ["tqdm_gui", "tgrange", "tqdm", "trange"] _T = TypeVar("_T") -class tqdm_gui(std_tqdm[_T], Generic[_T]): +class tqdm_gui(std_tqdm[_T]): mpl: Incomplete plt: Incomplete toolbar: Incomplete diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/notebook.pyi b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/notebook.pyi index 52f8d9c86..5f7d3f745 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/notebook.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/notebook.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete, SupportsWrite from collections.abc import Iterable, Iterator, Mapping -from typing import Generic, NoReturn, TypeVar, overload +from typing import NoReturn, TypeVar, overload from .std import tqdm as std_tqdm, trange as trange @@ -8,7 +8,7 @@ __all__ = ["tqdm_notebook", "tnrange", "tqdm", "trange"] _T = TypeVar("_T") -class tqdm_notebook(std_tqdm[_T], Generic[_T]): +class tqdm_notebook(std_tqdm[_T]): @staticmethod def status_printer( _: SupportsWrite[str] | None, total: float | None = None, desc: str | None = None, ncols: int | None = None diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/rich.pyi b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/rich.pyi index 993d6b7ef..39445c031 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/rich.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/rich.pyi @@ -1,12 +1,14 @@ from _typeshed import Incomplete, SupportsWrite from abc import ABC, abstractmethod from collections.abc import Iterable, Mapping -from typing import Generic, NoReturn, TypeVar, overload +from typing import NoReturn, TypeVar, overload from .std import tqdm as std_tqdm __all__ = ["tqdm_rich", "trrange", "tqdm", "trange"] +_T = TypeVar("_T") + # Actually rich.progress.ProgressColumn class _ProgressColumn(ABC): max_refresh: float | None @@ -31,9 +33,7 @@ class RateColumn(_ProgressColumn): def __init__(self, unit: str = ..., unit_scale: bool = ..., unit_divisor: int = ...) -> None: ... def render(self, task): ... -_T = TypeVar("_T") - -class tqdm_rich(std_tqdm[_T], Generic[_T]): +class tqdm_rich(std_tqdm[_T]): def close(self) -> None: ... def clear(self, *_, **__) -> None: ... def display(self, *_, **__) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/tk.pyi b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/tk.pyi index 49aebbf0a..e8a888d25 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/tk.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/tqdm/tqdm/tk.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete, SupportsWrite from collections.abc import Iterable, Mapping -from typing import Generic, NoReturn, TypeVar, overload +from typing import NoReturn, TypeVar, overload from .std import tqdm as std_tqdm @@ -8,7 +8,7 @@ __all__ = ["tqdm_tk", "ttkrange", "tqdm", "trange"] _T = TypeVar("_T") -class tqdm_tk(std_tqdm[_T], Generic[_T]): +class tqdm_tk(std_tqdm[_T]): @overload def __init__( self, diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tree-sitter-languages/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/tree-sitter-languages/METADATA.toml index 6b15f4dee..1e1da4c18 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tree-sitter-languages/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/tree-sitter-languages/METADATA.toml @@ -1,3 +1,3 @@ -version = "1.7.*" +version = "1.8.*" upstream_repository = "https://github.com/grantjenks/py-tree-sitter-languages" requires = ["types-tree-sitter"] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/tzlocal/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/tzlocal/METADATA.toml index 8f421a002..f3e200e94 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/tzlocal/METADATA.toml +++ b/packages/pyright-internal/typeshed-fallback/stubs/tzlocal/METADATA.toml @@ -1,3 +1,4 @@ -version = "5.0.1" +version = "5.1" upstream_repository = "https://github.com/regebro/tzlocal" requires = ["types-pytz"] +obsolete_since = "5.2" # Released on 2023-10-22 diff --git a/packages/pyright-internal/typeshed-fallback/stubs/untangle/untangle.pyi b/packages/pyright-internal/typeshed-fallback/stubs/untangle/untangle.pyi index f706aee02..3df430b10 100644 --- a/packages/pyright-internal/typeshed-fallback/stubs/untangle/untangle.pyi +++ b/packages/pyright-internal/typeshed-fallback/stubs/untangle/untangle.pyi @@ -1,7 +1,7 @@ from collections.abc import Iterator, Mapping from typing import Any from typing_extensions import Self -from xml.sax import handler +from xml.sax import handler, xmlreader def is_string(x: object) -> bool: ... @@ -29,7 +29,7 @@ class Handler(handler.ContentHandler): root: Element elements: list[Element] def __init__(self) -> None: ... - def startElement(self, name: str, attributes: Mapping[str, Any]) -> None: ... + def startElement(self, name: str, attributes: xmlreader.AttributesImpl) -> None: ... def endElement(self, name: str) -> None: ... def characters(self, cdata: str) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/@tests/stubtest_allowlist.txt b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/@tests/stubtest_allowlist.txt deleted file mode 100644 index 0a86c7a63..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/@tests/stubtest_allowlist.txt +++ /dev/null @@ -1,31 +0,0 @@ -urllib3.NullHandler -urllib3._collections.HTTPHeaderDict.from_httplib -urllib3._collections.HTTPHeaderDict.getlist -urllib3._collections.RLock -urllib3.connection.HTTPConnection.request -urllib3.connection.HTTPSConnection.__init__ -urllib3.connection.VerifiedHTTPSConnection.__init__ -urllib3.connection.VerifiedHTTPSConnection.set_cert -urllib3.connectionpool.ConnectionError -# TODO: remove ResponseCls ignore when https://github.com/python/mypy/issues/13316 is closed -urllib3.connectionpool.HTTPConnectionPool.ResponseCls -urllib3.connectionpool.HTTPConnectionPool.__init__ -urllib3.connectionpool.HTTPConnectionPool.urlopen -urllib3.connectionpool.HTTPSConnectionPool.__init__ -urllib3.connectionpool.VerifiedHTTPSConnection.__init__ -urllib3.connectionpool.VerifiedHTTPSConnection.set_cert -urllib3.poolmanager.PoolManager.connection_from_host -urllib3.poolmanager.PoolManager.connection_from_url -urllib3.poolmanager.PoolManager.urlopen -urllib3.poolmanager.ProxyManager.__init__ -urllib3.poolmanager.ProxyManager.connection_from_host -urllib3.poolmanager.ProxyManager.urlopen -urllib3.request.RequestMethods.request_encode_url -urllib3.response.BrotliDecoder -urllib3.util.connection.poll -urllib3.util.connection.select -urllib3.util.ssl_.create_default_context -urllib3.util.ssl_.ssl_wrap_socket - -# Metaclass differs: -urllib3.util.retry.Retry diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/METADATA.toml b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/METADATA.toml deleted file mode 100644 index 39f0246a6..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/METADATA.toml +++ /dev/null @@ -1,8 +0,0 @@ -version = "1.26.*" -upstream_repository = "https://github.com/urllib3/urllib3" -obsolete_since = "2.0.0" # Released on 2023-04-26 -partial_stub = true - -[tool.stubtest] -ignore_missing_stub = true -extras = ["socks"] diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/__init__.pyi deleted file mode 100644 index 8794ea575..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/__init__.pyi +++ /dev/null @@ -1,28 +0,0 @@ -import logging -from typing import TextIO - -from . import connectionpool, filepost, poolmanager, response -from .util import request as _request, retry, timeout, url - -__author__: str -__license__: str -__version__: str - -HTTPConnectionPool = connectionpool.HTTPConnectionPool -HTTPSConnectionPool = connectionpool.HTTPSConnectionPool -connection_from_url = connectionpool.connection_from_url -encode_multipart_formdata = filepost.encode_multipart_formdata -PoolManager = poolmanager.PoolManager -ProxyManager = poolmanager.ProxyManager -proxy_from_url = poolmanager.proxy_from_url -HTTPResponse = response.HTTPResponse -make_headers = _request.make_headers -get_host = url.get_host -Timeout = timeout.Timeout -Retry = retry.Retry - -class NullHandler(logging.Handler): - def emit(self, record): ... - -def add_stderr_logger(level: int = 10) -> logging.StreamHandler[TextIO]: ... -def disable_warnings(category: type[Warning] = ...) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/_collections.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/_collections.pyi deleted file mode 100644 index e282a9fc0..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/_collections.pyi +++ /dev/null @@ -1,55 +0,0 @@ -from collections.abc import MutableMapping -from types import TracebackType -from typing import Any, NoReturn, TypeVar - -_KT = TypeVar("_KT") -_VT = TypeVar("_VT") - -class RLock: - def __enter__(self): ... - def __exit__( - self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None - ) -> None: ... - -class RecentlyUsedContainer(MutableMapping[_KT, _VT]): - ContainerCls: Any - dispose_func: Any - lock: Any - def __init__(self, maxsize=10, dispose_func=None) -> None: ... - def __getitem__(self, key): ... - def __setitem__(self, key, value) -> None: ... - def __delitem__(self, key) -> None: ... - def __len__(self) -> int: ... - def __iter__(self): ... - def clear(self): ... - def keys(self): ... - -class HTTPHeaderDict(MutableMapping[str, str]): - def __init__(self, headers=None, **kwargs) -> None: ... - def __setitem__(self, key, val) -> None: ... - def __getitem__(self, key): ... - def __delitem__(self, key) -> None: ... - def __contains__(self, key): ... - def __eq__(self, other): ... - def __iter__(self) -> NoReturn: ... - def __len__(self) -> int: ... - def __ne__(self, other): ... - values: Any - get: Any - update: Any - iterkeys: Any - itervalues: Any - def pop(self, key, default=...): ... - def discard(self, key): ... - def add(self, key, val): ... - def extend(self, *args, **kwargs): ... - def getlist(self, key): ... - getheaders: Any - getallmatchingheaders: Any - iget: Any - def copy(self): ... - def iteritems(self): ... - def itermerged(self): ... - def items(self): ... - @classmethod - def from_httplib(cls, message, duplicates=...): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/connection.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/connection.pyi deleted file mode 100644 index 0ab662e21..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/connection.pyi +++ /dev/null @@ -1,56 +0,0 @@ -import ssl -from builtins import ConnectionError as ConnectionError -from http.client import HTTPConnection as _HTTPConnection, HTTPException as HTTPException -from typing import Any - -from . import exceptions, util -from .util import ssl_, ssl_match_hostname - -class DummyConnection: ... - -BaseSSLError = ssl.SSLError - -ConnectTimeoutError = exceptions.ConnectTimeoutError -SystemTimeWarning = exceptions.SystemTimeWarning -match_hostname = ssl_match_hostname.match_hostname -resolve_cert_reqs = ssl_.resolve_cert_reqs -resolve_ssl_version = ssl_.resolve_ssl_version -ssl_wrap_socket = ssl_.ssl_wrap_socket -assert_fingerprint = ssl_.assert_fingerprint -connection = util.connection - -port_by_scheme: Any -RECENT_DATE: Any - -class HTTPConnection(_HTTPConnection): - default_port: Any - default_socket_options: Any - is_verified: Any - source_address: Any - socket_options: Any - def __init__(self, *args, **kw) -> None: ... - def connect(self): ... - -class HTTPSConnection(HTTPConnection): - default_port: Any - key_file: Any - cert_file: Any - def __init__(self, host, port=None, key_file=None, cert_file=None, strict=None, timeout=..., **kw) -> None: ... - sock: Any - def connect(self): ... - -class VerifiedHTTPSConnection(HTTPSConnection): - cert_reqs: Any - ca_certs: Any - ssl_version: Any - assert_fingerprint: Any - key_file: Any - cert_file: Any - assert_hostname: Any - def set_cert( - self, key_file=None, cert_file=None, cert_reqs=None, ca_certs=None, assert_hostname=None, assert_fingerprint=None - ): ... - sock: Any - auto_open: Any - is_verified: Any - def connect(self): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/connectionpool.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/connectionpool.pyi deleted file mode 100644 index 20ca0e61b..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/connectionpool.pyi +++ /dev/null @@ -1,129 +0,0 @@ -import queue -from collections.abc import Mapping -from logging import Logger -from types import TracebackType -from typing import Any, ClassVar -from typing_extensions import Literal, Self, TypeAlias - -from . import connection, exceptions, request, response -from .connection import BaseSSLError as BaseSSLError, ConnectionError as ConnectionError, HTTPException as HTTPException -from .util import Url, connection as _connection, queue as urllib3queue, retry, ssl_match_hostname, timeout, url - -ClosedPoolError = exceptions.ClosedPoolError -ProtocolError = exceptions.ProtocolError -EmptyPoolError = exceptions.EmptyPoolError -HostChangedError = exceptions.HostChangedError -LocationValueError = exceptions.LocationValueError -MaxRetryError = exceptions.MaxRetryError -ProxyError = exceptions.ProxyError -ReadTimeoutError = exceptions.ReadTimeoutError -SSLError = exceptions.SSLError -TimeoutError = exceptions.TimeoutError -InsecureRequestWarning = exceptions.InsecureRequestWarning -CertificateError = ssl_match_hostname.CertificateError -port_by_scheme = connection.port_by_scheme -DummyConnection = connection.DummyConnection -HTTPConnection = connection.HTTPConnection -HTTPSConnection = connection.HTTPSConnection -VerifiedHTTPSConnection = connection.VerifiedHTTPSConnection -RequestMethods = request.RequestMethods -HTTPResponse = response.HTTPResponse -is_connection_dropped = _connection.is_connection_dropped -Retry = retry.Retry -Timeout = timeout.Timeout -get_host = url.get_host - -_Timeout: TypeAlias = Timeout | float -_Retries: TypeAlias = Retry | bool | int - -xrange: Any -log: Logger - -class ConnectionPool: - scheme: ClassVar[str | None] - QueueCls: ClassVar[type[queue.Queue[Any]]] - host: str - port: int | None - def __init__(self, host: str, port: int | None = None) -> None: ... - def __enter__(self) -> Self: ... - def __exit__( - self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None - ) -> Literal[False]: ... - def close(self) -> None: ... - -class HTTPConnectionPool(ConnectionPool, RequestMethods): - scheme: ClassVar[str] - ConnectionCls: ClassVar[type[HTTPConnection | HTTPSConnection]] - ResponseCls: ClassVar[type[HTTPResponse]] - strict: bool - timeout: _Timeout - retries: _Retries | None - pool: urllib3queue.LifoQueue | None - block: bool - proxy: Url | None - proxy_headers: Mapping[str, str] - num_connections: int - num_requests: int - conn_kw: Any - def __init__( - self, - host: str, - port: int | None = None, - strict: bool = False, - timeout: _Timeout = ..., - maxsize: int = 1, - block: bool = False, - headers: Mapping[str, str] | None = None, - retries: _Retries | None = None, - _proxy: Url | None = None, - _proxy_headers: Mapping[str, str] | None = None, - **conn_kw, - ) -> None: ... - def close(self) -> None: ... - def is_same_host(self, url: str) -> bool: ... - def urlopen( - self, - method, - url, - body=None, - headers=None, - retries=None, - redirect=True, - assert_same_host=True, - timeout=..., - pool_timeout=None, - release_conn=None, - **response_kw, - ): ... - -class HTTPSConnectionPool(HTTPConnectionPool): - key_file: str | None - cert_file: str | None - cert_reqs: int | str | None - ca_certs: str | None - ssl_version: int | str | None - assert_hostname: str | Literal[False] | None - assert_fingerprint: str | None - def __init__( - self, - host: str, - port: int | None = None, - strict: bool = False, - timeout: _Timeout = ..., - maxsize: int = 1, - block: bool = False, - headers: Mapping[str, str] | None = None, - retries: _Retries | None = None, - _proxy: Url | None = None, - _proxy_headers: Mapping[str, str] | None = None, - key_file: str | None = None, - cert_file: str | None = None, - cert_reqs: int | str | None = None, - ca_certs: str | None = None, - ssl_version: int | str | None = None, - assert_hostname: str | Literal[False] | None = None, - assert_fingerprint: str | None = None, - **conn_kw, - ) -> None: ... - -def connection_from_url(url: str, **kw) -> HTTPConnectionPool: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/contrib/socks.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/contrib/socks.pyi deleted file mode 100644 index f2137f8cf..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/contrib/socks.pyi +++ /dev/null @@ -1,45 +0,0 @@ -from collections.abc import Mapping -from typing import ClassVar -from typing_extensions import TypedDict - -from ..connection import HTTPConnection, HTTPSConnection -from ..connectionpool import HTTPConnectionPool, HTTPSConnectionPool -from ..poolmanager import PoolManager - -class _TYPE_SOCKS_OPTIONS(TypedDict): - socks_version: int - proxy_host: str | None - proxy_port: str | None - username: str | None - password: str | None - rdns: bool - -class SOCKSConnection(HTTPConnection): - def __init__(self, _socks_options: _TYPE_SOCKS_OPTIONS, *args, **kwargs) -> None: ... - -class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): ... - -class SOCKSHTTPConnectionPool(HTTPConnectionPool): - ConnectionCls: ClassVar[type[SOCKSConnection]] - -class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): - ConnectionCls: ClassVar[type[SOCKSHTTPSConnection]] - -class _ConnectionPoolClasses(TypedDict): - http: type[SOCKSHTTPConnectionPool] - https: type[SOCKSHTTPSConnectionPool] - -class SOCKSProxyManager(PoolManager): - # has a class-level default, but is overridden on instances, so not a ClassVar - pool_classes_by_scheme: _ConnectionPoolClasses - proxy_url: str - - def __init__( - self, - proxy_url: str, - username: str | None = ..., - password: str | None = ..., - num_pools: int = ..., - headers: Mapping[str, str] | None = ..., - **connection_pool_kw, - ) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/exceptions.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/exceptions.pyi deleted file mode 100644 index f55e8ad93..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/exceptions.pyi +++ /dev/null @@ -1,87 +0,0 @@ -from email.errors import MessageDefect -from http.client import IncompleteRead as httplib_IncompleteRead -from typing import Any - -from urllib3.connectionpool import ConnectionPool, HTTPResponse -from urllib3.util.retry import Retry - -class HTTPError(Exception): ... -class HTTPWarning(Warning): ... - -class PoolError(HTTPError): - pool: ConnectionPool - def __init__(self, pool: ConnectionPool, message: str) -> None: ... - -class RequestError(PoolError): - url: str - def __init__(self, pool: ConnectionPool, url: str, message: str) -> None: ... - -class SSLError(HTTPError): ... - -class ProxyError(HTTPError): - original_error: Exception - def __init__(self, message: str, error: Exception, *args: Any) -> None: ... - -class DecodeError(HTTPError): ... -class ProtocolError(HTTPError): ... - -ConnectionError = ProtocolError - -class MaxRetryError(RequestError): - reason: Exception | None - def __init__(self, pool: ConnectionPool, url: str, reason: Exception | None = None) -> None: ... - -class HostChangedError(RequestError): - retries: Retry | int - def __init__(self, pool: ConnectionPool, url: str, retries: Retry | int = 3) -> None: ... - -class TimeoutStateError(HTTPError): ... -class TimeoutError(HTTPError): ... -class ReadTimeoutError(TimeoutError, RequestError): ... -class ConnectTimeoutError(TimeoutError): ... -class NewConnectionError(ConnectTimeoutError, HTTPError): ... -class EmptyPoolError(PoolError): ... -class ClosedPoolError(PoolError): ... -class LocationValueError(ValueError, HTTPError): ... - -class LocationParseError(LocationValueError): - location: str - def __init__(self, location: str) -> None: ... - -class URLSchemeUnknown(LocationValueError): - scheme: str - def __init__(self, scheme: str) -> None: ... - -class ResponseError(HTTPError): - GENERIC_ERROR: str - SPECIFIC_ERROR: str - -class SecurityWarning(HTTPWarning): ... -class SubjectAltNameWarning(SecurityWarning): ... -class InsecureRequestWarning(SecurityWarning): ... -class SystemTimeWarning(SecurityWarning): ... -class InsecurePlatformWarning(SecurityWarning): ... -class SNIMissingWarning(HTTPWarning): ... -class DependencyWarning(HTTPWarning): ... -class ResponseNotChunked(ProtocolError, ValueError): ... -class BodyNotHttplibCompatible(HTTPError): ... - -class IncompleteRead(HTTPError, httplib_IncompleteRead): - def __init__(self, partial: bytes, expected: int | None) -> None: ... - -class InvalidChunkLength(HTTPError, httplib_IncompleteRead): - response: HTTPResponse - length: bytes - def __init__(self, response: HTTPResponse, length: bytes) -> None: ... - -class InvalidHeader(HTTPError): ... - -class ProxySchemeUnknown(AssertionError, URLSchemeUnknown): - def __init__(self, scheme: str | None) -> None: ... - -class ProxySchemeUnsupported(ValueError): ... - -class HeaderParsingError(HTTPError): - def __init__(self, defects: list[MessageDefect], unparsed_data: str | bytes | None) -> None: ... - -class UnrewindableBodyError(HTTPError): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/fields.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/fields.pyi deleted file mode 100644 index f2ce965e7..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/fields.pyi +++ /dev/null @@ -1,32 +0,0 @@ -from collections.abc import Callable, Mapping -from typing import Any -from typing_extensions import TypeAlias - -_FieldValue: TypeAlias = str | bytes -_FieldValueTuple: TypeAlias = _FieldValue | tuple[str, _FieldValue] | tuple[str, _FieldValue, str] - -def guess_content_type(filename: str | None, default: str = "application/octet-stream") -> str: ... -def format_header_param_rfc2231(name: str, value: _FieldValue) -> str: ... -def format_header_param_html5(name: str, value: _FieldValue) -> str: ... - -format_header_param = format_header_param_html5 - -class RequestField: - data: Any - headers: Any - def __init__( - self, - name: str, - data: _FieldValue, - filename: str | None = None, - headers: Mapping[str, str] | None = None, - header_formatter: Callable[[str, _FieldValue], str] = ..., - ) -> None: ... - @classmethod - def from_tuples( - cls, fieldname: str, value: _FieldValueTuple, header_formatter: Callable[[str, _FieldValue], str] = ... - ) -> RequestField: ... - def render_headers(self) -> str: ... - def make_multipart( - self, content_disposition: str | None = None, content_type: str | None = None, content_location: str | None = None - ) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/filepost.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/filepost.pyi deleted file mode 100644 index ee92d1122..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/filepost.pyi +++ /dev/null @@ -1,17 +0,0 @@ -from collections.abc import Iterable, Mapping, Sequence -from typing import Any -from typing_extensions import TypeAlias - -from . import fields - -RequestField = fields.RequestField - -writer: Any - -_TYPE_FIELDS_SEQUENCE: TypeAlias = Sequence[tuple[str, fields._FieldValueTuple] | RequestField] -_TYPE_FIELDS: TypeAlias = _TYPE_FIELDS_SEQUENCE | Mapping[str, fields._FieldValueTuple] - -def choose_boundary() -> str: ... -def iter_field_objects(fields: _TYPE_FIELDS) -> Iterable[RequestField]: ... -def iter_fields(fields): ... -def encode_multipart_formdata(fields: _TYPE_FIELDS, boundary: str | None = None) -> tuple[bytes, str]: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/packages/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/packages/__init__.pyi deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/poolmanager.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/poolmanager.pyi deleted file mode 100644 index 783197af8..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/poolmanager.pyi +++ /dev/null @@ -1,32 +0,0 @@ -from types import TracebackType -from typing import Any -from typing_extensions import Literal - -from .request import RequestMethods - -class PoolManager(RequestMethods): - proxy: Any - connection_pool_kw: Any - pools: Any - def __init__(self, num_pools=10, headers=None, **connection_pool_kw) -> None: ... - def __enter__(self): ... - def __exit__( - self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None - ) -> Literal[False]: ... - def clear(self): ... - def connection_from_host(self, host, port=None, scheme="http"): ... - def connection_from_url(self, url): ... - # TODO: This was the original signature -- copied another one from base class to fix complaint. - # def urlopen(self, method, url, redirect=True, **kw): ... - def urlopen(self, method, url, body=..., headers=..., encode_multipart=..., multipart_boundary=..., **kw): ... - -class ProxyManager(PoolManager): - proxy: Any - proxy_headers: Any - def __init__(self, proxy_url, num_pools=10, headers=None, proxy_headers=None, **connection_pool_kw) -> None: ... - def connection_from_host(self, host, port=None, scheme="http"): ... - # TODO: This was the original signature -- copied another one from base class to fix complaint. - # def urlopen(self, method, url, redirect=True, **kw): ... - def urlopen(self, method, url, body=..., headers=..., encode_multipart=..., multipart_boundary=..., **kw): ... - -def proxy_from_url(url, **kw): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/request.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/request.pyi deleted file mode 100644 index e9b14e225..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/request.pyi +++ /dev/null @@ -1,11 +0,0 @@ -from typing import Any - -class RequestMethods: - headers: Any - def __init__(self, headers=None) -> None: ... - def urlopen(self, method, url, body=None, headers=None, encode_multipart=True, multipart_boundary=None, **kw): ... - def request(self, method, url, fields=None, headers=None, **urlopen_kw): ... - def request_encode_url(self, method, url, fields=None, **urlopen_kw): ... - def request_encode_body( - self, method, url, fields=None, headers=None, encode_multipart=True, multipart_boundary=None, **urlopen_kw - ): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/response.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/response.pyi deleted file mode 100644 index ee28d2c01..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/response.pyi +++ /dev/null @@ -1,98 +0,0 @@ -import io -from collections.abc import Iterable, Iterator, Mapping -from http.client import HTTPMessage as _HttplibHTTPMessage, HTTPResponse as _HttplibHTTPResponse -from typing import IO, Any -from typing_extensions import Literal, Self, TypeAlias - -from urllib3.connectionpool import HTTPConnection - -from . import HTTPConnectionPool, Retry -from ._collections import HTTPHeaderDict - -_TYPE_BODY: TypeAlias = bytes | IO[Any] | Iterable[bytes] | str - -class DeflateDecoder: - def __getattr__(self, name: str) -> Any: ... - def decompress(self, data: bytes) -> bytes: ... - -class GzipDecoderState: - FIRST_MEMBER: Literal[0] - OTHER_MEMBERS: Literal[1] - SWALLOW_DATA: Literal[2] - -class GzipDecoder: - def __getattr__(self, name: str) -> Any: ... - def decompress(self, data: bytes) -> bytes: ... - -# This class is only available if -# `brotli` is available for import. -class BrotliDecoder: - def flush(self) -> bytes: ... - -class MultiDecoder: - def __init__(self, modes: str) -> None: ... - def flush(self) -> bytes: ... - def decompress(self, data: bytes) -> bytes: ... - -class HTTPResponse(io.IOBase): - CONTENT_DECODERS: list[str] - REDIRECT_STATUSES: list[int] - headers: HTTPHeaderDict - status: int - version: int - reason: str | None - strict: int - decode_content: bool - retries: Retry | None - enforce_content_length: bool - auto_close: bool - msg: _HttplibHTTPMessage | None - chunked: bool - chunk_left: int | None - length_remaining: int | None - def __init__( - self, - body: _TYPE_BODY = "", - headers: Mapping[str, str] | Mapping[bytes, bytes] | None = None, - status: int = 0, - version: int = 0, - reason: str | None = None, - strict: int = 0, - preload_content: bool = True, - decode_content: bool = True, - original_response: _HttplibHTTPResponse | None = None, - pool: HTTPConnectionPool | None = None, - connection: HTTPConnection | None = None, - msg: _HttplibHTTPMessage | None = None, - retries: Retry | None = None, - enforce_content_length: bool = False, - request_method: str | None = None, - request_url: str | None = None, - auto_close: bool = True, - ) -> None: ... - def get_redirect_location(self) -> Literal[False] | str | None: ... - def release_conn(self) -> None: ... - def drain_conn(self) -> None: ... - @property - def data(self) -> bytes | Any: ... - @property - def connection(self) -> HTTPConnection | Any: ... - def isclosed(self) -> bool: ... - def tell(self) -> int: ... - def read(self, amt: int | None = None, decode_content: bool | None = None, cache_content: bool = False) -> bytes: ... - def stream(self, amt: int | None = 65536, decode_content: bool | None = None) -> Iterator[bytes]: ... - @classmethod - def from_httplib(cls, r: _HttplibHTTPResponse, **response_kw: Any) -> Self: ... - def getheaders(self) -> HTTPHeaderDict: ... - def getheader(self, name, default=None) -> str | None: ... - def info(self) -> HTTPHeaderDict: ... - def close(self) -> None: ... - @property - def closed(self) -> bool: ... - def fileno(self) -> int: ... - def flush(self) -> None: ... - def readable(self) -> bool: ... - def readinto(self, b: bytearray) -> int: ... - def supports_chunked_reads(self) -> bool: ... - def read_chunked(self, amt: int | None = None, decode_content: bool | None = None) -> Iterator[bytes]: ... - def geturl(self) -> str | None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/__init__.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/__init__.pyi deleted file mode 100644 index 2d0d66dcb..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/__init__.pyi +++ /dev/null @@ -1,20 +0,0 @@ -import ssl - -from . import connection, request, response, retry, ssl_, timeout, url - -is_connection_dropped = connection.is_connection_dropped -make_headers = request.make_headers -is_fp_closed = response.is_fp_closed -SSLContext = ssl.SSLContext -HAS_SNI = ssl_.HAS_SNI -assert_fingerprint = ssl_.assert_fingerprint -resolve_cert_reqs = ssl_.resolve_cert_reqs -resolve_ssl_version = ssl_.resolve_ssl_version -ssl_wrap_socket = ssl_.ssl_wrap_socket -current_time = timeout.current_time -Timeout = timeout.Timeout -Retry = retry.Retry -get_host = url.get_host -parse_url = url.parse_url -split_first = url.split_first -Url = url.Url diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/connection.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/connection.pyi deleted file mode 100644 index 8d2e6c296..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/connection.pyi +++ /dev/null @@ -1,8 +0,0 @@ -from typing import Any - -poll: Any -select: Any -HAS_IPV6: bool - -def is_connection_dropped(conn): ... -def create_connection(address, timeout=..., source_address=None, socket_options=None): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/queue.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/queue.pyi deleted file mode 100644 index bffa68153..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/queue.pyi +++ /dev/null @@ -1,4 +0,0 @@ -from queue import Queue -from typing import Any - -class LifoQueue(Queue[Any]): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/request.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/request.pyi deleted file mode 100644 index a2f227120..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/request.pyi +++ /dev/null @@ -1,11 +0,0 @@ -from typing import Any - -# from ..packages import six - -# b = six.b - -ACCEPT_ENCODING: Any - -def make_headers( - keep_alive=None, accept_encoding=None, user_agent=None, basic_auth=None, proxy_basic_auth=None, disable_cache=None -): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/response.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/response.pyi deleted file mode 100644 index 30463da4e..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/response.pyi +++ /dev/null @@ -1 +0,0 @@ -def is_fp_closed(obj): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/retry.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/retry.pyi deleted file mode 100644 index d0f9cfe83..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/retry.pyi +++ /dev/null @@ -1,84 +0,0 @@ -import logging -from collections.abc import Collection -from types import TracebackType -from typing import Any, ClassVar, NamedTuple -from typing_extensions import Literal, Self - -from .. import exceptions -from ..connectionpool import ConnectionPool -from ..response import HTTPResponse - -ConnectTimeoutError = exceptions.ConnectTimeoutError -MaxRetryError = exceptions.MaxRetryError -ProtocolError = exceptions.ProtocolError -ReadTimeoutError = exceptions.ReadTimeoutError -ResponseError = exceptions.ResponseError - -log: logging.Logger - -class RequestHistory(NamedTuple): - method: str | None - url: str | None - error: Exception | None - status: int | None - redirect_location: str | None - -class Retry: - DEFAULT_ALLOWED_METHODS: ClassVar[frozenset[str]] - RETRY_AFTER_STATUS_CODES: ClassVar[frozenset[int]] - DEFAULT_REMOVE_HEADERS_ON_REDIRECT: ClassVar[frozenset[str]] - DEFAULT_BACKOFF_MAX: ClassVar[int] - - total: bool | int | None - connect: int | None - read: int | None - redirect: Literal[True] | int | None - status: int | None - other: int | None - allowed_methods: Collection[str] | Literal[False] | None - status_forcelist: Collection[int] - backoff_factor: float - raise_on_redirect: bool - raise_on_status: bool - history: tuple[RequestHistory, ...] - respect_retry_after_header: bool - remove_headers_on_redirect: frozenset[str] - def __init__( - self, - total: bool | int | None = 10, - connect: int | None = None, - read: int | None = None, - redirect: bool | int | None = None, - status: int | None = None, - other: int | None = None, - allowed_methods: Collection[str] | Literal[False] | None = ..., - status_forcelist: Collection[int] | None = None, - backoff_factor: float = 0, - raise_on_redirect: bool = True, - raise_on_status: bool = True, - history: tuple[RequestHistory, ...] | None = None, - respect_retry_after_header: bool = True, - remove_headers_on_redirect: Collection[str] = ..., - method_whitelist: Collection[str] | None = ..., - ) -> None: ... - def new(self, **kw: Any) -> Self: ... - @classmethod - def from_int( - cls, retries: Retry | bool | int | None, redirect: bool | int | None = True, default: Retry | bool | int | None = None - ) -> Retry: ... - def get_backoff_time(self) -> float: ... - def parse_retry_after(self, retry_after: str) -> float: ... - def get_retry_after(self, response: HTTPResponse) -> float | None: ... - def sleep_for_retry(self, response: HTTPResponse | None = None) -> bool: ... - def sleep(self, response: HTTPResponse | None = None) -> None: ... - def is_retry(self, method: str, status_code: int, has_retry_after: bool = False) -> bool: ... - def is_exhausted(self) -> bool: ... - def increment( - self, - method: str | None = None, - url: str | None = None, - response: HTTPResponse | None = None, - error: Exception | None = None, - _pool: ConnectionPool | None = None, - _stacktrace: TracebackType | None = None, - ) -> Retry: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/ssl_.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/ssl_.pyi deleted file mode 100644 index 999d3a336..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/ssl_.pyi +++ /dev/null @@ -1,31 +0,0 @@ -import ssl -from typing import Any - -from .. import exceptions - -SSLError = exceptions.SSLError -InsecurePlatformWarning = exceptions.InsecurePlatformWarning -SSLContext = ssl.SSLContext - -HAS_SNI: Any -create_default_context: Any -OP_NO_SSLv2: Any -OP_NO_SSLv3: Any -OP_NO_COMPRESSION: Any -DEFAULT_CIPHERS: str - -def assert_fingerprint(cert, fingerprint): ... -def resolve_cert_reqs(candidate): ... -def resolve_ssl_version(candidate): ... -def create_urllib3_context(ssl_version=None, cert_reqs=None, options=None, ciphers=None): ... -def ssl_wrap_socket( - sock, - keyfile=None, - certfile=None, - cert_reqs=None, - ca_certs=None, - server_hostname=None, - ssl_version=None, - ciphers=None, - ssl_context=None, -): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/ssl_match_hostname.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/ssl_match_hostname.pyi deleted file mode 100644 index d0e606fe2..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/ssl_match_hostname.pyi +++ /dev/null @@ -1,8 +0,0 @@ -from ssl import _PeerCertRetDictType -from typing_extensions import Final - -__version__: Final[str] - -class CertificateError(ValueError): ... - -def match_hostname(cert: _PeerCertRetDictType, hostname: str) -> None: ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/timeout.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/timeout.pyi deleted file mode 100644 index e9f2aad72..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/timeout.pyi +++ /dev/null @@ -1,21 +0,0 @@ -from typing import Any - -from .. import exceptions - -TimeoutStateError = exceptions.TimeoutStateError - -def current_time(): ... - -class Timeout: - DEFAULT_TIMEOUT: Any - total: Any - def __init__(self, total=None, connect=..., read=...) -> None: ... - @classmethod - def from_float(cls, timeout): ... - def clone(self): ... - def start_connect(self): ... - def get_connect_duration(self): ... - @property - def connect_timeout(self): ... - @property - def read_timeout(self): ... diff --git a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/url.pyi b/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/url.pyi deleted file mode 100644 index 678f09869..000000000 --- a/packages/pyright-internal/typeshed-fallback/stubs/urllib3/urllib3/util/url.pyi +++ /dev/null @@ -1,40 +0,0 @@ -from typing import NamedTuple - -from .. import exceptions - -LocationParseError = exceptions.LocationParseError - -url_attrs: list[str] - -class _UrlBase(NamedTuple): - auth: str | None - fragment: str | None - host: str | None - path: str | None - port: int | None - query: str | None - scheme: str | None - -class Url(_UrlBase): - def __new__( - cls, - scheme: str | None = None, - auth: str | None = None, - host: str | None = None, - port: int | None = None, - path: str | None = None, - query: str | None = None, - fragment: str | None = None, - ): ... - @property - def hostname(self) -> str | None: ... - @property - def request_uri(self) -> str: ... - @property - def netloc(self) -> str | None: ... - @property - def url(self) -> str: ... - -def split_first(s: str, delims: str) -> tuple[str, str, str | None]: ... -def parse_url(url: str) -> Url: ... -def get_host(url: str) -> tuple[str, str | None, str | None]: ... diff --git a/packages/pyright/package-lock.json b/packages/pyright/package-lock.json index 0b1543c1e..89ed40188 100644 --- a/packages/pyright/package-lock.json +++ b/packages/pyright/package-lock.json @@ -1,12 +1,12 @@ { "name": "@replit/pyright-extended", - "version": "2.0.6", + "version": "2.0.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@replit/pyright-extended", - "version": "2.0.6", + "version": "2.0.7", "license": "MIT", "bin": { "pyright": "index.js", diff --git a/packages/pyright/package.json b/packages/pyright/package.json index d6b8e2ef0..b4b6f230a 100644 --- a/packages/pyright/package.json +++ b/packages/pyright/package.json @@ -2,7 +2,7 @@ "name": "@replit/pyright-extended", "displayName": "pyright-extended", "description": "Extending pyright with yapf + ruff", - "version": "2.0.6", + "version": "2.0.7", "license": "MIT", "author": { "name": "Replit" diff --git a/packages/vscode-pyright/README.md b/packages/vscode-pyright/README.md index 7be170b1a..c985fde69 100644 --- a/packages/vscode-pyright/README.md +++ b/packages/vscode-pyright/README.md @@ -4,6 +4,7 @@ Pyright is a full-featured, standards-based static type checker for Python. It i Pyright includes both a [command-line tool](/docs/command-line.md) and an [extension for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-pyright.pyright). +For most VS Code users, we recommend using the Pylance extension rather than Pyright. Pylance incorporates the Pyright type checker but features additional capabilities such as semantic token highlighting and symbol indexing. When Pylance is installed, the Pyright extension will disable itself. ## Documentation diff --git a/packages/vscode-pyright/package-lock.json b/packages/vscode-pyright/package-lock.json index 21a74bb9a..dde945267 100644 --- a/packages/vscode-pyright/package-lock.json +++ b/packages/vscode-pyright/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-pyright", - "version": "1.1.328", + "version": "1.1.334", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-pyright", - "version": "1.1.328", + "version": "1.1.334", "license": "MIT", "dependencies": { "vscode-jsonrpc": "8.1.0", diff --git a/packages/vscode-pyright/package.json b/packages/vscode-pyright/package.json index c177f95a7..c44cffedb 100644 --- a/packages/vscode-pyright/package.json +++ b/packages/vscode-pyright/package.json @@ -2,7 +2,7 @@ "name": "vscode-pyright", "displayName": "Pyright", "description": "VS Code static type checking for Python", - "version": "1.1.328", + "version": "1.1.334", "private": true, "license": "MIT", "author": { @@ -159,6 +159,33 @@ ], "scope": "resource" }, + "python.analysis.include": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "description": "Paths of directories or files that should be included. If no paths are specified, pyright defaults to the workspace root directory. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character).", + "scope": "resource" + }, + "python.analysis.exclude": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "description": "Paths of directories or files that should not be included. These override the include directories, allowing specific subdirectories to be excluded. Note that files in the exclude paths may still be included in the analysis if they are referenced (imported) by source files that are not excluded. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character). If no exclude paths are specified, pyright automatically excludes the following: `**/node_modules`, `**/__pycache__`, `.git` and any virtual environment directories.", + "scope": "resource" + }, + "python.analysis.ignore": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "description": "Paths of directories or files whose diagnostic output (errors and warnings) should be suppressed even if they are an included file or within the transitive closure of an included file. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character). If no value is provided, the value of python.linting.ignorePatterns (if set) will be used.", + "scope": "resource" + }, "python.analysis.diagnosticSeverityOverrides": { "type": "object", "description": "Allows a user to override the severity levels for individual diagnostics.", diff --git a/packages/vscode-pyright/schemas/pyrightconfig.schema.json b/packages/vscode-pyright/schemas/pyrightconfig.schema.json index e2142878c..956318fd2 100644 --- a/packages/vscode-pyright/schemas/pyrightconfig.schema.json +++ b/packages/vscode-pyright/schemas/pyrightconfig.schema.json @@ -112,6 +112,12 @@ ], "pattern": "^(.*)$" }, + "disableBytesTypePromotions": { + "$id": "#/properties/disableBytesTypePromotions", + "type": "boolean", + "title": "Do not treat `bytearray` and `memoryview` as implicit subtypes of `bytes`", + "default": false + }, "strictListInference": { "$id": "#/properties/strictListInference", "type": "boolean", diff --git a/packages/vscode-pyright/src/extension.ts b/packages/vscode-pyright/src/extension.ts index d10422cfa..54ead952a 100644 --- a/packages/vscode-pyright/src/extension.ts +++ b/packages/vscode-pyright/src/extension.ts @@ -22,13 +22,14 @@ import { TextEditorEdit, Uri, window, + workspace, + WorkspaceConfiguration, } from 'vscode'; import { CancellationToken, ConfigurationParams, ConfigurationRequest, DidChangeConfigurationNotification, - HandlerResult, LanguageClient, LanguageClientOptions, ResponseError, @@ -109,26 +110,38 @@ export async function activate(context: ExtensionContext) { // us to inject the proper "python.pythonPath" setting from the Python extension's // private settings store. workspace: { - configuration: ( + configuration: async ( params: ConfigurationParams, token: CancellationToken, next: ConfigurationRequest.HandlerSignature - ): HandlerResult => { - // Hand-collapse "Thenable | Thenable | Thenable" into just "Thenable" to make TS happy. - const result: any[] | ResponseError | Thenable> = next( - params, - token - ); + ) => { + let result = next(params, token); + if (isThenable(result)) { + result = await result; + } + if (result instanceof ResponseError) { + return result; + } - // For backwards compatibility, set python.pythonPath to the configured - // value as though it were in the user's settings.json file. - const addPythonPath = ( - settings: any[] | ResponseError - ): Promise> => { - if (settings instanceof ResponseError) { - return Promise.resolve(settings); + for (const [i, item] of params.items.entries()) { + if (item.section === 'python.analysis') { + const analysisConfig = workspace.getConfiguration( + item.section, + item.scopeUri ? Uri.parse(item.scopeUri) : undefined + ); + + // If stubPath is not set, remove it rather than sending default value. + // This lets the server know that it's unset rather than explicitly + // set to the default value (typings) so it can behave differently. + if (!isConfigSettingSetByUser(analysisConfig, 'stubPath')) { + delete (result[i] as any).stubPath; + } } + } + // For backwards compatibility, set python.pythonPath to the configured + // value as though it were in the user's settings.json file. + const addPythonPath = (settings: any[]): Promise => { const pythonPathPromises: Promise[] = params.items.map((item) => { if (item.section === 'python') { const uri = item.scopeUri ? Uri.parse(item.scopeUri) : undefined; @@ -156,10 +169,6 @@ export async function activate(context: ExtensionContext) { }); }; - if (isThenable(result)) { - return result.then(addPythonPath); - } - return addPythonPath(result); }, }, @@ -373,3 +382,19 @@ function installPythonPathChangedListener( pythonPathChangedListenerMap.set(uriString, uriString); } + +function isConfigSettingSetByUser(configuration: WorkspaceConfiguration, setting: string): boolean { + const inspect = configuration.inspect(setting); + if (inspect === undefined) { + return false; + } + + return ( + inspect.globalValue !== undefined || + inspect.workspaceValue !== undefined || + inspect.workspaceFolderValue !== undefined || + inspect.globalLanguageValue !== undefined || + inspect.workspaceLanguageValue !== undefined || + inspect.workspaceFolderLanguageValue !== undefined + ); +}