diff --git a/ietf/api/views_rpc.py b/ietf/api/views_rpc.py index c5ad8cbe70..fce174ab72 100644 --- a/ietf/api/views_rpc.py +++ b/ietf/api/views_rpc.py @@ -1,10 +1,9 @@ -# Copyright The IETF Trust 2023-2025, All Rights Reserved +# Copyright The IETF Trust 2023-2026, All Rights Reserved import shutil from pathlib import Path from tempfile import TemporaryDirectory from django.conf import settings -from django.core.files.uploadedfile import UploadedFile from drf_spectacular.utils import OpenApiParameter from rest_framework import mixins, parsers, serializers, viewsets, status from rest_framework.decorators import action @@ -392,7 +391,7 @@ def post(self, request): ) serializer.is_valid(raise_exception=True) rfc = serializer.validated_data["rfc"] - uploaded_files: list[UploadedFile] = serializer.validated_data["contents"] + uploaded_files = serializer.validated_data["contents"] # list[UploadedFile] replace = serializer.validated_data["replace"] dest_stem = f"rfc{rfc.rfc_number}" @@ -413,7 +412,7 @@ def post(self, request): with TemporaryDirectory() as tempdir: # Save files in a temporary directory. Use the uploaded filename # extensions to identify files, but ignore the stems and generate our own. - files_to_move: list[Path] = [] + files_to_move = [] # list[Path] tmpfile_stem = Path(tempdir) / dest_stem for upfile in uploaded_files: uploaded_filename = Path(upfile.name) # name supplied by request diff --git a/ietf/doc/migrations/0027_alter_dochistory_title_alter_document_title.py b/ietf/doc/migrations/0027_alter_dochistory_title_alter_document_title.py index 79349e0e08..e0d8560e6f 100644 --- a/ietf/doc/migrations/0027_alter_dochistory_title_alter_document_title.py +++ b/ietf/doc/migrations/0027_alter_dochistory_title_alter_document_title.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): field=models.CharField( max_length=255, validators=[ - django.core.validators.ProhibitNullCharactersValidator, + django.core.validators.ProhibitNullCharactersValidator, # type:ignore django.core.validators.RegexValidator( message="Please enter a string without control characters.", regex="^[^\x01-\x1f]*$", @@ -30,7 +30,7 @@ class Migration(migrations.Migration): field=models.CharField( max_length=255, validators=[ - django.core.validators.ProhibitNullCharactersValidator, + django.core.validators.ProhibitNullCharactersValidator, # type:ignore django.core.validators.RegexValidator( message="Please enter a string without control characters.", regex="^[^\x01-\x1f]*$", diff --git a/ietf/doc/migrations/0030_alter_dochistory_title_alter_document_title.py b/ietf/doc/migrations/0030_alter_dochistory_title_alter_document_title.py new file mode 100644 index 0000000000..9ee858b2e8 --- /dev/null +++ b/ietf/doc/migrations/0030_alter_dochistory_title_alter_document_title.py @@ -0,0 +1,41 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0029_editedrfcauthorsdocevent"), + ] + + operations = [ + migrations.AlterField( + model_name="dochistory", + name="title", + field=models.CharField( + max_length=255, + validators=[ + django.core.validators.ProhibitNullCharactersValidator(), + django.core.validators.RegexValidator( + message="Please enter a string without control characters.", + regex="^[^\x01-\x1f]*$", + ), + ], + ), + ), + migrations.AlterField( + model_name="document", + name="title", + field=models.CharField( + max_length=255, + validators=[ + django.core.validators.ProhibitNullCharactersValidator(), + django.core.validators.RegexValidator( + message="Please enter a string without control characters.", + regex="^[^\x01-\x1f]*$", + ), + ], + ), + ), + ] diff --git a/ietf/doc/models.py b/ietf/doc/models.py index 667874b07d..cce9203d09 100644 --- a/ietf/doc/models.py +++ b/ietf/doc/models.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2010-2025, All Rights Reserved +# Copyright The IETF Trust 2010-2026, All Rights Reserved # -*- coding: utf-8 -*- @@ -115,7 +115,7 @@ class DocumentInfo(models.Model): title = models.CharField( max_length=255, validators=[ - ProhibitNullCharactersValidator, + ProhibitNullCharactersValidator(), validate_no_control_chars, ], ) diff --git a/ietf/doc/serializers.py b/ietf/doc/serializers.py index 6c431a46f3..1b5c59b1d8 100644 --- a/ietf/doc/serializers.py +++ b/ietf/doc/serializers.py @@ -1,10 +1,11 @@ -# Copyright The IETF Trust 2024-2025, All Rights Reserved +# Copyright The IETF Trust 2024-2026, All Rights Reserved """django-rest-framework serializers""" from dataclasses import dataclass from typing import Literal, ClassVar from django.db.models.manager import BaseManager +from django.db.models.query import QuerySet from drf_spectacular.utils import extend_schema_field from rest_framework import serializers @@ -134,7 +135,7 @@ def name(self): def from_document(cls, doc: Document): """Decide the status that applies to a document""" return cls( - slug=(cls.stdlevelname_slug_map.get(doc.std_level.slug, "unknown")), + slug=(cls.stdlevelname_slug_map.get(doc.std_level.slug, "unkn")), ) @classmethod @@ -237,13 +238,15 @@ class Meta: "errata", ] + @extend_schema_field(RfcAuthorSerializer(many=True)) def get_authors(self, doc: Document): # If doc has any RfcAuthors, use those, otherwise fall back to DocumentAuthors - if doc.rfcauthor_set.exists(): - author_queryset = doc.rfcauthor_set.all() - else: - author_queryset = doc.documentauthor_set.all() + author_queryset: QuerySet[RfcAuthor] | QuerySet[DocumentAuthor] = ( + doc.rfcauthor_set.all() + if doc.rfcauthor_set.exists() + else doc.documentauthor_set.all() + ) # RfcAuthorSerializer can deal with DocumentAuthor instances return RfcAuthorSerializer( instance=author_queryset, diff --git a/mypy.ini b/mypy.ini index 19df7ec9b0..4acaf98c95 100644 --- a/mypy.ini +++ b/mypy.ini @@ -2,6 +2,9 @@ ignore_missing_imports = True +# allow PEP 695 type aliases (flag needed until mypy >= 1.13) +enable_incomplete_feature = NewGenericSyntax + plugins = mypy_django_plugin.main diff --git a/requirements.txt b/requirements.txt index de551c1e38..3f89f6f16c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -52,7 +52,7 @@ markdown>=3.8.0 types-markdown>=3.8.0 mock>=5.2.0 # should replace with unittest.mock and remove dependency types-mock>=5.2.0 -mypy~=1.7.0 # Version requirements determined by django-stubs. +mypy~=1.11.2 # Version requirements loosely determined by django-stubs. oic>=1.7.0 # Used only by tests opentelemetry-sdk>=1.38.0 opentelemetry-instrumentation-django>=0.59b0