From 4938b84bc88a32827834a59cf2d5679a6f2bb2c0 Mon Sep 17 00:00:00 2001 From: Rafal Chlodnicki Date: Tue, 12 Dec 2023 01:35:20 +0100 Subject: [PATCH 1/6] chore(ci): add script and workflow for auto-updating schema --- .github/workflows/schema.yml | 41 ++ Makefile | 4 + scripts/update_schema.py | 89 ++++ sublime-package.json | 763 +++++++---------------------------- 4 files changed, 276 insertions(+), 621 deletions(-) create mode 100644 .github/workflows/schema.yml create mode 100755 scripts/update_schema.py diff --git a/.github/workflows/schema.yml b/.github/workflows/schema.yml new file mode 100644 index 0000000..0af9196 --- /dev/null +++ b/.github/workflows/schema.yml @@ -0,0 +1,41 @@ +name: Update schema in Dependabot PR + +on: + pull_request: + branches: + - master + +permissions: + pull-requests: write + repository-projects: write + +jobs: + update_schema: + name: Run schema update + runs-on: ubuntu-latest + + if: github.actor == 'dependabot[bot]' + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Update schema + run: | + make update-schema + + - name: Check for modified files + id: git-check + run: echo ::set-output name=modified::$(if [ -n "$(git status --porcelain)" ]; then echo "true"; else echo "false"; fi) + + - name: Update changes in the PR + if: steps.git-check.outputs.modified == 'true' + run: | + git config --global user.name 'workflow' + git config --global user.email 'worklow@workflow.com' + git add -A + git commit -m '[automated commit] update schema' + git push diff --git a/Makefile b/Makefile index ed3a23d..121fea3 100644 --- a/Makefile +++ b/Makefile @@ -13,3 +13,7 @@ fix: autoflake --in-place . black --preview . isort . + +.PHONY: update-schema +update-schema: + python3 ./scripts/update_schema.py diff --git a/scripts/update_schema.py b/scripts/update_schema.py new file mode 100755 index 0000000..bc428b7 --- /dev/null +++ b/scripts/update_schema.py @@ -0,0 +1,89 @@ +from json import dump, load +from typing import Any, Dict, Optional +from urllib.request import urlopen +import os + +DIRNAME = os.path.dirname(os.path.abspath(__file__)) +PYRIGHTCONFIG_SCHEMA_ID = 'sublime://pyrightconfig' +PYRIGHT_CONFIGURATION_SCHEMA_URL = 'https://raw.githubusercontent.com/microsoft/pyright/main/packages/vscode-pyright/schemas/pyrightconfig.schema.json' # noqa: E501 +SUBLIME_PACKAGE_JSON_PATH = os.path.join(DIRNAME, '..', 'sublime-package.json') +# Keys that are in the schema for pyrighconfig.json but should not raise a comment when not present in LSP schema. +IGNORED_PYRIGHTCONFIG_KEYS = [ + 'defineConstant', + 'exclude', + 'executionEnvironments', + 'ignore', + 'include', + 'pythonPlatform', + 'pythonVersion', + 'strict', + 'typeshedPath', + 'venv', + 'verboseOutput', +] + +JSON = Dict[str, Any] + + +def main() -> None: + pyrightconfig_schema_json = None + sublime_package_json = None + with urlopen(PYRIGHT_CONFIGURATION_SCHEMA_URL) as response: + pyrightconfig_schema_json = load(response) + with open(SUBLIME_PACKAGE_JSON_PATH, 'r', encoding='utf-8') as f: + sublime_package_json = load(f) + update_schema(sublime_package_json, pyrightconfig_schema_json) + with open(SUBLIME_PACKAGE_JSON_PATH, 'w', encoding='utf-8') as f: + dump(sublime_package_json, f, indent=2) + print('sublime-package.json file updated! If there are any changes then make sure to also update the LSP part of the configuration.') # noqa: E501 + + +def update_schema(sublime_package_json: JSON, pyrightconfig_schema_json: JSON) -> None: + pyrightconfig_contribution: Optional[JSON] = None + lsp_pyright_contribution: Optional[JSON] = None + for contribution in sublime_package_json['contributions']['settings']: + if '/pyrightconfig.json' in contribution['file_patterns']: + pyrightconfig_contribution = contribution + elif '/LSP-pyright.sublime-settings' in contribution['file_patterns']: + lsp_pyright_contribution = contribution + if not pyrightconfig_contribution or not lsp_pyright_contribution: + raise Exception('Expected contributions not found in sublime-package.json!') + # Update to latest pyrightconfig schema. + pyrightconfig_contribution['schema'] = pyrightconfig_schema_json + # Add ID. + pyrightconfig_contribution['schema']['$id'] = PYRIGHTCONFIG_SCHEMA_ID + # Update LSP settings to reference options from the pyrightconfig schema. + settings_properties: JSON = lsp_pyright_contribution['schema']['definitions']['PluginConfig']['properties']['settings']['properties'] # noqa: E501 + pyrightconfig_properties: JSON = pyrightconfig_contribution['schema']['properties'] + for setting_key, setting_value in settings_properties.items(): + # get last dotted component. + last_component_key = setting_key.split('.').pop() + if last_component_key in pyrightconfig_properties: + update_property_ref(last_component_key, setting_value, pyrightconfig_properties) + if setting_key == 'python.analysis.diagnosticSeverityOverrides': + overrides_properties: JSON = setting_value['properties'] + for override_key, override_value in overrides_properties.items(): + if override_key in pyrightconfig_properties: + update_property_ref(override_key, override_value, pyrightconfig_properties) + else: + del overrides_properties[override_key] + # Check if there are any properties that might need to be added to the LSP properties. + # If the property is neither in `diagnosticSeverityOverrides`, the root LSP settings nor in ignored keys + # then it might have to be added manually. + all_settings_keys = list(map(lambda k: k.split('.').pop(), settings_properties.keys())) + all_overrides_keys = settings_properties['python.analysis.diagnosticSeverityOverrides']['properties'].keys() + for pyrightconfig_key in pyrightconfig_properties.keys(): + if pyrightconfig_key not in all_settings_keys \ + and pyrightconfig_key not in all_overrides_keys \ + and pyrightconfig_key not in IGNORED_PYRIGHTCONFIG_KEYS: + print(pyrightconfig_key) + + +def update_property_ref(property_key: str, property_schema: JSON, pyrightconfig_properties: JSON) -> None: + property_schema.clear() + pyrightconfig_property_id: str = pyrightconfig_properties[property_key]['$id'] + property_schema['$ref'] = PYRIGHTCONFIG_SCHEMA_ID + pyrightconfig_property_id + + +if __name__ == '__main__': + main() diff --git a/sublime-package.json b/sublime-package.json index bd29dc0..c1e07db 100644 --- a/sublime-package.json +++ b/sublime-package.json @@ -21,7 +21,6 @@ "settings": { "additionalProperties": false, "properties": { - // lsp "pyright.dev_environment": { "default": "", "description": "Enables the pre-defined environment setup for specific developing needs.", @@ -38,8 +37,6 @@ "Similar to \"sublime_text\" but Python 3.8 forced." ] }, - // pyright - // @see https://github.com/microsoft/pyright/blob/main/packages/vscode-pyright/package.json "pyright.disableLanguageServices": { "default": false, "description": "Disables type completion, definitions, and references.", @@ -75,720 +72,230 @@ "python.analysis.diagnosticSeverityOverrides": { "description": "Allows a user to override the severity levels for individual diagnostics.", "properties": { + "analyzeUnannotatedFunctions": { + "$ref": "sublime://pyrightconfig#/properties/analyzeUnannotatedFunctions" + }, + "deprecateTypingAliases": { + "$ref": "sublime://pyrightconfig#/properties/deprecateTypingAliases" + }, + "disableBytesTypePromotions": { + "$ref": "sublime://pyrightconfig#/properties/disableBytesTypePromotions" + }, + "enableExperimentalFeatures": { + "$ref": "sublime://pyrightconfig#/properties/enableExperimentalFeatures" + }, + "enableTypeIgnoreComments": { + "$ref": "sublime://pyrightconfig#/properties/enableTypeIgnoreComments" + }, "reportAssertAlwaysTrue": { - "default": "warning", - "description": "Diagnostics for 'assert' statement that will provably always assert. This can be indicative of a programming error.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportAssertAlwaysTrue" }, "reportCallInDefaultInitializer": { - "default": "none", - "description": "Diagnostics for function calls within a default value initialization expression. Such calls can mask expensive operations that are performed at module initialization time.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportCallInDefaultInitializer" }, "reportConstantRedefinition": { - "default": "none", - "description": "Diagnostics for attempts to redefine variables whose names are all-caps with underscores and numerals.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportConstantRedefinition" }, "reportDeprecated": { - "default": "none", - "description": "Diagnostics for use of deprecated classes or functions.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportDeprecated" }, "reportDuplicateImport": { - "default": "none", - "description": "Diagnostics for an imported symbol or module that is imported more than once.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportDuplicateImport" }, "reportFunctionMemberAccess": { - "default": "none", - "description": "Diagnostics for member accesses on functions.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportFunctionMemberAccess" }, "reportGeneralTypeIssues": { - "default": "error", - "description": "Diagnostics for general type inconsistencies, unsupported operations, argument/parameter mismatches, etc. Covers all of the basic type-checking rules not covered by other rules. Does not include syntax errors.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportGeneralTypeIssues" }, "reportImplicitOverride": { - "default": "none", - "description": "Diagnostics for overridden methods that do not include an `@override` decorator.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportImplicitOverride" }, "reportImplicitStringConcatenation": { - "default": "none", - "description": "Diagnostics for two or more string literals that follow each other, indicating an implicit concatenation. This is considered a bad practice and often masks bugs such as missing commas.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportImplicitStringConcatenation" }, "reportImportCycles": { - "default": "none", - "description": "Diagnostics for cyclical import chains. These are not errors in Python, but they do slow down type analysis and often hint at architectural layering issues. Generally, they should be avoided.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportImportCycles" }, "reportIncompatibleMethodOverride": { - "default": "none", - "description": "Diagnostics for methods that override a method of the same name in a base class in an incompatible manner (wrong number of parameters, incompatible parameter types, or incompatible return type).", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportIncompatibleMethodOverride" }, "reportIncompatibleVariableOverride": { - "default": "none", - "description": "Diagnostics for overrides in subclasses that redefine a variable in an incompatible way.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportIncompatibleVariableOverride" }, "reportIncompleteStub": { - "default": "none", - "description": "Diagnostics for the use of a module-level \u201c__getattr__\u201d function, indicating that the stub is incomplete.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportIncompleteStub" }, "reportInconsistentConstructor": { - "default": "none", - "description": "Diagnostics for __init__ and __new__ methods whose signatures are inconsistent.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportInconsistentConstructor" }, "reportInvalidStringEscapeSequence": { - "default": "warning", - "description": "Diagnostics for invalid escape sequences used within string literals. The Python specification indicates that such sequences will generate a syntax error in future versions.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportInvalidStringEscapeSequence" }, "reportInvalidStubStatement": { - "default": "none", - "description": "Diagnostics for type stub statements that do not conform to PEP 484.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportInvalidStubStatement" }, "reportInvalidTypeVarUse": { - "default": "warning", - "description": "Diagnostics for improper use of type variables in a function signature.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportInvalidTypeVarUse" }, "reportMatchNotExhaustive": { - "default": "none", - "description": "Diagnostics for 'match' statements that do not exhaustively match all possible values.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportMatchNotExhaustive" }, "reportMissingImports": { - "default": "error", - "description": "Diagnostics for imports that have no corresponding imported python file or type stub file.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportMissingImports" }, "reportMissingModuleSource": { - "default": "warning", - "description": "Diagnostics for imports that have no corresponding source file. This happens when a type stub is found, but the module source file was not found, indicating that the code may fail at runtime when using this execution environment. Type checking will be done using the type stub.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportMissingModuleSource" }, "reportMissingParameterType": { - "default": "none", - "description": "Diagnostics for parameters that are missing a type annotation.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportMissingParameterType" }, "reportMissingSuperCall": { - "default": "none", - "description": "Diagnostics for missing call to parent class for inherited `__init__` methods.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportMissingSuperCall" }, "reportMissingTypeArgument": { - "default": "none", - "description": "Diagnostics for generic class reference with missing type arguments.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportMissingTypeArgument" }, "reportMissingTypeStubs": { - "default": "none", - "description": "Diagnostics for imports that have no corresponding type stub file (either a typeshed file or a custom type stub). The type checker requires type stubs to do its best job at analysis.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportMissingTypeStubs" }, "reportOptionalCall": { - "default": "error", - "description": "Diagnostics for an attempt to call a variable with an Optional type.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportOptionalCall" }, "reportOptionalContextManager": { - "default": "error", - "description": "Diagnostics for an attempt to use an Optional type as a context manager (as a parameter to a with statement).", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportOptionalContextManager" }, "reportOptionalIterable": { - "default": "error", - "description": "Diagnostics for an attempt to use an Optional type as an iterable value (e.g. within a for statement).", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportOptionalIterable" }, "reportOptionalMemberAccess": { - "default": "error", - "description": "Diagnostics for an attempt to access a member of a variable with an Optional type.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportOptionalMemberAccess" }, "reportOptionalOperand": { - "default": "error", - "description": "Diagnostics for an attempt to use an Optional type as an operand to a binary or unary operator (like '+', '==', 'or', 'not').", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportOptionalOperand" }, "reportOptionalSubscript": { - "default": "error", - "description": "Diagnostics for an attempt to subscript (index) a variable with an Optional type.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportOptionalSubscript" }, "reportOverlappingOverload": { - "default": "none", - "description": "Diagnostics for function overloads that overlap in signature and obscure each other or have incompatible return types.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportOverlappingOverload" }, "reportPrivateImportUsage": { - "default": "error", - "description": "Diagnostics for incorrect usage of symbol imported from a \"py.typed\" module that is not re-exported from that module.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportPrivateImportUsage" }, "reportPrivateUsage": { - "default": "none", - "description": "Diagnostics for incorrect usage of private or protected variables or functions. Protected class members begin with a single underscore _ and can be accessed only by subclasses. Private class members begin with a double underscore but do not end in a double underscore and can be accessed only within the declaring class. Variables and functions declared outside of a class are considered private if their names start with either a single or double underscore, and they cannot be accessed outside of the declaring module.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportPrivateUsage" }, "reportPropertyTypeMismatch": { - "default": "none", - "description": "Diagnostics for property whose setter and getter have mismatched types.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportPropertyTypeMismatch" }, "reportSelfClsParameterName": { - "default": "warning", - "description": "Diagnostics for a missing or misnamed \u201cself\u201d parameter in instance methods and \u201ccls\u201d parameter in class methods. Instance methods in metaclasses (classes that derive from \u201ctype\u201d) are allowed to use \u201ccls\u201d for instance methods.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportSelfClsParameterName" }, "reportShadowedImports": { - "default": "none", - "description": "Diagnostics for files that are overriding a module in the stdlib.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportShadowedImports" }, "reportTypeCommentUsage": { - "default": "none", - "description": "Diagnostics for usage of deprecated type comments.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportTypeCommentUsage" }, "reportTypedDictNotRequiredAccess": { - "default": "error", - "description": "Diagnostics for an attempt to access a non-required key within a TypedDict without a check for its presence.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportTypedDictNotRequiredAccess" }, "reportUnboundVariable": { - "default": "error", - "description": "Diagnostics for unbound and possibly unbound variables.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnboundVariable" }, "reportUndefinedVariable": { - "default": "error", - "description": "Diagnostics for undefined variables.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUndefinedVariable" }, "reportUninitializedInstanceVariable": { - "default": "none", - "description": "Diagnostics for instance variables that are not declared or initialized within class body or `__init__` method.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUninitializedInstanceVariable" }, "reportUnknownArgumentType": { - "default": "none", - "description": "Diagnostics for call arguments for functions or methods that have an unknown type.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnknownArgumentType" }, "reportUnknownLambdaType": { - "default": "none", - "description": "Diagnostics for input or return parameters for lambdas that have an unknown type.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnknownLambdaType" }, "reportUnknownMemberType": { - "default": "none", - "description": "Diagnostics for class or instance variables that have an unknown type.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnknownMemberType" }, "reportUnknownParameterType": { - "default": "none", - "description": "Diagnostics for input or return parameters for functions or methods that have an unknown type.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnknownParameterType" }, "reportUnknownVariableType": { - "default": "none", - "description": "Diagnostics for variables that have an unknown type..", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnknownVariableType" }, "reportUnnecessaryCast": { - "default": "none", - "description": "Diagnostics for 'cast' calls that are statically determined to be unnecessary. Such calls are sometimes indicative of a programming error.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnnecessaryCast" }, "reportUnnecessaryComparison": { - "default": "none", - "description": "Diagnostics for '==' and '!=' comparisons that are statically determined to be unnecessary. Such calls are sometimes indicative of a programming error.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnnecessaryComparison" }, "reportUnnecessaryContains": { - "default": "none", - "description": "Diagnostics for 'in' operation that is statically determined to be unnecessary. Such operations are sometimes indicative of a programming error.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnnecessaryContains" }, "reportUnnecessaryIsInstance": { - "default": "none", - "description": "Diagnostics for 'isinstance' or 'issubclass' calls where the result is statically determined to be always true. Such calls are often indicative of a programming error.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnnecessaryIsInstance" }, "reportUnnecessaryTypeIgnoreComment": { - "default": "none", - "description": "Diagnostics for '# type: ignore' comments that have no effect.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnnecessaryTypeIgnoreComment" }, "reportUnsupportedDunderAll": { - "default": "warning", - "description": "Diagnostics for unsupported operations performed on __all__.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnsupportedDunderAll" }, "reportUntypedBaseClass": { - "default": "none", - "description": "Diagnostics for base classes whose type cannot be determined statically. These obscure the class type, defeating many type analysis features.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUntypedBaseClass" }, "reportUntypedClassDecorator": { - "default": "none", - "description": "Diagnostics for class decorators that have no type annotations. These obscure the class type, defeating many type analysis features.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUntypedClassDecorator" }, "reportUntypedFunctionDecorator": { - "default": "none", - "description": "Diagnostics for function decorators that have no type annotations. These obscure the function type, defeating many type analysis features.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUntypedFunctionDecorator" }, "reportUntypedNamedTuple": { - "default": "none", - "description": "Diagnostics when \u201cnamedtuple\u201d is used rather than \u201cNamedTuple\u201d. The former contains no type information, whereas the latter does.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUntypedNamedTuple" }, "reportUnusedCallResult": { - "default": "none", - "description": "Diagnostics for call expressions whose results are not consumed and are not None.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnusedCallResult" }, "reportUnusedClass": { - "default": "none", - "description": "Diagnostics for a class with a private name (starting with an underscore) that is not accessed.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnusedClass" }, "reportUnusedCoroutine": { - "default": "error", - "description": "Diagnostics for call expressions that return a Coroutine and whose results are not consumed.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnusedCoroutine" }, "reportUnusedExpression": { - "default": "warning", - "description": "Diagnostics for simple expressions whose value is not used in any way.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnusedExpression" }, "reportUnusedFunction": { - "default": "none", - "description": "Diagnostics for a function or method with a private name (starting with an underscore) that is not accessed.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnusedFunction" }, "reportUnusedImport": { - "default": "none", - "description": "Diagnostics for an imported symbol that is not referenced within that file.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnusedImport" }, "reportUnusedVariable": { - "default": "none", - "description": "Diagnostics for a variable that is not accessed.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportUnusedVariable" }, "reportWildcardImportFromLibrary": { - "default": "warning", - "description": "Diagnostics for an wildcard import from an external library.", - "enum": [ - "none", - "information", - "warning", - "error" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/reportWildcardImportFromLibrary" + }, + "strictDictionaryInference": { + "$ref": "sublime://pyrightconfig#/properties/strictDictionaryInference" + }, + "strictListInference": { + "$ref": "sublime://pyrightconfig#/properties/strictListInference" + }, + "strictParameterNoneValue": { + "$ref": "sublime://pyrightconfig#/properties/strictParameterNoneValue" + }, + "strictSetInference": { + "$ref": "sublime://pyrightconfig#/properties/strictSetInference" } }, "type": "object" }, "python.analysis.extraPaths": { - "default": [], - "description": "Additional import search resolution paths", - "items": { - "type": "string" - }, - "type": "array" + "$ref": "sublime://pyrightconfig#/properties/extraPaths" }, "python.analysis.logLevel": { "default": "Information", @@ -802,19 +309,10 @@ "type": "string" }, "python.analysis.stubPath": { - "default": "typings", - "description": "Path to directory containing custom type stub files.", - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/stubPath" }, "python.analysis.typeCheckingMode": { - "default": "basic", - "description": "Defines the default rule set for type checking.", - "enum": [ - "off", - "basic", - "strict" - ], - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/typeCheckingMode" }, "python.analysis.typeshedPaths": { "default": [], @@ -825,9 +323,7 @@ "type": "array" }, "python.analysis.useLibraryCodeForTypes": { - "default": true, - "description": "Use library implementations to extract type information when type stub is not present.", - "type": "boolean" + "$ref": "sublime://pyrightconfig#/properties/useLibraryCodeForTypes" }, "python.pythonPath": { "default": "python", @@ -835,9 +331,7 @@ "type": "string" }, "python.venvPath": { - "default": "", - "description": "Path to folder with a list of Virtual Environments.", - "type": "string" + "$ref": "sublime://pyrightconfig#/properties/venvPath" } } } @@ -850,7 +344,6 @@ "file_patterns": [ "/pyrightconfig.json" ], - // @see https://github.com/microsoft/pyright/blob/main/packages/vscode-pyright/schemas/pyrightconfig.schema.json "schema": { "$schema": "http://json-schema.org/draft-07/schema#", "description": "Pyright Configuration Schema", @@ -924,11 +417,13 @@ "$id": "#/properties/defineConstant", "type": "object", "title": "Identifiers that should be treated as constants", - "properties": { - }, + "properties": {}, "additionalProperties": { - "type": ["string", "boolean"], - "title": "Value of constant (boolean or string)" + "type": [ + "string", + "boolean" + ], + "title": "Value of constant (boolean or string)" } }, "typeCheckingMode": { @@ -937,16 +432,17 @@ "enum": [ "off", "basic", + "standard", "strict" ], "title": "Specifies the default rule set to use for type checking", - "default": "basic" + "default": "standard" }, "useLibraryCodeForTypes": { "$id": "#/properties/useLibraryCodeForTypes", "type": "boolean", "title": "Use library implementations to extract type information when type stub is not present", - "default": false + "default": true }, "typeshedPath": { "$id": "#/properties/typeshedPath", @@ -965,6 +461,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", @@ -995,12 +497,24 @@ "title": "Allow implicit Optional when default parameter value is None", "default": true }, + "enableExperimentalFeatures": { + "$id": "#/properties/enableExperimentalFeatures", + "type": "boolean", + "title": "Enable the use of experimental features that are not part of the Python typing spec", + "default": true + }, "enableTypeIgnoreComments": { "$id": "#/properties/enableTypeIgnoreComments", "type": "boolean", "title": "Allow \"# type: ignore\" comments", "default": true }, + "deprecateTypingAliases": { + "$id": "#/properties/deprecateTypingAliases", + "type": "boolean", + "title": "Treat typing-specific aliases to standard types as deprecated", + "default": true + }, "reportGeneralTypeIssues": { "$id": "#/properties/reportGeneralTypeIssues", "$ref": "#/definitions/diagnostic", @@ -1017,7 +531,7 @@ "$id": "#/properties/reportFunctionMemberAccess", "$ref": "#/definitions/diagnostic", "title": "Controls reporting of member accesses on function objects", - "default": "none" + "default": "error" }, "reportMissingImports": { "$id": "#/properties/reportMissingImports", @@ -1169,17 +683,23 @@ "title": "Controls reporting of attempts to redefine variables that are in all-caps", "default": "none" }, + "reportDeprecated": { + "$id": "#/properties/reportDeprecated", + "$ref": "#/definitions/diagnostic", + "title": "Controls reporting of use of deprecated class or function", + "default": "none" + }, "reportIncompatibleMethodOverride": { "$id": "#/properties/reportIncompatibleMethodOverride", "$ref": "#/definitions/diagnostic", "title": "Controls reporting of method overrides in subclasses that redefine the method in an incompatible way", - "default": "none" + "default": "error" }, "reportIncompatibleVariableOverride": { "$id": "#/properties/reportIncompatibleVariableOverride", "$ref": "#/definitions/diagnostic", "title": "Controls reporting of overrides in subclasses that redefine a variable in an incompatible way", - "default": "none" + "default": "error" }, "reportInconsistentConstructor": { "$id": "#/properties/reportInconsistentConstructor", @@ -1191,7 +711,7 @@ "$id": "#/properties/reportOverlappingOverload", "$ref": "#/definitions/diagnostic", "title": "Controls reporting of function overloads that overlap in signature and obscure each other or do not agree on return type", - "default": "none" + "default": "error" }, "reportMissingSuperCall": { "$id": "#/properties/reportMissingSuperCall", @@ -1301,12 +821,6 @@ "title": "Controls reporting assert expressions that will always evaluate to true", "default": "warning" }, - "reportImplicitOverride": { - "$id": "#/properties/reportImplicitOverride", - "$ref": "#/definitions/diagnostic", - "title": "Controls reporting overridden methods that are missing an `@override` decorator", - "default": "none" - }, "reportImplicitStringConcatenation": { "$id": "#/properties/reportImplicitStringConcatenation", "$ref": "#/definitions/diagnostic", @@ -1379,6 +893,12 @@ "title": "Controls reporting of shadowed imports of stdlib modules", "default": "none" }, + "reportImplicitOverride": { + "$id": "#/properties/reportImplicitOverride", + "$ref": "#/definitions/diagnostic", + "title": "Controls reporting overridden methods that are missing an `@override` decorator", + "default": "none" + }, "extraPaths": { "$id": "#/properties/extraPaths", "type": "array", @@ -1488,7 +1008,8 @@ } } } - } + }, + "$id": "sublime://pyrightconfig" } }, { @@ -1513,4 +1034,4 @@ } ] } -} +} \ No newline at end of file From 0c91f0d216a5cad98f5ee008fe27315bcdf6aaa2 Mon Sep 17 00:00:00 2001 From: Rafal Chlodnicki Date: Tue, 12 Dec 2023 01:48:09 +0100 Subject: [PATCH 2/6] exclude script from horrible formatting --- pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a82cf48..7a4be92 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ skip_glob = [ "branch-*/**", "libs/**", "resources/**", + "scripts/**", "stubs/**", "typings/**", "vendor/**", @@ -20,7 +21,7 @@ skip_glob = [ quiet = true recursive = true remove-all-unused-imports = true -exclude = '\.git,\.?venv(-.*)?,\.mypy_cache,br-.*,branch-.*,libs,stubs,tests/files,typings' +exclude = '\.git,\.?venv(-.*)?,\.mypy_cache,br-.*,branch-.*,libs,scripts,stubs,tests/files,typings' [tool.black] preview = true # use latest feature @@ -33,6 +34,7 @@ exclude = ''' language-server | plugin/libs | resources | + scripts | stubs | typings | _resources From 9df0f60f8401461be19681c1c673faeec4644a26 Mon Sep 17 00:00:00 2001 From: Rafal Chlodnicki Date: Tue, 12 Dec 2023 07:57:13 +0100 Subject: [PATCH 3/6] update defaults after upstream update --- sublime-package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sublime-package.json b/sublime-package.json index c1e07db..bb536f8 100644 --- a/sublime-package.json +++ b/sublime-package.json @@ -501,7 +501,7 @@ "$id": "#/properties/enableExperimentalFeatures", "type": "boolean", "title": "Enable the use of experimental features that are not part of the Python typing spec", - "default": true + "default": false }, "enableTypeIgnoreComments": { "$id": "#/properties/enableTypeIgnoreComments", @@ -513,7 +513,7 @@ "$id": "#/properties/deprecateTypingAliases", "type": "boolean", "title": "Treat typing-specific aliases to standard types as deprecated", - "default": true + "default": false }, "reportGeneralTypeIssues": { "$id": "#/properties/reportGeneralTypeIssues", @@ -549,7 +549,7 @@ "$id": "#/properties/reportMissingTypeStubs", "$ref": "#/definitions/diagnostic", "title": "Controls reporting of imports that cannot be resolved to type stub files", - "default": "none" + "default": "warning" }, "reportImportCycles": { "$id": "#/properties/reportImportCycles", @@ -591,7 +591,7 @@ "$id": "#/properties/reportWildcardImportFromLibrary", "$ref": "#/definitions/diagnostic", "title": "Controls reporting of wlidcard import from external library", - "default": "none" + "default": "warning" }, "reportOptionalSubscript": { "$id": "#/properties/reportOptionalSubscript", From feb52a4635a66c2ff8218e15a1492c470a973c80 Mon Sep 17 00:00:00 2001 From: Rafal Chlodnicki Date: Tue, 12 Dec 2023 08:06:43 +0100 Subject: [PATCH 4/6] wording --- scripts/update_schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_schema.py b/scripts/update_schema.py index bc428b7..da35e44 100755 --- a/scripts/update_schema.py +++ b/scripts/update_schema.py @@ -7,7 +7,7 @@ PYRIGHTCONFIG_SCHEMA_ID = 'sublime://pyrightconfig' PYRIGHT_CONFIGURATION_SCHEMA_URL = 'https://raw.githubusercontent.com/microsoft/pyright/main/packages/vscode-pyright/schemas/pyrightconfig.schema.json' # noqa: E501 SUBLIME_PACKAGE_JSON_PATH = os.path.join(DIRNAME, '..', 'sublime-package.json') -# Keys that are in the schema for pyrighconfig.json but should not raise a comment when not present in LSP schema. +# Keys that are in the pyrightconfig.json schema but should not raise a comment when not present in the LSP schema. IGNORED_PYRIGHTCONFIG_KEYS = [ 'defineConstant', 'exclude', From 5e097a1d1a6a00793b560b5bd09753a7cb4bc067 Mon Sep 17 00:00:00 2001 From: Rafal Chlodnicki Date: Tue, 12 Dec 2023 09:49:19 +0100 Subject: [PATCH 5/6] add pr comment --- .github/workflows/schema.yml | 21 ++++++++++++++++++++- scripts/update_schema.py | 36 +++++++++++++++++++++++++----------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/.github/workflows/schema.yml b/.github/workflows/schema.yml index 0af9196..5613090 100644 --- a/.github/workflows/schema.yml +++ b/.github/workflows/schema.yml @@ -24,8 +24,9 @@ jobs: python-version: 3.11 - name: Update schema + id: update-schema run: | - make update-schema + echo "::set-output name=UPDATE_OUTPUT::$(make update-schema)" - name: Check for modified files id: git-check @@ -39,3 +40,21 @@ jobs: git add -A git commit -m '[automated commit] update schema' git push + + - name: Find Comment + uses: peter-evans/find-comment@v2 + id: find-comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: Build output + + - name: Create or update comment + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ steps.find-comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + schema-update output: + ${{ steps.update-schema.outputs.UPDATE_OUTPUT }} + edit-mode: replace diff --git a/scripts/update_schema.py b/scripts/update_schema.py index da35e44..a72a7fa 100755 --- a/scripts/update_schema.py +++ b/scripts/update_schema.py @@ -1,5 +1,5 @@ -from json import dump, load -from typing import Any, Dict, Optional +from json import dump, dumps, load +from typing import Any, Dict, List, Optional, Tuple from urllib.request import urlopen import os @@ -26,19 +26,31 @@ def main() -> None: - pyrightconfig_schema_json = None - sublime_package_json = None + pyrightconfig_schema_json, sublime_package_schema_json = read_sublime_package_json() + before = dumps(sublime_package_schema_json) + new_schema_keys = update_schema(sublime_package_schema_json, pyrightconfig_schema_json) + after = dumps(sublime_package_schema_json) + if before != after: + with open(SUBLIME_PACKAGE_JSON_PATH, 'w', encoding='utf-8') as f: + dump(sublime_package_schema_json, f, indent=2) + print('sublime-package.json schema updated.') + else: + print('No updates done to sublime-package.json.') + if new_schema_keys: + print('\nThe following new keys were found in the latest pyrightconfig.json schema: {}\n\n'.format( + '\n - '.join(new_schema_keys))) + print('Ensure that those are added to the sublime-package.json manually, if relevant.') + + +def read_sublime_package_json() -> Tuple[JSON, JSON]: with urlopen(PYRIGHT_CONFIGURATION_SCHEMA_URL) as response: pyrightconfig_schema_json = load(response) with open(SUBLIME_PACKAGE_JSON_PATH, 'r', encoding='utf-8') as f: - sublime_package_json = load(f) - update_schema(sublime_package_json, pyrightconfig_schema_json) - with open(SUBLIME_PACKAGE_JSON_PATH, 'w', encoding='utf-8') as f: - dump(sublime_package_json, f, indent=2) - print('sublime-package.json file updated! If there are any changes then make sure to also update the LSP part of the configuration.') # noqa: E501 + sublime_package_schema_json = load(f) + return (pyrightconfig_schema_json, sublime_package_schema_json) -def update_schema(sublime_package_json: JSON, pyrightconfig_schema_json: JSON) -> None: +def update_schema(sublime_package_json: JSON, pyrightconfig_schema_json: JSON) -> List[str]: pyrightconfig_contribution: Optional[JSON] = None lsp_pyright_contribution: Optional[JSON] = None for contribution in sublime_package_json['contributions']['settings']: @@ -72,11 +84,13 @@ def update_schema(sublime_package_json: JSON, pyrightconfig_schema_json: JSON) - # then it might have to be added manually. all_settings_keys = list(map(lambda k: k.split('.').pop(), settings_properties.keys())) all_overrides_keys = settings_properties['python.analysis.diagnosticSeverityOverrides']['properties'].keys() + new_schema_keys = [] for pyrightconfig_key in pyrightconfig_properties.keys(): if pyrightconfig_key not in all_settings_keys \ and pyrightconfig_key not in all_overrides_keys \ and pyrightconfig_key not in IGNORED_PYRIGHTCONFIG_KEYS: - print(pyrightconfig_key) + new_schema_keys.append(pyrightconfig_key) + return new_schema_keys def update_property_ref(property_key: str, property_schema: JSON, pyrightconfig_properties: JSON) -> None: From a2c600c4c4bd2278da7904530820c7a352a6ae9b Mon Sep 17 00:00:00 2001 From: Rafal Chlodnicki Date: Tue, 12 Dec 2023 23:05:01 +0100 Subject: [PATCH 6/6] use "standard" typeCheckingMode by default --- LSP-pyright.sublime-settings | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/LSP-pyright.sublime-settings b/LSP-pyright.sublime-settings index d063b10..97aa536 100644 --- a/LSP-pyright.sublime-settings +++ b/LSP-pyright.sublime-settings @@ -43,9 +43,8 @@ // Specifies the level of logging for the Output panel "python.analysis.logLevel": "Information", // Defines the default rule set for type checking. - "python.analysis.typeCheckingMode": "basic", + "python.analysis.typeCheckingMode": "standard", // Paths to look for typeshed modules. - // Hmm... doesn't seem to work on my side. May track https://github.com/microsoft/pylance-release/issues/29 "python.analysis.typeshedPaths": [], // Use library implementations to extract type information when type stub is not present. "python.analysis.useLibraryCodeForTypes": true, @@ -58,13 +57,5 @@ // Path to folder with a list of Virtual Environments. "python.venvPath": "", }, - // ST4 "selector": "source.python", - // ST3 - "languages": [ - { - "scopes": ["source.python - source.python.lsp"], - "syntaxes": ["Packages/Python/Python.sublime-syntax"], - }, - ], }