From 828db71f8ff38b0b9f9f778bed0b7c42224d36d8 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Tue, 30 Dec 2025 01:52:40 +0100 Subject: [PATCH 1/2] Update ty's JSON schema (#5251) --- src/schemas/json/ty.json | 54 +++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/schemas/json/ty.json b/src/schemas/json/ty.json index b38bc05b75a..dcbd3a40535 100644 --- a/src/schemas/json/ty.json +++ b/src/schemas/json/ty.json @@ -4,6 +4,16 @@ "title": "Options", "type": "object", "properties": { + "analysis": { + "anyOf": [ + { + "$ref": "#/definitions/AnalysisOptions" + }, + { + "type": "null" + } + ] + }, "environment": { "description": "Configures the type checking environment.", "anyOf": [ @@ -60,6 +70,16 @@ }, "additionalProperties": false, "definitions": { + "AnalysisOptions": { + "type": "object", + "properties": { + "respect-type-ignore-comments": { + "description": "Whether ty should respect `type: ignore` comments.\n\nWhen set to `false`, `type: ignore` comments are treated like any other normal\ncomment and can't be used to suppress ty errors (you have to use `ty: ignore` instead).\n\nSetting this option can be useful when using ty alongside other type checkers or when\nyou prefer using `ty: ignore` over `type: ignore`.\n\nDefaults to `true`.", + "type": ["boolean", "null"] + } + }, + "additionalProperties": false + }, "Array_of_string": { "type": "array", "items": { @@ -328,6 +348,16 @@ } ] }, + "call-top-callable": { + "title": "detects calls to the top callable type", + "description": "## What it does\nChecks for calls to objects typed as `Top[Callable[..., T]]` (the infinite union of all\ncallable types with return type `T`).\n\n## Why is this bad?\nWhen an object is narrowed to `Top[Callable[..., object]]` (e.g., via `callable(x)` or\n`isinstance(x, Callable)`), we know the object is callable, but we don't know its\nprecise signature. This type represents the set of all possible callable types\n(including, e.g., functions that take no arguments and functions that require arguments),\nso no specific set of arguments can be guaranteed to be valid.\n\n## Examples\n```python\ndef f(x: object):\n if callable(x):\n x() # error: We know `x` is callable, but not what arguments it accepts\n```", + "default": "error", + "oneOf": [ + { + "$ref": "#/definitions/Level" + } + ] + }, "conflicting-argument-forms": { "title": "detects when an argument is used as both a value and a type form in a call", "description": "## What it does\nChecks whether an argument is used as both a value and a type form in a call.\n\n## Why is this bad?\nSuch calls have confusing semantics and often indicate a logic error.\n\n## Examples\n```python\nfrom typing import reveal_type\nfrom ty_extensions import is_singleton\n\nif flag:\n f = repr # Expects a value\nelse:\n f = is_singleton # Expects a type form\n\nf(int) # error\n```", @@ -390,7 +420,7 @@ }, "division-by-zero": { "title": "detects division by zero", - "description": "## What it does\nIt detects division by zero.\n\n## Why is this bad?\nDividing by zero raises a `ZeroDivisionError` at runtime.\n\n## Examples\n```python\n5 / 0\n```", + "description": "## What it does\nIt detects division by zero.\n\n## Why is this bad?\nDividing by zero raises a `ZeroDivisionError` at runtime.\n\n## Rule status\nThis rule is currently disabled by default because of the number of\nfalse positives it can produce.\n\n## Examples\n```python\n5 / 0\n```", "default": "ignore", "oneOf": [ { @@ -420,7 +450,7 @@ }, "escape-character-in-forward-annotation": { "title": "detects forward type annotations with escape characters", - "description": "TODO #14889", + "description": "## What it does\nChecks for forward annotations that contain escape characters.\n\n## Why is this bad?\nStatic analysis tools like ty can't analyze type annotations that contain escape characters.\n\n## Example\n\n```python\ndef foo() -> \"intt\\b\": ...\n```", "default": "error", "oneOf": [ { @@ -740,7 +770,7 @@ }, "invalid-syntax-in-forward-annotation": { "title": "detects invalid syntax in forward annotations", - "description": "TODO #14889", + "description": "## What it does\nChecks for string-literal annotations where the string cannot be\nparsed as a Python expression.\n\n## Why is this bad?\nType annotations are expected to be Python expressions that\ndescribe the expected type of a variable, parameter, attribute or\n`return` statement.\n\nType annotations are permitted to be string-literal expressions, in\norder to enable forward references to names not yet defined.\nHowever, it must be possible to parse the contents of that string\nliteral as a normal Python expression.\n\n## Example\n\n```python\ndef foo() -> \"intstance of C\":\n return 42\n\nclass C: ...\n```\n\nUse instead:\n\n```python\ndef foo() -> \"C\":\n return 42\n\nclass C: ...\n```\n\n## References\n- [Typing spec: The meaning of annotations](https://typing.python.org/en/latest/spec/annotations.html#the-meaning-of-annotations)\n- [Typing spec: String annotations](https://typing.python.org/en/latest/spec/annotations.html#string-annotations)", "default": "error", "oneOf": [ { @@ -848,9 +878,9 @@ } ] }, - "non-subscriptable": { - "title": "detects subscripting objects that do not support subscripting", - "description": "## What it does\nChecks for subscripting objects that do not support subscripting.\n\n## Why is this bad?\nSubscripting an object that does not support it will raise a `TypeError` at runtime.\n\n## Examples\n```python\n4[1] # TypeError: 'int' object is not subscriptable\n```", + "not-iterable": { + "title": "detects iteration over an object that is not iterable", + "description": "## What it does\nChecks for objects that are not iterable but are used in a context that requires them to be.\n\n## Why is this bad?\nIterating over an object that is not iterable will raise a `TypeError` at runtime.\n\n## Examples\n\n```python\nfor i in 34: # TypeError: 'int' object is not iterable\n pass\n```", "default": "error", "oneOf": [ { @@ -858,9 +888,9 @@ } ] }, - "not-iterable": { - "title": "detects iteration over an object that is not iterable", - "description": "## What it does\nChecks for objects that are not iterable but are used in a context that requires them to be.\n\n## Why is this bad?\nIterating over an object that is not iterable will raise a `TypeError` at runtime.\n\n## Examples\n\n```python\nfor i in 34: # TypeError: 'int' object is not iterable\n pass\n```", + "not-subscriptable": { + "title": "detects subscripting objects that do not support subscripting", + "description": "## What it does\nChecks for subscripting objects that do not support subscripting.\n\n## Why is this bad?\nSubscripting an object that does not support it will raise a `TypeError` at runtime.\n\n## Examples\n```python\n4[1] # TypeError: 'int' object is not subscriptable\n```", "default": "error", "oneOf": [ { @@ -920,8 +950,8 @@ }, "possibly-missing-import": { "title": "detects possibly missing imports", - "description": "## What it does\nChecks for imports of symbols that may be missing.\n\n## Why is this bad?\nImporting a missing module or name will raise a `ModuleNotFoundError`\nor `ImportError` at runtime.\n\n## Examples\n```python\n# module.py\nimport datetime\n\nif datetime.date.today().weekday() != 6:\n a = 1\n\n# main.py\nfrom module import a # ImportError: cannot import name 'a' from 'module'\n```", - "default": "warn", + "description": "## What it does\nChecks for imports of symbols that may be missing.\n\n## Why is this bad?\nImporting a missing module or name will raise a `ModuleNotFoundError`\nor `ImportError` at runtime.\n\n## Rule status\nThis rule is currently disabled by default because of the number of\nfalse positives it can produce.\n\n## Examples\n```python\n# module.py\nimport datetime\n\nif datetime.date.today().weekday() != 6:\n a = 1\n\n# main.py\nfrom module import a # ImportError: cannot import name 'a' from 'module'\n```", + "default": "ignore", "oneOf": [ { "$ref": "#/definitions/Level" @@ -930,7 +960,7 @@ }, "possibly-unresolved-reference": { "title": "detects references to possibly undefined names", - "description": "## What it does\nChecks for references to names that are possibly not defined.\n\n## Why is this bad?\nUsing an undefined variable will raise a `NameError` at runtime.\n\n## Example\n\n```python\nfor i in range(0):\n x = i\n\nprint(x) # NameError: name 'x' is not defined\n```", + "description": "## What it does\nChecks for references to names that are possibly not defined.\n\n## Why is this bad?\nUsing an undefined variable will raise a `NameError` at runtime.\n\n## Rule status\nThis rule is currently disabled by default because of the number of\nfalse positives it can produce.\n\n## Example\n\n```python\nfor i in range(0):\n x = i\n\nprint(x) # NameError: name 'x' is not defined\n```", "default": "ignore", "oneOf": [ { From d370b3b7458297c948ec263a5ceac00b6df77c35 Mon Sep 17 00:00:00 2001 From: Jeong Min Oh Date: Tue, 30 Dec 2025 09:53:31 +0900 Subject: [PATCH 2/2] Add changepacks schema (#5248) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/api/json/catalog.json | 6 ++++ src/schemas/json/changepacks.json | 41 +++++++++++++++++++++++++++ src/test/changepacks/changepacks.json | 5 ++++ 3 files changed, 52 insertions(+) create mode 100644 src/schemas/json/changepacks.json create mode 100644 src/test/changepacks/changepacks.json diff --git a/src/api/json/catalog.json b/src/api/json/catalog.json index 6d697611bf8..77bd67e98d4 100644 --- a/src/api/json/catalog.json +++ b/src/api/json/catalog.json @@ -9075,6 +9075,12 @@ "v1beta1": "https://raw.githubusercontent.com/redhat-developer/vscode-tekton/refs/heads/main/scheme/tekton.dev/v1beta1_PipelineRun.json", "v1alpha1": "https://raw.githubusercontent.com/redhat-developer/vscode-tekton/refs/heads/main/scheme/tekton.dev/v1alpha1_PipelineRun.json" } + }, + { + "name": "Changepacks", + "description": "Changepacks are a way to package changes to a project", + "fileMatch": ["**/.changepacks/config.json"], + "url": "https://www.schemastore.org/changepacks.json" } ] } diff --git a/src/schemas/json/changepacks.json b/src/schemas/json/changepacks.json new file mode 100644 index 00000000000..0c823ad89ed --- /dev/null +++ b/src/schemas/json/changepacks.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://json.schemastore.org/changepacks.json", + "properties": { + "baseBranch": { + "default": "main", + "type": "string" + }, + "ignore": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "latestPackage": { + "default": null, + "type": ["string", "null"] + }, + "publish": { + "additionalProperties": { + "type": "string" + }, + "default": {}, + "type": "object" + }, + "updateOn": { + "additionalProperties": { + "items": { + "type": "string" + }, + "type": "array" + }, + "default": {}, + "description": "Dependency rules for forced updates.\nKey: glob pattern for trigger packages (e.g., \"crates/*\")\nValue: list of package paths that must be updated when trigger matches", + "type": "object" + } + }, + "title": "Changepacks Configuration", + "type": "object" +} diff --git a/src/test/changepacks/changepacks.json b/src/test/changepacks/changepacks.json new file mode 100644 index 00000000000..4c9e224def5 --- /dev/null +++ b/src/test/changepacks/changepacks.json @@ -0,0 +1,5 @@ +{ + "baseBranch": "main", + "ignore": ["**", "!package.json", "apps/**"], + "latestPackage": null +}