Skip to content

Commit 41028f3

Browse files
Initial stubtest testing with autogenerated allowlist (#493)
* Initial stubtest testing with autogenerated allowlist * [pre-commit.ci] auto fixes from pre-commit.com hooks * Update CONTRIBUTING.md --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent b7854f0 commit 41028f3

File tree

5 files changed

+268
-0
lines changed

5 files changed

+268
-0
lines changed

.github/workflows/test.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99

1010
jobs:
1111
mypy-self-check:
12+
timeout-minutes: 10
1213
runs-on: ubuntu-latest
1314
strategy:
1415
matrix:
@@ -31,6 +32,7 @@ jobs:
3132
run: mypy --cache-dir=/dev/null --no-incremental rest_framework-stubs
3233

3334
test:
35+
timeout-minutes: 10
3436
runs-on: ubuntu-latest
3537
strategy:
3638
matrix:
@@ -52,3 +54,28 @@ jobs:
5254
5355
- name: Run tests
5456
run: pytest
57+
58+
stubtest:
59+
timeout-minutes: 10
60+
runs-on: ubuntu-latest
61+
strategy:
62+
matrix:
63+
python-version: ['3.12']
64+
fail-fast: false
65+
steps:
66+
- uses: actions/checkout@v4
67+
- name: Setup system dependencies
68+
run: |
69+
sudo apt-get update
70+
sudo apt-get install binutils libproj-dev gdal-bin
71+
- name: Set up Python ${{ matrix.python-version }}
72+
uses: actions/setup-python@v4
73+
with:
74+
python-version: ${{ matrix.python-version }}
75+
- name: Install dependencies
76+
run: |
77+
pip install -U pip setuptools wheel
78+
SETUPTOOLS_ENABLE_FEATURES=legacy-editable pip install -r ./requirements.txt
79+
80+
- name: Run stubtest
81+
run: bash ./scripts/stubtest.sh

CONTRIBUTING.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This project is open source and community driven. As such we encourage code cont
77
3. Improve plugin code and extend its capabilities
88
4. Write tests
99
5. Update dependencies
10+
6. Fix and remove things from our `scripts/stubtest/allowlist_todo.txt`
1011

1112
Type stubs in `.pyi` files should follow
1213
[coding conventions from typeshed project](https://github.com/python/typeshed/blob/main/CONTRIBUTING.md#conventions).
@@ -73,6 +74,19 @@ To execute the unit tests, simply run:
7374
pytest
7475
```
7576

77+
### Testing stubs with `stubtest`
78+
79+
Run `bash ./scripts/stubtest.sh` to test that stubs and sources are in-line.
80+
81+
We have two special files to allow errors:
82+
1. `scripts/stubtest/allowlist.txt` where we store things that we really don't care about: hacks, DRF internal utility modules, things that are handled by our plugin, things that are not representable by type system, etc
83+
2. `scripts/stubtest/allowlist_todo.txt` where we store all errors there are right now. Basically, this is a TODO list: we need to work through this list and fix things (or move entries to real `allowlist.txt`). In the end, ideally we can remove this file
84+
85+
You might also want to disable `incremental` mode while working on `stubtest` changes.
86+
This mode leads to several known problems (stubs do not show up or have strange errors).
87+
88+
**Important**: right now we only run `stubtest` on Python 3.12 (because it is the latest released version at the moment), any other versions might generate different outputs. Any work to create per-version allowlists is welcome.
89+
7690
## Submission Guidelines
7791

7892
The workflow for contributions is fairly simple:

scripts/stubtest.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
3+
# Run this script as `bash ./scripts/stubtest.sh`
4+
5+
set -e
6+
7+
export MYPYPATH='.'
8+
9+
# TODO: remove `--ignore-positional-only` when ready
10+
stubtest rest_framework \
11+
--mypy-config-file mypy.ini \
12+
--ignore-positional-only \
13+
--allowlist scripts/stubtest/allowlist.txt \
14+
--allowlist scripts/stubtest/allowlist_todo.txt

scripts/stubtest/allowlist.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# This is a true allow list with things that we really don't care about.
2+
# `allowlist_todo.txt` is autogenerated by `stubtest --generate-allowlist`
3+
# and might contain actual problems and things that we *do want* to fix.
4+
#
5+
# Please, move things here when you are sure that they really should be ignored.
6+
# Comments about why things are ignored are mandatory.
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# Autogenerated by `stubtest`
2+
# Unsorted: there are real problems and things we can really ignore.
3+
4+
rest_framework.RemovedInDRF313Warning
5+
rest_framework.RemovedInDRF314Warning
6+
rest_framework.RemovedInDRF315Warning
7+
rest_framework.__license__
8+
rest_framework.__title__
9+
rest_framework.authtoken.admin.TokenAdmin
10+
rest_framework.authtoken.admin.TokenChangeList
11+
rest_framework.authtoken.default_app_config
12+
rest_framework.authtoken.management.commands.drf_create_token.UserModel
13+
rest_framework.authtoken.migrations
14+
rest_framework.authtoken.migrations.0001_initial
15+
rest_framework.authtoken.migrations.0002_auto_20160226_1747
16+
rest_framework.authtoken.migrations.0003_tokenproxy
17+
rest_framework.authtoken.models.Token.created
18+
rest_framework.authtoken.models.Token.get_next_by_created
19+
rest_framework.authtoken.models.Token.get_previous_by_created
20+
rest_framework.authtoken.models.Token.key
21+
rest_framework.authtoken.models.Token.user
22+
rest_framework.authtoken.models.Token.user_id
23+
rest_framework.authtoken.models.TokenProxy.get_next_by_created
24+
rest_framework.authtoken.models.TokenProxy.get_previous_by_created
25+
rest_framework.authtoken.models.TokenProxy.pk
26+
rest_framework.authtoken.models.TokenProxy.user_id
27+
rest_framework.authtoken.views.ObtainAuthToken.get_serializer
28+
rest_framework.authtoken.views.ObtainAuthToken.get_serializer_context
29+
rest_framework.authtoken.views.ObtainAuthToken.serializer_class
30+
rest_framework.authtoken.views.obtain_auth_token
31+
rest_framework.compat.CodeBlockPreprocessor
32+
rest_framework.compat.Preprocessor
33+
rest_framework.compat.QuerySet
34+
rest_framework.compat.__all__
35+
rest_framework.compat.apply_markdown
36+
rest_framework.decorators.ViewSetAction
37+
rest_framework.decorators.action
38+
rest_framework.default_app_config
39+
rest_framework.documentation.get_docs_view
40+
rest_framework.documentation.get_schemajs_view
41+
rest_framework.documentation.include_docs_urls
42+
rest_framework.fields.BooleanField.initial
43+
rest_framework.fields.CharField.initial
44+
rest_framework.fields.DateField.__init__
45+
rest_framework.fields.DateField.to_internal_value
46+
rest_framework.fields.DateTimeField.__init__
47+
rest_framework.fields.DateTimeField.to_internal_value
48+
rest_framework.fields.DecimalField.__init__
49+
rest_framework.fields.DictField.__init__
50+
rest_framework.fields.DictField.initial
51+
rest_framework.fields.DurationField.to_internal_value
52+
rest_framework.fields.Field.__init__
53+
rest_framework.fields.FilePathField.__init__
54+
rest_framework.fields.HStoreField.__init__
55+
rest_framework.fields.HiddenField.__init__
56+
rest_framework.fields.JSONField.__init__
57+
rest_framework.fields.ListField.__init__
58+
rest_framework.fields.ListField.initial
59+
rest_framework.fields.ListField.to_representation
60+
rest_framework.fields.ModelField.get_attribute
61+
rest_framework.fields.ModelField.to_representation
62+
rest_framework.fields.MultipleChoiceField.__init__
63+
rest_framework.fields.NullBooleanField
64+
rest_framework.fields.Option
65+
rest_framework.fields.REGEX_TYPE
66+
rest_framework.fields.ReadOnlyField.__init__
67+
rest_framework.fields.SupportsToPython
68+
rest_framework.fields.TimeField.__init__
69+
rest_framework.fields.TimeField.to_internal_value
70+
rest_framework.fields._UnvalidatedField.__init__
71+
rest_framework.fields.empty
72+
rest_framework.generics.BaseFilterProtocol
73+
rest_framework.generics.UsesQuerySet
74+
rest_framework.negotiation.DefaultContentNegotiation.settings
75+
rest_framework.pagination.HtmlContext
76+
rest_framework.pagination.HtmlContextWithPageLinks
77+
rest_framework.parsers.BaseParser.media_type
78+
rest_framework.parsers.FileUploadParser.get_encoded_filename
79+
rest_framework.relations.HyperlinkedIdentityField.__init__
80+
rest_framework.relations.HyperlinkedRelatedField.__init__
81+
rest_framework.relations.HyperlinkedRelatedField.get_object
82+
rest_framework.relations.ManyRelatedField.__init__
83+
rest_framework.relations.ManyRelatedField.initial
84+
rest_framework.relations.ManyRelatedField.to_representation
85+
rest_framework.relations.PrimaryKeyRelatedField.__init__
86+
rest_framework.relations.RelatedField.__init__
87+
rest_framework.relations.SlugRelatedField.__init__
88+
rest_framework.relations.SlugRelatedField.to_representation
89+
rest_framework.relations.StringRelatedField.__init__
90+
rest_framework.renderers.BaseRenderer.format
91+
rest_framework.renderers.BaseRenderer.media_type
92+
rest_framework.renderers.BrowsableAPIRenderer.get_extra_actions
93+
rest_framework.renderers.CoreAPIJSONOpenAPIRenderer.ensure_ascii
94+
rest_framework.renderers.CoreJSONRenderer.render
95+
rest_framework.renderers.JSONOpenAPIRenderer.encoder_class
96+
rest_framework.renderers.JSONOpenAPIRenderer.ensure_ascii
97+
rest_framework.renderers._BaseOpenAPIRenderer.__init__
98+
rest_framework.renderers._BaseOpenAPIRenderer.render
99+
rest_framework.request.Request.DATA
100+
rest_framework.request.Request.QUERY_PARAMS
101+
rest_framework.routers.BaseRouter
102+
rest_framework.routers.BaseRouter.register
103+
rest_framework.routers.DefaultRouter
104+
rest_framework.routers.DefaultRouter.APIRootView
105+
rest_framework.routers.DefaultRouter.APISchemaView
106+
rest_framework.routers.DefaultRouter.SchemaGenerator
107+
rest_framework.routers.RenameRouterMethods
108+
rest_framework.routers.SimpleRouter
109+
rest_framework.schemas.SchemaGenerator.__init__
110+
rest_framework.schemas.coreapi.SchemaGenerator.__init__
111+
rest_framework.schemas.generators.common_path
112+
rest_framework.schemas.generators.endpoint_ordering
113+
rest_framework.schemas.get_schema_view
114+
rest_framework.schemas.openapi.AutoSchema.__init__
115+
rest_framework.schemas.openapi.AutoSchema.get_reference
116+
rest_framework.schemas.openapi.AutoSchema.get_request_serializer
117+
rest_framework.schemas.openapi.AutoSchema.get_response_serializer
118+
rest_framework.schemas.openapi.DRFOpenAPIInfo
119+
rest_framework.schemas.openapi.DRFOpenAPISchema
120+
rest_framework.schemas.openapi.ExternalDocumentationObject
121+
rest_framework.schemas.openapi.SchemaGenerator.get_schema
122+
rest_framework.schemas.views.SchemaView.__init__
123+
rest_framework.schemas.views.SchemaView.get
124+
rest_framework.schemas.views.SchemaView.renderer_classes
125+
rest_framework.serializers.APIException
126+
rest_framework.serializers.AuthenticationFailed
127+
rest_framework.serializers.BaseSerializer.__init__
128+
rest_framework.serializers.BaseSerializer.is_valid
129+
rest_framework.serializers.BooleanField.initial
130+
rest_framework.serializers.CharField.initial
131+
rest_framework.serializers.DateField.__init__
132+
rest_framework.serializers.DateField.to_internal_value
133+
rest_framework.serializers.DateTimeField.__init__
134+
rest_framework.serializers.DateTimeField.to_internal_value
135+
rest_framework.serializers.DecimalField.__init__
136+
rest_framework.serializers.DictField.__init__
137+
rest_framework.serializers.DictField.initial
138+
rest_framework.serializers.DurationField.to_internal_value
139+
rest_framework.serializers.Field.__init__
140+
rest_framework.serializers.FilePathField.__init__
141+
rest_framework.serializers.HStoreField.__init__
142+
rest_framework.serializers.HiddenField.__init__
143+
rest_framework.serializers.HyperlinkedIdentityField.__init__
144+
rest_framework.serializers.HyperlinkedRelatedField.__init__
145+
rest_framework.serializers.HyperlinkedRelatedField.get_object
146+
rest_framework.serializers.JSONField.__init__
147+
rest_framework.serializers.ListField.__init__
148+
rest_framework.serializers.ListField.initial
149+
rest_framework.serializers.ListField.to_representation
150+
rest_framework.serializers.ListSerializer.is_valid
151+
rest_framework.serializers.ListSerializer.to_representation
152+
rest_framework.serializers.ManyRelatedField.__init__
153+
rest_framework.serializers.ManyRelatedField.initial
154+
rest_framework.serializers.ManyRelatedField.to_representation
155+
rest_framework.serializers.MethodNotAllowed
156+
rest_framework.serializers.ModelField.get_attribute
157+
rest_framework.serializers.ModelField.to_representation
158+
rest_framework.serializers.ModelSerializer.Meta
159+
rest_framework.serializers.ModelSerializer.__init__
160+
rest_framework.serializers.MultipleChoiceField.__init__
161+
rest_framework.serializers.NotAcceptable
162+
rest_framework.serializers.NotAuthenticated
163+
rest_framework.serializers.NotFound
164+
rest_framework.serializers.NullBooleanField
165+
rest_framework.serializers.ParseError
166+
rest_framework.serializers.PermissionDenied
167+
rest_framework.serializers.PrimaryKeyRelatedField.__init__
168+
rest_framework.serializers.ReadOnlyField.__init__
169+
rest_framework.serializers.RelatedField.__init__
170+
rest_framework.serializers.SlugRelatedField.__init__
171+
rest_framework.serializers.SlugRelatedField.to_representation
172+
rest_framework.serializers.StringRelatedField.__init__
173+
rest_framework.serializers.Throttled
174+
rest_framework.serializers.TimeField.__init__
175+
rest_framework.serializers.TimeField.to_internal_value
176+
rest_framework.serializers.UnsupportedMediaType
177+
rest_framework.serializers.empty
178+
rest_framework.settings.DefaultsSettings
179+
rest_framework.settings.api_settings
180+
rest_framework.status.HTTP_102_PROCESSING
181+
rest_framework.status.HTTP_103_EARLY_HINTS
182+
rest_framework.status.HTTP_421_MISDIRECTED_REQUEST
183+
rest_framework.status.HTTP_425_TOO_EARLY
184+
rest_framework.templatetags.rest_framework.urlize_quoted_links
185+
rest_framework.test.APIClient.options
186+
rest_framework.test.APIRequestFactory.delete
187+
rest_framework.test.APIRequestFactory.get
188+
rest_framework.test.APIRequestFactory.options
189+
rest_framework.test.APIRequestFactory.patch
190+
rest_framework.test.APIRequestFactory.post
191+
rest_framework.test.APIRequestFactory.put
192+
rest_framework.test.RequestsClient.__init__
193+
rest_framework.test.cleanup_url_patterns
194+
rest_framework.throttling.SimpleRateThrottle.cache
195+
rest_framework.utils.encoders.JSONEncoder.default
196+
rest_framework.utils.field_mapping.get_unique_error_message
197+
rest_framework.utils.formatting.lazy_format.__mod__
198+
rest_framework.utils.json.dump
199+
rest_framework.utils.json.dumps
200+
rest_framework.utils.json.load
201+
rest_framework.utils.json.loads
202+
rest_framework.validators.BaseUniqueForValidator.message
203+
rest_framework.validators.ContextValidator
204+
rest_framework.validators.Validator
205+
rest_framework.views.APIView.metadata_class
206+
rest_framework.views.AsView
207+
rest_framework.views.GenericView

0 commit comments

Comments
 (0)