From a730e2f0f39bace8e01da0501848de9a0e16286b Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Mon, 16 Jan 2023 15:50:36 +0100 Subject: [PATCH 1/6] Rework the "Incomplete stubs" section Also move it to the "Conventions" section due its scope change. Closes: #8955 --- CONTRIBUTING.md | 68 ++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dfbcc30b105e..95e62366143d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -368,40 +368,6 @@ introduced in, say, Python 3.7.4, your check: When your stub contains if statements for different Python versions, always put the code for the most recent Python version first. -### Incomplete stubs - -We accept partial stubs, especially for larger packages. These need to -follow the following guidelines: - -* Included functions and methods must list all arguments, but the arguments - can be left unannotated. Do not use `Any` to mark unannotated arguments - or return values. -* Partial classes must include a `__getattr__()` method marked with an - `# incomplete` comment (see example below). -* Partial modules (i.e. modules that are missing some or all classes, - functions, or attributes) must include a top-level `__getattr__()` - function marked with an `Incomplete` return type (see example below). -* Partial packages (i.e. packages that are missing one or more sub-modules) - must have a `__init__.pyi` stub that is marked as incomplete (see above). - A better alternative is to create empty stubs for all sub-modules and - mark them as incomplete individually. - -Example of a partial module with a partial class `Foo` and a partially -annotated function `bar()`: - -```python -from _typeshed import Incomplete - -class Foo: - def __getattr__(self, name: str) -> Incomplete: ... - x: int - y: str - -def bar(x: str, y, *, z=...): ... - -def __getattr__(name: str) -> Incomplete: ... -``` - ## Stub file coding style ### Syntax example @@ -524,6 +490,40 @@ into any of those categories, use your best judgement. * Use `HasX` for protocols that have readable and/or writable attributes or getter/setter methods (e.g. `HasItems`, `HasFileno`). +### Incomplete stubs + +We accept partially annotated stubs, especially for larger packages. +These need to follow the following guidelines: + +* A package must include all public submodules, all public classes, + functions and methods, and all other public fields. +* Included functions and methods must list all arguments, but the argument + types and the return type can be left unannotated or only be partially + annotated. +* A type can be partially annotated by using the `_typeshed.Incomplete` + marker. A field can be left unannotated by using `Incomplete` as well. + Do not use `Incomplete` unless it's syntactically required. See below for + an example. + +Example of an unannotated field and a partially annotated function: + +```python +from _typeshed import Incomplete + +pub_field1: Incomplete # unannotated +pub_field2: list[Incomplete] # partially annotated + +def pub_func(x: str, y, z: Incomplete | None = None) -> Any | None: ... +``` + +In this example, argument `x` is fully annotated and `y` is left unannotated. +`Incomplete` is not used for `y` as it's not syntactically required. +`z` is partially annotated; `None` is one of the allowed types, but other +types are allowed as well, but this needs further investigation. The return +type is fully annotated. In this case, the return type was investigated and +it was found that it can't be fully represented using the current type system, +which is why `Any` was used. A return type that could potentially be improved +would be annotated as `Incomplete | None`. ## Submitting Changes From 75c21184a69ac19d09c3e0272c7d4b22c6460fa6 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Mon, 16 Jan 2023 21:45:44 +0100 Subject: [PATCH 2/6] Clarify wording around using Incomplete --- CONTRIBUTING.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 95e62366143d..649c04992cb7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -501,23 +501,22 @@ These need to follow the following guidelines: types and the return type can be left unannotated or only be partially annotated. * A type can be partially annotated by using the `_typeshed.Incomplete` - marker. A field can be left unannotated by using `Incomplete` as well. - Do not use `Incomplete` unless it's syntactically required. See below for - an example. + marker. Do not use `Incomplete` as the only type for argument or return + types. See below for an example. -Example of an unannotated field and a partially annotated function: +Example: ```python from _typeshed import Incomplete -pub_field1: Incomplete # unannotated +pub_field1: Incomplete # unannotated field with required annotation pub_field2: list[Incomplete] # partially annotated def pub_func(x: str, y, z: Incomplete | None = None) -> Any | None: ... ``` In this example, argument `x` is fully annotated and `y` is left unannotated. -`Incomplete` is not used for `y` as it's not syntactically required. +`Incomplete` is not used for `y`. `z` is partially annotated; `None` is one of the allowed types, but other types are allowed as well, but this needs further investigation. The return type is fully annotated. In this case, the return type was investigated and From 0604f0353f6d0aa3f59db38b8cd36bf5ccb42ff8 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 31 Jan 2023 11:11:22 +0100 Subject: [PATCH 3/6] Update CONTRIBUTING.md Co-authored-by: Akuli --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 649c04992cb7..80d755beab27 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -493,7 +493,7 @@ into any of those categories, use your best judgement. ### Incomplete stubs We accept partially annotated stubs, especially for larger packages. -These need to follow the following guidelines: +These should follow the following guidelines: * A package must include all public submodules, all public classes, functions and methods, and all other public fields. From 591a993fe2879f9b466b372c70fd628b079b310e Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 3 Feb 2023 10:40:24 +0100 Subject: [PATCH 4/6] Simplify --- CONTRIBUTING.md | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 80d755beab27..0391e52247e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -490,39 +490,27 @@ into any of those categories, use your best judgement. * Use `HasX` for protocols that have readable and/or writable attributes or getter/setter methods (e.g. `HasItems`, `HasFileno`). -### Incomplete stubs +### Incomplete annotations -We accept partially annotated stubs, especially for larger packages. -These should follow the following guidelines: - -* A package must include all public submodules, all public classes, - functions and methods, and all other public fields. -* Included functions and methods must list all arguments, but the argument - types and the return type can be left unannotated or only be partially - annotated. -* A type can be partially annotated by using the `_typeshed.Incomplete` - marker. Do not use `Incomplete` as the only type for argument or return - types. See below for an example. - -Example: +When submitting new stubs, it is not necessary to annotate all arguments, return types, and fields. Such items should either be left unannotated or use `_typeshed.Incomplete` if this is not possible: ```python from _typeshed import Incomplete -pub_field1: Incomplete # unannotated field with required annotation -pub_field2: list[Incomplete] # partially annotated +field: Incomplete # unannotated + +def foo(x): ... # unannotated argument and return type +``` + +`Incomplete` can also be used for partially known types: -def pub_func(x: str, y, z: Incomplete | None = None) -> Any | None: ... +```python +def foo(x: Incomplete | None = None) -> list[Incomplete]: ... ``` -In this example, argument `x` is fully annotated and `y` is left unannotated. -`Incomplete` is not used for `y`. -`z` is partially annotated; `None` is one of the allowed types, but other -types are allowed as well, but this needs further investigation. The return -type is fully annotated. In this case, the return type was investigated and -it was found that it can't be fully represented using the current type system, -which is why `Any` was used. A return type that could potentially be improved -would be annotated as `Incomplete | None`. +### `Any` vs. `Incomplete` + +While `Incomplete` is a type alias of `Any`, they serve difference purposes: `Incomplete` is a placeholder where a proper type might be substituted. It's a "to do" item and should be replaced if possible. `Any` is used when it's not possible to accurately type an item using the current type system. It should be used sparingly. ## Submitting Changes From e0a7ea4dd8f4da41e079bd00c3d74cb8dc1b4df9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 3 Feb 2023 09:44:01 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0391e52247e5..b41a0105ca3a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -497,7 +497,7 @@ When submitting new stubs, it is not necessary to annotate all arguments, return ```python from _typeshed import Incomplete -field: Incomplete # unannotated +field: Incomplete # unannotated def foo(x): ... # unannotated argument and return type ``` From 263780494de325cbef8b5993f13af97c9457fb81 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 3 Feb 2023 11:25:33 +0100 Subject: [PATCH 6/6] Word wrap --- CONTRIBUTING.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b41a0105ca3a..1908ea6a8e10 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -492,7 +492,9 @@ into any of those categories, use your best judgement. ### Incomplete annotations -When submitting new stubs, it is not necessary to annotate all arguments, return types, and fields. Such items should either be left unannotated or use `_typeshed.Incomplete` if this is not possible: +When submitting new stubs, it is not necessary to annotate all arguments, +return types, and fields. Such items should either be left unannotated or +use `_typeshed.Incomplete` if this is not possible: ```python from _typeshed import Incomplete @@ -510,7 +512,11 @@ def foo(x: Incomplete | None = None) -> list[Incomplete]: ... ### `Any` vs. `Incomplete` -While `Incomplete` is a type alias of `Any`, they serve difference purposes: `Incomplete` is a placeholder where a proper type might be substituted. It's a "to do" item and should be replaced if possible. `Any` is used when it's not possible to accurately type an item using the current type system. It should be used sparingly. +While `Incomplete` is a type alias of `Any`, they serve difference purposes: +`Incomplete` is a placeholder where a proper type might be substituted. +It's a "to do" item and should be replaced if possible. `Any` is used when +it's not possible to accurately type an item using the current type system. +It should be used sparingly. ## Submitting Changes