From 4a3b234e90ffda101988587a75d812fb1d6a808d Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 5 Oct 2023 13:08:20 +0200 Subject: [PATCH 01/11] Add a section "Stub package versioning" --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/README.md b/README.md index 68e2d636fdab..1028a9c75597 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,50 @@ and are automatically released (multiple times a day, when needed) by Type checkers should be able to use these stub packages when installed. For more details, see the documentation for your type checker. +### Stub package versioning + +Version numbers of third-party stub packages consist of at least four elements, +where the last element represents the stub version. The other elements +are the version of the package being stubbed. + +While we try to minimize the number of breaking changes, due to the nature +of stubs, every version can introduce changes that make your code fail +to type check. + +There are several strategies to pin the version of the stubs you are using, +all with their own tradeoffs: + +* Use the same pin that you use for the package being stubbed. For example, + if you use `requests>=2.30.0,<2.32`, you can use + `types-requests>=2.30.0,<2.32`. This ensures that the stubs are compatible + with the package you are using, but it carries a small risk of breaking + type checking due to changes in the stubs. Also, stubs often lag behind + the package being stubbed. You might want to force the package being stubbed + to a certain minimum version, because it fixes a critical bug, but you + could be unable to update the stubs, since an update has not been released. +* When the package being stubbed is using [Semantic Versioning](https://semver.org/lang/de/), + you could use the same major version for the stubs. For example, if you use + `requests>=2.30.0,<2.33`, you can use `types-requests>=2.29.3.4,<3`. This + means that the stubs are not as tighly coupled to the package being stubbed, + and you will gain potential improvements in the stubs, but it carries a + risk, since the stubs might provide a different API surface than the + implementation. It also works around the problem that stubs often lag behind + the package being stubbed. +* Pin the stubs to a known good version and update manually. For example, if + you use `types-requests==2.31.0.1`, you can be sure that upgrading + dependencies will not break type checking. However, you will miss out on + improvements in the stubs that could potentially improve type checking. + It also has the risk that the stubs you are using are not compatible with + the package being stubbed. +* Don't pin the stubs. This is the most flexible option, but it carries the + risk that the stubs become incompatible with the package being stubbed. + For example, when a new major version of the package is released and the + stubs are updated before you update the package being stubbed. + +You can also use the different strategies as needed. For example, you could +default match the pinning, but pin the stubs to a known good version when +a problem arises that can't easily be fixed. + ### The `_typeshed` package typeshed includes a package `_typeshed` as part of the standard library. From 56b93d29e4be8468d4047658dccfe44d581ec2dc Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 5 Oct 2023 14:06:58 +0200 Subject: [PATCH 02/11] Apply suggestions from code review Co-authored-by: Alex Waygood --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1028a9c75597..4d9b8778d476 100644 --- a/README.md +++ b/README.md @@ -46,24 +46,26 @@ and are automatically released (multiple times a day, when needed) by Type checkers should be able to use these stub packages when installed. For more details, see the documentation for your type checker. -### Stub package versioning +### Package versioning for third-party stubs Version numbers of third-party stub packages consist of at least four elements, where the last element represents the stub version. The other elements are the version of the package being stubbed. -While we try to minimize the number of breaking changes, due to the nature -of stubs, every version can introduce changes that make your code fail -to type check. +At typeshed, we try to keep breaking changes to a minimum. However, due to the +nature of stubs, any version bump can introduce changes that might make your +code fail to type check. -There are several strategies to pin the version of the stubs you are using, -all with their own tradeoffs: +There are several strategies available for specifying the version of a stubs +package you're using, each with its own tradeoffs * Use the same pin that you use for the package being stubbed. For example, if you use `requests>=2.30.0,<2.32`, you can use `types-requests>=2.30.0,<2.32`. This ensures that the stubs are compatible with the package you are using, but it carries a small risk of breaking - type checking due to changes in the stubs. Also, stubs often lag behind + type checking due to changes in the stubs. + + Another risk of this strategy is that stubs often lag behind the package being stubbed. You might want to force the package being stubbed to a certain minimum version, because it fixes a critical bug, but you could be unable to update the stubs, since an update has not been released. @@ -83,8 +85,9 @@ all with their own tradeoffs: the package being stubbed. * Don't pin the stubs. This is the most flexible option, but it carries the risk that the stubs become incompatible with the package being stubbed. - For example, when a new major version of the package is released and the - stubs are updated before you update the package being stubbed. + For example, if a new major version of the package is released, there's a + chance the stubs might be updated to reflect the new version of the runtime + package before you update the package being stubbed. You can also use the different strategies as needed. For example, you could default match the pinning, but pin the stubs to a known good version when From 2be4a4761028dd58c9083d8d2c25e9cac9abbd68 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 12:08:58 +0000 Subject: [PATCH 03/11] [pre-commit.ci] auto fixes from pre-commit.com hooks --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d9b8778d476..9c6d00fd918c 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ package you're using, each with its own tradeoffs `types-requests>=2.30.0,<2.32`. This ensures that the stubs are compatible with the package you are using, but it carries a small risk of breaking type checking due to changes in the stubs. - + Another risk of this strategy is that stubs often lag behind the package being stubbed. You might want to force the package being stubbed to a certain minimum version, because it fixes a critical bug, but you From 13f2668355db6f7517165215e1a59526f788be7b Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 5 Oct 2023 14:15:25 +0200 Subject: [PATCH 04/11] Reword version explanation, based on @AlexWaygood's suggestion Remove a confusing strategy --- README.md | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9c6d00fd918c..16d696bd87cf 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,15 @@ details, see the documentation for your type checker. ### Package versioning for third-party stubs -Version numbers of third-party stub packages consist of at least four elements, -where the last element represents the stub version. The other elements -are the version of the package being stubbed. +Version numbers of third-party stub packages consist of at least four parts. +All parts of the stub version, except for the last part, correspond to the +version of the runtime package being stubbed. For example, if the `types-foo` +package has version `1.1.2.0`, this signifies that the package contains stubs +for the `foo==1.1.2`. In this example, the final element of the version +indicates that this is the first revision of the stubs for `foo`. If an update +to the stubs was pushed (but the stubs were still aiming to provide +annotations for `foo==1.1.2`), then the version of `types-foo` would +increment to `1.1.2.1`. At typeshed, we try to keep breaking changes to a minimum. However, due to the nature of stubs, any version bump can introduce changes that might make your @@ -69,14 +75,6 @@ package you're using, each with its own tradeoffs the package being stubbed. You might want to force the package being stubbed to a certain minimum version, because it fixes a critical bug, but you could be unable to update the stubs, since an update has not been released. -* When the package being stubbed is using [Semantic Versioning](https://semver.org/lang/de/), - you could use the same major version for the stubs. For example, if you use - `requests>=2.30.0,<2.33`, you can use `types-requests>=2.29.3.4,<3`. This - means that the stubs are not as tighly coupled to the package being stubbed, - and you will gain potential improvements in the stubs, but it carries a - risk, since the stubs might provide a different API surface than the - implementation. It also works around the problem that stubs often lag behind - the package being stubbed. * Pin the stubs to a known good version and update manually. For example, if you use `types-requests==2.31.0.1`, you can be sure that upgrading dependencies will not break type checking. However, you will miss out on From 78c3f5cd2a70433b8a2a6ff06f0ffd26582a0d27 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 5 Oct 2023 14:18:18 +0200 Subject: [PATCH 05/11] Needs manual update --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 16d696bd87cf..4709f36a855e 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,8 @@ package you're using, each with its own tradeoffs * Pin the stubs to a known good version and update manually. For example, if you use `types-requests==2.31.0.1`, you can be sure that upgrading dependencies will not break type checking. However, you will miss out on - improvements in the stubs that could potentially improve type checking. + improvements in the stubs that could potentially improve type checking, + unless you manually update the stubs. It also has the risk that the stubs you are using are not compatible with the package being stubbed. * Don't pin the stubs. This is the most flexible option, but it carries the From 4d7599add224b0126da379fc3bfeb8a4c4c8e163 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 5 Oct 2023 14:19:18 +0200 Subject: [PATCH 06/11] Number strategies --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4709f36a855e..e9d79b26d18d 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ code fail to type check. There are several strategies available for specifying the version of a stubs package you're using, each with its own tradeoffs -* Use the same pin that you use for the package being stubbed. For example, +1. Use the same pin that you use for the package being stubbed. For example, if you use `requests>=2.30.0,<2.32`, you can use `types-requests>=2.30.0,<2.32`. This ensures that the stubs are compatible with the package you are using, but it carries a small risk of breaking @@ -75,21 +75,21 @@ package you're using, each with its own tradeoffs the package being stubbed. You might want to force the package being stubbed to a certain minimum version, because it fixes a critical bug, but you could be unable to update the stubs, since an update has not been released. -* Pin the stubs to a known good version and update manually. For example, if +2. Pin the stubs to a known good version and update manually. For example, if you use `types-requests==2.31.0.1`, you can be sure that upgrading dependencies will not break type checking. However, you will miss out on improvements in the stubs that could potentially improve type checking, unless you manually update the stubs. It also has the risk that the stubs you are using are not compatible with the package being stubbed. -* Don't pin the stubs. This is the most flexible option, but it carries the +3. Don't pin the stubs. This is the most flexible option, but it carries the risk that the stubs become incompatible with the package being stubbed. For example, if a new major version of the package is released, there's a chance the stubs might be updated to reflect the new version of the runtime package before you update the package being stubbed. You can also use the different strategies as needed. For example, you could -default match the pinning, but pin the stubs to a known good version when +default to strategy (1), but fall back to strategy (2) when a problem arises that can't easily be fixed. ### The `_typeshed` package From 1fb15bde9530c9eefb277edd38a19ef231863c1b Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 5 Oct 2023 15:27:38 +0200 Subject: [PATCH 07/11] Update from review --- README.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index e9d79b26d18d..8dca7c625fad 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,9 @@ Version numbers of third-party stub packages consist of at least four parts. All parts of the stub version, except for the last part, correspond to the version of the runtime package being stubbed. For example, if the `types-foo` package has version `1.1.2.0`, this signifies that the package contains stubs -for the `foo==1.1.2`. In this example, the final element of the version +for `foo==1.1.2`. In this example, the final element of the version indicates that this is the first revision of the stubs for `foo`. If an update -to the stubs was pushed (but the stubs were still aiming to provide +to the stubs were pushed (but the stubs were still aiming to provide annotations for `foo==1.1.2`), then the version of `types-foo` would increment to `1.1.2.1`. @@ -66,27 +66,27 @@ There are several strategies available for specifying the version of a stubs package you're using, each with its own tradeoffs 1. Use the same pin that you use for the package being stubbed. For example, - if you use `requests>=2.30.0,<2.32`, you can use - `types-requests>=2.30.0,<2.32`. This ensures that the stubs are compatible - with the package you are using, but it carries a small risk of breaking - type checking due to changes in the stubs. - - Another risk of this strategy is that stubs often lag behind - the package being stubbed. You might want to force the package being stubbed - to a certain minimum version, because it fixes a critical bug, but you - could be unable to update the stubs, since an update has not been released. + if you use `requests>=2.30.0,<2.32`, you can use + `types-requests>=2.30.0,<2.32`. This ensures that the stubs are compatible + with the package you are using, but it carries a small risk of breaking + type checking due to changes in the stubs. + + Another risk of this strategy is that stubs often lag behind + the package being stubbed. You might want to force the package being stubbed + to a certain minimum version, because it fixes a critical bug, but you + could be unable to update the stubs, since an update has not been released. 2. Pin the stubs to a known good version and update manually. For example, if - you use `types-requests==2.31.0.1`, you can be sure that upgrading - dependencies will not break type checking. However, you will miss out on - improvements in the stubs that could potentially improve type checking, - unless you manually update the stubs. - It also has the risk that the stubs you are using are not compatible with - the package being stubbed. + you use `types-requests==2.31.0.1`, you can be sure that upgrading + dependencies will not break type checking. However, you will miss out on + improvements in the stubs that could potentially improve type checking, + until you update the pin. + It also has the risk that the stubs you are using are not compatible with + the package being stubbed. 3. Don't pin the stubs. This is the most flexible option, but it carries the - risk that the stubs become incompatible with the package being stubbed. - For example, if a new major version of the package is released, there's a - chance the stubs might be updated to reflect the new version of the runtime - package before you update the package being stubbed. + risk that the stubs become incompatible with the package being stubbed. + For example, if a new major version of the package is released, there's a + chance the stubs might be updated to reflect the new version of the runtime + package before you update the package being stubbed. You can also use the different strategies as needed. For example, you could default to strategy (1), but fall back to strategy (2) when From 637dffb58faa2805d30a82580cdf7735e05665f5 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 6 Oct 2023 11:25:21 +0200 Subject: [PATCH 08/11] Apply suggestions from code review --- README.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 8dca7c625fad..c95d86d41bda 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ nature of stubs, any version bump can introduce changes that might make your code fail to type check. There are several strategies available for specifying the version of a stubs -package you're using, each with its own tradeoffs +package you're using, each with its own tradeoffs: 1. Use the same pin that you use for the package being stubbed. For example, if you use `requests>=2.30.0,<2.32`, you can use @@ -75,21 +75,26 @@ package you're using, each with its own tradeoffs the package being stubbed. You might want to force the package being stubbed to a certain minimum version, because it fixes a critical bug, but you could be unable to update the stubs, since an update has not been released. -2. Pin the stubs to a known good version and update manually. For example, if - you use `types-requests==2.31.0.1`, you can be sure that upgrading - dependencies will not break type checking. However, you will miss out on - improvements in the stubs that could potentially improve type checking, - until you update the pin. - It also has the risk that the stubs you are using are not compatible with - the package being stubbed. -3. Don't pin the stubs. This is the most flexible option, but it carries the - risk that the stubs become incompatible with the package being stubbed. +2. Pin the stubs to a known good version and update the pin from time to time + (either manually, or using a tool such as dependabot or renovate). + + For example, if you use `types-requests==2.31.0.1`, you can have confidence + that upgrading dependencies will not break type checking. However, you will + miss out on improvements in the stubs that could potentially improve type + checking until you update the pin. This strategy also has the risk that the + stubs you are using might become incompatible with the package being stubbed. +3. Don't pin the stubs. This is the option that demands the least work from + you when it comes to updating version pins, and has the advantage that you + will automatically benefit from improved stubs whenever a new version of the + stubs package is released. However, it carries the risk that the stubs + become incompatible with the package being stubbed. + For example, if a new major version of the package is released, there's a chance the stubs might be updated to reflect the new version of the runtime package before you update the package being stubbed. -You can also use the different strategies as needed. For example, you could -default to strategy (1), but fall back to strategy (2) when +You can also switch between the different strategies as needed. For example, +you could default to strategy (1), but fall back to strategy (2) when a problem arises that can't easily be fixed. ### The `_typeshed` package From f30eb10007c5a37e5f0eb6a2432becd14de5b6da Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 6 Oct 2023 16:32:25 +0200 Subject: [PATCH 09/11] Update README.md Co-authored-by: Alex Waygood --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c95d86d41bda..869912d15454 100644 --- a/README.md +++ b/README.md @@ -52,11 +52,11 @@ Version numbers of third-party stub packages consist of at least four parts. All parts of the stub version, except for the last part, correspond to the version of the runtime package being stubbed. For example, if the `types-foo` package has version `1.1.2.0`, this signifies that the package contains stubs -for `foo==1.1.2`. In this example, the final element of the version -indicates that this is the first revision of the stubs for `foo`. If an update -to the stubs were pushed (but the stubs were still aiming to provide -annotations for `foo==1.1.2`), then the version of `types-foo` would -increment to `1.1.2.1`. +for `foo>=1.1.2`, but which have only been tested against `foo<1.2`. +In this example, the final element of the version indicates that this is the +first revision of the stubs for `foo>=1.1.2`. If an update to the stubs were +pushed (but the stubs were still aiming to provide annotations for +`foo>=1.1.2`), then the version of `types-foo` would increment to `1.1.2.1`. At typeshed, we try to keep breaking changes to a minimum. However, due to the nature of stubs, any version bump can introduce changes that might make your From cfe67da5e262ea58b4af91800e5a355d868e4a12 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Sat, 7 Oct 2023 21:45:33 +0200 Subject: [PATCH 10/11] Apply suggestions from code review Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 869912d15454..529fa2abda6e 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ code fail to type check. There are several strategies available for specifying the version of a stubs package you're using, each with its own tradeoffs: -1. Use the same pin that you use for the package being stubbed. For example, +1. Use the same bounds that you use for the package being stubbed. For example, if you use `requests>=2.30.0,<2.32`, you can use `types-requests>=2.30.0,<2.32`. This ensures that the stubs are compatible with the package you are using, but it carries a small risk of breaking @@ -73,8 +73,9 @@ package you're using, each with its own tradeoffs: Another risk of this strategy is that stubs often lag behind the package being stubbed. You might want to force the package being stubbed - to a certain minimum version, because it fixes a critical bug, but you - could be unable to update the stubs, since an update has not been released. + to a certain minimum version because it fixes a critical bug, but if + correspondingly updated stubs have not been released, your type + checking results may not be fully accurate. 2. Pin the stubs to a known good version and update the pin from time to time (either manually, or using a tool such as dependabot or renovate). From ad4a46f08a87e81a95ccb5a6f65326b19fefa2cb Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Sat, 7 Oct 2023 21:47:14 +0200 Subject: [PATCH 11/11] Update README.md Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 529fa2abda6e..d679eedf3930 100644 --- a/README.md +++ b/README.md @@ -51,12 +51,13 @@ details, see the documentation for your type checker. Version numbers of third-party stub packages consist of at least four parts. All parts of the stub version, except for the last part, correspond to the version of the runtime package being stubbed. For example, if the `types-foo` -package has version `1.1.2.0`, this signifies that the package contains stubs -for `foo>=1.1.2`, but which have only been tested against `foo<1.2`. -In this example, the final element of the version indicates that this is the -first revision of the stubs for `foo>=1.1.2`. If an update to the stubs were -pushed (but the stubs were still aiming to provide annotations for -`foo>=1.1.2`), then the version of `types-foo` would increment to `1.1.2.1`. +package has version `1.2.0.7`, this guarantees that the `types-foo` package +contains stubs targeted against `foo==1.2.*` and tested against the latest +version of `foo` matching that specifier. In this example, the final element +of the version (7) indicates that this is the eighth revision of the stubs for +`foo==1.2.*`. If an update to the stubs were pushed (but the stubs were still +aiming to provide annotations for `foo==1.2.*`), then the version of +`types-foo` would increment to `1.2.0.8`. At typeshed, we try to keep breaking changes to a minimum. However, due to the nature of stubs, any version bump can introduce changes that might make your