Repository: tefra/xsdata
Pull request #1101 (2024-12-01 10:00:53)

Remove subscriptable types config
## 📒 Description

> Write a brief description of your PR.

Resolves #xxxx

## 🔗 What I've Done

> Write a description of the steps taken to resolve the issue

## 💬 Comments

> A place to write any comments to the reviewer.

## 🛫 Checklist

- [ ] Updated docs
- [ ] Added unit-tests
- [ ] [Sample tests](https://github.com/tefra/xsdata-samples) pass
- [ ] [W3C tests](https://github.com/tefra/xsdata-w3c-tests) pass


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=1101) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=1101&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=1101&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=1101&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=1101&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=1101&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=1101)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/tefra/xsdata/pull/1101?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 99.95%. Comparing base [(`ab4dc9c`)](https://app.codecov.io/gh/tefra/xsdata/commit/ab4dc9cc2834c4375402f9d811af2600810325ab?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) to head [(`0d70a35`)](https://app.codecov.io/gh/tefra/xsdata/commit/0d70a351fd4694bc26da1459efd01b56fa616fe2?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1101      +/-   ##
==========================================
+ Coverage   99.84%   99.95%   +0.10%     
==========================================
  Files         115      115              
  Lines        9284     9284              
  Branches     1419     1419              
==========================================
+ Hits         9270     9280      +10     
+ Misses         11        3       -8     
+ Partials        3        1       -2     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/tefra/xsdata/pull/1101?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).

sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=1101) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [4 New issues](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=1101&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=1101&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=1101&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=1101&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=1101&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=1101)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=1101) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [4 New issues](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=1101&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=1101&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=1101&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=1101&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=1101&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=1101)



Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 01cd0c28..daea7b66 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -8,12 +8,12 @@ repos:
       - id: end-of-file-fixer
       - id: debug-statements
   - repo: https://github.com/crate-ci/typos
-    rev: v1.27.0
+    rev: v1.28.2
     hooks:
       - id: typos
         exclude: ^tests/|.xsd|xsdata/models/datatype.py$
   - repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.7.2
+    rev: v0.8.2
     hooks:
       - id: ruff
         args: [ --fix, --show-fixes]
@@ -31,11 +31,9 @@ repos:
           - types-docutils
           - types-toposort
         args: [ "--check-untyped-defs", "--ignore-missing-imports" ]
-  - repo: https://github.com/pre-commit/mirrors-prettier
-    rev: v4.0.0-alpha.8
+  - repo: https://github.com/rbubley/mirrors-prettier
+    rev: v3.4.2
     hooks:
       - id: prettier
-        additional_dependencies:
-          - prettier@3.2.5
         types_or: [markdown]
         args: [--prose-wrap=always, --print-width=88]
diff --git a/docs/codegen/config.md b/docs/codegen/config.md
index 446523f2..dfc731e2 100644
--- a/docs/codegen/config.md
+++ b/docs/codegen/config.md
@@ -43,23 +43,6 @@ The maximum line length of the generated code.
 
 **CLI Option:** `-mll, --max-line-length INTEGER`
 
-### `subscriptableTypes`
-
-Use [PEP-585](https://peps.python.org/pep-0585/) type hinting generics in standard
-collections.
-
-```
-tuple # typing.Tuple
-list # typing.List
-dict # typing.Dict
-set # typing.Set
-type # typing.Type
-```
-
-**Default Value:** `False`
-
-**CLI Option:** `--subscriptable-types / --no-subscriptable-types`
-
 ### `genericCollections`
 
 Use `collections.abc.Iterable` and `collections.abc.Mapping` instead of `List|Tuple` and
diff --git a/pyproject.toml b/pyproject.toml
index 126f2dfb..6d361be0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -83,7 +83,7 @@ license-files = ["LICENSE"]
 version = {attr = "xsdata.__version__"}
 
 [tool.ruff]
-target-version = "py38"
+target-version = "py39"
 
 [tool.ruff.lint]
 select = [
@@ -114,8 +114,6 @@ select = [
 ]
 
 ignore = [
-    "ANN101",
-    "ANN102",
     "ANN201",
     "ANN202",
     "ANN204",
@@ -133,6 +131,7 @@ ignore = [
 
 [tool.ruff.lint.per-file-ignores]
 "**/{tests}/*" = ["ANN001", "ANN002", "ANN003", "E501", "B018", "D"]
+"tests/formats/dataclass/cases/**" = ["UP"]
 "**/utils/testing.py" = ["D"]
 "docs/*" = ["D"]
 
diff --git a/xsdata/cli.py b/xsdata/cli.py
index a34a73d9..3be1c8f4 100644
--- a/xsdata/cli.py
+++ b/xsdata/cli.py
@@ -2,8 +2,9 @@ import logging
 import platform
 import sys
 import warnings
+from collections.abc import Iterator
 from pathlib import Path
-from typing import Any, Iterator
+from typing import Any
 
 import click
 from click_default_group import DefaultGroup
diff --git a/xsdata/codegen/container.py b/xsdata/codegen/container.py
index ae706abc..394e3dc3 100644
--- a/xsdata/codegen/container.py
+++ b/xsdata/codegen/container.py
@@ -1,4 +1,5 @@
-from typing import Callable, Dict, Iterator, List, Optional
+from collections.abc import Iterator
+from typing import Callable, Optional
 
 from xsdata.codegen.handlers import (
     AddAttributeSubstitutions,
@@ -72,7 +73,7 @@ class ClassContainer(ContainerInterface):
         """
         super().__init__(config)
         self.step: int = 0
-        self.processors: Dict[int, List] = {
+        self.processors: dict[int, list] = {
             Steps.UNGROUP: [
                 FlattenAttributeGroups(self),
             ],
@@ -271,7 +272,7 @@ class ClassContainer(ContainerInterface):
         self.data[qname] = [c for c in self.data[qname] if c.ref != item.ref]
         self.add(item)
 
-    def set(self, items: List[Class]):
+    def set(self, items: list[Class]):
         """Set the list of classes to the container.
 
         Args:
@@ -280,7 +281,7 @@ class ClassContainer(ContainerInterface):
         self.data.clear()
         self.extend(items)
 
-    def extend(self, items: List[Class]):
+    def extend(self, items: list[Class]):
         """Add a list of classes to the container.
 
         Args:
diff --git a/xsdata/codegen/handlers/add_attribute_substitutions.py b/xsdata/codegen/handlers/add_attribute_substitutions.py
index 48cc6e27..3ddcf37e 100644
--- a/xsdata/codegen/handlers/add_attribute_substitutions.py
+++ b/xsdata/codegen/handlers/add_attribute_substitutions.py
@@ -1,5 +1,5 @@
 from collections import defaultdict
-from typing import Dict, List, Optional
+from typing import Optional
 
 from xsdata.codegen.mixins import ContainerInterface, RelativeHandlerInterface
 from xsdata.codegen.models import Attr, AttrType, Class
@@ -22,7 +22,7 @@ class AddAttributeSubstitutions(RelativeHandlerInterface):
 
     def __init__(self, container: ContainerInterface):
         super().__init__(container)
-        self.substitutions: Optional[Dict[str, List[Attr]]] = None
+        self.substitutions: Optional[dict[str, list[Attr]]] = None
 
     def process(self, target: Class):
         """Process the given class attrs for substitution groups.
diff --git a/xsdata/codegen/handlers/create_compound_fields.py b/xsdata/codegen/handlers/create_compound_fields.py
index 5ba308ff..1356ba9e 100644
--- a/xsdata/codegen/handlers/create_compound_fields.py
+++ b/xsdata/codegen/handlers/create_compound_fields.py
@@ -1,5 +1,4 @@
 from collections import Counter
-from typing import Dict, List, Set, Tuple
 
 from xsdata.codegen.mixins import ContainerInterface, RelativeHandlerInterface
 from xsdata.codegen.models import Attr, Class, Restrictions, get_restriction_choice
@@ -50,7 +49,7 @@ class CreateCompoundFields(RelativeHandlerInterface):
                     self.calculate_choice_min_occurs(attrs)
 
     @classmethod
-    def calculate_choice_min_occurs(cls, attrs: List[Attr]):
+    def calculate_choice_min_occurs(cls, attrs: list[Attr]):
         """Calculate the min occurs restriction of the attrs.
 
         If that attr has a path that includes a xs:choice
@@ -68,7 +67,7 @@ class CreateCompoundFields(RelativeHandlerInterface):
                     attr.restrictions.min_occurs = 0
 
     @classmethod
-    def update_counters(cls, attr: Attr, counters: Dict):
+    def update_counters(cls, attr: Attr, counters: dict):
         """Update the counters dictionary with the attr min/max restrictions.
 
         This method builds a nested counters mapping per path.
@@ -106,7 +105,7 @@ class CreateCompoundFields(RelativeHandlerInterface):
         counters["min"].append(attr.restrictions.min_occurs)
         counters["max"].append(attr.restrictions.max_occurs)
 
-    def group_fields(self, target: Class, attrs: List[Attr]):
+    def group_fields(self, target: Class, attrs: list[Attr]):
         """Group attributes into a new compound field.
 
         Args:
@@ -121,7 +120,7 @@ class CreateCompoundFields(RelativeHandlerInterface):
         names = []
         substitutions = []
         choices = []
-        counters: Dict = {"min": [], "max": []}
+        counters: dict = {"min": [], "max": []}
 
         for attr in attrs:
             ClassUtils.remove_attribute(target, attr)
@@ -147,7 +146,7 @@ class CreateCompoundFields(RelativeHandlerInterface):
         )
         target.attrs.insert(pos, compound_attr)
 
-    def sum_counters(self, counters: Dict) -> Tuple[List[int], List[int]]:
+    def sum_counters(self, counters: dict) -> tuple[list[int], list[int]]:
         """Sum the min/max occurrences for the compound attr.
 
         Args:
@@ -171,8 +170,8 @@ class CreateCompoundFields(RelativeHandlerInterface):
     def choose_name(
         self,
         target: Class,
-        names: List[str],
-        substitutions: List[str],
+        names: list[str],
+        substitutions: list[str],
     ) -> str:
         """Choose a name for the compound attr.
 
@@ -209,7 +208,7 @@ class CreateCompoundFields(RelativeHandlerInterface):
         reserved = self.build_reserved_names(target, names)
         return ClassUtils.unique_name(name, reserved)
 
-    def build_reserved_names(self, target: Class, names: List[str]) -> Set[str]:
+    def build_reserved_names(self, target: Class, names: list[str]) -> set[str]:
         """Build a set of reserved attr names.
 
         The method will also check parent attrs.
diff --git a/xsdata/codegen/handlers/create_wrapper_fields.py b/xsdata/codegen/handlers/create_wrapper_fields.py
index b9dee744..8258f70b 100644
--- a/xsdata/codegen/handlers/create_wrapper_fields.py
+++ b/xsdata/codegen/handlers/create_wrapper_fields.py
@@ -1,4 +1,4 @@
-from typing import Optional, Tuple
+from typing import Optional
 
 from xsdata.codegen.mixins import RelativeHandlerInterface
 from xsdata.codegen.models import Attr, Class
@@ -61,7 +61,7 @@ class CreateWrapperFields(RelativeHandlerInterface):
 
     def find_source_attr(
         self, parent: Class, attr: Attr
-    ) -> Tuple[bool, Optional[Attr]]:
+    ) -> tuple[bool, Optional[Attr]]:
         """Find the source type for the given attr type instance.
 
         If it's a forward reference, look up the source in
diff --git a/xsdata/codegen/handlers/designate_class_packages.py b/xsdata/codegen/handlers/designate_class_packages.py
index 9a113291..04718ce3 100644
--- a/xsdata/codegen/handlers/designate_class_packages.py
+++ b/xsdata/codegen/handlers/designate_class_packages.py
@@ -1,8 +1,9 @@
 import os
 import re
 from collections import defaultdict
+from collections.abc import Iterable, Iterator
 from pathlib import Path
-from typing import Iterable, Iterator, List, Optional, Set
+from typing import Optional
 from urllib.parse import urlparse
 
 from toposort import toposort_flatten
@@ -132,7 +133,7 @@ class DesignateClassPackages(ContainerHandlerInterface):
             module = classes[0].name
             self.assign(classes, ".".join(parts), module)
 
-    def sort_classes(self, qnames: Set[str]) -> List[Class]:
+    def sort_classes(self, qnames: set[str]) -> list[Class]:
         """Sort classes by their dependencies graph.
 
         Args:
@@ -148,7 +149,7 @@ class DesignateClassPackages(ContainerHandlerInterface):
         }
         return [self.container.first(qname) for qname in toposort_flatten(edges)]
 
-    def strongly_connected_classes(self) -> Iterator[Set[str]]:
+    def strongly_connected_classes(self) -> Iterator[set[str]]:
         """Compute strongly connected classes of a directed graph.
 
         Returns:
@@ -170,7 +171,7 @@ class DesignateClassPackages(ContainerHandlerInterface):
             cls.assign(obj.inner, package, module)
 
     @classmethod
-    def group_common_paths(cls, paths: Iterable[str]) -> List[List[str]]:
+    def group_common_paths(cls, paths: Iterable[str]) -> list[list[str]]:
         """Group a list of file paths by their common paths.
 
         Args:
@@ -198,7 +199,7 @@ class DesignateClassPackages(ContainerHandlerInterface):
 
         return list(groups.values())
 
-    def combine_ns_package(self, namespace: Optional[str]) -> List[str]:
+    def combine_ns_package(self, namespace: Optional[str]) -> list[str]:
         """Combine the output package with a namespace.
 
         You can add aliases to namespace uri with the
diff --git a/xsdata/codegen/handlers/detect_circular_references.py b/xsdata/codegen/handlers/detect_circular_references.py
index 4db8f725..3ac6e002 100644
--- a/xsdata/codegen/handlers/detect_circular_references.py
+++ b/xsdata/codegen/handlers/detect_circular_references.py
@@ -1,5 +1,3 @@
-from typing import Dict, List
-
 from xsdata.codegen.mixins import (
     ContainerInterface,
     RelativeHandlerInterface,
@@ -21,7 +19,7 @@ class DetectCircularReferences(RelativeHandlerInterface):
 
     def __init__(self, container: ContainerInterface):
         super().__init__(container)
-        self.reference_types: Dict[int, List[AttrType]] = {}
+        self.reference_types: dict[int, list[AttrType]] = {}
 
     def process(self, target: Class):
         """Go through all the attr types and find circular references.
@@ -38,7 +36,7 @@ class DetectCircularReferences(RelativeHandlerInterface):
             for choice in attr.choices:
                 self.process_types(choice.types, target.ref)
 
-    def process_types(self, types: List[AttrType], class_reference: int):
+    def process_types(self, types: list[AttrType], class_reference: int):
         """Go through the types and find circular references.
 
         Args:
diff --git a/xsdata/codegen/handlers/disambiguate_choices.py b/xsdata/codegen/handlers/disambiguate_choices.py
index 50018ebb..5b3122d3 100644
--- a/xsdata/codegen/handlers/disambiguate_choices.py
+++ b/xsdata/codegen/handlers/disambiguate_choices.py
@@ -1,5 +1,5 @@
 from collections import defaultdict
-from typing import Iterator
+from collections.abc import Iterator
 
 from xsdata.codegen.mixins import ContainerInterface, RelativeHandlerInterface
 from xsdata.codegen.models import Attr, AttrType, Class, Extension, Restrictions
diff --git a/xsdata/codegen/handlers/filter_classes.py b/xsdata/codegen/handlers/filter_classes.py
index 7dcc7a59..f11d9556 100644
--- a/xsdata/codegen/handlers/filter_classes.py
+++ b/xsdata/codegen/handlers/filter_classes.py
@@ -1,5 +1,3 @@
-from typing import List
-
 from xsdata.codegen.mixins import ContainerHandlerInterface
 from xsdata.codegen.models import Class
 from xsdata.logger import logger
@@ -25,7 +23,7 @@ class FilterClasses(ContainerHandlerInterface):
         else:
             logger.warning("No global types exist, will generate all types.")
 
-    def filter_all_globals(self) -> List[Class]:
+    def filter_all_globals(self) -> list[Class]:
         """Filter all globals and any referenced types.
 
         This filter is trying to remove unused simple
diff --git a/xsdata/codegen/handlers/merge_attributes.py b/xsdata/codegen/handlers/merge_attributes.py
index a8d531db..a9846af6 100644
--- a/xsdata/codegen/handlers/merge_attributes.py
+++ b/xsdata/codegen/handlers/merge_attributes.py
@@ -1,5 +1,3 @@
-from typing import List
-
 from xsdata.codegen.mixins import HandlerInterface
 from xsdata.codegen.models import Attr, Class
 from xsdata.codegen.utils import ClassUtils
@@ -47,7 +45,7 @@ class MergeAttributes(HandlerInterface):
         Args:
             target: The target class instance
         """
-        result: List[Attr] = []
+        result: list[Attr] = []
         for attr in target.attrs:
             pos = collections.find(result, attr)
             existing = result[pos] if pos > -1 else None
diff --git a/xsdata/codegen/handlers/process_attributes_types.py b/xsdata/codegen/handlers/process_attributes_types.py
index ba98bbb2..adba61e1 100644
--- a/xsdata/codegen/handlers/process_attributes_types.py
+++ b/xsdata/codegen/handlers/process_attributes_types.py
@@ -1,4 +1,4 @@
-from typing import Dict, Optional
+from typing import Optional
 
 from xsdata.codegen.mixins import ContainerInterface, RelativeHandlerInterface
 from xsdata.codegen.models import Attr, AttrType, Class
@@ -22,7 +22,7 @@ class ProcessAttributeTypes(RelativeHandlerInterface):
 
     def __init__(self, container: ContainerInterface):
         super().__init__(container)
-        self.dependencies: Dict = {}
+        self.dependencies: dict = {}
 
     def process(self, target: Class):
         """Process the given class attrs and their types.
diff --git a/xsdata/codegen/handlers/rename_duplicate_classes.py b/xsdata/codegen/handlers/rename_duplicate_classes.py
index d026471e..af7c9f68 100644
--- a/xsdata/codegen/handlers/rename_duplicate_classes.py
+++ b/xsdata/codegen/handlers/rename_duplicate_classes.py
@@ -1,5 +1,3 @@
-from typing import Dict, List, Set
-
 from xsdata.codegen.mixins import ContainerHandlerInterface, ContainerInterface
 from xsdata.codegen.models import (
     Attr,
@@ -27,15 +25,15 @@ class RenameDuplicateClasses(ContainerHandlerInterface):
         reserved: The reserved class names or qualified names
     """
 
-    __slots__ = ("use_names", "renames", "merges", "reserved")
+    __slots__ = ("merges", "renames", "reserved", "use_names")
 
     def __init__(self, container: ContainerInterface):
         super().__init__(container)
 
         self.use_names = self.should_use_names()
-        self.renames: Dict[int, str] = {}
-        self.merges: Dict[int, int] = {}
-        self.reserved: Set[str] = set()
+        self.renames: dict[int, str] = {}
+        self.merges: dict[int, int] = {}
+        self.reserved: set[str] = set()
 
     def run(self):
         """Detect and resolve class name conflicts."""
@@ -68,7 +66,7 @@ class RenameDuplicateClasses(ContainerHandlerInterface):
             or len(set(map(get_location, self.container))) == 1
         )
 
-    def merge_classes(self, classes: List[Class]):
+    def merge_classes(self, classes: list[Class]):
         """Remove the duplicate classes and update all references.
 
         Args:
@@ -81,7 +79,7 @@ class RenameDuplicateClasses(ContainerHandlerInterface):
         for item in classes:
             self.merges[item.ref] = replace
 
-    def rename_classes(self, classes: List[Class]):
+    def rename_classes(self, classes: list[Class]):
         """Rename the classes in the list.
 
         Cases:
@@ -154,7 +152,7 @@ class RenameDuplicateClasses(ContainerHandlerInterface):
                 reserved.add(cmp)
                 return qname
 
-    def get_reserved(self) -> Set[str]:
+    def get_reserved(self) -> set[str]:
         """Build the reserved names or qualified names of the container."""
         if not self.reserved:
             getter = get_name if self.use_names else get_qname
diff --git a/xsdata/codegen/handlers/sanitize_enumeration_class.py b/xsdata/codegen/handlers/sanitize_enumeration_class.py
index edc392c2..36ad4cd4 100644
--- a/xsdata/codegen/handlers/sanitize_enumeration_class.py
+++ b/xsdata/codegen/handlers/sanitize_enumeration_class.py
@@ -1,4 +1,4 @@
-from typing import Any, List
+from typing import Any
 
 from xsdata.codegen.mixins import RelativeHandlerInterface
 from xsdata.codegen.models import Class
@@ -46,7 +46,7 @@ class SanitizeEnumerationClass(RelativeHandlerInterface):
         if len(target.attrs) != 1 or target.attrs[0].tag != Tag.UNION:
             return
 
-        enums: List[Any] = []
+        enums: list[Any] = []
         for attr_type in target.attrs[0].types:
             if attr_type.forward:
                 enums.extend(target.inner)
diff --git a/xsdata/codegen/handlers/unnest_inner_classes.py b/xsdata/codegen/handlers/unnest_inner_classes.py
index 9f42cfcb..2cb46dc7 100644
--- a/xsdata/codegen/handlers/unnest_inner_classes.py
+++ b/xsdata/codegen/handlers/unnest_inner_classes.py
@@ -1,5 +1,5 @@
 from collections import defaultdict
-from typing import Iterator, List, Tuple
+from collections.abc import Iterator
 
 from xsdata.codegen.mixins import RelativeHandlerInterface
 from xsdata.codegen.models import AttrType, Class
@@ -52,7 +52,7 @@ class UnnestInnerClasses(RelativeHandlerInterface):
                 target.inner.remove(inner)
 
     @classmethod
-    def find_forward_refs(cls, target: Class) -> Iterator[Tuple[AttrType, Class]]:
+    def find_forward_refs(cls, target: Class) -> Iterator[tuple[AttrType, Class]]:
         """Find all forward references for all inner classes.
 
         Args:
@@ -89,7 +89,7 @@ class UnnestInnerClasses(RelativeHandlerInterface):
         target.local_type = True
 
     @classmethod
-    def update_types(cls, types: List[AttrType], qname: str):
+    def update_types(cls, types: list[AttrType], qname: str):
         """Search and replace forward references.
 
         Return the number changes.
diff --git a/xsdata/codegen/handlers/update_attributes_effective_choice.py b/xsdata/codegen/handlers/update_attributes_effective_choice.py
index 5e2940e9..41d083b7 100644
--- a/xsdata/codegen/handlers/update_attributes_effective_choice.py
+++ b/xsdata/codegen/handlers/update_attributes_effective_choice.py
@@ -1,5 +1,4 @@
 from collections import defaultdict
-from typing import List, Tuple
 
 from xsdata.codegen.mixins import HandlerInterface
 from xsdata.codegen.models import Attr, Class, get_restriction_choice
@@ -70,7 +69,7 @@ class UpdateAttributesEffectiveChoice(HandlerInterface):
     @classmethod
     def reset_effective_choice(
         cls,
-        paths: List[Tuple[str, int, int, int]],
+        paths: list[tuple[str, int, int, int]],
         index: int,
         max_occur: int,
     ):
@@ -88,7 +87,7 @@ class UpdateAttributesEffectiveChoice(HandlerInterface):
                 break
 
     @classmethod
-    def merge_attrs(cls, target: Class, groups: List[List[int]]) -> List[Attr]:
+    def merge_attrs(cls, target: Class, groups: list[list[int]]) -> list[Attr]:
         """Merge same name/tag/namespace attrs.
 
         Args:
@@ -122,7 +121,7 @@ class UpdateAttributesEffectiveChoice(HandlerInterface):
         return attrs
 
     @classmethod
-    def group_repeating_attrs(cls, target: Class) -> List[List[int]]:
+    def group_repeating_attrs(cls, target: Class) -> list[list[int]]:
         """Create a list of indexes of the same attrs.
 
         Example: [
diff --git a/xsdata/codegen/handlers/vacuum_inner_classes.py b/xsdata/codegen/handlers/vacuum_inner_classes.py
index 340d04c9..552080d7 100644
--- a/xsdata/codegen/handlers/vacuum_inner_classes.py
+++ b/xsdata/codegen/handlers/vacuum_inner_classes.py
@@ -1,4 +1,4 @@
-from typing import Iterator
+from collections.abc import Iterator
 
 from xsdata.codegen.mixins import HandlerInterface
 from xsdata.codegen.models import AttrType, Class
diff --git a/xsdata/codegen/handlers/validate_attributes_overrides.py b/xsdata/codegen/handlers/validate_attributes_overrides.py
index ad7cf138..b3f6e996 100644
--- a/xsdata/codegen/handlers/validate_attributes_overrides.py
+++ b/xsdata/codegen/handlers/validate_attributes_overrides.py
@@ -1,5 +1,5 @@
 import sys
-from typing import Dict, List, Optional, Set
+from typing import Optional
 
 from xsdata.codegen.mixins import RelativeHandlerInterface
 from xsdata.codegen.models import Attr, Class, get_slug
@@ -36,8 +36,8 @@ class ValidateAttributesOverrides(RelativeHandlerInterface):
     def prohibit_parent_attrs(
         cls,
         target: Class,
-        explicit_attrs: Set[str],
-        base_attrs_map: Dict[str, List[Attr]],
+        explicit_attrs: set[str],
+        base_attrs_map: dict[str, list[Attr]],
     ):
         """Prepend prohibited parent attrs to the target class.
 
@@ -61,7 +61,7 @@ class ValidateAttributesOverrides(RelativeHandlerInterface):
                 target.attrs.insert(0, attr_restricted)
 
     @classmethod
-    def validate_attrs(cls, target: Class, base_attrs_map: Dict[str, List[Attr]]):
+    def validate_attrs(cls, target: Class, base_attrs_map: dict[str, list[Attr]]):
         """Validate overriding attrs.
 
         Cases:
@@ -99,7 +99,7 @@ class ValidateAttributesOverrides(RelativeHandlerInterface):
         """
         return a.xml_type == b.xml_type and a.namespace == b.namespace
 
-    def base_attrs_map(self, target: Class) -> Dict[str, List[Attr]]:
+    def base_attrs_map(self, target: Class) -> dict[str, list[Attr]]:
         """Create a mapping of qualified names to lists of parent attrs.
 
         Args:
diff --git a/xsdata/codegen/handlers/validate_references.py b/xsdata/codegen/handlers/validate_references.py
index de6dff40..5d00beb3 100644
--- a/xsdata/codegen/handlers/validate_references.py
+++ b/xsdata/codegen/handlers/validate_references.py
@@ -1,4 +1,4 @@
-from typing import Optional, Set
+from typing import Optional
 
 from xsdata.codegen.exceptions import CodegenError
 from xsdata.codegen.mixins import ContainerHandlerInterface
@@ -36,7 +36,7 @@ class ValidateReferences(ContainerHandlerInterface):
 
     def validate_unique_instances(self):
         """Validate all codegen instances are unique."""
-        references: Set[int] = set()
+        references: set[int] = set()
         for item in self.container:
             item_references = {id(child) for child in item.children()}
             if item_references.intersection(references):
diff --git a/xsdata/codegen/mappers/definitions.py b/xsdata/codegen/mappers/definitions.py
index c3402c38..715a6652 100644
--- a/xsdata/codegen/mappers/definitions.py
+++ b/xsdata/codegen/mappers/definitions.py
@@ -1,5 +1,6 @@
 import itertools
-from typing import Dict, Iterator, List, Optional, Tuple
+from collections.abc import Iterator
+from typing import Optional
 
 from xsdata.codegen.models import Attr, AttrType, Class, Restrictions, Status
 from xsdata.formats.dataclass.models.generics import AnyElement
@@ -27,7 +28,7 @@ class DefinitionsMapper:
     """
 
     @classmethod
-    def map(cls, definitions: Definitions) -> List[Class]:
+    def map(cls, definitions: Definitions) -> list[Class]:
         """Main entrypoint for this mapper.
 
         Iterates over their services and their ports and build
@@ -74,7 +75,7 @@ class DefinitionsMapper:
         definitions: Definitions,
         binding: Binding,
         port_type: PortType,
-        config: Dict,
+        config: dict,
     ) -> Iterator[Class]:
         """Map binding operations into binding and service classes.
 
@@ -105,7 +106,7 @@ class DefinitionsMapper:
         definitions: Definitions,
         binding_operation: BindingOperation,
         port_type_operation: PortTypeOperation,
-        config: Dict,
+        config: dict,
         name: str,
     ) -> Iterator[Class]:
         """Map a binding operation to a service and binding classes.
@@ -185,7 +186,7 @@ class DefinitionsMapper:
         Yields:
             An iterator of class instances.
         """
-        messages: List[Tuple[str, BindingMessage, PortTypeMessage, Optional[str]]] = []
+        messages: list[tuple[str, BindingMessage, PortTypeMessage, Optional[str]]] = []
 
         if binding_operation.input:
             messages.append(
@@ -235,11 +236,11 @@ class DefinitionsMapper:
             port_type_operation: The port type operation instance
             target: The target class instance
         """
-        ns_map: Dict = {}
+        ns_map: dict = {}
         body = next(inner for inner in target.inner if inner.name == "Body")
         fault_class = cls.build_inner_class(body, "Fault", target.namespace)
 
-        detail_attrs: List[Attr] = []
+        detail_attrs: list[Attr] = []
         for fault in port_type_operation.faults:
             message = definitions.find_message(text.suffix(fault.message))
             detail_attrs.extend(cls.build_parts_attributes(message.parts, ns_map))
@@ -417,7 +418,7 @@ class DefinitionsMapper:
 
     @classmethod
     def map_binding_message_parts(
-        cls, definitions: Definitions, message: str, extended: AnyElement, ns_map: Dict
+        cls, definitions: Definitions, message: str, extended: AnyElement, ns_map: dict
     ) -> Iterator[Attr]:
         """Find a Message instance and map its parts to attrs.
 
@@ -450,7 +451,7 @@ class DefinitionsMapper:
         yield from cls.build_parts_attributes(message_parts, ns_map)
 
     @classmethod
-    def build_parts_attributes(cls, parts: List[Part], ns_map: Dict) -> Iterator[Attr]:
+    def build_parts_attributes(cls, parts: list[Part], ns_map: dict) -> Iterator[Attr]:
         """Build attributes for the given list of parts.
 
         Args:
@@ -482,7 +483,7 @@ class DefinitionsMapper:
             yield cls.build_attr(name, type_qname, namespace=namespace, native=native)
 
     @classmethod
-    def operation_namespace(cls, config: Dict) -> Optional[str]:
+    def operation_namespace(cls, config: dict) -> Optional[str]:
         """Return the operation namespace by the operation transport.
 
         Args:
@@ -499,7 +500,7 @@ class DefinitionsMapper:
         return namespace
 
     @classmethod
-    def attributes(cls, elements: Iterator[AnyElement]) -> Dict:
+    def attributes(cls, elements: Iterator[AnyElement]) -> dict:
         """Return all attributes from all extended elements as a dictionary.
 
         Args:
diff --git a/xsdata/codegen/mappers/dict.py b/xsdata/codegen/mappers/dict.py
index 8aae9b09..f2e069cd 100644
--- a/xsdata/codegen/mappers/dict.py
+++ b/xsdata/codegen/mappers/dict.py
@@ -1,5 +1,5 @@
 import sys
-from typing import Any, Dict, List
+from typing import Any
 
 from xsdata.codegen.mappers.mixins import RawDocumentMapper
 from xsdata.codegen.models import AttrType, Class
@@ -14,7 +14,7 @@ class DictMapper(RawDocumentMapper):
     """
 
     @classmethod
-    def map(cls, data: Dict, name: str, location: str) -> List[Class]:
+    def map(cls, data: dict, name: str, location: str) -> list[Class]:
         """Map a dictionary to classes.
 
         Args:
@@ -29,7 +29,7 @@ class DictMapper(RawDocumentMapper):
         return list(ClassUtils.flatten(target, f"{location}/{name}"))
 
     @classmethod
-    def build_class(cls, data: Dict, name: str) -> Class:
+    def build_class(cls, data: dict, name: str) -> Class:
         """Build a class from a data dictionary.
 
         Args:
diff --git a/xsdata/codegen/mappers/dtd.py b/xsdata/codegen/mappers/dtd.py
index 016ccab1..7bcc7255 100644
--- a/xsdata/codegen/mappers/dtd.py
+++ b/xsdata/codegen/mappers/dtd.py
@@ -1,5 +1,6 @@
 import sys
-from typing import Any, Dict, Iterator, List, Optional
+from collections.abc import Iterator
+from typing import Any, Optional
 
 from xsdata.codegen.models import Attr, AttrType, Class, Extension, Restrictions
 from xsdata.models.dtd import (
@@ -228,7 +229,7 @@ class DtdMapper:
             cls.build_content(target, content.right, **kwargs)
 
     @classmethod
-    def build_occurs(cls, occur: DtdContentOccur) -> Dict:
+    def build_occurs(cls, occur: DtdContentOccur) -> dict:
         """Calculate min/max occurs from the dtd content occur instance.
 
         Args:
@@ -306,7 +307,7 @@ class DtdMapper:
         target.attrs.append(attr)
 
     @classmethod
-    def build_enumeration(cls, target: Class, name: str, values: List[str]):
+    def build_enumeration(cls, target: Class, name: str, values: list[str]):
         """Build a nested enumeration class from the given values list.
 
         Args:
diff --git a/xsdata/codegen/mappers/element.py b/xsdata/codegen/mappers/element.py
index a89c9fda..cf56987a 100644
--- a/xsdata/codegen/mappers/element.py
+++ b/xsdata/codegen/mappers/element.py
@@ -1,5 +1,5 @@
 from collections import defaultdict
-from typing import List, Optional
+from typing import Optional
 
 from xsdata.codegen.mappers.mixins import RawDocumentMapper
 from xsdata.codegen.models import AttrType, Class
@@ -17,7 +17,7 @@ class ElementMapper(RawDocumentMapper):
     """
 
     @classmethod
-    def map(cls, element: AnyElement, location: str) -> List[Class]:
+    def map(cls, element: AnyElement, location: str) -> list[Class]:
         """Map schema children elements to classes.
 
         Args:
@@ -138,7 +138,7 @@ class ElementMapper(RawDocumentMapper):
                 target.mixed = True
 
     @classmethod
-    def sequential_groups(cls, element: AnyElement) -> List[List[int]]:
+    def sequential_groups(cls, element: AnyElement) -> list[list[int]]:
         """Identify sequential groups of repeating attributes.
 
         Args:
@@ -151,7 +151,7 @@ class ElementMapper(RawDocumentMapper):
         return list(collections.connected_components(groups))
 
     @classmethod
-    def group_repeating_attrs(cls, element: AnyElement) -> List[List[int]]:
+    def group_repeating_attrs(cls, element: AnyElement) -> list[list[int]]:
         """Group repeating children in the given generic element.
 
         Args:
@@ -165,7 +165,7 @@ class ElementMapper(RawDocumentMapper):
             if isinstance(child, AnyElement) and child.qname:
                 counters[child.qname].append(index)
 
-        groups: List[List[int]] = []
+        groups: list[list[int]] = []
         if len(counters) > 1:
             groups.extend(
                 list(range(x[0], x[-1] + 1)) for x in counters.values() if len(x) > 1
diff --git a/xsdata/codegen/mappers/schema.py b/xsdata/codegen/mappers/schema.py
index 257bfeb4..a1d56403 100644
--- a/xsdata/codegen/mappers/schema.py
+++ b/xsdata/codegen/mappers/schema.py
@@ -1,4 +1,5 @@
-from typing import Dict, Iterator, List, Optional, Tuple
+from collections.abc import Iterator
+from typing import Optional
 
 from xsdata.codegen.models import Attr, AttrType, Class, Extension, Restrictions
 from xsdata.models.enums import DataType, Tag
@@ -25,7 +26,7 @@ class SchemaMapper:
     """
 
     @classmethod
-    def map(cls, schema: Schema) -> List[Class]:
+    def map(cls, schema: Schema) -> list[Class]:
         """Map schema children elements to classes.
 
         Args:
@@ -45,7 +46,7 @@ class SchemaMapper:
         ]
 
     @classmethod
-    def root_elements(cls, schema: Schema) -> Iterator[Tuple[str, ElementBase]]:
+    def root_elements(cls, schema: Schema) -> Iterator[tuple[str, ElementBase]]:
         """Return the schema root elements.
 
         Qualified Elements:
@@ -121,7 +122,7 @@ class SchemaMapper:
         cls,
         obj: ElementBase,
         target_namespace: Optional[str],
-    ) -> List[str]:
+    ) -> list[str]:
         """Builds a list of qualified substitution group names.
 
         Args:
@@ -199,7 +200,7 @@ class SchemaMapper:
         cls,
         obj: ElementBase,
         parent_restrictions: Restrictions,
-    ) -> Iterator[Tuple[ElementBase, Restrictions]]:
+    ) -> Iterator[tuple[ElementBase, Restrictions]]:
         """Recursively find and return all child elements.
 
         Args:
@@ -289,7 +290,7 @@ class SchemaMapper:
         tag: str,
         target: Class,
         name: str,
-        restrictions: Dict,
+        restrictions: dict,
     ) -> Extension:
         """Create a reference extension for the target class.
 
@@ -345,7 +346,7 @@ class SchemaMapper:
         )
 
     @classmethod
-    def build_attr_types(cls, target: Class, obj: ElementBase) -> List[AttrType]:
+    def build_attr_types(cls, target: Class, obj: ElementBase) -> list[AttrType]:
         """Convert the element types and inner types to an attr types.
 
         Args:
diff --git a/xsdata/codegen/mixins.py b/xsdata/codegen/mixins.py
index 61d14805..eed39dab 100644
--- a/xsdata/codegen/mixins.py
+++ b/xsdata/codegen/mixins.py
@@ -1,5 +1,6 @@
 import abc
-from typing import Callable, Dict, Iterator, List, Optional
+from collections.abc import Iterator
+from typing import Callable, Optional
 
 from xsdata.codegen.models import Attr, Class
 from xsdata.models.config import GeneratorConfig
@@ -17,7 +18,7 @@ class ContainerInterface(abc.ABC):
 
     def __init__(self, config: GeneratorConfig):
         self.config = config
-        self.data: Dict[str, List[Class]] = {}
+        self.data: dict[str, list[Class]] = {}
 
     @abc.abstractmethod
     def __iter__(self) -> Iterator[Class]:
@@ -89,7 +90,7 @@ class ContainerInterface(abc.ABC):
         """
 
     @abc.abstractmethod
-    def extend(self, items: List[Class]):
+    def extend(self, items: list[Class]):
         """Add a list of classes to the container.
 
         Args:
@@ -106,7 +107,7 @@ class ContainerInterface(abc.ABC):
         """
 
     @abc.abstractmethod
-    def set(self, items: List[Class]):
+    def set(self, items: list[Class]):
         """Set the list of classes to the container.
 
         Args:
@@ -140,7 +141,7 @@ class RelativeHandlerInterface(HandlerInterface, abc.ABC):
     def __init__(self, container: ContainerInterface):
         self.container = container
 
-    def base_attrs(self, target: Class) -> List[Attr]:
+    def base_attrs(self, target: Class) -> list[Attr]:
         """Return a list of all parent attrs recursively.
 
         Args:
@@ -150,7 +151,7 @@ class RelativeHandlerInterface(HandlerInterface, abc.ABC):
             A list of attr instances.
 
         """
-        attrs: List[Attr] = []
+        attrs: list[Attr] = []
         for extension in target.extensions:
             base = self.container.find(extension.type.qname)
 
diff --git a/xsdata/codegen/models.py b/xsdata/codegen/models.py
index f8b28444..8197ebf0 100644
--- a/xsdata/codegen/models.py
+++ b/xsdata/codegen/models.py
@@ -2,9 +2,10 @@ import copy
 import operator
 import sys
 import unicodedata
+from collections.abc import Iterator
 from dataclasses import asdict, dataclass, field, fields, replace
 from enum import IntEnum
-from typing import Any, Dict, Iterator, List, Optional, Tuple, Type, TypeVar
+from typing import Any, Optional, TypeVar
 
 from xsdata.codegen.exceptions import CodegenError
 from xsdata.formats.converter import converter
@@ -98,7 +99,7 @@ class Restrictions(CodegenModel):
     choice: Optional[int] = field(default=None, compare=False)
     group: Optional[int] = field(default=None)
     process_contents: Optional[str] = field(default=None)
-    path: List[Tuple[str, int, int, int]] = field(default_factory=list)
+    path: list[tuple[str, int, int, int]] = field(default_factory=list)
 
     @property
     def is_list(self) -> bool:
@@ -155,7 +156,7 @@ class Restrictions(CodegenModel):
         if self.max_occurs is None and source.max_occurs is not None:
             self.max_occurs = source.max_occurs
 
-    def asdict(self, types: Optional[List[Type]] = None) -> Dict:
+    def asdict(self, types: Optional[list[type]] = None) -> dict:
         """Return the initialized only properties as a dictionary.
 
         Skip None or implied values, and optionally use the
@@ -294,8 +295,8 @@ class Attr(CodegenModel):
     default: Optional[str] = field(default=None, compare=False)
     fixed: bool = field(default=False, compare=False)
     mixed: bool = field(default=False, compare=False)
-    types: List[AttrType] = field(default_factory=list, compare=False)
-    choices: List["Attr"] = field(default_factory=list, compare=False)
+    types: list[AttrType] = field(default_factory=list, compare=False)
+    choices: list["Attr"] = field(default_factory=list, compare=False)
     namespace: Optional[str] = field(default=None)
     help: Optional[str] = field(default=None, compare=False)
     restrictions: Restrictions = field(default_factory=Restrictions, compare=False)
@@ -420,7 +421,7 @@ class Attr(CodegenModel):
         return any(tp is object for tp in self.get_native_types())
 
     @property
-    def native_types(self) -> List[Type]:
+    def native_types(self) -> list[type]:
         """Return a list of all the builtin data types."""
         return list(set(self.get_native_types()))
 
@@ -441,7 +442,7 @@ class Attr(CodegenModel):
         """Return the xml type this attribute is mapped to."""
         return xml_type_map.get(self.tag)
 
-    def get_native_types(self) -> Iterator[Type]:
+    def get_native_types(self) -> Iterator[type]:
         """Yield an iterator of all the native attr types."""
         for tp in self.types:
             datatype = tp.datatype
@@ -531,11 +532,11 @@ class Class(CodegenModel):
     meta_name: Optional[str] = field(default=None)
     default: Any = field(default=None, compare=False)
     fixed: bool = field(default=False, compare=False)
-    substitutions: List[str] = field(default_factory=list)
-    extensions: List[Extension] = field(default_factory=list)
-    attrs: List[Attr] = field(default_factory=list)
-    inner: List["Class"] = field(default_factory=list)
-    ns_map: Dict = field(default_factory=dict)
+    substitutions: list[str] = field(default_factory=list)
+    extensions: list[Extension] = field(default_factory=list)
+    attrs: list[Attr] = field(default_factory=list)
+    inner: list["Class"] = field(default_factory=list)
+    ns_map: dict = field(default_factory=dict)
     parent: Optional["Class"] = field(default=None, compare=False)
 
     @property
@@ -663,7 +664,7 @@ class Class(CodegenModel):
         for _, tp in self.types_with_parents():
             yield tp
 
-    def types_with_parents(self) -> Iterator[Tuple[CodegenModel, AttrType]]:
+    def types_with_parents(self) -> Iterator[tuple[CodegenModel, AttrType]]:
         """Yields all class types with their parent codegen instance."""
         for ext in self.extensions:
             yield ext, ext.type
@@ -685,15 +686,13 @@ class Class(CodegenModel):
             yield attr
             yield attr.restrictions
 
-            for tp in attr.types:
-                yield tp
+            yield from attr.types
 
             for choice in attr.choices:
                 yield choice
                 yield choice.restrictions
 
-                for tp in choice.types:
-                    yield tp
+                yield from choice.types
 
         for ext in self.extensions:
             yield ext
@@ -714,7 +713,7 @@ class Class(CodegenModel):
 
         return any(inner.has_forward_ref() for inner in self.inner)
 
-    def parent_names(self) -> List[str]:
+    def parent_names(self) -> list[str]:
         """Return the outer class names."""
         result = []
         target = self.parent
diff --git a/xsdata/codegen/parsers/definitions.py b/xsdata/codegen/parsers/definitions.py
index 1cfc7f87..c9778f14 100644
--- a/xsdata/codegen/parsers/definitions.py
+++ b/xsdata/codegen/parsers/definitions.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass
-from typing import Any, List, Optional
+from typing import Any, Optional
 
 from xsdata.codegen.parsers.schema import SchemaParser
 from xsdata.formats.dataclass.parsers.bases import Parsed
@@ -14,8 +14,8 @@ class DefinitionsParser(SchemaParser):
 
     def end(
         self,
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
         text: Optional[str],
         tail: Optional[str],
diff --git a/xsdata/codegen/parsers/dtd.py b/xsdata/codegen/parsers/dtd.py
index fa6105f4..6fd2e1da 100644
--- a/xsdata/codegen/parsers/dtd.py
+++ b/xsdata/codegen/parsers/dtd.py
@@ -1,5 +1,5 @@
 import io
-from typing import Any, Dict, List, Optional
+from typing import Any, Optional
 
 from xsdata.exceptions import ParserError
 from xsdata.models.dtd import (
@@ -106,7 +106,7 @@ class DtdParser:
         )
 
     @classmethod
-    def build_ns_map(cls, prefix: str, attributes: List[DtdAttribute]) -> Dict:
+    def build_ns_map(cls, prefix: str, attributes: list[DtdAttribute]) -> dict:
         """Build the dtd element namespace prefix-URI map.
 
         It also adds common namespaces like xs, xsi, xlink and xml.
diff --git a/xsdata/codegen/parsers/schema.py b/xsdata/codegen/parsers/schema.py
index 6513c32d..c84783b0 100644
--- a/xsdata/codegen/parsers/schema.py
+++ b/xsdata/codegen/parsers/schema.py
@@ -1,6 +1,6 @@
 import sys
 from dataclasses import dataclass, field
-from typing import Any, Dict, List, Optional, Type, Union
+from typing import Any, Optional, Union
 from urllib.parse import urljoin
 
 from xsdata.formats.dataclass.parsers.bases import Parsed
@@ -37,7 +37,7 @@ class SchemaParser(UserXmlParser):
     location: Optional[str] = field(default=None)
     target_namespace: Optional[str] = field(default=None)
     index: int = field(default_factory=int, init=False)
-    indices: List[int] = field(default_factory=list, init=False)
+    indices: list[int] = field(default_factory=list, init=False)
     element_form: Optional[str] = field(default=None, init=False)
     attribute_form: Optional[str] = field(default=None, init=False)
     default_attributes: Optional[str] = field(default=None, init=False)
@@ -47,12 +47,12 @@ class SchemaParser(UserXmlParser):
 
     def start(
         self,
-        clazz: Optional[Type[T]],
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        clazz: Optional[type[T]],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
     ):
         """Build and queue the XmlNode for the starting element.
 
@@ -73,8 +73,8 @@ class SchemaParser(UserXmlParser):
 
     def end(
         self,
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
         text: Optional[str],
         tail: Optional[str],
@@ -102,7 +102,7 @@ class SchemaParser(UserXmlParser):
 
         return obj
 
-    def start_schema(self, attrs: Dict[str, str]):
+    def start_schema(self, attrs: dict[str, str]):
         """Start schema element entrypoint.
 
         Store the element/attribute default forms and the
@@ -361,7 +361,7 @@ class SchemaParser(UserXmlParser):
         )
 
     @classmethod
-    def set_namespace_map(cls, obj: Any, ns_map: Optional[Dict]):
+    def set_namespace_map(cls, obj: Any, ns_map: Optional[dict]):
         """Add common namespaces like xml, xsi, xlink if they are missing.
 
         These prefixes are implied and we need to support them.
diff --git a/xsdata/codegen/resolver.py b/xsdata/codegen/resolver.py
index 58a7a82e..0b450372 100644
--- a/xsdata/codegen/resolver.py
+++ b/xsdata/codegen/resolver.py
@@ -1,6 +1,5 @@
 import logging
 import re
-from typing import Dict, List
 
 from toposort import toposort_flatten
 
@@ -28,16 +27,16 @@ class DependenciesResolver:
 
     """
 
-    __slots__ = "registry", "aliases", "imports", "class_list", "class_map"
+    __slots__ = "aliases", "class_list", "class_map", "imports", "registry"
 
-    def __init__(self, registry: Dict[str, str]):
+    def __init__(self, registry: dict[str, str]):
         self.registry = registry
-        self.aliases: Dict[str, str] = {}
-        self.imports: List[Import] = []
-        self.class_list: List[str] = []
-        self.class_map: Dict[str, Class] = {}
+        self.aliases: dict[str, str] = {}
+        self.imports: list[Import] = []
+        self.class_list: list[str] = []
+        self.class_map: dict[str, Class] = {}
 
-    def process(self, classes: List[Class]):
+    def process(self, classes: list[Class]):
         """Resolve the dependencies for the given class list.
 
         Reset previously resolved imports and aliases.
@@ -51,11 +50,11 @@ class DependenciesResolver:
         self.class_list = self.create_class_list(classes)
         self.resolve_imports()
 
-    def sorted_imports(self) -> List[Import]:
+    def sorted_imports(self) -> list[Import]:
         """Return a new sorted by name list of import instances."""
         return sorted(self.imports, key=lambda x: x.name)
 
-    def sorted_classes(self) -> List[Class]:
+    def sorted_classes(self) -> list[Class]:
         """Apply aliases and return the sorted the generated class list."""
         result = []
         for name in self.class_list:
@@ -102,7 +101,7 @@ class DependenciesResolver:
         self.aliases = {imp.qname: imp.alias for imp in self.imports if imp.alias}
 
     @classmethod
-    def resolve_conflicts(cls, imports: List[Import], protected: set):
+    def resolve_conflicts(cls, imports: list[Import], protected: set):
         """Find naming conflicts between imports and generate aliases.
 
         Example:
@@ -142,17 +141,17 @@ class DependenciesResolver:
             raise CodegenError("Failed to resolve dependency", qname=qname)
         return self.registry[qname]
 
-    def import_classes(self) -> List[str]:
+    def import_classes(self) -> list[str]:
         """Return a list of class qnames that need to be imported."""
         return [qname for qname in self.class_list if qname not in self.class_map]
 
     @staticmethod
-    def create_class_list(classes: List[Class]) -> List[str]:
+    def create_class_list(classes: list[Class]) -> list[str]:
         """Use topology sort to return a flat list for all the dependencies."""
         return toposort_flatten({obj.qname: set(obj.dependencies()) for obj in classes})
 
     @staticmethod
-    def create_class_map(classes: List[Class]) -> Dict[str, Class]:
+    def create_class_map(classes: list[Class]) -> dict[str, Class]:
         """Index the list of classes by their qualified names.
 
         Raises:
@@ -161,7 +160,7 @@ class DependenciesResolver:
         Returns:
             A qname-class map.
         """
-        result: Dict[str, Class] = {}
+        result: dict[str, Class] = {}
         for obj in classes:
             if obj.qname in result:
                 raise CodegenError("Duplicate class during resolve", qname=obj.qname)
diff --git a/xsdata/codegen/stopwatch.py b/xsdata/codegen/stopwatch.py
index 6ac3b4c9..2a93c6aa 100644
--- a/xsdata/codegen/stopwatch.py
+++ b/xsdata/codegen/stopwatch.py
@@ -1,7 +1,6 @@
 from collections import defaultdict
 from contextlib import contextmanager
 from time import perf_counter_ns
-from typing import Dict, List
 
 
 @contextmanager
@@ -13,4 +12,4 @@ def stopwatch(name: str):
     stopwatches[name].append(stop_time - start_time)
 
 
-stopwatches: Dict[str, List[int]] = defaultdict(list)
+stopwatches: dict[str, list[int]] = defaultdict(list)
diff --git a/xsdata/codegen/transformer.py b/xsdata/codegen/transformer.py
index fb1e5999..4f22ade1 100644
--- a/xsdata/codegen/transformer.py
+++ b/xsdata/codegen/transformer.py
@@ -6,7 +6,7 @@ import pickle
 import tempfile
 from collections import defaultdict
 from pathlib import Path
-from typing import Callable, Dict, List, NamedTuple, Optional, Tuple
+from typing import Callable, NamedTuple, Optional
 
 from toposort import CircularDependencyError
 
@@ -108,15 +108,15 @@ class ResourceTransformer:
         preloaded: A uri/content map used as cache
     """
 
-    __slots__ = ("config", "classes", "processed", "preloaded")
+    __slots__ = ("classes", "config", "preloaded", "processed")
 
     def __init__(self, config: GeneratorConfig):
         self.config = config
-        self.classes: List[Class] = []
-        self.processed: List[str] = []
-        self.preloaded: Dict = {}
+        self.classes: list[Class] = []
+        self.processed: list[str] = []
+        self.preloaded: dict = {}
 
-    def process(self, uris: List[str], cache: bool = False):
+    def process(self, uris: list[str], cache: bool = False):
         """Process a list of resolved URI strings.
 
         Args:
@@ -148,7 +148,7 @@ class ResourceTransformer:
         for name, times in stopwatches.items():
             logger.debug(f"{name} - {sum(times) / 1e9}s")
 
-    def process_sources(self, uris: List[str]):
+    def process_sources(self, uris: list[str]):
         """Process a list of resolved URI strings.
 
         Load the source URI strings and map them to codegen
@@ -168,7 +168,7 @@ class ResourceTransformer:
         self.process_xml_documents(sources[TYPE_XML])
         self.process_json_documents(sources[TYPE_JSON])
 
-    def process_definitions(self, uris: List[str]):
+    def process_definitions(self, uris: list[str]):
         """Process a list of wsdl resources.
 
         Args:
@@ -186,7 +186,7 @@ class ResourceTransformer:
             collections.apply(definitions.schemas, self.convert_schema)
             self.convert_definitions(definitions)
 
-    def process_schemas(self, uris: List[str]):
+    def process_schemas(self, uris: list[str]):
         """Process a list of xsd resources.
 
         Args:
@@ -195,13 +195,13 @@ class ResourceTransformer:
         for uri in uris:
             self.process_schema(uri)
 
-    def process_dtds(self, uris: List[str]):
+    def process_dtds(self, uris: list[str]):
         """Process a list of dtd resources.
 
         Args:
             uris: A list of dtd URI strings to process
         """
-        classes: List[Class] = []
+        classes: list[Class] = []
 
         for uri in uris:
             input_stream = self.load_resource(uri)
@@ -225,7 +225,7 @@ class ResourceTransformer:
         if schema:
             self.convert_schema(schema)
 
-    def process_xml_documents(self, uris: List[str]):
+    def process_xml_documents(self, uris: list[str]):
         """Process a list of xml resources.
 
         Args:
@@ -243,7 +243,7 @@ class ResourceTransformer:
 
         self.classes.extend(ClassUtils.reduce_classes(classes))
 
-    def process_json_documents(self, uris: List[str]):
+    def process_json_documents(self, uris: list[str]):
         """Process a list of json resources.
 
         Args:
@@ -305,7 +305,7 @@ class ResourceTransformer:
         """Convert a definitions instance to codegen classes."""
         self.classes.extend(DefinitionsMapper.map(definitions))
 
-    def generate_classes(self, schema: Schema) -> List[Class]:
+    def generate_classes(self, schema: Schema) -> list[Class]:
         """Convert the given schema instance to a list of classes."""
         uri = schema.location
         logger.info("Compiling schema %s", uri or "...")
@@ -409,14 +409,14 @@ class ResourceTransformer:
 
         return TYPE_UNKNOWN
 
-    def analyze_classes(self, classes: List[Class]) -> List[Class]:
+    def analyze_classes(self, classes: list[Class]) -> list[Class]:
         """Analyzer the given class list and return the final list of classes."""
         container = ClassContainer(config=self.config)
         container.extend(classes)
         container.process()
         return list(container)
 
-    def count_classes(self, classes: List[Class]) -> Tuple[int, int]:
+    def count_classes(self, classes: list[Class]) -> tuple[int, int]:
         """Return a tuple of counters for the main and inner classes.
 
         Args:
@@ -433,7 +433,7 @@ class ResourceTransformer:
         return main, inner
 
     @classmethod
-    def get_cache_file(cls, uris: List[str]) -> Path:
+    def get_cache_file(cls, uris: list[str]) -> Path:
         """Return the cache path for the raw mapped classes.
 
         Args:
diff --git a/xsdata/codegen/utils.py b/xsdata/codegen/utils.py
index 616c4830..89be0d90 100644
--- a/xsdata/codegen/utils.py
+++ b/xsdata/codegen/utils.py
@@ -1,6 +1,7 @@
 import sys
 from collections import deque
-from typing import Deque, Iterator, List, Optional, Set
+from collections.abc import Iterator
+from typing import Optional
 
 from xsdata.codegen.exceptions import CodegenError
 from xsdata.codegen.models import (
@@ -259,7 +260,7 @@ class ClassUtils:
         yield target
 
     @classmethod
-    def reduce_classes(cls, classes: List[Class]) -> List[Class]:
+    def reduce_classes(cls, classes: list[Class]) -> list[Class]:
         """Find duplicate classes and attrs and reduce them.
 
         Args:
@@ -280,7 +281,7 @@ class ClassUtils:
         return result
 
     @classmethod
-    def reduce_attributes(cls, classes: List[Class]) -> List[Attr]:
+    def reduce_attributes(cls, classes: list[Class]) -> list[Attr]:
         """Find and merge duplicate attrs from the given class list.
 
         Args:
@@ -309,7 +310,7 @@ class ClassUtils:
         return result
 
     @classmethod
-    def sorted_attrs(cls, classes: List[Class]) -> List[Attr]:
+    def sorted_attrs(cls, classes: list[Class]) -> list[Attr]:
         """Sort and return the attrs from all the class list.
 
         The list contains duplicate classes, the method tries
@@ -321,7 +322,7 @@ class ClassUtils:
         Returns:
             A list of sorted duplicate attr instances.
         """
-        attrs: List[Attr] = []
+        attrs: list[Attr] = []
         classes.sort(key=lambda x: len(x.attrs), reverse=True)
 
         for obj in classes:
@@ -410,7 +411,7 @@ class ClassUtils:
             change.name = f"{change.name}_{change.tag}"
 
     @classmethod
-    def rename_attributes_by_index(cls, attrs: List[Attr], rename: List[Attr]):
+    def rename_attributes_by_index(cls, attrs: list[Attr], rename: list[Attr]):
         """Append the next available index number to all the rename attr names.
 
         Args:
@@ -423,7 +424,7 @@ class ClassUtils:
             rename[index].name = cls.unique_name(name, reserved)
 
     @classmethod
-    def unique_name(cls, name: str, reserved: Set[str]) -> str:
+    def unique_name(cls, name: str, reserved: set[str]) -> str:
         """Append the next available index number to the name.
 
         Args:
@@ -455,7 +456,7 @@ class ClassUtils:
             attr.types = cls.filter_types(attr.types)
 
     @classmethod
-    def filter_types(cls, types: List[AttrType]) -> List[AttrType]:
+    def filter_types(cls, types: list[AttrType]) -> list[AttrType]:
         """Remove duplicate and invalid types.
 
         Invalid:
@@ -500,8 +501,8 @@ class ClassUtils:
         Returns:
             The nested class instance.
         """
-        queue: Deque[Class] = deque()
-        visited: Set[int] = set()
+        queue: deque[Class] = deque()
+        visited: set[int] = set()
 
         if target.inner:
             queue.extend(target.inner)
diff --git a/xsdata/codegen/validator.py b/xsdata/codegen/validator.py
index b191daa0..f3750e36 100644
--- a/xsdata/codegen/validator.py
+++ b/xsdata/codegen/validator.py
@@ -1,4 +1,4 @@
-from typing import List, Optional
+from typing import Optional
 
 from xsdata.codegen.mixins import ContainerInterface
 from xsdata.codegen.models import Attr, Class, Extension, get_tag
@@ -42,7 +42,7 @@ class ClassValidator:
             if len(classes) > 1:
                 self.merge_global_types(classes)
 
-    def remove_invalid_classes(self, classes: List[Class]):
+    def remove_invalid_classes(self, classes: list[Class]):
         """Remove classes with undefined extensions.
 
         Args:
@@ -58,7 +58,7 @@ class ClassValidator:
                 classes.remove(target)
 
     @classmethod
-    def handle_duplicate_types(cls, classes: List[Class]):
+    def handle_duplicate_types(cls, classes: list[Class]):
         """Find and handle duplicate classes.
 
         If a class is defined more than once, keep either
@@ -115,7 +115,7 @@ class ClassValidator:
             ClassUtils.copy_group_attributes(source, target, circular_group)
 
     @classmethod
-    def select_winner(cls, candidates: List[Class]) -> int:
+    def select_winner(cls, candidates: list[Class]) -> int:
         """From a list of classes select which class index will remain.
 
         Classes that were extracted from in xs:override/xs:redefined
@@ -170,7 +170,7 @@ class ClassValidator:
         return ClassUtils.find_attr(target, target.name)
 
     @classmethod
-    def merge_global_types(cls, classes: List[Class]):
+    def merge_global_types(cls, classes: list[Class]):
         """Merge parent-child global types.
 
         Conditions
diff --git a/xsdata/codegen/writer.py b/xsdata/codegen/writer.py
index 198d5ed1..08004c1b 100644
--- a/xsdata/codegen/writer.py
+++ b/xsdata/codegen/writer.py
@@ -1,4 +1,4 @@
-from typing import ClassVar, Dict, List, Type
+from typing import ClassVar
 
 from xsdata.codegen.exceptions import CodegenError
 from xsdata.codegen.models import Class
@@ -20,14 +20,14 @@ class CodeWriter:
 
     __slots__ = "generator"
 
-    generators: ClassVar[Dict[str, Type[AbstractGenerator]]] = {
+    generators: ClassVar[dict[str, type[AbstractGenerator]]] = {
         "dataclasses": DataclassGenerator,
     }
 
     def __init__(self, generator: AbstractGenerator):
         self.generator = generator
 
-    def write(self, classes: List[Class]):
+    def write(self, classes: list[Class]):
         """Write the classes to the designated modules.
 
         The classes may be written in the same module or
@@ -68,7 +68,7 @@ class CodeWriter:
         return cls(generator=generator_class(config))
 
     @classmethod
-    def register_generator(cls, name: str, clazz: Type[AbstractGenerator]):
+    def register_generator(cls, name: str, clazz: type[AbstractGenerator]):
         """Register a generator by name.
 
         Args:
diff --git a/xsdata/formats/converter.py b/xsdata/formats/converter.py
index deab184f..a9f15695 100644
--- a/xsdata/formats/converter.py
+++ b/xsdata/formats/converter.py
@@ -3,6 +3,7 @@ import base64
 import binascii
 import math
 import re
+from collections.abc import Sequence
 from contextlib import suppress
 from datetime import date, datetime, time
 from decimal import Decimal, InvalidOperation
@@ -10,12 +11,7 @@ from enum import Enum, EnumMeta
 from typing import (
     Any,
     Callable,
-    Dict,
-    List,
     Optional,
-    Sequence,
-    Tuple,
-    Type,
     Union,
     cast,
 )
@@ -65,7 +61,7 @@ class Converter(abc.ABC):
         """
 
     @classmethod
-    def validate_input_type(cls, value: Any, tp: Type):
+    def validate_input_type(cls, value: Any, tp: type):
         """Validate the input value type matches the required type."""
         if not isinstance(value, tp):
             raise ConverterError(
@@ -83,9 +79,9 @@ class ConverterFactory:
     __slots__ = "registry"
 
     def __init__(self):
-        self.registry: Dict[Type, Converter] = {}
+        self.registry: dict[type, Converter] = {}
 
-    def deserialize(self, value: Any, types: Sequence[Type], **kwargs: Any) -> Any:
+    def deserialize(self, value: Any, types: Sequence[type], **kwargs: Any) -> Any:
         """Attempt to convert any value to one of the given types.
 
         Args:
@@ -132,7 +128,7 @@ class ConverterFactory:
     def test(
         self,
         value: Optional[str],
-        types: Sequence[Type],
+        types: Sequence[type],
         strict: bool = False,
         **kwargs: Any,
     ) -> bool:
@@ -166,7 +162,7 @@ class ConverterFactory:
 
         return True
 
-    def register_converter(self, data_type: Type, func: Union[Callable, Converter]):
+    def register_converter(self, data_type: type, func: Union[Callable, Converter]):
         """Register a callable or converter for the given data type.
 
         Args:
@@ -178,7 +174,7 @@ class ConverterFactory:
         else:
             self.registry[data_type] = ProxyConverter(func)
 
-    def unregister_converter(self, data_type: Type):
+    def unregister_converter(self, data_type: type):
         """Unregister the converter for the given data type.
 
         Args:
@@ -189,7 +185,7 @@ class ConverterFactory:
         """
         self.registry.pop(data_type)
 
-    def type_converter(self, data_type: Type) -> Converter:
+    def type_converter(self, data_type: type) -> Converter:
         """Find a suitable converter for given data type.
 
         Iterate over all but last mro items and check for registered
@@ -220,7 +216,7 @@ class ConverterFactory:
         return self.type_converter(value.__class__)
 
     @classmethod
-    def sort_types(cls, types: Sequence[Type]) -> List[Type]:
+    def sort_types(cls, types: Sequence[type]) -> list[type]:
         """Sort a list of types by giving priority to strict types first."""
         if len(types) < 2:
             return list(types)
@@ -228,7 +224,7 @@ class ConverterFactory:
         return sorted(types, key=lambda x: __PYTHON_TYPES_SORTED__.get(x, 0))
 
     @classmethod
-    def explicit_types(cls) -> Tuple[Type, ...]:
+    def explicit_types(cls) -> tuple[type, ...]:
         """Get a list of types that need strict test."""
         return __EXPLICIT_TYPES__
 
@@ -503,7 +499,7 @@ class QNameConverter(Converter):
     def deserialize(
         self,
         value: str,
-        ns_map: Optional[Dict] = None,
+        ns_map: Optional[dict] = None,
         **kwargs: Any,
     ) -> QName:
         """Convert a string value to QName instance.
@@ -534,7 +530,7 @@ class QNameConverter(Converter):
     def serialize(
         self,
         value: QName,
-        ns_map: Optional[Dict] = None,
+        ns_map: Optional[dict] = None,
         **kwargs: Any,
     ) -> str:
         """Convert a QName instance value sto string.
@@ -568,7 +564,7 @@ class QNameConverter(Converter):
         return f"{prefix}:{tag}" if prefix else tag
 
     @staticmethod
-    def resolve(value: str, ns_map: Optional[Dict] = None) -> Tuple[str, str]:
+    def resolve(value: str, ns_map: Optional[dict] = None) -> tuple[str, str]:
         """Split a qname or ns prefixed string value or a uri, name pair.
 
         Args:
@@ -645,7 +641,7 @@ class EnumConverter(Converter):
             values = [value]
 
         length = len(values)
-        for member in cast(Type[Enum], data_type):
+        for member in cast(type[Enum], data_type):
             if self.match(value, values, length, member.value, **kwargs):
                 return member
 
diff --git a/xsdata/formats/dataclass/client.py b/xsdata/formats/dataclass/client.py
index 98a90ff6..f484fadf 100644
--- a/xsdata/formats/dataclass/client.py
+++ b/xsdata/formats/dataclass/client.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, fields
-from typing import Any, Dict, Optional, Type, Union
+from typing import Any, Optional, Union
 
 from xsdata.exceptions import ClientValueError
 from xsdata.formats.dataclass.context import XmlContext
@@ -25,8 +25,8 @@ class Config:
     location: str
     transport: str
     soap_action: str
-    input: Type
-    output: Type
+    input: type
+    output: type
     encoding: Optional[str] = None
 
     @classmethod
@@ -97,7 +97,7 @@ class Client:
         self.serializer = serializer
 
     @classmethod
-    def from_service(cls, obj: Type, **kwargs: Any) -> "Client":
+    def from_service(cls, obj: type, **kwargs: Any) -> "Client":
         """Instantiate client from a service class.
 
         Args:
@@ -115,7 +115,7 @@ class Client:
         """
         return cls(config=Config.from_service(obj, **kwargs))
 
-    def send(self, obj: Any, headers: Optional[Dict] = None) -> Any:
+    def send(self, obj: Any, headers: Optional[dict] = None) -> Any:
         """Build and send a request for the input object.
 
         ```py
@@ -142,7 +142,7 @@ class Client:
         response = self.transport.post(self.config.location, data=data, headers=headers)
         return self.parser.from_bytes(response, self.config.output)
 
-    def prepare_headers(self, headers: Dict) -> Dict:
+    def prepare_headers(self, headers: dict) -> dict:
         """Prepare the request headers.
 
         It merges the custom user headers with the necessary headers
@@ -178,7 +178,7 @@ class Client:
         Raises:
             ClientValueError: If the config input type doesn't match the given object.
         """
-        if isinstance(obj, Dict):
+        if isinstance(obj, dict):
             decoder = DictDecoder(context=self.serializer.context)
             obj = decoder.decode(obj, self.config.input)
 
diff --git a/xsdata/formats/dataclass/compat.py b/xsdata/formats/dataclass/compat.py
index b51722b0..12aad358 100644
--- a/xsdata/formats/dataclass/compat.py
+++ b/xsdata/formats/dataclass/compat.py
@@ -1,7 +1,8 @@
 import abc
+from collections.abc import Iterator
 from dataclasses import MISSING, fields, is_dataclass
 from types import MappingProxyType
-from typing import Any, Dict, Iterator, Optional, Protocol, Set, Type
+from typing import Any, Optional, Protocol
 
 from xsdata.exceptions import XmlContextError
 from xsdata.formats.dataclass.models.generics import AnyElement, DerivedElement
@@ -25,21 +26,21 @@ class ClassType(abc.ABC):
 
     @property
     @abc.abstractmethod
-    def any_element(self) -> Type:
+    def any_element(self) -> Any:
         """Return the AnyElement used to bind wildcard element nodes."""
 
     @property
     @abc.abstractmethod
-    def derived_element(self) -> Type:
+    def derived_element(self) -> Any:
         """Return the DerivedElement used to bind ambiguous element nodes."""
 
     @property
-    def any_keys(self) -> Set[str]:
+    def any_keys(self) -> set[str]:
         """Return the field names of the AnyElement class."""
         return {field.name for field in self.get_fields(self.any_element)}
 
     @property
-    def derived_keys(self) -> Set[str]:
+    def derived_keys(self) -> set[str]:
         """Return the field names of the DerivedElement class."""
         return {field.name for field in self.get_fields(self.derived_element)}
 
@@ -67,7 +68,7 @@ class ClassType(abc.ABC):
         """Return the default value or factory of the given model field."""
 
     @abc.abstractmethod
-    def default_choice_value(self, choice: Dict) -> Any:
+    def default_choice_value(self, choice: dict) -> Any:
         """Return the default value or factory of the given model field choice."""
 
     def score_object(self, obj: Any) -> float:
@@ -114,7 +115,7 @@ class ClassTypes:
     __slots__ = "types"
 
     def __init__(self):
-        self.types: Dict[str, ClassType] = {}
+        self.types: dict[str, ClassType] = {}
 
     def register(self, name: str, fmt: ClassType, **_: Any):
         """Register a class type instance by name.
@@ -147,12 +148,12 @@ class Dataclasses(ClassType):
     __slots__ = ()
 
     @property
-    def any_element(self) -> Type:
+    def any_element(self) -> Any:
         """Return the generic any element class."""
         return AnyElement
 
     @property
-    def derived_element(self) -> Type:
+    def derived_element(self) -> Any:
         """Return the generic derived element class."""
         return DerivedElement
 
@@ -186,7 +187,7 @@ class Dataclasses(ClassType):
 
         return default
 
-    def default_choice_value(self, choice: Dict) -> Any:
+    def default_choice_value(self, choice: dict) -> Any:
         """Return the default value or factory of the given model field choice."""
         factory = choice.get("default_factory")
         if callable(factory):
diff --git a/xsdata/formats/dataclass/context.py b/xsdata/formats/dataclass/context.py
index 466448e2..73a5372f 100644
--- a/xsdata/formats/dataclass/context.py
+++ b/xsdata/formats/dataclass/context.py
@@ -1,7 +1,8 @@
 import sys
 from collections import defaultdict
+from collections.abc import Iterator
 from contextlib import suppress
-from typing import Any, Callable, Dict, Iterator, List, Optional, Set, Type
+from typing import Any, Callable, Optional
 
 from xsdata.exceptions import XmlContextError
 from xsdata.formats.dataclass.compat import class_types
@@ -51,8 +52,8 @@ class XmlContext:
         self.attribute_name_generator = attribute_name_generator
         self.class_type = class_types.get_type(class_type)
 
-        self.cache: Dict[Type, XmlMeta] = {}
-        self.xsi_cache: Dict[str, List[Type]] = defaultdict(list)
+        self.cache: dict[type, XmlMeta] = {}
+        self.xsi_cache: dict[str, list[type]] = defaultdict(list)
         self.models_package = models_package
         self.sys_modules = 0
 
@@ -64,7 +65,7 @@ class XmlContext:
 
     def get_builder(
         self,
-        globalns: Optional[Dict[str, Callable]] = None,
+        globalns: Optional[dict[str, Callable]] = None,
     ) -> XmlMetaBuilder:
         """Return a new xml meta builder instance."""
         return XmlMetaBuilder(
@@ -76,7 +77,7 @@ class XmlContext:
 
     def fetch(
         self,
-        clazz: Type,
+        clazz: type,
         parent_ns: Optional[str] = None,
         xsi_type: Optional[str] = None,
     ) -> XmlMeta:
@@ -115,7 +116,7 @@ class XmlContext:
 
         self.sys_modules = len(sys.modules)
 
-    def is_binding_model(self, clazz: Type[T]) -> bool:
+    def is_binding_model(self, clazz: type[T]) -> bool:
         """Return whether the clazz is a binding model.
 
         If the models package is not empty also validate
@@ -136,7 +137,7 @@ class XmlContext:
             and clazz.__module__.startswith(self.models_package)
         )
 
-    def find_types(self, qname: str) -> List[Type[T]]:
+    def find_types(self, qname: str) -> list[type[T]]:
         """Find all classes that match the given xsi:type qname.
 
         - Ignores native schema types, xs:string, xs:float, xs:int, ...
@@ -155,7 +156,7 @@ class XmlContext:
 
         return []
 
-    def find_type(self, qname: str) -> Optional[Type[T]]:
+    def find_type(self, qname: str) -> Optional[type[T]]:
         """Return the last imported class that matches the given xsi:type qname.
 
         Args:
@@ -164,10 +165,10 @@ class XmlContext:
         Returns:
             A class type or None if no matches.
         """
-        types: List[Type] = self.find_types(qname)
+        types: list[type] = self.find_types(qname)
         return types[-1] if types else None
 
-    def find_type_by_fields(self, field_names: Set[str]) -> Optional[Type[T]]:
+    def find_type_by_fields(self, field_names: set[str]) -> Optional[type[T]]:
         """Find a data class that matches best the given list of field names.
 
         Args:
@@ -179,7 +180,7 @@ class XmlContext:
             fields, return the one with the least extra fields.
         """
 
-        def get_field_diff(clazz: Type) -> int:
+        def get_field_diff(clazz: type) -> int:
             meta = self.cache[clazz]
             local_names = {var.local_name for var in meta.get_all_vars()}
             return len(local_names - field_names)
@@ -195,7 +196,7 @@ class XmlContext:
         choices.sort(key=lambda x: (x[1], x[0].__name__))
         return choices[0][0] if choices else None
 
-    def find_subclass(self, clazz: Type, qname: str) -> Optional[Type]:
+    def find_subclass(self, clazz: type, qname: str) -> Optional[type]:
         """Find a subclass for the given clazz and xsi:type qname.
 
         Compare all classes that match the given xsi:type qname and return the
@@ -209,7 +210,7 @@ class XmlContext:
         Returns:
             The matching class type or None if no matches.
         """
-        types: List[Type] = self.find_types(qname)
+        types: list[type] = self.find_types(qname)
         for tp in types:
             # Why would a xml node with have a xsi:type that points
             # to parent class is beyond me, but it happens, let's protect
@@ -225,9 +226,9 @@ class XmlContext:
 
     def build(
         self,
-        clazz: Type,
+        clazz: type,
         parent_ns: Optional[str] = None,
-        globalns: Optional[Dict[str, Callable]] = None,
+        globalns: Optional[dict[str, Callable]] = None,
     ) -> XmlMeta:
         """Fetch or build the binding metadata for the given class.
 
@@ -244,7 +245,7 @@ class XmlContext:
             self.cache[clazz] = builder.build(clazz, parent_ns)
         return self.cache[clazz]
 
-    def build_recursive(self, clazz: Type, parent_ns: Optional[str] = None):
+    def build_recursive(self, clazz: type, parent_ns: Optional[str] = None):
         """Build the binding metadata for the given class and all of its dependencies.
 
         This method is used in benchmarks!
@@ -261,7 +262,7 @@ class XmlContext:
                     if self.class_type.is_model(tp):
                         self.build_recursive(tp, meta.namespace)
 
-    def local_names_match(self, names: Set[str], clazz: Type) -> bool:
+    def local_names_match(self, names: set[str], clazz: type) -> bool:
         """Check if the given field names match the given class type.
 
         Silently ignore, typing errors. These classes are from third
@@ -289,7 +290,7 @@ class XmlContext:
             return False
 
     @classmethod
-    def is_derived(cls, obj: Any, clazz: Type) -> bool:
+    def is_derived(cls, obj: Any, clazz: type) -> bool:
         """Return whether the obj is a subclass or a parent of the given class type."""
         if obj is None:
             return False
@@ -300,7 +301,7 @@ class XmlContext:
         return any(x is not object and isinstance(obj, x) for x in clazz.__bases__)
 
     @classmethod
-    def get_subclasses(cls, clazz: Type) -> Iterator[Type]:
+    def get_subclasses(cls, clazz: type) -> Iterator[type]:
         """Return an iterator of the given class subclasses."""
         with suppress(TypeError):
             for subclass in clazz.__subclasses__():
diff --git a/xsdata/formats/dataclass/filters.py b/xsdata/formats/dataclass/filters.py
index ed05d150..33854348 100644
--- a/xsdata/formats/dataclass/filters.py
+++ b/xsdata/formats/dataclass/filters.py
@@ -2,17 +2,11 @@ import re
 import sys
 import textwrap
 from collections import defaultdict
+from collections.abc import Iterable, Iterator
 from typing import (
     Any,
     Callable,
-    Dict,
-    Iterable,
-    Iterator,
-    List,
     Optional,
-    Set,
-    Tuple,
-    Type,
 )
 
 from docformatter import configuration, format
@@ -57,7 +51,6 @@ class Filters:
         "docstring_style",
         "max_line_length",
         "union_type",
-        "subscriptable_types",
         "generic_collections",
         "relative_imports",
         "postponed_annotations",
@@ -67,14 +60,14 @@ class Filters:
     )
 
     def __init__(self, config: GeneratorConfig):
-        self.substitutions: Dict[ObjectType, Dict[str, str]] = defaultdict(dict)
+        self.substitutions: dict[ObjectType, dict[str, str]] = defaultdict(dict)
         for sub in config.substitutions.substitution:
             self.substitutions[sub.type][sub.search] = sub.replace
 
-        self.import_patterns: Dict[str, Dict[str, Set[str]]] = defaultdict(
+        self.import_patterns: dict[str, dict[str, set[str]]] = defaultdict(
             lambda: defaultdict(set)
         )
-        self.extensions: Dict[ExtensionType, List[GeneratorExtension]] = defaultdict(
+        self.extensions: dict[ExtensionType, list[GeneratorExtension]] = defaultdict(
             list
         )
         for ext in config.extensions.extension:
@@ -106,7 +99,6 @@ class Filters:
         self.docstring_style: DocstringStyle = config.output.docstring_style
         self.max_line_length: int = config.output.max_line_length
         self.union_type: bool = config.output.union_type
-        self.subscriptable_types: bool = config.output.subscriptable_types
         self.generic_collections: bool = config.output.generic_collections
         self.relative_imports: bool = config.output.relative_imports
         self.postponed_annotations: bool = config.output.postponed_annotations
@@ -173,7 +165,7 @@ class Filters:
 
         return f"@dataclass({', '.join(args)})" if args else "@dataclass"
 
-    def class_params(self, obj: Class) -> Iterator[Tuple[str, str]]:
+    def class_params(self, obj: Class) -> Iterator[tuple[str, str]]:
         """Yield the class variables with their docstring text."""
         is_enum = obj.is_enumeration
         for attr in obj.attrs:
@@ -202,7 +194,7 @@ class Filters:
         name = self.safe_name(name, self.class_safe_prefix, self.class_case)
         return self.apply_substitutions(name, ObjectType.CLASS)
 
-    def class_bases(self, obj: Class, class_name: str) -> List[str]:
+    def class_bases(self, obj: Class, class_name: str) -> list[str]:
         """Return a list of base class names."""
         bases = [self.type_name(x.type) for x in obj.extensions]
 
@@ -217,7 +209,7 @@ class Filters:
 
         return collections.unique_sequence(bases)
 
-    def class_annotations(self, obj: Class, class_name: str) -> List[str]:
+    def class_annotations(self, obj: Class, class_name: str) -> list[str]:
         """Return a list of decorator names."""
         annotations = []
         if self.default_class_annotation:
@@ -252,7 +244,7 @@ class Filters:
         default_value = self.field_default_value(attr, ns_map)
         metadata = self.field_metadata(obj, attr, parent_namespace)
 
-        kwargs: Dict[str, Any] = {}
+        kwargs: dict[str, Any] = {}
         if attr.fixed or attr.is_prohibited:
             kwargs["init"] = False
 
@@ -427,7 +419,7 @@ class Filters:
         obj: Class,
         attr: Attr,
         parent_namespace: Optional[str],
-    ) -> Dict:
+    ) -> dict:
         """Return a metadata dictionary for the given attribute."""
         if attr.is_prohibited:
             return {"type": XmlType.IGNORE}
@@ -464,7 +456,7 @@ class Filters:
         obj: Class,
         attr: Attr,
         parent_namespace: Optional[str],
-    ) -> Optional[Tuple]:
+    ) -> Optional[tuple]:
         """Return a tuple of field metadata if the attr has choices."""
         if not attr.choices:
             return None
@@ -500,7 +492,7 @@ class Filters:
         return tuple(result)
 
     @classmethod
-    def filter_metadata(cls, data: Dict) -> Dict:
+    def filter_metadata(cls, data: dict) -> dict:
         """Filter out false,none keys from the given dict."""
         return {
             key: value
@@ -508,7 +500,7 @@ class Filters:
             if value is not None and value is not False
         }
 
-    def format_arguments(self, data: Dict, indent: int = 0) -> str:
+    def format_arguments(self, data: dict, indent: int = 0) -> str:
         """Return a pretty keyword arguments representation."""
         ind = " " * indent
         fmt = "    {}{}={}"
@@ -532,7 +524,7 @@ class Filters:
 
         return literal_value(data)
 
-    def format_dict(self, data: Dict, indent: int) -> str:
+    def format_dict(self, data: dict, indent: int) -> str:
         """Return a pretty string representation of a dict."""
         ind = " " * indent
         fmt = '    {}"{}": {},'
@@ -682,7 +674,7 @@ class Filters:
 
         return content
 
-    def field_default_value(self, attr: Attr, ns_map: Optional[Dict] = None) -> Any:
+    def field_default_value(self, attr: Attr, ns_map: Optional[dict] = None) -> Any:
         """Generate the field default value/factory for the given attribute."""
         if attr.is_list or (attr.is_tokens and not attr.default):
             return "tuple" if self.format.frozen else "list"
@@ -725,7 +717,7 @@ class Filters:
         return f"{class_name}.{self.constant_name(reference, name)}"
 
     def field_default_tokens(
-        self, attr: Attr, types: List[Type], ns_map: Optional[Dict]
+        self, attr: Attr, types: list[type], ns_map: Optional[dict]
     ) -> str:
         """Generate the default value for tokens fields."""
         assert isinstance(attr.default, str)
@@ -766,7 +758,7 @@ class Filters:
             if self.generic_collections:
                 return "Mapping[str, str]"
 
-            return "dict[str, str]" if self.subscriptable_types else "Dict[str, str]"
+            return "dict[str, str]"
 
         if attr.is_nillable or (
             attr.default is None and (attr.is_optional or not self.format.kw_only)
@@ -840,7 +832,7 @@ class Filters:
         type_names = [self._field_type_name(obj, x, choice=choice) for x in attr.types]
         return self._join_type_names(type_names)
 
-    def _join_type_names(self, type_names: List[str]) -> str:
+    def _join_type_names(self, type_names: list[str]) -> str:
         type_names = collections.unique_sequence(type_names)
         if len(type_names) == 1:
             return type_names[0]
@@ -901,11 +893,10 @@ class Filters:
         if self.generic_collections:
             return "Iterable[{}]"
 
-        fmt = "Tuple[{}, ...]" if self.format.frozen else "List[{}]"
-        return fmt.lower() if self.subscriptable_types else fmt
+        return "tuple[{}, ...]" if self.format.frozen else "list[{}]"
 
     @classmethod
-    def build_import_patterns(cls) -> Dict[str, Dict]:
+    def build_import_patterns(cls) -> dict[str, dict]:
         """Build import search patterns."""
         type_patterns = cls.build_type_patterns
         return {
@@ -913,10 +904,7 @@ class Filters:
             "decimal": {"Decimal": type_patterns("Decimal")},
             "enum": {"Enum": ["(Enum)"]},
             "typing": {
-                "Dict": [": Dict["],
-                "List": [": List["],
                 "Optional": ["Optional["],
-                "Tuple": ["Tuple["],
                 "Union": ["Union["],
                 "ForwardRef": [": ForwardRef("],
                 "Any": type_patterns("Any"),
@@ -936,7 +924,7 @@ class Filters:
         }
 
     @classmethod
-    def build_type_patterns(cls, x: str) -> Tuple:
+    def build_type_patterns(cls, x: str) -> tuple[str, ...]:
         """Return all possible type occurrences in the generated code."""
         return (
             f": {x} =",
diff --git a/xsdata/formats/dataclass/generator.py b/xsdata/formats/dataclass/generator.py
index 1c155836..285c1055 100644
--- a/xsdata/formats/dataclass/generator.py
+++ b/xsdata/formats/dataclass/generator.py
@@ -1,10 +1,10 @@
 import importlib
 import pkgutil
-import re
 import subprocess
 import sys
+from collections.abc import Iterator
 from pathlib import Path
-from typing import Iterator, List, Optional
+from typing import Optional
 
 from jinja2 import Environment, FileSystemLoader
 
@@ -46,11 +46,11 @@ class DataclassGenerator(AbstractGenerator):
         self.ruff_config = Path(__file__).parent / "ruff.toml"
 
     @classmethod
-    def get_template_paths(cls) -> List[str]:
+    def get_template_paths(cls) -> list[str]:
         """Return a list of template paths to feed the jinja2 loader."""
         return [str(Path(__file__).parent.joinpath("templates"))]
 
-    def render(self, classes: List[Class]) -> Iterator[GeneratorResult]:
+    def render(self, classes: list[Class]) -> Iterator[GeneratorResult]:
         """Render the given classes to python packages and modules.
 
         Args:
@@ -111,7 +111,7 @@ class DataclassGenerator(AbstractGenerator):
         package = self.config.output.package
         import_package(self.package_name(package))
 
-    def render_package(self, classes: List[Class], module: str) -> str:
+    def render_package(self, classes: list[Class], module: str) -> str:
         """Render the package for the given classes.
 
         Args:
@@ -135,7 +135,7 @@ class DataclassGenerator(AbstractGenerator):
     def render_module(
         self,
         resolver: DependenciesResolver,
-        classes: List[Class],
+        classes: list[Class],
     ) -> str:
         """Render the module for the given classes.
 
@@ -167,7 +167,7 @@ class DataclassGenerator(AbstractGenerator):
 
     def render_classes(
         self,
-        classes: List[Class],
+        classes: list[Class],
         module_namespace: Optional[str],
     ) -> str:
         """Render the classes source code in a module.
@@ -232,7 +232,7 @@ class DataclassGenerator(AbstractGenerator):
         """Initialize the filters instance by the generator configuration."""
         return Filters(config)
 
-    def ruff_code(self, file_paths: List[str]):
+    def ruff_code(self, file_paths: list[str]):
         """Run ruff lint and format on a list of file names.
 
         Args:
diff --git a/xsdata/formats/dataclass/models/builders.py b/xsdata/formats/dataclass/models/builders.py
index 62d9cd9f..b934411a 100644
--- a/xsdata/formats/dataclass/models/builders.py
+++ b/xsdata/formats/dataclass/models/builders.py
@@ -1,18 +1,11 @@
 import sys
 from collections import defaultdict
+from collections.abc import Iterator, Mapping, Sequence
 from enum import Enum
 from typing import (
     Any,
     Callable,
-    Dict,
-    Iterator,
-    List,
-    Mapping,
     Optional,
-    Sequence,
-    Set,
-    Tuple,
-    Type,
     get_type_hints,
 )
 
@@ -34,7 +27,7 @@ from xsdata.utils.collections import first
 from xsdata.utils.constants import EMPTY_SEQUENCE, return_input
 from xsdata.utils.namespaces import build_qname
 
-evaluations: Dict[str, Callable] = {
+evaluations: dict[str, Callable] = {
     XmlType.TEXT: evaluate_text,
     XmlType.ELEMENT: evaluate_element,
     XmlType.ELEMENTS: evaluate_elements,
@@ -108,14 +101,14 @@ class XmlMetaBuilder:
         class_type: ClassType,
         element_name_generator: Callable,
         attribute_name_generator: Callable,
-        globalns: Optional[Dict[str, Callable]] = None,
+        globalns: Optional[dict[str, Callable]] = None,
     ):
         self.class_type = class_type
         self.element_name_generator = element_name_generator
         self.attribute_name_generator = attribute_name_generator
         self.globalns = globalns
 
-    def build(self, clazz: Type, parent_namespace: Optional[str]) -> XmlMeta:
+    def build(self, clazz: type, parent_namespace: Optional[str]) -> XmlMeta:
         """Build the binding metadata for a dataclass and its fields.
 
         Args:
@@ -136,8 +129,8 @@ class XmlMetaBuilder:
         )
 
         attributes = {}
-        elements: Dict[str, List[XmlVar]] = defaultdict(list)
-        wrappers: Dict[str, str] = {}
+        elements: dict[str, list[XmlVar]] = defaultdict(list)
+        wrappers: dict[str, str] = {}
         choices = []
         any_attributes = []
         wildcards = []
@@ -175,7 +168,7 @@ class XmlMetaBuilder:
 
     def build_vars(
         self,
-        clazz: Type,
+        clazz: type,
         namespace: Optional[str],
         element_name_generator: Callable,
         attribute_name_generator: Callable,
@@ -221,7 +214,7 @@ class XmlMetaBuilder:
 
     def build_class_meta(
         self,
-        clazz: Type,
+        clazz: Any,
         parent_namespace: Optional[str] = None,
     ) -> ClassMeta:
         """Build the class meta options and merge with the defaults.
@@ -267,7 +260,7 @@ class XmlMetaBuilder:
         )
 
     @classmethod
-    def find_declared_class(cls, clazz: Type, name: str) -> Type:
+    def find_declared_class(cls, clazz: type, name: str) -> Any:
         """Find the user class that matches the name.
 
         Todo: Honestly I have no idea why we needed this.
@@ -280,7 +273,7 @@ class XmlMetaBuilder:
         raise XmlContextError(f"Failed to detect the declared class for field {name}")
 
     @classmethod
-    def is_inner_class(cls, clazz: Type) -> bool:
+    def is_inner_class(cls, clazz: type) -> bool:
         """Return whether the given type is nested inside another type."""
         return "." in clazz.__qualname__
 
@@ -297,7 +290,7 @@ class XmlMetaBuilder:
 
         return getattr(meta, "namespace", None)
 
-    def default_xml_type(self, clazz: Type) -> str:
+    def default_xml_type(self, clazz: type) -> str:
         """Return the default xml type for the fields of the given dataclass.
 
         If a class has fields with no xml type defined, attempt
@@ -306,7 +299,7 @@ class XmlMetaBuilder:
 
         # Todo hacks like this are so unnecessary...
         """
-        counters: Dict[str, int] = defaultdict(int)
+        counters: dict[str, int] = defaultdict(int)
         for var in self.class_type.get_fields(clazz):
             xml_type = var.metadata.get("type")
             counters[xml_type or "undefined"] += 1
@@ -358,7 +351,7 @@ class XmlVarBuilder:
 
     def build(
         self,
-        model: Type,
+        model: type,
         name: str,
         type_hint: Any,
         metadata: Mapping[str, Any],
@@ -459,9 +452,9 @@ class XmlVarBuilder:
 
     def build_choices(
         self,
-        model: Type,
+        model: type,
         name: str,
-        choices: List[Dict],
+        choices: list[dict],
         factory: Optional[Callable],
         globalns: Any,
         parent_namespace: Optional[str],
@@ -479,7 +472,7 @@ class XmlVarBuilder:
         Yields:
             An iterator of field choice binding metadata instance.
         """
-        existing_types: Set[type] = set()
+        existing_types: set[type] = set()
 
         for choice in choices:
             default_value = self.class_type.default_choice_value(choice)
@@ -539,7 +532,7 @@ class XmlVarBuilder:
         xml_type: Optional[str],
         namespace: Optional[str],
         parent_namespace: Optional[str],
-    ) -> Tuple[str, ...]:
+    ) -> tuple[str, ...]:
         """Resolve a fields supported namespaces.
 
         Only elements and wildcards are allowed to inherit the parent
@@ -576,14 +569,14 @@ class XmlVarBuilder:
         return tuple(result)
 
     @classmethod
-    def is_any_type(cls, types: Sequence[Type], xml_type: str) -> bool:
+    def is_any_type(cls, types: Sequence[type], xml_type: str) -> bool:
         """Return whether the given xml type supports generic values."""
         if xml_type in (XmlType.ELEMENT, XmlType.ELEMENTS):
             return object in types
 
         return False
 
-    def is_typing_supported(self, types: Sequence[Type]) -> bool:
+    def is_typing_supported(self, types: Sequence[type]) -> bool:
         """Validate all types are registered in the converter."""
         for tp in types:
             if (
diff --git a/xsdata/formats/dataclass/models/elements.py b/xsdata/formats/dataclass/models/elements.py
index 01faf2d3..a6fde4bb 100644
--- a/xsdata/formats/dataclass/models/elements.py
+++ b/xsdata/formats/dataclass/models/elements.py
@@ -1,18 +1,11 @@
 import itertools
 import operator
 import sys
+from collections.abc import Iterator, Mapping, Sequence
 from typing import (
     Any,
     Callable,
-    Dict,
-    Iterator,
-    List,
-    Mapping,
     Optional,
-    Sequence,
-    Set,
-    Tuple,
-    Type,
 )
 
 from xsdata.formats.converter import converter
@@ -38,7 +31,7 @@ class XmlType:
 class MetaMixin:
     """Use this mixin for unit tests only!!!"""
 
-    __slots__: Tuple[str, ...] = ()
+    __slots__: tuple[str, ...] = ()
 
     def __eq__(self, other: Any) -> bool:
         """Implement equality operator."""
@@ -156,8 +149,8 @@ class XmlVar(MetaMixin):
         name: str,
         local_name: str,
         wrapper: Optional[str],
-        types: Sequence[Type],
-        clazz: Optional[Type],
+        types: Sequence[type],
+        clazz: Optional[type],
         init: bool,
         mixed: bool,
         factory: Optional[Callable],
@@ -199,7 +192,7 @@ class XmlVar(MetaMixin):
         self.factory = factory
         self.tokens_factory = tokens_factory
 
-        self.namespace_matches: Optional[Dict[str, bool]] = None
+        self.namespace_matches: Optional[dict[str, bool]] = None
         self.is_clazz_union = self.clazz and len(types) > 1
 
         namespace = default_namespace(namespaces)
@@ -230,7 +223,7 @@ class XmlVar(MetaMixin):
             self.is_text = True
 
     @property
-    def element_types(self) -> Set[Type]:
+    def element_types(self) -> set[type]:
         """Return the unique element types."""
         return {tp for element in self.elements.values() for tp in element.types}
 
@@ -285,7 +278,7 @@ class XmlVar(MetaMixin):
             if element.nillable and is_tokens == element.tokens
         )
 
-    def find_clazz_choice(self, clazz: Type) -> Optional["XmlVar"]:
+    def find_clazz_choice(self, clazz: type) -> Optional["XmlVar"]:
         """Find the best matching choice for the given class.
 
         Best Matches:
@@ -431,7 +424,7 @@ class XmlMeta(MetaMixin):
 
     def __init__(
         self,
-        clazz: Type,
+        clazz: type,
         qname: str,
         target_qname: Optional[str],
         nillable: bool,
@@ -459,7 +452,7 @@ class XmlMeta(MetaMixin):
         self.wrappers = wrappers
 
     @property
-    def element_types(self) -> Set[Type]:
+    def element_types(self) -> set[type]:
         """Return a unique list of all elements types."""
         return {
             tp
@@ -468,7 +461,7 @@ class XmlMeta(MetaMixin):
             for tp in element.types
         }
 
-    def get_element_vars(self) -> List[XmlVar]:
+    def get_element_vars(self) -> list[XmlVar]:
         """Return a sorted list of the class element variables."""
         result = list(
             itertools.chain(self.wildcards, self.choices, *self.elements.values())
@@ -478,12 +471,12 @@ class XmlMeta(MetaMixin):
 
         return sorted(result, key=get_index)
 
-    def get_attribute_vars(self) -> List[XmlVar]:
+    def get_attribute_vars(self) -> list[XmlVar]:
         """Return a sorted list of the class attribute variables."""
         result = itertools.chain(self.any_attributes, self.attributes.values())
         return sorted(result, key=get_index)
 
-    def get_all_vars(self) -> List[XmlVar]:
+    def get_all_vars(self) -> list[XmlVar]:
         """Return a sorted list of all the class variables."""
         result = list(
             itertools.chain(
diff --git a/xsdata/formats/dataclass/models/generics.py b/xsdata/formats/dataclass/models/generics.py
index af1f7b4f..5c2ddc33 100644
--- a/xsdata/formats/dataclass/models/generics.py
+++ b/xsdata/formats/dataclass/models/generics.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import Dict, Generic, List, Optional, TypeVar
+from typing import Generic, Optional, TypeVar
 
 from xsdata.formats.dataclass.models.elements import XmlType
 
@@ -21,10 +21,10 @@ class AnyElement:
     qname: Optional[str] = field(default=None)
     text: Optional[str] = field(default=None)
     tail: Optional[str] = field(default=None)
-    children: List[object] = field(
+    children: list[object] = field(
         default_factory=list, metadata={"type": XmlType.WILDCARD}
     )
-    attributes: Dict[str, str] = field(
+    attributes: dict[str, str] = field(
         default_factory=dict, metadata={"type": XmlType.ATTRIBUTES}
     )
 
diff --git a/xsdata/formats/dataclass/parsers/bases.py b/xsdata/formats/dataclass/parsers/bases.py
index d0a3f434..16fec4c1 100644
--- a/xsdata/formats/dataclass/parsers/bases.py
+++ b/xsdata/formats/dataclass/parsers/bases.py
@@ -1,9 +1,8 @@
 import copy
-import warnings
 from dataclasses import dataclass, field
-from typing import Any, Dict, List, Optional, Tuple, Type, cast
+from typing import Any, Optional, cast
 
-from xsdata.exceptions import ConverterWarning, ParserError
+from xsdata.exceptions import ParserError
 from xsdata.formats.dataclass.context import XmlContext
 from xsdata.formats.dataclass.parsers.mixins import (
     EventsHandler,
@@ -15,7 +14,7 @@ from xsdata.formats.dataclass.parsers.utils import ParserUtils
 from xsdata.formats.types import T
 from xsdata.models.enums import EventType
 
-Parsed = Tuple[Optional[str], Any]
+Parsed = tuple[Optional[str], Any]
 
 
 @dataclass
@@ -31,13 +30,13 @@ class NodeParser(PushParser):
     """
 
     context: XmlContext = field(default_factory=XmlContext)
-    handler: Type[XmlHandler] = field(default=EventsHandler)
+    handler: type[XmlHandler] = field(default=EventsHandler)
 
     def parse(
         self,
         source: Any,
-        clazz: Optional[Type[T]] = None,
-        ns_map: Optional[Dict[Optional[str], str]] = None,
+        clazz: Optional[type[T]] = None,
+        ns_map: Optional[dict[Optional[str], str]] = None,
     ) -> T:
         """Parse the input file or stream into the target class type.
 
@@ -68,12 +67,12 @@ class NodeParser(PushParser):
 
     def start(
         self,
-        clazz: Optional[Type],
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        clazz: Optional[type],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
     ):
         """Build and queue the XmlNode for the starting element.
 
@@ -131,8 +130,8 @@ class NodeParser(PushParser):
 
     def end(
         self,
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
         text: Optional[str],
         tail: Optional[str],
@@ -154,12 +153,12 @@ class NodeParser(PushParser):
 
     def find_root_clazz(
         self,
-        clazz: Optional[Type],
+        clazz: Optional[type],
         qname: str,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
         xsi_type: Optional[str],
-    ) -> Optional[Type]:
+    ) -> Optional[type]:
         """
         Obtain the root clazz, maybe from the provided clazz.
 
@@ -191,16 +190,16 @@ class RecordParser(NodeParser):
         events: The list of recorded events
     """
 
-    events: List = field(init=False, default_factory=list)
+    events: list = field(init=False, default_factory=list)
 
     def start(
         self,
-        clazz: Optional[Type],
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        clazz: Optional[type],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
     ):
         """Build and queue the XmlNode for the starting element.
 
@@ -219,8 +218,8 @@ class RecordParser(NodeParser):
 
     def end(
         self,
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
         text: Optional[str],
         tail: Optional[str],
@@ -243,7 +242,7 @@ class RecordParser(NodeParser):
         return super().end(queue, objects, qname, text, tail)
 
     def register_namespace(
-        self, ns_map: Dict[Optional[str], str], prefix: Optional[str], uri: str
+        self, ns_map: dict[Optional[str], str], prefix: Optional[str], uri: str
     ):
         """Register the uri prefix in the namespace prefix-URI map.
 
diff --git a/xsdata/formats/dataclass/parsers/config.py b/xsdata/formats/dataclass/parsers/config.py
index bed20517..c339090e 100644
--- a/xsdata/formats/dataclass/parsers/config.py
+++ b/xsdata/formats/dataclass/parsers/config.py
@@ -1,10 +1,10 @@
 from dataclasses import dataclass, field
-from typing import Any, Callable, Dict, Optional, Type
+from typing import Any, Callable, Optional
 
 from xsdata.formats.types import T
 
 
-def default_class_factory(cls: Type[T], params: Dict[str, Any]) -> T:
+def default_class_factory(cls: type[T], params: dict[str, Any]) -> T:
     """The default class factory.
 
     To be used as a hook for plugins.
@@ -39,7 +39,7 @@ class ParserConfig:
     base_url: Optional[str] = None
     load_dtd: bool = False
     process_xinclude: bool = False
-    class_factory: Callable[[Type[T], Dict[str, Any]], T] = field(
+    class_factory: Callable[[type[T], dict[str, Any]], T] = field(
         default=default_class_factory
     )
     fail_on_unknown_properties: bool = True
diff --git a/xsdata/formats/dataclass/parsers/dict.py b/xsdata/formats/dataclass/parsers/dict.py
index 5b167fd3..f031de54 100644
--- a/xsdata/formats/dataclass/parsers/dict.py
+++ b/xsdata/formats/dataclass/parsers/dict.py
@@ -1,6 +1,7 @@
+from collections.abc import Iterable
 from contextlib import suppress
 from dataclasses import dataclass, field, replace
-from typing import Any, Dict, Iterable, List, Optional, Type, Union
+from typing import Any, Optional, Union
 
 from typing_extensions import get_args, get_origin
 
@@ -27,7 +28,7 @@ class DictDecoder:
     config: ParserConfig = field(default_factory=ParserConfig)
     context: XmlContext = field(default_factory=XmlContext)
 
-    def decode(self, data: Union[List, Dict], clazz: Optional[Type[T]] = None) -> T:
+    def decode(self, data: Union[list, dict], clazz: Optional[type[T]] = None) -> T:
         """Parse the input stream into the target class type.
 
         If no clazz is provided, the binding context will try
@@ -46,7 +47,7 @@ class DictDecoder:
 
         return [self.bind_dataclass(obj, tp) for obj in data]  # type: ignore
 
-    def verify_type(self, clazz: Optional[Type[T]], data: Union[Dict, List]) -> Type[T]:
+    def verify_type(self, clazz: Optional[type[T]], data: Union[dict, list]) -> type[T]:
         """Verify the given data matches the given clazz.
 
         If no clazz is provided, the binding context will try
@@ -85,7 +86,7 @@ class DictDecoder:
 
         return clazz  # type: ignore
 
-    def detect_type(self, data: Union[Dict, List]) -> Type[T]:
+    def detect_type(self, data: Union[dict, list]) -> type[T]:
         """Locate the target clazz type from the data keys.
 
         Args:
@@ -98,14 +99,14 @@ class DictDecoder:
             raise ParserError("Document is empty, can not detect type")
 
         keys = data[0].keys() if isinstance(data, list) else data.keys()
-        clazz: Optional[Type[T]] = self.context.find_type_by_fields(set(keys))
+        clazz: Optional[type[T]] = self.context.find_type_by_fields(set(keys))
 
         if clazz:
             return clazz
 
         raise ParserError(f"Unable to locate model with properties({list(keys)})")
 
-    def bind_dataclass(self, data: Dict, clazz: Type[T]) -> T:
+    def bind_dataclass(self, data: dict, clazz: type[T]) -> T:
         """Create a new instance of the given class type with the given data.
 
         Args:
@@ -145,7 +146,7 @@ class DictDecoder:
         except TypeError as e:
             raise ParserError(e)
 
-    def bind_derived_dataclass(self, data: Dict, clazz: Type[T]) -> Any:
+    def bind_derived_dataclass(self, data: dict, clazz: type[T]) -> Any:
         """Bind the input data to the given class type.
 
         Examples:
@@ -169,7 +170,7 @@ class DictDecoder:
         generic = self.context.class_type.derived_element
 
         if clazz is generic:
-            real_clazz: Optional[Type[T]] = None
+            real_clazz: Optional[type[T]] = None
             if xsi_type:
                 real_clazz = self.context.find_type(xsi_type)
 
@@ -185,7 +186,7 @@ class DictDecoder:
 
         return generic(qname=qname, type=xsi_type, value=value)
 
-    def bind_best_dataclass(self, data: Dict, classes: Iterable[Type[T]]) -> T:
+    def bind_best_dataclass(self, data: dict, classes: Iterable[type[T]]) -> T:
         """Bind the input data to all the given classes and return best match.
 
         Args:
@@ -309,7 +310,7 @@ class DictDecoder:
             ns_map=EMPTY_MAP,
         )
 
-    def bind_complex_type(self, meta: XmlMeta, var: XmlVar, data: Dict) -> Any:
+    def bind_complex_type(self, meta: XmlMeta, var: XmlVar, data: dict) -> Any:
         """Bind complex values entrypoint.
 
         Args:
@@ -340,7 +341,7 @@ class DictDecoder:
 
         return self.bind_dataclass(data, var.clazz)
 
-    def bind_derived_value(self, meta: XmlMeta, var: XmlVar, data: Dict) -> Any:
+    def bind_derived_value(self, meta: XmlMeta, var: XmlVar, data: dict) -> Any:
         """Bind derived data entrypoint.
 
         The data is representation of a derived element, e.g. {
@@ -376,7 +377,7 @@ class DictDecoder:
             # Is this scenario still possible???
             value = self.bind_text(meta, var, params)
         elif xsi_type:
-            clazz: Optional[Type] = self.context.find_type(xsi_type)
+            clazz: Optional[type] = self.context.find_type(xsi_type)
 
             if clazz is None:
                 raise ParserError(f"Unable to locate xsi:type `{xsi_type}`")
@@ -393,7 +394,7 @@ class DictDecoder:
     @classmethod
     def find_var(
         cls,
-        xml_vars: List[XmlVar],
+        xml_vars: list[XmlVar],
         key: str,
         value: Any,
     ) -> Optional[XmlVar]:
diff --git a/xsdata/formats/dataclass/parsers/handlers/__init__.py b/xsdata/formats/dataclass/parsers/handlers/__init__.py
index cf1bc05a..d718b93a 100644
--- a/xsdata/formats/dataclass/parsers/handlers/__init__.py
+++ b/xsdata/formats/dataclass/parsers/handlers/__init__.py
@@ -1,18 +1,16 @@
-from typing import Type
-
 from xsdata.formats.dataclass.parsers.handlers.native import XmlEventHandler
 from xsdata.formats.dataclass.parsers.mixins import XmlHandler
 
 try:
     from xsdata.formats.dataclass.parsers.handlers.lxml import LxmlEventHandler
 
-    def default_handler() -> Type[XmlHandler]:
+    def default_handler() -> type[XmlHandler]:
         """Return the default xml handler."""
         return LxmlEventHandler
 
 except ImportError:  # pragma: no cover
 
-    def default_handler() -> Type[XmlHandler]:
+    def default_handler() -> type[XmlHandler]:
         """Return the default xml handler."""
         return XmlEventHandler
 
diff --git a/xsdata/formats/dataclass/parsers/handlers/lxml.py b/xsdata/formats/dataclass/parsers/handlers/lxml.py
index b5fd8fc3..44187780 100644
--- a/xsdata/formats/dataclass/parsers/handlers/lxml.py
+++ b/xsdata/formats/dataclass/parsers/handlers/lxml.py
@@ -1,4 +1,5 @@
-from typing import Any, Dict, Iterable, Optional, Tuple
+from collections.abc import Iterable
+from typing import Any, Optional
 
 from lxml import etree
 
@@ -12,7 +13,7 @@ EVENTS = (EventType.START, EventType.END, EventType.START_NS)
 class LxmlEventHandler(XmlHandler):
     """An lxml event handler."""
 
-    def parse(self, source: Any, ns_map: Dict[Optional[str], str]) -> Any:
+    def parse(self, source: Any, ns_map: dict[Optional[str], str]) -> Any:
         """Parse the source XML document.
 
         Args:
@@ -42,8 +43,8 @@ class LxmlEventHandler(XmlHandler):
 
     def process_context(
         self,
-        context: Iterable[Tuple[str, Any]],
-        ns_map: Dict[Optional[str], str],
+        context: Iterable[tuple[str, Any]],
+        ns_map: dict[Optional[str], str],
     ) -> Any:
         """Iterate context and push events to main parser.
 
diff --git a/xsdata/formats/dataclass/parsers/handlers/native.py b/xsdata/formats/dataclass/parsers/handlers/native.py
index f149d795..d935de67 100644
--- a/xsdata/formats/dataclass/parsers/handlers/native.py
+++ b/xsdata/formats/dataclass/parsers/handlers/native.py
@@ -1,5 +1,6 @@
 import functools
-from typing import Any, Dict, Iterable, Iterator, Optional, Tuple
+from collections.abc import Iterable, Iterator
+from typing import Any, Optional
 from urllib.parse import urljoin
 from xml.etree import ElementInclude as xinclude
 from xml.etree import ElementTree as etree
@@ -15,7 +16,7 @@ EVENTS = (EventType.START, EventType.END, EventType.START_NS)
 class XmlEventHandler(XmlHandler):
     """A native xml event handler."""
 
-    def parse(self, source: Any, ns_map: Dict[Optional[str], str]) -> Any:
+    def parse(self, source: Any, ns_map: dict[Optional[str], str]) -> Any:
         """Parse the source XML document.
 
         Args:
@@ -44,7 +45,7 @@ class XmlEventHandler(XmlHandler):
         return self.process_context(ctx, ns_map)
 
     def process_context(
-        self, context: Iterable[Tuple[str, Any]], ns_map: Dict[Optional[str], str]
+        self, context: Iterable[tuple[str, Any]], ns_map: dict[Optional[str], str]
     ) -> Any:
         """Iterate context and push events to main parser.
 
@@ -55,7 +56,7 @@ class XmlEventHandler(XmlHandler):
         Returns:
             An instance of the class type representing the parsed content.
         """
-        element_ns_map: Dict = {}
+        element_ns_map: dict = {}
         for event, element in context:
             if event == EventType.START:
                 self.parser.start(
@@ -87,7 +88,7 @@ class XmlEventHandler(XmlHandler):
 
         return self.objects[-1][1] if self.objects else None
 
-    def merge_parent_namespaces(self, ns_map: Dict[Optional[str], str]) -> Dict:
+    def merge_parent_namespaces(self, ns_map: dict[Optional[str], str]) -> dict:
         """Merge the given prefix-URI map with the parent node map.
 
         This method also registers new prefixes with the parser.
@@ -114,7 +115,7 @@ class XmlEventHandler(XmlHandler):
         return result
 
 
-def iterwalk(element: etree.Element, ns_map: Dict) -> Iterator[Tuple[str, Any]]:
+def iterwalk(element: etree.Element, ns_map: dict) -> Iterator[tuple[str, Any]]:
     """Walk over the element tree and emit events.
 
     The ElementTree doesn't preserve the original namespace prefixes, we
diff --git a/xsdata/formats/dataclass/parsers/json.py b/xsdata/formats/dataclass/parsers/json.py
index 0b95b0b1..a350ccb2 100644
--- a/xsdata/formats/dataclass/parsers/json.py
+++ b/xsdata/formats/dataclass/parsers/json.py
@@ -2,7 +2,7 @@ import io
 import json
 import pathlib
 from dataclasses import dataclass, field
-from typing import Any, Callable, Dict, List, Optional, Type, Union
+from typing import Any, Callable, Optional, Union
 
 from xsdata.formats.dataclass.parsers import DictDecoder
 from xsdata.formats.types import T
@@ -20,7 +20,7 @@ class JsonParser(DictDecoder):
 
     load_factory: Callable = field(default=json.load)
 
-    def from_path(self, path: pathlib.Path, clazz: Optional[Type[T]] = None) -> T:
+    def from_path(self, path: pathlib.Path, clazz: Optional[type[T]] = None) -> T:
         """Parse the input file into the target class type.
 
         If no clazz is provided, the binding context will try
@@ -35,7 +35,7 @@ class JsonParser(DictDecoder):
         """
         return self.parse(str(path.resolve()), clazz)
 
-    def from_string(self, source: str, clazz: Optional[Type[T]] = None) -> T:
+    def from_string(self, source: str, clazz: Optional[type[T]] = None) -> T:
         """Parse the input source string into the target class type.
 
         If no clazz is provided, the binding context will try
@@ -50,7 +50,7 @@ class JsonParser(DictDecoder):
         """
         return self.from_bytes(source.encode(), clazz)
 
-    def from_bytes(self, source: bytes, clazz: Optional[Type[T]] = None) -> T:
+    def from_bytes(self, source: bytes, clazz: Optional[type[T]] = None) -> T:
         """Parse the input source bytes object into the target class type.
 
         If no clazz is provided, the binding context will try
@@ -65,7 +65,7 @@ class JsonParser(DictDecoder):
         """
         return self.parse(io.BytesIO(source), clazz)
 
-    def parse(self, source: Any, clazz: Optional[Type[T]] = None) -> T:
+    def parse(self, source: Any, clazz: Optional[type[T]] = None) -> T:
         """Parse the input stream into the target class type.
 
         If no clazz is provided, the binding context will try
@@ -81,7 +81,7 @@ class JsonParser(DictDecoder):
         data = self.load_json(source)
         return self.decode(data, clazz)
 
-    def load_json(self, source: Any) -> Union[Dict, List]:
+    def load_json(self, source: Any) -> Union[dict, list]:
         """Load the given json source filename or stream.
 
         Args:
diff --git a/xsdata/formats/dataclass/parsers/mixins.py b/xsdata/formats/dataclass/parsers/mixins.py
index 3c739957..fdd3853f 100644
--- a/xsdata/formats/dataclass/parsers/mixins.py
+++ b/xsdata/formats/dataclass/parsers/mixins.py
@@ -2,7 +2,7 @@ import abc
 import io
 import pathlib
 from dataclasses import dataclass, field
-from typing import Any, Dict, List, Optional, Tuple, Type
+from typing import Any, Optional
 
 from xsdata.exceptions import XmlHandlerError
 from xsdata.formats.dataclass.parsers.config import ParserConfig
@@ -22,13 +22,13 @@ class PushParser:
     """
 
     config: ParserConfig = field(default_factory=ParserConfig)
-    ns_map: Dict[Optional[str], str] = field(init=False, default_factory=dict)
+    ns_map: dict[Optional[str], str] = field(init=False, default_factory=dict)
 
     def from_path(
         self,
         path: pathlib.Path,
-        clazz: Optional[Type[T]] = None,
-        ns_map: Optional[Dict[Optional[str], str]] = None,
+        clazz: Optional[type[T]] = None,
+        ns_map: Optional[dict[Optional[str], str]] = None,
     ) -> T:
         """Parse the input file into the target class type.
 
@@ -48,8 +48,8 @@ class PushParser:
     def from_string(
         self,
         source: str,
-        clazz: Optional[Type[T]] = None,
-        ns_map: Optional[Dict[Optional[str], str]] = None,
+        clazz: Optional[type[T]] = None,
+        ns_map: Optional[dict[Optional[str], str]] = None,
     ) -> T:
         """Parse the input source string into the target class type.
 
@@ -69,8 +69,8 @@ class PushParser:
     def from_bytes(
         self,
         source: bytes,
-        clazz: Optional[Type[T]] = None,
-        ns_map: Optional[Dict[Optional[str], str]] = None,
+        clazz: Optional[type[T]] = None,
+        ns_map: Optional[dict[Optional[str], str]] = None,
     ) -> T:
         """Parse the input source bytes object into the target class type.
 
@@ -91,8 +91,8 @@ class PushParser:
     def parse(
         self,
         source: Any,
-        clazz: Optional[Type[T]] = None,
-        ns_map: Optional[Dict[Optional[str], str]] = None,
+        clazz: Optional[type[T]] = None,
+        ns_map: Optional[dict[Optional[str], str]] = None,
     ) -> T:
         """Parse the input file or stream into the target class type.
 
@@ -111,12 +111,12 @@ class PushParser:
     @abc.abstractmethod
     def start(
         self,
-        clazz: Optional[Type],
-        queue: List[Any],
-        objects: List[Any],
+        clazz: Optional[type],
+        queue: list[Any],
+        objects: list[Any],
         qname: str,
-        attrs: Dict[str, str],
-        ns_map: Dict[Optional[str], str],
+        attrs: dict[str, str],
+        ns_map: dict[Optional[str], str],
     ):
         """Build and queue the XmlNode for the starting element.
 
@@ -132,8 +132,8 @@ class PushParser:
     @abc.abstractmethod
     def end(
         self,
-        queue: List,
-        objects: List,
+        queue: list,
+        objects: list,
         qname: str,
         text: Optional[str],
         tail: Optional[str],
@@ -152,7 +152,7 @@ class PushParser:
         """
 
     def register_namespace(
-        self, ns_map: Dict[Optional[str], str], prefix: Optional[str], uri: str
+        self, ns_map: dict[Optional[str], str], prefix: Optional[str], uri: str
     ):
         """Register the uri prefix in the namespace prefix-URI map.
 
@@ -177,7 +177,7 @@ class XmlNode(abc.ABC):
     __slots__ = ()
 
     @abc.abstractmethod
-    def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> "XmlNode":
+    def child(self, qname: str, attrs: dict, ns_map: dict, position: int) -> "XmlNode":
         """Initialize the next child node to be queued, when an element starts.
 
         This entry point is responsible to create the next node type
@@ -200,7 +200,7 @@ class XmlNode(abc.ABC):
         qname: str,
         text: Optional[str],
         tail: Optional[str],
-        objects: List[Any],
+        objects: list[Any],
     ) -> bool:
         """Bind the parsed data into an object for the ending element.
 
@@ -233,13 +233,13 @@ class XmlHandler:
 
     __slots__ = ("parser", "clazz", "queue", "objects")
 
-    def __init__(self, parser: PushParser, clazz: Optional[Type]):
+    def __init__(self, parser: PushParser, clazz: Optional[type]):
         self.parser = parser
         self.clazz = clazz
-        self.queue: List = []
-        self.objects: List = []
+        self.queue: list = []
+        self.objects: list = []
 
-    def parse(self, source: Any, ns_map: Dict[Optional[str], str]) -> Any:
+    def parse(self, source: Any, ns_map: dict[Optional[str], str]) -> Any:
         """Parse the source XML document.
 
         Args:
@@ -255,7 +255,7 @@ class XmlHandler:
 class EventsHandler(XmlHandler):
     """Sax content handler for pre-recorded events."""
 
-    def parse(self, source: List[Tuple], ns_map: Dict[Optional[str], str]) -> Any:
+    def parse(self, source: list[tuple], ns_map: dict[Optional[str], str]) -> Any:
         """Forward the pre-recorded events to the main parser.
 
         Args:
diff --git a/xsdata/formats/dataclass/parsers/nodes/element.py b/xsdata/formats/dataclass/parsers/nodes/element.py
index 1a280808..a6a6ce78 100644
--- a/xsdata/formats/dataclass/parsers/nodes/element.py
+++ b/xsdata/formats/dataclass/parsers/nodes/element.py
@@ -1,6 +1,5 @@
-import math
 from itertools import starmap
-from typing import Any, Dict, List, Optional, Set, Type
+from typing import Any, Optional
 
 from xsdata.exceptions import ParserError
 from xsdata.formats.converter import converter
@@ -54,13 +53,13 @@ class ElementNode(XmlNode):
     def __init__(
         self,
         meta: XmlMeta,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
         config: ParserConfig,
         context: XmlContext,
         position: int,
         mixed: bool = False,
-        derived_factory: Optional[Type] = None,
+        derived_factory: Optional[type] = None,
         xsi_type: Optional[str] = None,
         xsi_nil: Optional[bool] = None,
     ):
@@ -74,7 +73,7 @@ class ElementNode(XmlNode):
         self.derived_factory = derived_factory
         self.xsi_type = xsi_type
         self.xsi_nil = xsi_nil
-        self.assigned: Set[int] = set()
+        self.assigned: set[int] = set()
         self.tail_processed: bool = False
 
     def bind(
@@ -82,7 +81,7 @@ class ElementNode(XmlNode):
         qname: str,
         text: Optional[str],
         tail: Optional[str],
-        objects: List[Any],
+        objects: list[Any],
     ) -> bool:
         """Bind the parsed data into an object for the ending element.
 
@@ -101,7 +100,7 @@ class ElementNode(XmlNode):
         """
         obj: Any = None
         if not self.xsi_nil or self.meta.nillable:
-            params: Dict = {}
+            params: dict = {}
             self.bind_attrs(params)
             self.bind_content(params, text, tail, objects)
             obj = self.config.class_factory(self.meta.clazz, params)
@@ -120,10 +119,10 @@ class ElementNode(XmlNode):
 
     def bind_content(
         self,
-        params: Dict,
+        params: dict,
         text: Optional[str],
         tail: Optional[str],
-        objects: List[Any],
+        objects: list[Any],
     ):
         """Parse the text and tail content.
 
@@ -149,7 +148,7 @@ class ElementNode(XmlNode):
             if isinstance(params[key], PendingCollection):
                 params[key] = params[key].evaluate()
 
-    def bind_attrs(self, params: Dict[str, Any]):
+    def bind_attrs(self, params: dict[str, Any]):
         """Parse the element attributes.
 
         Scenarios:
@@ -183,7 +182,7 @@ class ElementNode(XmlNode):
                             f"Unknown attribute {self.meta.qname}:{qname}"
                         )
 
-    def bind_attr(self, params: Dict, var: XmlVar, value: Any):
+    def bind_attr(self, params: dict, var: XmlVar, value: Any):
         """Parse an element attribute.
 
         Ignores fields with init==false!
@@ -206,7 +205,7 @@ class ElementNode(XmlNode):
         else:
             ParserUtils.validate_fixed_value(self.meta, var, value)
 
-    def bind_any_attr(self, params: Dict, var: XmlVar, qname: str, value: Any):
+    def bind_any_attr(self, params: dict, var: XmlVar, qname: str, value: Any):
         """Parse an element attribute to a wildcard field.
 
         Args:
@@ -220,7 +219,7 @@ class ElementNode(XmlNode):
 
         params[var.name][qname] = ParserUtils.parse_any_attribute(value, self.ns_map)
 
-    def bind_objects(self, params: Dict, objects: List):
+    def bind_objects(self, params: dict, objects: list):
         """Bind children objects.
 
         Emit a warning if an object doesn't fit in any
@@ -237,7 +236,7 @@ class ElementNode(XmlNode):
 
         del objects[position:]
 
-    def bind_object(self, params: Dict, qname: str, value: Any) -> bool:
+    def bind_object(self, params: dict, qname: str, value: Any) -> bool:
         """Bind a child object.
 
         Args:
@@ -259,7 +258,7 @@ class ElementNode(XmlNode):
         return False
 
     @classmethod
-    def bind_var(cls, params: Dict, var: XmlVar, value: Any) -> bool:
+    def bind_var(cls, params: dict, var: XmlVar, value: Any) -> bool:
         """Bind a child object to an element field.
 
         Args:
@@ -285,7 +284,7 @@ class ElementNode(XmlNode):
 
         return True
 
-    def bind_wild_var(self, params: Dict, var: XmlVar, qname: str, value: Any) -> bool:
+    def bind_wild_var(self, params: dict, var: XmlVar, qname: str, value: Any) -> bool:
         """Bind a child object to a wildcard field.
 
         The wildcard might support one or more values. If it
@@ -322,7 +321,7 @@ class ElementNode(XmlNode):
 
         return True
 
-    def bind_mixed_objects(self, params: Dict, var: XmlVar, objects: List):
+    def bind_mixed_objects(self, params: dict, var: XmlVar, objects: list):
         """Bind children objects to a mixed content wildcard field.
 
         Args:
@@ -351,7 +350,7 @@ class ElementNode(XmlNode):
 
         return value
 
-    def bind_text(self, params: Dict, text: Optional[str]) -> bool:
+    def bind_text(self, params: dict, text: Optional[str]) -> bool:
         """Bind the element text content.
 
         Args:
@@ -387,7 +386,7 @@ class ElementNode(XmlNode):
 
     def bind_wild_text(
         self,
-        params: Dict,
+        params: dict,
         var: XmlVar,
         text: Optional[str],
         tail: Optional[str],
@@ -438,7 +437,7 @@ class ElementNode(XmlNode):
 
         return True
 
-    def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
+    def child(self, qname: str, attrs: dict, ns_map: dict, position: int) -> XmlNode:
         """Initialize the next child node to be queued, when an element starts.
 
         This entry point is responsible to create the next node type
@@ -474,8 +473,8 @@ class ElementNode(XmlNode):
         self,
         qname: str,
         var: XmlVar,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
         position: int,
     ) -> Optional[XmlNode]:
         """Build the next child node based on the xml var instance.
@@ -585,13 +584,13 @@ class ElementNode(XmlNode):
 
     def build_element_node(
         self,
-        clazz: Type,
+        clazz: type,
         derived: bool,
         nillable: bool,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
         position: int,
-        derived_factory: Type,
+        derived_factory: type,
         xsi_type: Optional[str] = None,
         xsi_nil: Optional[bool] = None,
     ) -> Optional["ElementNode"]:
diff --git a/xsdata/formats/dataclass/parsers/nodes/primitive.py b/xsdata/formats/dataclass/parsers/nodes/primitive.py
index f915d416..fb7fc543 100644
--- a/xsdata/formats/dataclass/parsers/nodes/primitive.py
+++ b/xsdata/formats/dataclass/parsers/nodes/primitive.py
@@ -1,4 +1,4 @@
-from typing import Dict, List, Optional
+from typing import Optional
 
 from xsdata.exceptions import XmlContextError
 from xsdata.formats.dataclass.models.elements import XmlMeta, XmlVar
@@ -19,7 +19,7 @@ class PrimitiveNode(XmlNode):
 
     __slots__ = "meta", "var", "ns_map", "config"
 
-    def __init__(self, meta: XmlMeta, var: XmlVar, ns_map: Dict, config: ParserConfig):
+    def __init__(self, meta: XmlMeta, var: XmlVar, ns_map: dict, config: ParserConfig):
         self.meta = meta
         self.var = var
         self.ns_map = ns_map
@@ -30,7 +30,7 @@ class PrimitiveNode(XmlNode):
         qname: str,
         text: Optional[str],
         tail: Optional[str],
-        objects: List,
+        objects: list,
     ) -> bool:
         """Bind the parsed data into an object for the ending element.
 
@@ -67,6 +67,6 @@ class PrimitiveNode(XmlNode):
 
         return True
 
-    def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
+    def child(self, qname: str, attrs: dict, ns_map: dict, position: int) -> XmlNode:
         """Raise an exception if there is a child element inside this node."""
         raise XmlContextError("Primitive node doesn't support child nodes!")
diff --git a/xsdata/formats/dataclass/parsers/nodes/skip.py b/xsdata/formats/dataclass/parsers/nodes/skip.py
index 2044c253..60753d65 100644
--- a/xsdata/formats/dataclass/parsers/nodes/skip.py
+++ b/xsdata/formats/dataclass/parsers/nodes/skip.py
@@ -1,4 +1,4 @@
-from typing import Dict, List, Optional
+from typing import Optional
 
 from xsdata.formats.dataclass.parsers.mixins import XmlNode
 
@@ -11,12 +11,12 @@ class SkipNode(XmlNode):
     def __init__(self):
         self.ns_map = {}
 
-    def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
+    def child(self, qname: str, attrs: dict, ns_map: dict, position: int) -> XmlNode:
         """Skip nodes children are skipped as well."""
         return self
 
     def bind(
-        self, qname: str, text: Optional[str], tail: Optional[str], objects: List
+        self, qname: str, text: Optional[str], tail: Optional[str], objects: list
     ) -> bool:
         """Skip nodes are not building any objects."""
         return False
diff --git a/xsdata/formats/dataclass/parsers/nodes/standard.py b/xsdata/formats/dataclass/parsers/nodes/standard.py
index d919e0e5..f765a8ca 100644
--- a/xsdata/formats/dataclass/parsers/nodes/standard.py
+++ b/xsdata/formats/dataclass/parsers/nodes/standard.py
@@ -1,4 +1,4 @@
-from typing import Dict, List, Optional, Type
+from typing import Optional
 
 from xsdata.exceptions import XmlContextError
 from xsdata.formats.dataclass.models.elements import XmlMeta, XmlVar
@@ -36,10 +36,10 @@ class StandardNode(XmlNode):
         meta: XmlMeta,
         var: XmlVar,
         datatype: DataType,
-        ns_map: Dict,
+        ns_map: dict,
         config: ParserConfig,
         nillable: bool,
-        derived_factory: Optional[Type],
+        derived_factory: Optional[type],
     ):
         self.meta = meta
         self.var = var
@@ -54,7 +54,7 @@ class StandardNode(XmlNode):
         qname: str,
         text: Optional[str],
         tail: Optional[str],
-        objects: List,
+        objects: list,
     ) -> bool:
         """Bind the parsed data into an object for the ending element.
 
@@ -93,6 +93,6 @@ class StandardNode(XmlNode):
         objects.append((qname, obj))
         return True
 
-    def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
+    def child(self, qname: str, attrs: dict, ns_map: dict, position: int) -> XmlNode:
         """Raise an exception if there is a child element inside this node."""
         raise XmlContextError("StandardNode node doesn't support child nodes!")
diff --git a/xsdata/formats/dataclass/parsers/nodes/union.py b/xsdata/formats/dataclass/parsers/nodes/union.py
index b1e9b507..ca56a82a 100644
--- a/xsdata/formats/dataclass/parsers/nodes/union.py
+++ b/xsdata/formats/dataclass/parsers/nodes/union.py
@@ -2,7 +2,7 @@ import copy
 import functools
 from contextlib import suppress
 from dataclasses import replace
-from typing import Any, Dict, List, Optional, Tuple, Type
+from typing import Any, Optional
 
 from xsdata.exceptions import ParserError
 from xsdata.formats.dataclass.context import XmlContext
@@ -48,8 +48,8 @@ class UnionNode(XmlNode):
         self,
         meta: XmlMeta,
         var: XmlVar,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
         position: int,
         config: ParserConfig,
         context: XmlContext,
@@ -63,9 +63,9 @@ class UnionNode(XmlNode):
         self.context = context
         self.level = 0
         self.candidates = self.filter_candidates()
-        self.events: List[Tuple[str, str, Any, Any]] = []
+        self.events: list[tuple[str, str, Any, Any]] = []
 
-    def filter_candidates(self) -> List[Type]:
+    def filter_candidates(self) -> list[type]:
         """Filter union candidates by fixed attributes."""
         candidates = list(self.var.types)
         fixed_attribute = functools.partial(
@@ -74,7 +74,7 @@ class UnionNode(XmlNode):
 
         return list(filter(fixed_attribute, candidates))
 
-    def filter_fixed_attrs(self, candidate: Type, parent_ns: Optional[str]) -> bool:
+    def filter_fixed_attrs(self, candidate: type, parent_ns: Optional[str]) -> bool:
         """Return whether the node attrs are incompatible with fixed attrs.
 
         Args:
@@ -97,7 +97,7 @@ class UnionNode(XmlNode):
 
         return True
 
-    def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
+    def child(self, qname: str, attrs: dict, ns_map: dict, position: int) -> XmlNode:
         """Record the event for the child element.
 
         This entry point records all events, as it's not possible
@@ -120,7 +120,7 @@ class UnionNode(XmlNode):
         qname: str,
         text: Optional[str],
         tail: Optional[str],
-        objects: List,
+        objects: list,
     ) -> bool:
         """Bind the parsed data into an object for the ending element.
 
diff --git a/xsdata/formats/dataclass/parsers/nodes/wildcard.py b/xsdata/formats/dataclass/parsers/nodes/wildcard.py
index 34ca6902..ca8e898c 100644
--- a/xsdata/formats/dataclass/parsers/nodes/wildcard.py
+++ b/xsdata/formats/dataclass/parsers/nodes/wildcard.py
@@ -1,4 +1,4 @@
-from typing import Dict, List, Optional, Type
+from typing import Optional
 
 from xsdata.formats.dataclass.models.elements import XmlVar
 from xsdata.formats.dataclass.parsers.mixins import XmlNode
@@ -26,10 +26,10 @@ class WildcardNode(XmlNode):
     def __init__(
         self,
         var: XmlVar,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
         position: int,
-        factory: Type,
+        factory: type,
     ):
         self.var = var
         self.attrs = attrs
@@ -38,7 +38,7 @@ class WildcardNode(XmlNode):
         self.factory = factory
 
     def bind(
-        self, qname: str, text: Optional[str], tail: Optional[str], objects: List
+        self, qname: str, text: Optional[str], tail: Optional[str], objects: list
     ) -> bool:
         """Bind the parsed data into a generic element.
 
@@ -78,7 +78,7 @@ class WildcardNode(XmlNode):
         return True
 
     @classmethod
-    def fetch_any_children(cls, position: int, objects: List) -> List:
+    def fetch_any_children(cls, position: int, objects: list) -> list:
         """Fetch the children of this node in the objects list.
 
         The children are removed from the objects list.
@@ -96,7 +96,7 @@ class WildcardNode(XmlNode):
 
         return children
 
-    def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
+    def child(self, qname: str, attrs: dict, ns_map: dict, position: int) -> XmlNode:
         """Initialize the next child wildcard node to be queued, when an element starts.
 
         This entry point is responsible to create the next node type
diff --git a/xsdata/formats/dataclass/parsers/nodes/wrapper.py b/xsdata/formats/dataclass/parsers/nodes/wrapper.py
index ec65942d..de6bc998 100644
--- a/xsdata/formats/dataclass/parsers/nodes/wrapper.py
+++ b/xsdata/formats/dataclass/parsers/nodes/wrapper.py
@@ -1,4 +1,4 @@
-from typing import Dict, List, Optional
+from typing import Optional
 
 from xsdata.formats.dataclass.parsers.mixins import XmlNode
 from xsdata.formats.dataclass.parsers.nodes.element import ElementNode
@@ -26,7 +26,7 @@ class WrapperNode(XmlNode):
         self.ns_map = parent.ns_map
 
     def bind(
-        self, qname: str, text: Optional[str], tail: Optional[str], objects: List
+        self, qname: str, text: Optional[str], tail: Optional[str], objects: list
     ) -> bool:
         """This node will never appear in the xml, so it never binds any data.
 
@@ -41,7 +41,7 @@ class WrapperNode(XmlNode):
         """
         return False
 
-    def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
+    def child(self, qname: str, attrs: dict, ns_map: dict, position: int) -> XmlNode:
         """Proxy the next child node to the parent node.
 
         Args:
diff --git a/xsdata/formats/dataclass/parsers/tree.py b/xsdata/formats/dataclass/parsers/tree.py
index 72132f01..7d9c35e0 100644
--- a/xsdata/formats/dataclass/parsers/tree.py
+++ b/xsdata/formats/dataclass/parsers/tree.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import Dict, List, Optional, Type
+from typing import Optional
 
 from xsdata.formats.dataclass.models.elements import XmlType, XmlVar
 from xsdata.formats.dataclass.parsers.bases import NodeParser, Parsed
@@ -13,16 +13,16 @@ from xsdata.utils import namespaces
 class TreeParser(NodeParser):
     """Bind xml nodes to a tree of AnyElement objects."""
 
-    handler: Type[XmlHandler] = field(default=default_handler())
+    handler: type[XmlHandler] = field(default=default_handler())
 
     def start(
         self,
-        clazz: Optional[Type],
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        clazz: Optional[type],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
     ):
         """Build and queue the XmlNode for the starting element.
 
diff --git a/xsdata/formats/dataclass/parsers/utils.py b/xsdata/formats/dataclass/parsers/utils.py
index 1c3b1ba4..9e5093e9 100644
--- a/xsdata/formats/dataclass/parsers/utils.py
+++ b/xsdata/formats/dataclass/parsers/utils.py
@@ -1,7 +1,8 @@
 import math
 import warnings
 from collections import UserList
-from typing import Any, Callable, Dict, Iterable, Optional, Sequence, Type
+from collections.abc import Iterable, Sequence
+from typing import Any, Callable, Optional
 
 from xsdata.exceptions import ConverterError, ConverterWarning, ParserError
 from xsdata.formats.converter import QNameConverter, converter
@@ -49,7 +50,7 @@ class ParserUtils:
     """Random parser util functions."""
 
     @classmethod
-    def xsi_type(cls, attrs: Dict, ns_map: Dict) -> Optional[str]:
+    def xsi_type(cls, attrs: dict, ns_map: dict) -> Optional[str]:
         """Parse the xsi:type attribute value if present.
 
         Args:
@@ -67,7 +68,7 @@ class ParserUtils:
         return build_qname(namespace, name)
 
     @classmethod
-    def xsi_nil(cls, attrs: Dict) -> Optional[bool]:
+    def xsi_nil(cls, attrs: dict) -> Optional[bool]:
         """Return whether xsi:nil attribute value.
 
         Args:
@@ -86,9 +87,9 @@ class ParserUtils:
         var: XmlVar,
         config: ParserConfig,
         value: Any,
-        ns_map: Optional[Dict] = None,
+        ns_map: Optional[dict] = None,
         default: Any = None,
-        types: Optional[Sequence[Type]] = None,
+        types: Optional[Sequence[type]] = None,
         tokens_factory: Optional[Callable] = None,
         format: Optional[str] = None,
     ) -> Any:
@@ -130,9 +131,9 @@ class ParserUtils:
     def parse_value(
         cls,
         value: Any,
-        types: Sequence[Type],
+        types: Sequence[type],
         default: Optional[Any] = None,
-        ns_map: Optional[Dict] = None,
+        ns_map: Optional[dict] = None,
         tokens_factory: Optional[Callable] = None,
         format: Optional[str] = None,
     ) -> Any:
@@ -185,8 +186,8 @@ class ParserUtils:
 
     @classmethod
     def parse_any_attributes(
-        cls, attrs: Dict[str, str], ns_map: Dict[Optional[str], str]
-    ) -> Dict[str, str]:
+        cls, attrs: dict[str, str], ns_map: dict[Optional[str], str]
+    ) -> dict[str, str]:
         """Parse attributes with qname support.
 
         Example:
@@ -205,7 +206,7 @@ class ParserUtils:
         }
 
     @classmethod
-    def parse_any_attribute(cls, value: str, ns_map: Dict) -> str:
+    def parse_any_attribute(cls, value: str, ns_map: dict) -> str:
         """Expand the value with the full namespace if it has a prefix.
 
         Args:
diff --git a/xsdata/formats/dataclass/parsers/xml.py b/xsdata/formats/dataclass/parsers/xml.py
index 1a77fa42..da37a08f 100644
--- a/xsdata/formats/dataclass/parsers/xml.py
+++ b/xsdata/formats/dataclass/parsers/xml.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import Any, Dict, List, Optional, Type
+from typing import Any, Optional
 
 from xsdata.formats.dataclass.parsers.bases import NodeParser, Parsed
 from xsdata.formats.dataclass.parsers.handlers import default_handler
@@ -22,7 +22,7 @@ class XmlParser(NodeParser):
         ns_map: The parsed namespace prefix-URI map
     """
 
-    handler: Type[XmlHandler] = field(default=default_handler())
+    handler: type[XmlHandler] = field(default=default_handler())
 
 
 @dataclass
@@ -44,17 +44,17 @@ class UserXmlParser(NodeParser):
             on duplicate events.
     """
 
-    handler: Type[XmlHandler] = field(default=default_handler())
-    hooks_cache: Dict = field(init=False, default_factory=dict)
+    handler: type[XmlHandler] = field(default=default_handler())
+    hooks_cache: dict = field(init=False, default_factory=dict)
 
     def start(
         self,
-        clazz: Optional[Type],
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        clazz: Optional[type],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
-        attrs: Dict,
-        ns_map: Dict,
+        attrs: dict,
+        ns_map: dict,
     ):
         """Build and queue the XmlNode for the starting element.
 
@@ -73,8 +73,8 @@ class UserXmlParser(NodeParser):
 
     def end(
         self,
-        queue: List[XmlNode],
-        objects: List[Parsed],
+        queue: list[XmlNode],
+        objects: list[Parsed],
         qname: str,
         text: Optional[str],
         tail: Optional[str],
diff --git a/xsdata/formats/dataclass/serializers/code.py b/xsdata/formats/dataclass/serializers/code.py
index d9183d06..44ecb91b 100644
--- a/xsdata/formats/dataclass/serializers/code.py
+++ b/xsdata/formats/dataclass/serializers/code.py
@@ -1,7 +1,8 @@
+from collections.abc import Iterator, Mapping
 from dataclasses import dataclass, field
 from enum import Enum
 from io import StringIO
-from typing import Any, Iterator, List, Mapping, Set, TextIO, Tuple, Type, Union
+from typing import Any, TextIO, Union
 
 from xsdata.formats.dataclass.context import XmlContext
 from xsdata.utils import collections
@@ -47,7 +48,7 @@ class PycodeSerializer:
             obj: The input model instance to serialize
             var_name: The var name to assign the model instance
         """
-        types: Set[Type] = set()
+        types: set[type] = set()
 
         tmp = StringIO()
         for chunk in self.repr_object(obj, 0, types):
@@ -61,7 +62,7 @@ class PycodeSerializer:
         out.write("\n")
 
     @classmethod
-    def build_imports(cls, types: Set[Type]) -> str:
+    def build_imports(cls, types: set[type]) -> str:
         """Build a list of imports from the given types.
 
         Args:
@@ -82,7 +83,7 @@ class PycodeSerializer:
 
         return "".join(sorted(imports))
 
-    def repr_object(self, obj: Any, level: int, types: Set[Type]) -> Iterator[str]:
+    def repr_object(self, obj: Any, level: int, types: set[type]) -> Iterator[str]:
         """Write the given object as repr code.
 
         Args:
@@ -107,9 +108,9 @@ class PycodeSerializer:
 
     def repr_array(
         self,
-        obj: Union[List, Set, Tuple],
+        obj: Union[list, set, tuple],
         level: int,
-        types: Set[Type],
+        types: set[type],
     ) -> Iterator[str]:
         """Convert an iterable object to repr code.
 
@@ -134,7 +135,7 @@ class PycodeSerializer:
 
         yield f"{spaces * level}]"
 
-    def repr_mapping(self, obj: Mapping, level: int, types: Set[Type]) -> Iterator[str]:
+    def repr_mapping(self, obj: Mapping, level: int, types: set[type]) -> Iterator[str]:
         """Convert a map object to repr code.
 
         Args:
@@ -160,7 +161,7 @@ class PycodeSerializer:
 
         yield f"{spaces * level}}}"
 
-    def repr_model(self, obj: Any, level: int, types: Set[Type]) -> Iterator[str]:
+    def repr_model(self, obj: Any, level: int, types: set[type]) -> Iterator[str]:
         """Convert a data model instance to repr code.
 
         Args:
diff --git a/xsdata/formats/dataclass/serializers/config.py b/xsdata/formats/dataclass/serializers/config.py
index b3ae555d..28a01128 100644
--- a/xsdata/formats/dataclass/serializers/config.py
+++ b/xsdata/formats/dataclass/serializers/config.py
@@ -1,6 +1,6 @@
 import warnings
 from dataclasses import InitVar, dataclass
-from typing import Any, Callable, Dict, Optional
+from typing import Any, Callable, Optional
 
 
 @dataclass
@@ -28,7 +28,7 @@ class SerializerConfig:
     ignore_default_attributes: bool = False
     schema_location: Optional[str] = None
     no_namespace_schema_location: Optional[str] = None
-    globalns: Optional[Dict[str, Callable]] = None
+    globalns: Optional[dict[str, Callable]] = None
 
     # Deprecated
     pretty_print: InitVar[bool] = False
diff --git a/xsdata/formats/dataclass/serializers/dict.py b/xsdata/formats/dataclass/serializers/dict.py
index 0996cde2..8afe9e94 100644
--- a/xsdata/formats/dataclass/serializers/dict.py
+++ b/xsdata/formats/dataclass/serializers/dict.py
@@ -1,6 +1,7 @@
+from collections.abc import Iterator
 from dataclasses import dataclass, field
 from enum import Enum
-from typing import Any, Callable, Dict, Iterator, Optional, Tuple
+from typing import Any, Callable, Optional
 
 from xsdata.formats.converter import converter
 from xsdata.formats.dataclass.context import XmlContext
@@ -9,7 +10,7 @@ from xsdata.formats.dataclass.serializers.config import SerializerConfig
 from xsdata.utils import collections
 
 
-def filter_none(x: Tuple) -> Dict:
+def filter_none(x: tuple) -> dict:
     """Convert a key-value pairs to dict, ignoring None values.
 
     Args:
@@ -80,7 +81,7 @@ class DictEncoder:
 
         return converter.serialize(value, format=var.format)
 
-    def next_value(self, obj: Any) -> Iterator[Tuple[str, Any]]:
+    def next_value(self, obj: Any) -> Iterator[tuple[str, Any]]:
         """Fetch the next value of a model instance to convert.
 
         Args:
diff --git a/xsdata/formats/dataclass/serializers/mixins.py b/xsdata/formats/dataclass/serializers/mixins.py
index 3e7c31fc..33531616 100644
--- a/xsdata/formats/dataclass/serializers/mixins.py
+++ b/xsdata/formats/dataclass/serializers/mixins.py
@@ -1,18 +1,14 @@
 import abc
 from abc import ABC
+from collections.abc import Iterable, Iterator
 from dataclasses import dataclass, field
 from enum import Enum
 from typing import (
     Any,
-    Dict,
     Final,
-    Iterable,
-    Iterator,
-    List,
     Literal,
     Optional,
     TextIO,
-    Tuple,
     Union,
 )
 from xml.etree.ElementTree import QName
@@ -42,10 +38,10 @@ class XmlWriterEvent:
     END: Final = "end"
 
 
-StartEvent: TypeAlias = Tuple[Literal["start"], str]
-AttrEvent: TypeAlias = Tuple[Literal["attr"], str, Any]
-DataEvent: TypeAlias = Tuple[Literal["data"], str]
-EndEvent: TypeAlias = Tuple[Literal["end"], str]
+StartEvent: TypeAlias = tuple[Literal["start"], str]
+AttrEvent: TypeAlias = tuple[Literal["attr"], str, Any]
+DataEvent: TypeAlias = tuple[Literal["data"], str]
+EndEvent: TypeAlias = tuple[Literal["end"], str]
 
 EventIterator = Iterator[Union[StartEvent, AttrEvent, DataEvent, EndEvent]]
 
@@ -78,16 +74,16 @@ class EventHandler(abc.ABC):
         "pending_prefixes",
     )
 
-    def __init__(self, config: SerializerConfig, ns_map: Dict):
+    def __init__(self, config: SerializerConfig, ns_map: dict):
         self.config = config
         self.ns_map = ns_map
 
         self.in_tail = False
         self.tail: Optional[str] = None
-        self.attrs: Dict = {}
-        self.ns_context: List[Dict] = []
-        self.pending_tag: Optional[Tuple] = None
-        self.pending_prefixes: List[List] = []
+        self.attrs: dict = {}
+        self.ns_context: list[dict] = []
+        self.pending_tag: Optional[tuple] = None
+        self.pending_prefixes: list[list] = []
 
     def write(self, events: EventIterator):
         """Feed the sax content handler with events.
@@ -268,7 +264,7 @@ class EventHandler(abc.ABC):
         Save the list of prefixes to be removed at the end of the
         current pending tag.
         """
-        prefixes: List[str] = []
+        prefixes: list[str] = []
         self.pending_prefixes.append(prefixes)
 
         try:
@@ -328,7 +324,7 @@ class EventHandler(abc.ABC):
         """End document notification receiver."""
 
     @abc.abstractmethod
-    def start_element(self, name: Tuple[str, str], qname: str, attrs: Dict):
+    def start_element(self, name: tuple[str, str], qname: str, attrs: dict):
         """Start element notification receiver.
 
         Args:
@@ -338,7 +334,7 @@ class EventHandler(abc.ABC):
         """
 
     @abc.abstractmethod
-    def end_element(self, name: Tuple[str, str], qname: str):
+    def end_element(self, name: tuple[str, str], qname: str):
         """End element notification receiver.
 
         Args:
@@ -389,7 +385,7 @@ class EventContentHandler(EventHandler):
         pending_prefixes: The pending element namespace prefixes
     """
 
-    def __init__(self, config: SerializerConfig, ns_map: Dict):
+    def __init__(self, config: SerializerConfig, ns_map: dict):
         super().__init__(config, ns_map)
         self.handler = self.build_handler()
 
@@ -413,7 +409,7 @@ class EventContentHandler(EventHandler):
         """End document entrypoint."""
         self.handler.endDocument()
 
-    def end_element(self, name: Tuple[str, str], qname: str):
+    def end_element(self, name: tuple[str, str], qname: str):
         """End element notification receiver.
 
         Args:
@@ -438,7 +434,7 @@ class EventContentHandler(EventHandler):
         """
         self.handler.endPrefixMapping(prefix)
 
-    def start_element(self, name: Tuple[str, str], qname: str, attrs: Dict):
+    def start_element(self, name: tuple[str, str], qname: str, attrs: dict):
         """Start element notification receiver.
 
         Args:
@@ -476,7 +472,7 @@ class XmlWriter(EventContentHandler, ABC):
         pending_prefixes: The pending element namespace prefixes
     """
 
-    def __init__(self, config: SerializerConfig, output: TextIO, ns_map: Dict):
+    def __init__(self, config: SerializerConfig, output: TextIO, ns_map: dict):
         self.output = output
         super().__init__(config, ns_map)
 
@@ -674,7 +670,7 @@ class EventGenerator:
 
     def convert_mixed_content(
         self,
-        values: List,
+        values: list,
         var: XmlVar,
         namespace: Optional[str],
     ) -> EventIterator:
@@ -909,7 +905,7 @@ class EventGenerator:
         yield XmlWriterEvent.DATA, cls.encode_primitive(value, var)
 
     @classmethod
-    def next_value(cls, obj: Any, meta: XmlMeta) -> Iterator[Tuple[XmlVar, Any]]:
+    def next_value(cls, obj: Any, meta: XmlMeta) -> Iterator[tuple[XmlVar, Any]]:
         """Produce the next non attribute value of a model instance to convert.
 
         The generator will produce the values in the order the fields
@@ -972,7 +968,7 @@ class EventGenerator:
         nillable: bool,
         xsi_type: Optional[str],
         ignore_optionals: bool,
-    ) -> Iterator[Tuple[str, Any]]:
+    ) -> Iterator[tuple[str, Any]]:
         """Produce the next attribute value to convert.
 
         Args:
diff --git a/xsdata/formats/dataclass/serializers/tree.py b/xsdata/formats/dataclass/serializers/tree.py
index 61d99353..975f5b27 100644
--- a/xsdata/formats/dataclass/serializers/tree.py
+++ b/xsdata/formats/dataclass/serializers/tree.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass
-from typing import Any, Dict, Optional
+from typing import Any, Optional
 
 from lxml.etree import ElementTree
 
@@ -17,7 +17,7 @@ class TreeSerializer(EventGenerator):
         context: The models context instance
     """
 
-    def render(self, obj: Any, ns_map: Optional[Dict] = None) -> ElementTree:
+    def render(self, obj: Any, ns_map: Optional[dict] = None) -> ElementTree:
         """Serialize the input model instance to a lxml etree instance.
 
         Args:
diff --git a/xsdata/formats/dataclass/serializers/writers/__init__.py b/xsdata/formats/dataclass/serializers/writers/__init__.py
index b8e3320f..4bcf6360 100644
--- a/xsdata/formats/dataclass/serializers/writers/__init__.py
+++ b/xsdata/formats/dataclass/serializers/writers/__init__.py
@@ -1,5 +1,3 @@
-from typing import Type
-
 from xsdata.formats.dataclass.serializers.mixins import XmlWriter
 from xsdata.formats.dataclass.serializers.writers.native import (
     XmlEventWriter,
@@ -8,7 +6,7 @@ from xsdata.formats.dataclass.serializers.writers.native import (
 try:
     from xsdata.formats.dataclass.serializers.writers.lxml import LxmlEventWriter
 
-    DEFAULT_XML_WRITER: Type[XmlWriter] = LxmlEventWriter
+    DEFAULT_XML_WRITER: type[XmlWriter] = LxmlEventWriter
 except ImportError:  # pragma: no cover
     DEFAULT_XML_WRITER = XmlEventWriter
 
diff --git a/xsdata/formats/dataclass/serializers/writers/lxml.py b/xsdata/formats/dataclass/serializers/writers/lxml.py
index a3bb8f98..e327cf5b 100644
--- a/xsdata/formats/dataclass/serializers/writers/lxml.py
+++ b/xsdata/formats/dataclass/serializers/writers/lxml.py
@@ -1,4 +1,4 @@
-from typing import Iterator
+from collections.abc import Iterator
 
 from lxml import etree
 from lxml.sax import ElementTreeContentHandler
diff --git a/xsdata/formats/dataclass/serializers/writers/native.py b/xsdata/formats/dataclass/serializers/writers/native.py
index be528d31..c4b1388f 100644
--- a/xsdata/formats/dataclass/serializers/writers/native.py
+++ b/xsdata/formats/dataclass/serializers/writers/native.py
@@ -1,4 +1,4 @@
-from typing import Dict, TextIO
+from typing import TextIO
 from xml.sax.saxutils import XMLGenerator
 
 from xsdata.formats.dataclass.serializers.config import SerializerConfig
@@ -28,7 +28,7 @@ class XmlEventWriter(XmlWriter):
 
     __slots__ = ("current_level", "pending_end_element")
 
-    def __init__(self, config: SerializerConfig, output: TextIO, ns_map: Dict):
+    def __init__(self, config: SerializerConfig, output: TextIO, ns_map: dict):
         super().__init__(config, output, ns_map)
 
         self.current_level = 0
diff --git a/xsdata/formats/dataclass/serializers/xml.py b/xsdata/formats/dataclass/serializers/xml.py
index e3086870..b2ae1141 100644
--- a/xsdata/formats/dataclass/serializers/xml.py
+++ b/xsdata/formats/dataclass/serializers/xml.py
@@ -2,10 +2,8 @@ from dataclasses import dataclass, field
 from io import StringIO
 from typing import (
     Any,
-    Dict,
     Optional,
     TextIO,
-    Type,
 )
 
 from xsdata.formats.dataclass.serializers.mixins import (
@@ -26,9 +24,9 @@ class XmlSerializer(EventGenerator):
         writer: The xml writer class
     """
 
-    writer: Type[XmlWriter] = field(default=DEFAULT_XML_WRITER)
+    writer: type[XmlWriter] = field(default=DEFAULT_XML_WRITER)
 
-    def render(self, obj: Any, ns_map: Optional[Dict] = None) -> str:
+    def render(self, obj: Any, ns_map: Optional[dict] = None) -> str:
         """Serialize the input model instance to xml string.
 
         Args:
@@ -42,7 +40,7 @@ class XmlSerializer(EventGenerator):
         self.write(output, obj, ns_map)
         return output.getvalue()
 
-    def write(self, out: TextIO, obj: Any, ns_map: Optional[Dict] = None):
+    def write(self, out: TextIO, obj: Any, ns_map: Optional[dict] = None):
         """Serialize the given object to the output text stream.
 
         Args:
diff --git a/xsdata/formats/dataclass/transports.py b/xsdata/formats/dataclass/transports.py
index 20adff16..78f7db69 100644
--- a/xsdata/formats/dataclass/transports.py
+++ b/xsdata/formats/dataclass/transports.py
@@ -1,5 +1,5 @@
 import abc
-from typing import Any, Dict, Optional
+from typing import Any, Optional
 
 from requests import Response, Session
 
@@ -10,11 +10,11 @@ class Transport(abc.ABC):
     __slots__ = ()
 
     @abc.abstractmethod
-    def get(self, url: str, params: Dict, headers: Dict) -> bytes:
+    def get(self, url: str, params: dict, headers: dict) -> bytes:
         """Send a GET request."""
 
     @abc.abstractmethod
-    def post(self, url: str, data: Any, headers: Dict) -> bytes:
+    def post(self, url: str, data: Any, headers: dict) -> bytes:
         """Send a POST request."""
 
 
@@ -31,7 +31,7 @@ class DefaultTransport(Transport):
         self.timeout = timeout
         self.session = session or Session()
 
-    def get(self, url: str, params: Dict, headers: Dict) -> bytes:
+    def get(self, url: str, params: dict, headers: dict) -> bytes:
         """Send a GET request.
 
         Args:
@@ -53,7 +53,7 @@ class DefaultTransport(Transport):
         )
         return self.handle_response(res)
 
-    def post(self, url: str, data: Any, headers: Dict) -> Any:
+    def post(self, url: str, data: Any, headers: dict) -> Any:
         """Send a POST request.
 
         Args:
diff --git a/xsdata/formats/dataclass/typing.py b/xsdata/formats/dataclass/typing.py
index b190c0bc..c8fa645e 100644
--- a/xsdata/formats/dataclass/typing.py
+++ b/xsdata/formats/dataclass/typing.py
@@ -5,8 +5,6 @@ from typing import (
     Callable,
     NamedTuple,
     Optional,
-    Tuple,
-    Type,
     TypeVar,
     Union,
 )
@@ -66,12 +64,12 @@ def evaluate(tp: Any, globalns: Any, localns: Any = None) -> Any:
 
 
 class Result(NamedTuple):
-    types: Tuple[Type[Any], ...]
+    types: tuple[type[Any], ...]
     factory: Optional[Callable] = None
     tokens_factory: Optional[Callable] = None
 
 
-def analyze_token_args(origin: Any, args: Tuple[Any, ...]) -> Tuple[Any]:
+def analyze_token_args(origin: Any, args: tuple[Any, ...]) -> tuple[Any]:
     """Analyze token arguments.
 
     Ensure it only has one argument, filter out ellipsis.
@@ -97,8 +95,8 @@ def analyze_token_args(origin: Any, args: Tuple[Any, ...]) -> Tuple[Any]:
 
 
 def analyze_optional_origin(
-    origin: Any, args: Tuple[Any, ...], types: Tuple[Any, ...]
-) -> Tuple[Any, ...]:
+    origin: Any, args: tuple[Any, ...], types: tuple[Any, ...]
+) -> tuple[Any, ...]:
     """Analyze optional type annotations.
 
     Remove the NoneType, adjust and return the origin, args and types.
@@ -119,11 +117,11 @@ def analyze_optional_origin(
     return origin, args, types
 
 
-def filter_none_type(args: Tuple[Any, ...]) -> Tuple[Any, ...]:
+def filter_none_type(args: tuple[Any, ...]) -> tuple[Any, ...]:
     return tuple(arg for arg in args if arg is not NONE_TYPE)
 
 
-def filter_ellipsis(args: Tuple[Any, ...]) -> Tuple[Any]:
+def filter_ellipsis(args: tuple[Any, ...]) -> tuple[Any]:
     return tuple(arg for arg in args if arg is not Ellipsis)
 
 
diff --git a/xsdata/formats/mixins.py b/xsdata/formats/mixins.py
index dc978ca2..32f66bc7 100644
--- a/xsdata/formats/mixins.py
+++ b/xsdata/formats/mixins.py
@@ -1,7 +1,8 @@
 import abc
 import datetime
+from collections.abc import Iterator
 from pathlib import Path
-from typing import Dict, Iterator, List, NamedTuple
+from typing import NamedTuple
 
 from xsdata import __version__
 from xsdata.codegen.exceptions import CodegenError
@@ -46,16 +47,16 @@ class AbstractGenerator(abc.ABC):
         return package
 
     @abc.abstractmethod
-    def render(self, classes: List[Class]) -> Iterator[GeneratorResult]:
+    def render(self, classes: list[Class]) -> Iterator[GeneratorResult]:
         """Return an iterator of the generated results."""
 
     @classmethod
-    def group_by_package(cls, classes: List[Class]) -> Dict[Path, List[Class]]:
+    def group_by_package(cls, classes: list[Class]) -> dict[Path, list[Class]]:
         """Group the given list of classes by the target package directory."""
         return group_by(classes, lambda x: package_path(x.target_module))
 
     @classmethod
-    def group_by_module(cls, classes: List[Class]) -> Dict[Path, List[Class]]:
+    def group_by_module(cls, classes: list[Class]) -> dict[Path, list[Class]]:
         """Group the given list of classes by the target module directory."""
         return group_by(classes, lambda x: module_path(x.target_module))
 
@@ -72,7 +73,7 @@ class AbstractGenerator(abc.ABC):
             '"""\n'
         )
 
-    def normalize_packages(self, classes: List[Class]):
+    def normalize_packages(self, classes: list[Class]):
         """Normalize the classes module and package names.
 
         Args:
diff --git a/xsdata/models/config.py b/xsdata/models/config.py
index 7b11b9a0..acd2d63f 100644
--- a/xsdata/models/config.py
+++ b/xsdata/models/config.py
@@ -4,7 +4,8 @@ import warnings
 from dataclasses import dataclass, field
 from enum import Enum
 from pathlib import Path
-from typing import Any, Callable, Dict, List, Pattern, TextIO
+from re import Pattern
+from typing import Any, Callable, TextIO
 
 from xsdata import __version__
 from xsdata.codegen.exceptions import CodegenError, CodegenWarning
@@ -75,7 +76,7 @@ class NameCase(Enum):
         return __name_case_func__[self.value]
 
 
-__name_case_func__: Dict[str, Callable] = {
+__name_case_func__: dict[str, Callable] = {
     "originalCase": text.original_case,
     "pascalCase": text.pascal_case,
     "camelCase": text.camel_case,
@@ -223,8 +224,6 @@ class GeneratorOutput:
         compound_fields: Use compound fields for repeatable elements
         wrapper_fields: Generate wrapper fields
         max_line_length: Adjust the maximum line length
-        subscriptable_types: Use PEP-585 generics for standard
-            collections, python>=3.9 Only
         generic_collections: Use generic collections (Iterable, Mapping)
         union_type: Use PEP-604 union type, python>=3.10 Only
         postponed_annotations: Use 563 postponed evaluation of  annotations
@@ -243,7 +242,6 @@ class GeneratorOutput:
     compound_fields: CompoundFields = element(default_factory=CompoundFields)
     wrapper_fields: bool = element(default=False)
     max_line_length: int = attribute(default=79)
-    subscriptable_types: bool = attribute(default=False)
     generic_collections: bool = attribute(default=False)
     union_type: bool = attribute(default=False)
     postponed_annotations: bool = element(default=False)
@@ -363,10 +361,10 @@ class GeneratorAliases:
         module_name: A list of module name aliases
     """
 
-    class_name: List[GeneratorAlias] = array_element()
-    field_name: List[GeneratorAlias] = array_element()
-    package_name: List[GeneratorAlias] = array_element()
-    module_name: List[GeneratorAlias] = array_element()
+    class_name: list[GeneratorAlias] = array_element()
+    field_name: list[GeneratorAlias] = array_element()
+    package_name: list[GeneratorAlias] = array_element()
+    module_name: list[GeneratorAlias] = array_element()
 
 
 @dataclass
@@ -460,7 +458,7 @@ class GeneratorSubstitutions:
         substitution: The list of substitution instances
     """
 
-    substitution: List[GeneratorSubstitution] = array_element()
+    substitution: list[GeneratorSubstitution] = array_element()
 
 
 @dataclass
@@ -475,7 +473,7 @@ class GeneratorExtensions:
         extension: The list of extension instances
     """
 
-    extension: List[GeneratorExtension] = array_element()
+    extension: list[GeneratorExtension] = array_element()
 
 
 @dataclass
diff --git a/xsdata/models/datatype.py b/xsdata/models/datatype.py
index 703b65f5..03324069 100644
--- a/xsdata/models/datatype.py
+++ b/xsdata/models/datatype.py
@@ -2,7 +2,7 @@ import datetime
 import operator
 import re
 from collections import UserString
-from typing import Any, Callable, Dict, NamedTuple, Optional, Union
+from typing import Any, Callable, NamedTuple, Optional, Union
 
 from xsdata.utils.dates import (
     calculate_offset,
@@ -571,7 +571,7 @@ class XmlDuration(UserString):
             seconds=float(seconds) if seconds else None,
         )
 
-    def asdict(self) -> Dict:
+    def asdict(self) -> dict:
         """Return instance as a dict."""
         return self._interval._asdict()
 
@@ -658,7 +658,7 @@ class XmlPeriod(UserString):
 
         return TimePeriod(year=year, month=month, day=day, offset=offset)
 
-    def as_dict(self) -> Dict:
+    def as_dict(self) -> dict:
         """Return date units as dict."""
         return self._period._asdict()
 
diff --git a/xsdata/models/dtd.py b/xsdata/models/dtd.py
index 9e96e3ed..a15ee102 100644
--- a/xsdata/models/dtd.py
+++ b/xsdata/models/dtd.py
@@ -1,6 +1,6 @@
 import enum
 from dataclasses import dataclass
-from typing import Dict, List, Optional
+from typing import Optional
 
 from xsdata.models.enums import DataType
 from xsdata.utils.namespaces import build_qname
@@ -76,7 +76,7 @@ class DtdAttribute:
     type: DtdAttributeType
     default: DtdAttributeDefault
     default_value: Optional[str]
-    values: List[str]
+    values: list[str]
 
     @property
     def data_type(self) -> DataType:
@@ -120,8 +120,8 @@ class DtdElement:
     type: DtdElementType
     prefix: Optional[str]
     content: Optional[DtdContent]
-    attributes: List[DtdAttribute]
-    ns_map: Dict
+    attributes: list[DtdAttribute]
+    ns_map: dict
 
     @property
     def qname(self) -> str:
@@ -140,4 +140,4 @@ class Dtd:
     """
 
     location: str
-    elements: List[DtdElement]
+    elements: list[DtdElement]
diff --git a/xsdata/models/enums.py b/xsdata/models/enums.py
index 5fd625de..a547ddb1 100644
--- a/xsdata/models/enums.py
+++ b/xsdata/models/enums.py
@@ -2,7 +2,7 @@ import sys
 from decimal import Decimal
 from enum import Enum
 from pathlib import Path
-from typing import Any, Callable, Dict, Optional, Tuple, Type
+from typing import Any, Callable, Optional
 from xml.etree.ElementTree import QName
 
 from xsdata.models.datatype import (
@@ -48,7 +48,7 @@ class Namespace(Enum):
         return __STANDARD_NAMESPACES__.get(uri) if uri else None
 
     @classmethod
-    def common(cls) -> Tuple["Namespace", ...]:
+    def common(cls) -> tuple["Namespace", ...]:
         """Return the common namespaces."""
         return Namespace.XS, Namespace.XSI, Namespace.XML, Namespace.XLINK
 
@@ -167,7 +167,7 @@ class DataType(Enum):
         code: str,
         python_type: type,
         fmt: Optional[str] = None,
-        wrapper: Optional[Type] = None,
+        wrapper: Optional[type] = None,
     ):
         self.code = code
         self.type = python_type
@@ -193,7 +193,7 @@ class DataType(Enum):
         return cls.from_type(_type)
 
     @classmethod
-    def from_type(cls, tp: Type) -> "DataType":
+    def from_type(cls, tp: type) -> "DataType":
         """Load from a python type."""
         return __DataTypeIndex__.get(tp, DataType.STRING)
 
@@ -251,7 +251,7 @@ __DataTypeIndex__ = {
     XmlHexBinary: DataType.HEX_BINARY,
     XmlBase64Binary: DataType.BASE64_BINARY,
 }
-__DataTypeInferIndex__: Dict[Type, Callable] = {
+__DataTypeInferIndex__: dict[type, Callable] = {
     int: int_datatype,
     float: float_datatype,
     XmlPeriod: period_datatype,
diff --git a/xsdata/models/mixins.py b/xsdata/models/mixins.py
index 44c560c8..adc36cc5 100644
--- a/xsdata/models/mixins.py
+++ b/xsdata/models/mixins.py
@@ -1,5 +1,6 @@
+from collections.abc import Iterator
 from dataclasses import dataclass, field, fields
-from typing import Any, Callable, Dict, Iterator, List, Optional
+from typing import Any, Callable, Optional
 
 from xsdata.codegen.exceptions import CodegenError
 from xsdata.formats.dataclass.models.elements import XmlType
@@ -22,7 +23,7 @@ class ElementBase:
         init=False,
         metadata={"type": "Ignore"},
     )
-    ns_map: Dict[str, str] = field(
+    ns_map: dict[str, str] = field(
         default_factory=dict,
         init=False,
         metadata={"type": "Ignore"},
@@ -142,7 +143,7 @@ class ElementBase:
         yield from ()
 
     @property
-    def substitutions(self) -> List[str]:
+    def substitutions(self) -> list[str]:
         """Return the substitution groups of this element."""
         return []
 
@@ -155,7 +156,7 @@ class ElementBase:
 
         return None
 
-    def get_restrictions(self) -> Dict[str, Any]:
+    def get_restrictions(self) -> dict[str, Any]:
         """Return the restrictions dictionary of this element."""
         return {}
 
@@ -193,7 +194,7 @@ def element(optional: bool = True, **kwargs: Any) -> Any:
     return field(metadata=metadata, **kwargs)
 
 
-def add_default_value(params: Dict, optional: bool):
+def add_default_value(params: dict, optional: bool):
     """Add the default value if it's missing and the optional flag is true."""
     if optional and not ("default" in params or "default_factory" in params):
         params["default"] = None
@@ -213,7 +214,7 @@ def array_any_element(**kwargs: Any) -> Any:
     return field(metadata=metadata, default_factory=list, **kwargs)
 
 
-def extract_metadata(params: Dict, **kwargs: Any) -> Dict:
+def extract_metadata(params: dict, **kwargs: Any) -> dict:
     """Remove dataclasses standard field properties and merge any additional."""
     metadata = {
         key: params.pop(key) for key in list(params.keys()) if key not in FIELD_PARAMS
diff --git a/xsdata/models/wsdl.py b/xsdata/models/wsdl.py
index 04bd8e73..914d641e 100644
--- a/xsdata/models/wsdl.py
+++ b/xsdata/models/wsdl.py
@@ -1,5 +1,6 @@
+from collections.abc import Iterator
 from dataclasses import dataclass, field
-from typing import Dict, Iterator, List, Optional, TypeVar
+from typing import Optional, TypeVar
 
 from xsdata.codegen.exceptions import CodegenError
 from xsdata.codegen.models import get_name
@@ -18,7 +19,7 @@ class Documentation:
         elements: A list of generic any elements
     """
 
-    elements: List[object] = array_any_element()
+    elements: list[object] = array_any_element()
 
 
 @dataclass
@@ -35,7 +36,7 @@ class WsdlElement:
     name: str = attribute()
     documentation: Optional[Documentation] = element()
     location: Optional[str] = field(default=None, metadata={"type": "Ignore"})
-    ns_map: Dict[str, str] = field(
+    ns_map: dict[str, str] = field(
         default_factory=dict, init=False, metadata={"type": "Ignore"}
     )
 
@@ -52,7 +53,7 @@ class ExtensibleElement(WsdlElement):
         extended: A list of generic elements
     """
 
-    extended: List[object] = array_any_element()
+    extended: list[object] = array_any_element()
 
     @property
     def extended_elements(self) -> Iterator[AnyElement]:
@@ -69,7 +70,7 @@ class Types:
         documentation: The type documentation
     """
 
-    schemas: List[Schema] = array_element(name="schema", namespace=Namespace.XS.uri)
+    schemas: list[Schema] = array_element(name="schema", namespace=Namespace.XS.uri)
     documentation: Optional[Documentation] = element()
 
 
@@ -115,7 +116,7 @@ class Message(WsdlElement):
         parts: The message parts
     """
 
-    parts: List[Part] = array_element(name="part")
+    parts: list[Part] = array_element(name="part")
 
 
 @dataclass
@@ -146,7 +147,7 @@ class PortTypeOperation(WsdlElement):
 
     input: PortTypeMessage = element()
     output: PortTypeMessage = element()
-    faults: List[PortTypeMessage] = array_element(name="fault")
+    faults: list[PortTypeMessage] = array_element(name="fault")
 
 
 @dataclass
@@ -162,7 +163,7 @@ class PortType(ExtensibleElement):
         operations: The port type operations
     """
 
-    operations: List[PortTypeOperation] = array_element(name="operation")
+    operations: list[PortTypeOperation] = array_element(name="operation")
 
     def find_operation(self, name: str) -> PortTypeOperation:
         """Find an operation by name or raise an error."""
@@ -199,7 +200,7 @@ class BindingOperation(ExtensibleElement):
 
     input: BindingMessage = element()
     output: BindingMessage = element()
-    faults: List[BindingMessage] = array_element(name="fault")
+    faults: list[BindingMessage] = array_element(name="fault")
 
 
 @dataclass
@@ -217,7 +218,7 @@ class Binding(ExtensibleElement):
     """
 
     type: str = attribute()
-    operations: List[BindingOperation] = array_element(name="operation")
+    operations: list[BindingOperation] = array_element(name="operation")
 
     def unique_operations(self) -> Iterator[BindingOperation]:
         """Yields all unique operation instances."""
@@ -255,7 +256,7 @@ class Service(WsdlElement):
         ports: The service ports
     """
 
-    ports: List[ServicePort] = array_element(name="port")
+    ports: list[ServicePort] = array_element(name="port")
 
 
 @dataclass
@@ -285,11 +286,11 @@ class Definitions(ExtensibleElement):
 
     target_namespace: Optional[str] = attribute(name="targetNamespace")
     types: Optional[Types] = element()
-    imports: List[Import] = array_element(name="import")
-    messages: List[Message] = array_element(name="message")
-    port_types: List[PortType] = array_element(name="portType")
-    bindings: List[Binding] = array_element(name="binding")
-    services: List[Service] = array_element(name="service")
+    imports: list[Import] = array_element(name="import")
+    messages: list[Message] = array_element(name="message")
+    port_types: list[PortType] = array_element(name="portType")
+    bindings: list[Binding] = array_element(name="binding")
+    services: list[Service] = array_element(name="service")
 
     @property
     def schemas(self) -> Iterator[Schema]:
@@ -330,7 +331,7 @@ class Definitions(ExtensibleElement):
 T = TypeVar("T", bound=WsdlElement)
 
 
-def find_or_die(items: List[T], name: str, type_name: str) -> T:
+def find_or_die(items: list[T], name: str, type_name: str) -> T:
     """Find an item by name or raise an error."""
     for msg in items:
         if msg.name == name:
diff --git a/xsdata/models/xsd.py b/xsdata/models/xsd.py
index 134dd1b2..7d8d0d73 100644
--- a/xsdata/models/xsd.py
+++ b/xsdata/models/xsd.py
@@ -1,9 +1,9 @@
 import sys
 import textwrap
+from collections.abc import Iterator
 from dataclasses import dataclass, field
 from typing import Any as Anything
-from typing import Dict, Iterator, Optional
-from typing import List as Array
+from typing import Optional
 from typing import Union as UnionType
 
 from xsdata.formats.dataclass.serializers import XmlSerializer
@@ -56,7 +56,7 @@ class Docstring:
 
         namespace = "http://www.w3.org/1999/xhtml"
 
-    content: Array[object] = array_any_element()
+    content: list[object] = array_any_element()
 
 
 @dataclass
@@ -66,7 +66,7 @@ class Documentation(ElementBase):
     lang: Optional[str] = attribute()
     source: Optional[str] = attribute()
     attributes: Optional["AnyAttribute"] = element()
-    content: Array[object] = array_any_element(mixed=True)
+    content: list[object] = array_any_element(mixed=True)
 
     def tostring(self) -> Optional[str]:
         """Convert the content to a help string."""
@@ -89,15 +89,15 @@ class Appinfo(ElementBase):
 
     source: Optional[str] = attribute()
     any_attribute: Optional["AnyAttribute"] = element(name="anyAttribute")
-    content: Array[object] = array_any_element(mixed=True)
+    content: list[object] = array_any_element(mixed=True)
 
 
 @dataclass
 class Annotation(ElementBase):
     """XSD Annotation model representation."""
 
-    app_infos: Array[Appinfo] = array_element(name="appinfo")
-    documentations: Array[Documentation] = array_element(name="documentation")
+    app_infos: list[Appinfo] = array_element(name="appinfo")
+    documentations: list[Documentation] = array_element(name="documentation")
     any_attribute: Optional["AnyAttribute"] = element(name="anyAttribute")
 
 
@@ -106,7 +106,7 @@ class AnnotationBase(ElementBase):
     """XSD AnnotationBase model representation."""
 
     id: Optional[str] = attribute()
-    annotations: Array[Annotation] = array_element(name="annotation")
+    annotations: list[Annotation] = array_element(name="annotation")
     any_attribute: Optional["AnyAttribute"] = element(name="anyAttribute")
 
     @property
@@ -199,7 +199,7 @@ class SimpleType(AnnotationBase):
         elif self.union:
             yield from self.union.bases
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         if self.restriction:
             return self.restriction.get_restrictions()
@@ -231,7 +231,7 @@ class List(AnnotationBase):
         if self.item_type:
             yield self.item_type
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         return {"tokens": True}
 
@@ -241,7 +241,7 @@ class Union(AnnotationBase):
     """XSD Union model representation."""
 
     member_types: Optional[str] = attribute(name="memberTypes")
-    simple_types: Array[SimpleType] = array_element(name="simpleType")
+    simple_types: list[SimpleType] = array_element(name="simpleType")
 
     @property
     def bases(self) -> Iterator[str]:
@@ -268,7 +268,7 @@ class Union(AnnotationBase):
         if self.member_types:
             yield from self.member_types.split()
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         restrictions = {}
         for simple_type in self.simple_types:
@@ -319,7 +319,7 @@ class Attribute(AnnotationBase):
         datatype = DataType.STRING if self.fixed else DataType.ANY_SIMPLE_TYPE
         return datatype.prefixed(self.xs_prefix)
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         if self.use == UseType.REQUIRED:
             restrictions = {"min_occurs": 1, "max_occurs": 1}
@@ -340,8 +340,8 @@ class AttributeGroup(AnnotationBase):
 
     ref: str = attribute(default="")
     name: Optional[str] = attribute()
-    attributes: Array[Attribute] = array_element(name="attribute")
-    attribute_groups: Array["AttributeGroup"] = array_element(name="attributeGroup")
+    attributes: list[Attribute] = array_element(name="attribute")
+    attribute_groups: list["AttributeGroup"] = array_element(name="attributeGroup")
 
     @property
     def is_property(self) -> bool:
@@ -392,7 +392,7 @@ class Any(AnnotationBase):
         """Return the attr types for this element."""
         yield DataType.ANY_TYPE.prefixed(self.xs_prefix)
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         max_occurs = sys.maxsize if self.max_occurs == "unbounded" else self.max_occurs
 
@@ -409,15 +409,15 @@ class All(AnnotationBase):
 
     min_occurs: int = attribute(default=1, name="minOccurs")
     max_occurs: UnionType[str, int] = attribute(default=1, name="maxOccurs")
-    any: Array[Any] = array_element(name="any")
-    elements: Array["Element"] = array_element(name="element")
-    groups: Array["Group"] = array_element(name="group")
+    any: list[Any] = array_element(name="any")
+    elements: list["Element"] = array_element(name="element")
+    groups: list["Group"] = array_element(name="group")
 
     def __post_init__(self):
         """Post initialization validations."""
         self.max_occurs = validate_max_occurs(self.min_occurs, self.max_occurs)
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         return {
             "path": [("a", id(self), self.min_occurs, self.max_occurs)],
@@ -430,17 +430,17 @@ class Sequence(AnnotationBase):
 
     min_occurs: int = attribute(default=1, name="minOccurs")
     max_occurs: UnionType[str, int] = attribute(default=1, name="maxOccurs")
-    elements: Array["Element"] = array_element(name="element")
-    groups: Array["Group"] = array_element(name="group")
-    choices: Array["Choice"] = array_element(name="choice")
-    sequences: Array["Sequence"] = array_element(name="sequence")
-    any: Array["Any"] = array_element()
+    elements: list["Element"] = array_element(name="element")
+    groups: list["Group"] = array_element(name="group")
+    choices: list["Choice"] = array_element(name="choice")
+    sequences: list["Sequence"] = array_element(name="sequence")
+    any: list["Any"] = array_element()
 
     def __post_init__(self):
         """Post initialization validations."""
         self.max_occurs = validate_max_occurs(self.min_occurs, self.max_occurs)
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         return {
             "path": [("s", id(self), self.min_occurs, self.max_occurs)],
@@ -453,17 +453,17 @@ class Choice(AnnotationBase):
 
     min_occurs: int = attribute(default=1, name="minOccurs")
     max_occurs: UnionType[str, int] = attribute(default=1, name="maxOccurs")
-    elements: Array["Element"] = array_element(name="element")
-    groups: Array["Group"] = array_element(name="group")
-    choices: Array["Choice"] = array_element(name="choice")
-    sequences: Array[Sequence] = array_element(name="sequence")
-    any: Array["Any"] = array_element()
+    elements: list["Element"] = array_element(name="element")
+    groups: list["Group"] = array_element(name="group")
+    choices: list["Choice"] = array_element(name="choice")
+    sequences: list[Sequence] = array_element(name="sequence")
+    any: list["Any"] = array_element()
 
     def __post_init__(self):
         """Post initialization validations."""
         self.max_occurs = validate_max_occurs(self.min_occurs, self.max_occurs)
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         return {
             "path": [("c", id(self), self.min_occurs, self.max_occurs)],
@@ -497,7 +497,7 @@ class Group(AnnotationBase):
         if self.ref:
             yield self.ref
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         return {
             "path": [("g", id(self), self.min_occurs, self.max_occurs)],
@@ -529,9 +529,9 @@ class Extension(AnnotationBase):
     sequence: Optional[Sequence] = element()
     any_attribute: Optional[AnyAttribute] = element(name="anyAttribute")
     open_content: Optional[OpenContent] = element(name="openContent")
-    attributes: Array[Attribute] = array_element(name="attribute")
-    attribute_groups: Array[AttributeGroup] = array_element(name="attributeGroup")
-    assertions: Array[Assertion] = array_element(name="assert")
+    attributes: list[Attribute] = array_element(name="attribute")
+    attribute_groups: list[AttributeGroup] = array_element(name="attributeGroup")
+    assertions: list[Assertion] = array_element(name="assert")
 
     @property
     def bases(self) -> Iterator[str]:
@@ -662,12 +662,12 @@ class Restriction(AnnotationBase):
     choice: Optional[Choice] = element()
     sequence: Optional[Sequence] = element()
     open_content: Optional[OpenContent] = element(name="openContent")
-    attributes: Array[Attribute] = array_element(name="attribute")
-    attribute_groups: Array[AttributeGroup] = array_element(name="attributeGroup")
-    enumerations: Array[Enumeration] = array_element(name="enumeration")
-    asserts: Array[Assertion] = array_element(name="assert")
-    assertions: Array[Assertion] = array_element(name="assertion")
-    any_element: Array[object] = array_any_element()
+    attributes: list[Attribute] = array_element(name="attribute")
+    attribute_groups: list[AttributeGroup] = array_element(name="attributeGroup")
+    enumerations: list[Enumeration] = array_element(name="enumeration")
+    asserts: list[Assertion] = array_element(name="assert")
+    assertions: list[Assertion] = array_element(name="assertion")
+    any_element: list[object] = array_any_element()
     min_exclusive: Optional[MinExclusive] = element(name="minExclusive")
     min_inclusive: Optional[MinInclusive] = element(name="minInclusive")
     min_length: Optional[MinLength] = element(name="minLength")
@@ -678,7 +678,7 @@ class Restriction(AnnotationBase):
     fraction_digits: Optional[FractionDigits] = element(name="fractionDigits")
     length: Optional[Length] = element()
     white_space: Optional[WhiteSpace] = element(name="whiteSpace")
-    patterns: Array[Pattern] = array_element(name="pattern")
+    patterns: list[Pattern] = array_element(name="pattern")
     explicit_timezone: Optional[ExplicitTimezone] = element(name="explicitTimezone")
     simple_type: Optional[SimpleType] = element(name="simpleType")
 
@@ -701,7 +701,7 @@ class Restriction(AnnotationBase):
         if self.base:
             yield self.base
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         restrictions = {}
         if self.simple_type:
@@ -766,9 +766,9 @@ class ComplexType(AnnotationBase):
     sequence: Optional[Sequence] = element()
     any_attribute: Optional[AnyAttribute] = element(name="anyAttribute")
     open_content: Optional[OpenContent] = element(name="openContent")
-    attributes: Array[Attribute] = array_element(name="attribute")
-    attribute_groups: Array[AttributeGroup] = array_element(name="attributeGroup")
-    assertion: Array[Assertion] = array_element(name="assert")
+    attributes: list[Attribute] = array_element(name="attribute")
+    attribute_groups: list[AttributeGroup] = array_element(name="attributeGroup")
+    assertion: list[Assertion] = array_element(name="assert")
     abstract: bool = attribute(default=False)
     mixed: bool = attribute(default=False)
     default_attributes_apply: bool = attribute(
@@ -806,7 +806,7 @@ class Unique(AnnotationBase):
     name: Optional[str] = attribute()
     ref: Optional[str] = attribute()
     selector: Optional[Selector] = element()
-    fields: Array[Field] = array_element(name="field")
+    fields: list[Field] = array_element(name="field")
 
 
 @dataclass
@@ -816,7 +816,7 @@ class Key(AnnotationBase):
     name: Optional[str] = attribute()
     ref: Optional[str] = attribute()
     selector: Optional[Selector] = element()
-    fields: Array[Selector] = array_element(name="field")
+    fields: list[Selector] = array_element(name="field")
 
 
 @dataclass
@@ -827,7 +827,7 @@ class Keyref(AnnotationBase):
     ref: Optional[str] = attribute()
     refer: Optional[str] = attribute()
     selector: Optional[Selector] = element()
-    fields: Array[Selector] = array_element(name="field")
+    fields: list[Selector] = array_element(name="field")
 
 
 @dataclass
@@ -854,7 +854,7 @@ class Alternative(AnnotationBase):
         if self.type:
             yield self.type
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         return {
             "path": [("alt", id(self), 0, 1)],
@@ -877,10 +877,10 @@ class Element(AnnotationBase):
     target_namespace: Optional[str] = attribute(name="targetNamespace")
     simple_type: Optional[SimpleType] = element(name="simpleType")
     complex_type: Optional[ComplexType] = element(name="complexType")
-    alternatives: Array[Alternative] = array_element(name="alternative")
-    uniques: Array[Unique] = array_element(name="unique")
-    keys: Array[Key] = array_element(name="key")
-    keyrefs: Array[Keyref] = array_element(name="keyref")
+    alternatives: list[Alternative] = array_element(name="alternative")
+    uniques: list[Unique] = array_element(name="unique")
+    keys: list[Key] = array_element(name="key")
+    keyrefs: list[Keyref] = array_element(name="keyref")
     min_occurs: int = attribute(default=1, name="minOccurs")
     max_occurs: UnionType[str, int] = attribute(default=1, name="maxOccurs")
     nillable: bool = attribute(default=False)
@@ -927,11 +927,11 @@ class Element(AnnotationBase):
         yield from (alt.type for alt in self.alternatives if alt.type)
 
     @property
-    def substitutions(self) -> Array[str]:
+    def substitutions(self) -> list[str]:
         """Return a list of the substitution groups."""
         return self.substitution_group.split() if self.substitution_group else []
 
-    def get_restrictions(self) -> Dict[str, Anything]:
+    def get_restrictions(self) -> dict[str, Anything]:
         """Return the restrictions dictionary of this element."""
         restrictions = {
             "min_occurs": self.min_occurs,
@@ -978,10 +978,10 @@ class Redefine(AnnotationBase):
     """XSD Redefine model representation."""
 
     schema_location: Optional[str] = attribute(name="schemaLocation")
-    simple_types: Array[SimpleType] = array_element(name="simpleType")
-    complex_types: Array[ComplexType] = array_element(name="complexType")
-    groups: Array[Group] = array_element(name="group")
-    attribute_groups: Array[AttributeGroup] = array_element(name="attributeGroup")
+    simple_types: list[SimpleType] = array_element(name="simpleType")
+    complex_types: list[ComplexType] = array_element(name="complexType")
+    groups: list[Group] = array_element(name="group")
+    attribute_groups: list[AttributeGroup] = array_element(name="attributeGroup")
     location: Optional[str] = field(default=None, metadata={"type": "Ignore"})
 
 
@@ -990,13 +990,13 @@ class Override(AnnotationBase):
     """XSD Override model representation."""
 
     schema_location: Optional[str] = attribute(name="schemaLocation")
-    simple_types: Array[SimpleType] = array_element(name="simpleType")
-    complex_types: Array[ComplexType] = array_element(name="complexType")
-    groups: Array[Group] = array_element(name="group")
-    attribute_groups: Array[AttributeGroup] = array_element(name="attributeGroup")
-    elements: Array[Element] = array_element(name="element")
-    attributes: Array[Attribute] = array_element(name="attribute")
-    notations: Array[Notation] = array_element(name="notation")
+    simple_types: list[SimpleType] = array_element(name="simpleType")
+    complex_types: list[ComplexType] = array_element(name="complexType")
+    groups: list[Group] = array_element(name="group")
+    attribute_groups: list[AttributeGroup] = array_element(name="attributeGroup")
+    elements: list[Element] = array_element(name="element")
+    attributes: list[Attribute] = array_element(name="attribute")
+    notations: list[Notation] = array_element(name="notation")
     location: Optional[str] = field(default=None, metadata={"type": "Ignore"})
 
 
@@ -1028,18 +1028,18 @@ class Schema(AnnotationBase):
     default_open_content: Optional[DefaultOpenContent] = element(
         name="defaultOpenContent"
     )
-    includes: Array[Include] = array_element(name="include")
-    imports: Array[Import] = array_element(name="import")
-    redefines: Array[Redefine] = array_element(name="redefine")
-    overrides: Array[Override] = array_element(name="override")
-    annotations: Array[Annotation] = array_element(name="annotation")
-    simple_types: Array[SimpleType] = array_element(name="simpleType")
-    complex_types: Array[ComplexType] = array_element(name="complexType")
-    groups: Array[Group] = array_element(name="group")
-    attribute_groups: Array[AttributeGroup] = array_element(name="attributeGroup")
-    elements: Array[Element] = array_element(name="element")
-    attributes: Array[Attribute] = array_element(name="attribute")
-    notations: Array[Notation] = array_element(name="notation")
+    includes: list[Include] = array_element(name="include")
+    imports: list[Import] = array_element(name="import")
+    redefines: list[Redefine] = array_element(name="redefine")
+    overrides: list[Override] = array_element(name="override")
+    annotations: list[Annotation] = array_element(name="annotation")
+    simple_types: list[SimpleType] = array_element(name="simpleType")
+    complex_types: list[ComplexType] = array_element(name="complexType")
+    groups: list[Group] = array_element(name="group")
+    attribute_groups: list[AttributeGroup] = array_element(name="attributeGroup")
+    elements: list[Element] = array_element(name="element")
+    attributes: list[Attribute] = array_element(name="attribute")
+    notations: list[Notation] = array_element(name="notation")
     location: Optional[str] = field(default=None, metadata={"type": "Ignore"})
 
     def included(self) -> Iterator[UnionType[Import, Include, Redefine, Override]]:
diff --git a/xsdata/utils/click.py b/xsdata/utils/click.py
index 5baebe35..47746ada 100644
--- a/xsdata/utils/click.py
+++ b/xsdata/utils/click.py
@@ -1,14 +1,11 @@
 import enum
 import inspect
 import logging
+from collections.abc import Iterator
 from dataclasses import fields, is_dataclass
 from typing import (
     Any,
     Callable,
-    Dict,
-    Iterator,
-    List,
-    Type,
     TypeVar,
     Union,
     get_type_hints,
@@ -90,7 +87,7 @@ def build_options(obj: Any, parent: str) -> Iterator[Callable[[FC], FC]]:
             )
 
 
-def get_doc_hints(obj: Any) -> Dict[str, str]:
+def get_doc_hints(obj: Any) -> dict[str, str]:
     """Return a param-docstring map of the class arguments."""
     docstrings = inspect.getdoc(obj)
     assert docstrings is not None
@@ -109,7 +106,7 @@ def get_doc_hints(obj: Any) -> Dict[str, str]:
 class EnumChoice(click.Choice):
     """Custom click choice widget for enumerations."""
 
-    def __init__(self, enumeration: Type[enum.Enum]):
+    def __init__(self, enumeration: type[enum.Enum]):
         self.enumeration = enumeration
         super().__init__([e.value for e in enumeration])
 
@@ -121,7 +118,7 @@ class EnumChoice(click.Choice):
 class LogFormatter(logging.Formatter):
     """Custom log formatter with click colors."""
 
-    colors: Dict[str, Any] = {
+    colors: dict[str, Any] = {
         "error": {"fg": "red"},
         "exception": {"fg": "red"},
         "critical": {"fg": "red"},
@@ -147,7 +144,7 @@ class LogHandler(logging.Handler):
 
     def __init__(self, level: Union[int, str] = logging.NOTSET):
         super().__init__(level)
-        self.warnings: List[str] = []
+        self.warnings: list[str] = []
 
     def emit(self, record: logging.LogRecord):
         """Override emit to record warnings."""
diff --git a/xsdata/utils/collections.py b/xsdata/utils/collections.py
index ab1e8ec3..9652c8aa 100644
--- a/xsdata/utils/collections.py
+++ b/xsdata/utils/collections.py
@@ -1,15 +1,9 @@
 from collections import defaultdict
+from collections.abc import Generator, Iterable, Iterator, Sequence
 from typing import (
     Any,
     Callable,
-    Dict,
-    Generator,
-    Iterable,
-    Iterator,
-    List,
     Optional,
-    Sequence,
-    Set,
     TypeVar,
 )
 
@@ -24,7 +18,7 @@ def is_array(value: Any) -> bool:
     return isinstance(value, (list, set, frozenset, Generator))
 
 
-def unique_sequence(items: Iterable[T], key: Optional[str] = None) -> List[T]:
+def unique_sequence(items: Iterable[T], key: Optional[str] = None) -> list[T]:
     """Return a new unique list, preserving the original order.
 
     Args:
@@ -49,12 +43,12 @@ def unique_sequence(items: Iterable[T], key: Optional[str] = None) -> List[T]:
     return [item for item in items if is_new(item)]
 
 
-def remove(items: Iterable[T], predicate: Callable) -> List[T]:
+def remove(items: Iterable[T], predicate: Callable) -> list[T]:
     """Return a new list without the items that match the predicate."""
     return [x for x in items if not predicate(x)]
 
 
-def group_by(items: Iterable[T], key: Callable) -> Dict[Any, List[T]]:
+def group_by(items: Iterable[T], key: Callable) -> dict[Any, list[T]]:
     """Group the items of an iterable object by the result of the callable."""
     result = defaultdict(list)
     for item in items:
@@ -89,19 +83,19 @@ def first(items: Iterator[T]) -> Optional[T]:
     return next(items, None)
 
 
-def prepend(target: List, *args: Any):
+def prepend(target: list, *args: Any):
     """Prepend items to the target list."""
     target[:0] = args
 
 
-def connected_components(lists: List[List[Any]]) -> Iterator[List[Any]]:
+def connected_components(lists: list[list[Any]]) -> Iterator[list[Any]]:
     """Merge lists of lists that share common elements."""
     neighbors = defaultdict(set)
     for each in lists:
         for item in each:
             neighbors[item].update(each)
 
-    def component(node: Any, neigh: Dict[Any, Set], see: Set[Any]):
+    def component(node: Any, neigh: dict[Any, set], see: set[Any]):
         nodes = {node}
         while nodes:
             next_node = nodes.pop()
@@ -109,13 +103,13 @@ def connected_components(lists: List[List[Any]]) -> Iterator[List[Any]]:
             nodes |= neigh[next_node] - see
             yield next_node
 
-    seen: Set[Any] = set()
+    seen: set[Any] = set()
     for item in neighbors:
         if item not in seen:
             yield sorted(component(item, neighbors, seen))
 
 
-def find_connected_component(groups: List[List[Any]], value: Any) -> int:
+def find_connected_component(groups: list[list[Any]], value: Any) -> int:
     """Find the list index that contains the given value."""
     for index, group in enumerate(groups):
         if value in group:
diff --git a/xsdata/utils/constants.py b/xsdata/utils/constants.py
index b2465076..c295b17b 100644
--- a/xsdata/utils/constants.py
+++ b/xsdata/utils/constants.py
@@ -1,9 +1,10 @@
 import sys
-from typing import Any, Dict, Sequence, Tuple
+from collections.abc import Sequence
+from typing import Any
 
-EMPTY_MAP: Dict = {}
+EMPTY_MAP: dict = {}
 EMPTY_SEQUENCE: Sequence = []
-EMPTY_TUPLE: Tuple = ()
+EMPTY_TUPLE: tuple = ()
 
 XML_FALSE = sys.intern("false")
 XML_TRUE = sys.intern("true")
diff --git a/xsdata/utils/dates.py b/xsdata/utils/dates.py
index 3f6fbe61..c048ec85 100644
--- a/xsdata/utils/dates.py
+++ b/xsdata/utils/dates.py
@@ -1,6 +1,7 @@
 import datetime
 from calendar import isleap
-from typing import Any, Iterator, Optional, Union
+from collections.abc import Iterator
+from typing import Any, Optional, Union
 
 
 def parse_date_args(value: Any, fmt: str) -> Iterator[int]:
diff --git a/xsdata/utils/downloader.py b/xsdata/utils/downloader.py
index 588472cc..1b8f03e3 100644
--- a/xsdata/utils/downloader.py
+++ b/xsdata/utils/downloader.py
@@ -1,7 +1,7 @@
 import os
 import re
 from pathlib import Path
-from typing import Dict, Optional, Union
+from typing import Optional, Union
 
 from xsdata.codegen import opener
 from xsdata.codegen.parsers import DefinitionsParser, SchemaParser
@@ -24,12 +24,12 @@ class Downloader:
         downloaded: A cache of the downloaded resources
     """
 
-    __slots__ = ("output", "base_path", "downloaded")
+    __slots__ = ("base_path", "downloaded", "output")
 
     def __init__(self, output: Path):
         self.output = output
         self.base_path: Optional[Path] = None
-        self.downloaded: Dict = {}
+        self.downloaded: dict = {}
 
     def wget(self, uri: str, location: Optional[str] = None):
         """Download handler for any uri input with circular protection."""
diff --git a/xsdata/utils/graphs.py b/xsdata/utils/graphs.py
index 5d4c8606..d35a61bf 100644
--- a/xsdata/utils/graphs.py
+++ b/xsdata/utils/graphs.py
@@ -1,7 +1,7 @@
-from typing import Dict, Iterator, List, Set
+from collections.abc import Iterator
 
 
-def strongly_connected_components(edges: Dict[str, List[str]]) -> Iterator[Set[str]]:
+def strongly_connected_components(edges: dict[str, list[str]]) -> Iterator[set[str]]:
     """Compute Strongly Connected Components of a directed graph.
 
     From https://code.activestate.com/recipes/578507/ From
@@ -13,12 +13,12 @@ def strongly_connected_components(edges: Dict[str, List[str]]) -> Iterator[Set[s
     Yields:
         A set of the strongly connected components
     """
-    identified: Set[str] = set()
-    stack: List[str] = []
-    index: Dict[str, int] = {}
-    boundaries: List[int] = []
+    identified: set[str] = set()
+    stack: list[str] = []
+    index: dict[str, int] = {}
+    boundaries: list[int] = []
 
-    def dfs(v: str) -> Iterator[Set[str]]:
+    def dfs(v: str) -> Iterator[set[str]]:
         index[v] = len(stack)
         stack.append(v)
         boundaries.append(index[v])
diff --git a/xsdata/utils/namespaces.py b/xsdata/utils/namespaces.py
index aad90a25..4f08f51a 100644
--- a/xsdata/utils/namespaces.py
+++ b/xsdata/utils/namespaces.py
@@ -1,6 +1,6 @@
 import functools
 import re
-from typing import Dict, Optional, Tuple
+from typing import Optional
 
 from xsdata.models.enums import Namespace
 from xsdata.utils import text
@@ -14,7 +14,7 @@ URI_REGEX = re.compile(
 )
 
 
-def load_prefix(uri: str, ns_map: Dict) -> Optional[str]:
+def load_prefix(uri: str, ns_map: dict) -> Optional[str]:
     """Get or create a prefix for the uri in the prefix-URI map."""
     for prefix, ns in ns_map.items():
         if ns == uri:
@@ -23,7 +23,7 @@ def load_prefix(uri: str, ns_map: Dict) -> Optional[str]:
     return generate_prefix(uri, ns_map)
 
 
-def generate_prefix(uri: str, ns_map: Dict) -> str:
+def generate_prefix(uri: str, ns_map: dict) -> str:
     """Generate a prefix for the given uri and append it in the prefix-URI map."""
     namespace = Namespace.get_enum(uri)
     if namespace:
@@ -37,17 +37,17 @@ def generate_prefix(uri: str, ns_map: Dict) -> str:
     return prefix
 
 
-def prefix_exists(uri: str, ns_map: Dict) -> bool:
+def prefix_exists(uri: str, ns_map: dict) -> bool:
     """Check if the uri exists in the prefix-URI namespace mapping."""
     return uri in ns_map.values()
 
 
-def is_default(uri: str, ns_map: Dict) -> bool:
+def is_default(uri: str, ns_map: dict) -> bool:
     """Check if the uri exists and it has no prefix."""
     return any(uri == ns and not prefix for prefix, ns in ns_map.items())
 
 
-def clean_prefixes(ns_map: Dict) -> Dict:
+def clean_prefixes(ns_map: dict) -> dict:
     """Remove default namespace if it's also assigned to a prefix."""
     result = {}
     for prefix, ns in ns_map.items():
@@ -91,7 +91,7 @@ def build_qname(tag_or_uri: Optional[str], tag: Optional[str] = None) -> str:
 
 
 @functools.lru_cache(maxsize=50)
-def split_qname(qname: str) -> Tuple:
+def split_qname(qname: str) -> tuple:
     """Split namespace qualified strings."""
     if qname[0] == "{":
         left, right = text.split(qname[1:], "}")
diff --git a/xsdata/utils/text.py b/xsdata/utils/text.py
index 58cb7c66..24228333 100644
--- a/xsdata/utils/text.py
+++ b/xsdata/utils/text.py
@@ -1,22 +1,19 @@
 import re
 import string
-from typing import Any, List, Match, Tuple
+from re import Match
+from typing import Any
 
 stop_words = {
     "",
     "Any",
     "Decimal",
-    "Dict",
     "Enum",
     "False",
-    "List",
     "Meta",
     "None",
     "Optional",
     "QName",
     "True",
-    "Type",
-    "Tuple",
     "Union",
     "and",
     "as",
@@ -76,7 +73,7 @@ def suffix(value: str, sep: str = ":") -> str:
     return split(value, sep)[1]
 
 
-def split(value: str, sep: str = ":") -> Tuple:
+def split(value: str, sep: str = ":") -> tuple:
     """Split the given value with the given separator once."""
     left, _, right = value.partition(sep)
     return (left, right) if right else (None, left)
@@ -136,10 +133,10 @@ def kebab_case(value: str, **kwargs: Any) -> str:
     return "-".join(split_words(value))
 
 
-def split_words(value: str) -> List[str]:
+def split_words(value: str) -> list[str]:
     """Split a string on capital letters and not alphanumeric characters."""
-    words: List[str] = []
-    buffer: List[str] = []
+    words: list[str] = []
+    buffer: list[str] = []
     previous = None
 
     def flush():


Test patch:
diff --git a/tests/codegen/handlers/test_vacuum_inner_classes.py b/tests/codegen/handlers/test_vacuum_inner_classes.py
index f11216bc..d922b7e6 100644
--- a/tests/codegen/handlers/test_vacuum_inner_classes.py
+++ b/tests/codegen/handlers/test_vacuum_inner_classes.py
@@ -1,4 +1,4 @@
-from typing import Generator
+from collections.abc import Generator
 
 from xsdata.codegen.handlers import VacuumInnerClasses
 from xsdata.models.enums import DataType
diff --git a/tests/codegen/mappers/test_definitions.py b/tests/codegen/mappers/test_definitions.py
index 12de60b5..07c91cfd 100644
--- a/tests/codegen/mappers/test_definitions.py
+++ b/tests/codegen/mappers/test_definitions.py
@@ -1,4 +1,4 @@
-from typing import Generator
+from collections.abc import Generator
 from unittest import mock
 
 from xsdata.codegen.mappers import DefinitionsMapper
diff --git a/tests/codegen/mappers/test_dtd.py b/tests/codegen/mappers/test_dtd.py
index e437d928..c71c1a23 100644
--- a/tests/codegen/mappers/test_dtd.py
+++ b/tests/codegen/mappers/test_dtd.py
@@ -1,5 +1,5 @@
 import sys
-from typing import Iterator
+from collections.abc import Iterator
 from unittest import mock
 
 from xsdata.codegen.mappers import DtdMapper
diff --git a/tests/codegen/mappers/test_schema.py b/tests/codegen/mappers/test_schema.py
index fc514993..a505f84a 100644
--- a/tests/codegen/mappers/test_schema.py
+++ b/tests/codegen/mappers/test_schema.py
@@ -1,5 +1,5 @@
+from collections.abc import Iterator
 from types import GeneratorType
-from typing import Iterator
 from unittest import mock
 
 from xsdata.codegen.mappers import SchemaMapper
diff --git a/tests/codegen/models/test_codegen.py b/tests/codegen/models/test_codegen.py
index 9fcd146c..66f8d8ce 100644
--- a/tests/codegen/models/test_codegen.py
+++ b/tests/codegen/models/test_codegen.py
@@ -1,13 +1,12 @@
 import unittest
 from dataclasses import dataclass
-from typing import List
 
 from xsdata.codegen.models import CodegenModel
 
 
 @dataclass
 class Foo(CodegenModel):
-    bar: List["Bar"]
+    bar: list["Bar"]
 
     @dataclass
     class Bar(CodegenModel):
diff --git a/tests/codegen/test_utils.py b/tests/codegen/test_utils.py
index 864f3440..540450d4 100644
--- a/tests/codegen/test_utils.py
+++ b/tests/codegen/test_utils.py
@@ -1,5 +1,5 @@
 import sys
-from typing import Generator
+from collections.abc import Generator
 from unittest import mock
 
 from xsdata.codegen.exceptions import CodegenError
diff --git a/tests/codegen/test_writer.py b/tests/codegen/test_writer.py
index 82ba694d..5398dc2a 100644
--- a/tests/codegen/test_writer.py
+++ b/tests/codegen/test_writer.py
@@ -1,6 +1,6 @@
+from collections.abc import Iterator
 from pathlib import Path
 from tempfile import TemporaryDirectory
-from typing import Iterator, List
 from unittest import mock
 
 from xsdata.codegen.exceptions import CodegenError
@@ -13,7 +13,7 @@ from xsdata.utils.testing import ClassFactory, FactoryTestCase
 
 
 class NoneGenerator(AbstractGenerator):
-    def render(self, classes: List[Class]) -> Iterator[GeneratorResult]:
+    def render(self, classes: list[Class]) -> Iterator[GeneratorResult]:
         pass
 
 
diff --git a/tests/conftest.py b/tests/conftest.py
index 00fc3679..88ae0933 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,5 +1,4 @@
 from pathlib import Path
-from typing import Type
 
 from lxml import etree
 
@@ -13,7 +12,7 @@ from xsdata.formats.dataclass.serializers import (
 from xsdata.formats.dataclass.serializers.config import SerializerConfig
 
 
-def validate_bindings(schema: Path, clazz: Type):
+def validate_bindings(schema: Path, clazz: type):
     __tracebackhide__ = True
 
     sample = schema.parent.joinpath("sample.xml")
diff --git a/tests/fixtures/artists/metadata.py b/tests/fixtures/artists/metadata.py
index 87d01e42..61f0541e 100644
--- a/tests/fixtures/artists/metadata.py
+++ b/tests/fixtures/artists/metadata.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import List, Optional, Union
+from typing import Optional, Union
 
 from xsdata.models.datatype import XmlDate, XmlPeriod
 
@@ -111,7 +111,7 @@ class IpiList:
         name = "ipi-list"
         namespace = "http://musicbrainz.org/ns/mmd-2.0#"
 
-    ipi: List[str] = field(
+    ipi: list[str] = field(
         default_factory=list,
         metadata={
             "type": "Element",
@@ -126,7 +126,7 @@ class IsniList:
         name = "isni-list"
         namespace = "http://musicbrainz.org/ns/mmd-2.0#"
 
-    isni: List[str] = field(
+    isni: list[str] = field(
         default_factory=list,
         metadata={
             "type": "Element",
@@ -207,7 +207,7 @@ class AliasList:
             "required": True,
         },
     )
-    alias: List[Alias] = field(
+    alias: list[Alias] = field(
         default_factory=list,
         metadata={
             "type": "Element",
diff --git a/tests/fixtures/books/books.py b/tests/fixtures/books/books.py
index e4d55ac4..3a0bc917 100644
--- a/tests/fixtures/books/books.py
+++ b/tests/fixtures/books/books.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import List, Optional
+from typing import Optional
 
 from xsdata.models.datatype import XmlDate
 
@@ -87,7 +87,7 @@ class BookForm:
 
 @dataclass
 class BooksForm:
-    book: List[BookForm] = field(
+    book: list[BookForm] = field(
         default_factory=list,
         metadata={
             "type": "Element",
diff --git a/tests/fixtures/compound/models.py b/tests/fixtures/compound/models.py
index abf5fc96..f555276a 100644
--- a/tests/fixtures/compound/models.py
+++ b/tests/fixtures/compound/models.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import List, Union
+from typing import Union
 
 
 @dataclass
@@ -35,7 +35,7 @@ class Root:
     class Meta:
         name = "root"
 
-    alpha_or_bravo_or_charlie: List[Union[Alpha, Bravo, List[str]]] = field(
+    alpha_or_bravo_or_charlie: list[Union[Alpha, Bravo, list[str]]] = field(
         default_factory=list,
         metadata={
             "type": "Elements",
@@ -50,7 +50,7 @@ class Root:
                 },
                 {
                     "name": "charlie",
-                    "type": List[str],
+                    "type": list[str],
                     "namespace": "",
                     "default_factory": list,
                     "tokens": True,
diff --git a/tests/fixtures/dtd/models/complete_example.py b/tests/fixtures/dtd/models/complete_example.py
index edeeba95..e2c97b30 100644
--- a/tests/fixtures/dtd/models/complete_example.py
+++ b/tests/fixtures/dtd/models/complete_example.py
@@ -1,6 +1,6 @@
 from dataclasses import dataclass, field
 from enum import Enum
-from typing import List, Optional
+from typing import Optional
 
 
 @dataclass
@@ -60,7 +60,7 @@ class Title:
 
 @dataclass
 class Tags:
-    tag: List[Tag] = field(
+    tag: list[Tag] = field(
         default_factory=list,
         metadata={
             "name": "Tag",
@@ -100,14 +100,14 @@ class Post:
             "required": True,
         },
     )
-    origin: List[Origin] = field(
+    origin: list[Origin] = field(
         default_factory=list,
         metadata={
             "name": "Origin",
             "type": "Element",
         },
     )
-    source: List[Source] = field(
+    source: list[Source] = field(
         default_factory=list,
         metadata={
             "name": "Source",
@@ -142,7 +142,7 @@ class Post:
 
 @dataclass
 class Blog:
-    post: List[Post] = field(
+    post: list[Post] = field(
         default_factory=list,
         metadata={
             "name": "Post",
diff --git a/tests/fixtures/models.py b/tests/fixtures/models.py
index b841ca17..581a3d79 100644
--- a/tests/fixtures/models.py
+++ b/tests/fixtures/models.py
@@ -8,8 +8,6 @@ from typing import Type
 from typing import Union
 from xml.etree.ElementTree import QName
 
-from xsdata.utils.constants import return_true
-
 __NAMESPACE__ = "xsdata"
 
 
diff --git a/tests/fixtures/primer/order.py b/tests/fixtures/primer/order.py
index 1495572a..e7f338db 100644
--- a/tests/fixtures/primer/order.py
+++ b/tests/fixtures/primer/order.py
@@ -1,6 +1,6 @@
 from dataclasses import dataclass, field
 from decimal import Decimal
-from typing import List, Optional
+from typing import Optional
 
 from xsdata.models.datatype import XmlDate
 
@@ -74,7 +74,7 @@ class Comment:
 
 @dataclass
 class Items:
-    item: List["Items.Item"] = field(
+    item: list["Items.Item"] = field(
         default_factory=list,
         metadata={
             "type": "Element",
diff --git a/tests/fixtures/series/series.py b/tests/fixtures/series/series.py
index cff7c716..674b49be 100644
--- a/tests/fixtures/series/series.py
+++ b/tests/fixtures/series/series.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import List, Optional
+from typing import Optional
 
 from xsdata.models.datatype import XmlDate
 
@@ -119,7 +119,7 @@ class Schedule:
             "required": True,
         },
     )
-    days: List[str] = field(
+    days: list[str] = field(
         default_factory=list,
         metadata={
             "type": "Element",
@@ -231,7 +231,7 @@ class Series:
             "required": True,
         },
     )
-    genres: List[str] = field(
+    genres: list[str] = field(
         default_factory=list,
         metadata={
             "type": "Element",
diff --git a/tests/fixtures/stripe/models/balance.py b/tests/fixtures/stripe/models/balance.py
index 47719fb8..60b6dc0f 100644
--- a/tests/fixtures/stripe/models/balance.py
+++ b/tests/fixtures/stripe/models/balance.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import Optional, Tuple
+from typing import Optional
 
 
 @dataclass(order=True, frozen=True)
@@ -113,14 +113,14 @@ class Balance:
             "required": True,
         },
     )
-    available: Tuple[Available, ...] = field(
+    available: tuple[Available, ...] = field(
         default_factory=tuple,
         metadata={
             "type": "Element",
             "min_occurs": 1,
         },
     )
-    connect_reserved: Tuple[ConnectReserved, ...] = field(
+    connect_reserved: tuple[ConnectReserved, ...] = field(
         default_factory=tuple,
         metadata={
             "type": "Element",
@@ -134,7 +134,7 @@ class Balance:
             "required": True,
         },
     )
-    pending: Tuple[Pending, ...] = field(
+    pending: tuple[Pending, ...] = field(
         default_factory=tuple,
         metadata={
             "type": "Element",
diff --git a/tests/fixtures/wrapper/models.py b/tests/fixtures/wrapper/models.py
index 0ec44b80..abcaed62 100644
--- a/tests/fixtures/wrapper/models.py
+++ b/tests/fixtures/wrapper/models.py
@@ -1,5 +1,5 @@
 from dataclasses import dataclass, field
-from typing import List, Optional
+from typing import Optional
 
 __NAMESPACE__ = "xsdata"
 
@@ -25,7 +25,7 @@ class Bravos:
         name = "bravos"
         namespace = "xsdata"
 
-    bravo: List[int] = field(
+    bravo: list[int] = field(
         default_factory=list,
         metadata={
             "type": "Element",
@@ -60,7 +60,7 @@ class Charlies:
         name = "charlies"
         namespace = "xsdata"
 
-    charlie: List[Charlie] = field(
+    charlie: list[Charlie] = field(
         default_factory=list,
         metadata={
             "type": "Element",
@@ -83,7 +83,7 @@ class Wrapper:
             "required": True,
         },
     )
-    bravo: List[int] = field(
+    bravo: list[int] = field(
         default_factory=list,
         metadata={
             "wrapper": "bravos",
@@ -91,7 +91,7 @@ class Wrapper:
             "min_occurs": 1,
         },
     )
-    charlie: List[Charlie] = field(
+    charlie: list[Charlie] = field(
         default_factory=list,
         metadata={
             "wrapper": "charlies",
diff --git a/tests/formats/dataclass/models/test_builders.py b/tests/formats/dataclass/models/test_builders.py
index 5523f018..f43442a8 100644
--- a/tests/formats/dataclass/models/test_builders.py
+++ b/tests/formats/dataclass/models/test_builders.py
@@ -1,7 +1,8 @@
 import sys
+from collections.abc import Iterator
 from dataclasses import dataclass, field, fields, make_dataclass
 from decimal import Decimal
-from typing import Iterator, List, get_type_hints
+from typing import get_type_hints
 from unittest import TestCase, mock
 from xml.etree.ElementTree import QName
 
@@ -392,7 +393,7 @@ class XmlVarBuilderTests(TestCase):
             self.builder.build(
                 BookForm,
                 "foo",
-                List[int],
+                list[int],
                 {"type": "Attributes"},
                 True,
                 None,
@@ -401,7 +402,7 @@ class XmlVarBuilderTests(TestCase):
             )
 
         self.assertEqual(
-            "Error on BookForm::foo: Xml Attributes does not support typing `typing.List[int]`",
+            "Error on BookForm::foo: Xml Attributes does not support typing `list[int]`",
             str(cm.exception),
         )
 
diff --git a/tests/formats/dataclass/parsers/nodes/test_wrapper.py b/tests/formats/dataclass/parsers/nodes/test_wrapper.py
index 536af327..7a5c4e4a 100644
--- a/tests/formats/dataclass/parsers/nodes/test_wrapper.py
+++ b/tests/formats/dataclass/parsers/nodes/test_wrapper.py
@@ -1,5 +1,4 @@
 from dataclasses import dataclass, field
-from typing import List
 from unittest import TestCase
 
 from xsdata.formats.dataclass.parsers import XmlParser
@@ -12,7 +11,7 @@ class WrapperTests(TestCase):
     def test_namespace(self):
         @dataclass
         class NamespaceWrapper:
-            items: List[str] = field(
+            items: list[str] = field(
                 metadata={
                     "wrapper": "Items",
                     "type": "Element",
@@ -32,7 +31,7 @@ class WrapperTests(TestCase):
     def test_primitive(self):
         @dataclass
         class PrimitiveWrapper:
-            primitive_list: List[str] = field(
+            primitive_list: list[str] = field(
                 metadata={
                     "wrapper": "PrimitiveList",
                     "type": "Element",
@@ -55,7 +54,7 @@ class WrapperTests(TestCase):
 
         @dataclass
         class ElementWrapper:
-            elements: List[ElementObject] = field(
+            elements: list[ElementObject] = field(
                 metadata={"wrapper": "Elements", "type": "Element", "name": "Object"}
             )
 
diff --git a/tests/formats/dataclass/parsers/test_dict.py b/tests/formats/dataclass/parsers/test_dict.py
index e9b7c783..67f602f2 100644
--- a/tests/formats/dataclass/parsers/test_dict.py
+++ b/tests/formats/dataclass/parsers/test_dict.py
@@ -1,7 +1,7 @@
 import json
 from dataclasses import asdict, dataclass, field
 from decimal import Decimal
-from typing import List, Optional, Union
+from typing import Optional, Union
 from xml.etree.ElementTree import QName
 
 from tests import fixtures_dir
@@ -69,14 +69,14 @@ class DictDecoderTests(FactoryTestCase):
 
     def test_decode_empty_document(self):
         self.assertEqual(BookForm(), self.decoder.decode({}, BookForm))
-        self.assertEqual([], self.decoder.decode([], List[BookForm]))
+        self.assertEqual([], self.decoder.decode([], list[BookForm]))
 
     def test_decode_list_of_objects(self):
         path = fixtures_dir.joinpath("books/books.json")
         data = json.loads(path.read_text())
         book_list = data["book"]
 
-        books = self.decoder.decode(book_list, List[BookForm])
+        books = self.decoder.decode(book_list, list[BookForm])
         self.assertIsInstance(books, list)
         self.assertEqual(2, len(books))
         self.assertIsInstance(books[0], BookForm)
@@ -138,14 +138,13 @@ class DictDecoderTests(FactoryTestCase):
             ),
             ({}, None, "Document is empty, can not detect type"),
             ([], BookForm, "Document is array, expected object"),
-            ({}, List[BookForm], "Document is object, expected array"),
+            ({}, list[BookForm], "Document is object, expected array"),
             (
                 {},
                 Optional[ChoiceType],
                 f"Invalid clazz argument: {Optional[ChoiceType]}",
             ),
-            ([], List[int], f"Invalid clazz argument: {List[int]}"),
-            ([], List, f"Invalid clazz argument: {List}"),
+            ([], list[int], f"Invalid clazz argument: {list[int]}"),
         ]
 
         for source, clazz, exc_msg in invalid_cases:
@@ -391,7 +390,7 @@ class DictDecoderTests(FactoryTestCase):
     def test_bind_text_with_unions(self):
         @dataclass
         class Fixture:
-            x: List[Union[int, float, str, bool]] = field(metadata={"tokens": True})
+            x: list[Union[int, float, str, bool]] = field(metadata={"tokens": True})
 
         values = ["foo", 12.2, "12.2", 12, "12", True, "false"]
 
diff --git a/tests/formats/dataclass/parsers/test_node.py b/tests/formats/dataclass/parsers/test_node.py
index 4bfef17a..cf787c74 100644
--- a/tests/formats/dataclass/parsers/test_node.py
+++ b/tests/formats/dataclass/parsers/test_node.py
@@ -1,5 +1,5 @@
 from dataclasses import make_dataclass
-from typing import Any, Dict
+from typing import Any
 from unittest import mock
 from unittest.case import TestCase
 
@@ -25,7 +25,7 @@ class NodeParserTests(TestCase):
 
     def test_parse(self):
         class TestHandler(XmlHandler):
-            def parse(self, source: Any, ns_map: Dict) -> Any:
+            def parse(self, source: Any, ns_map: dict) -> Any:
                 return Books()
 
         self.parser.handler = TestHandler
diff --git a/tests/formats/dataclass/serializers/test_mixins.py b/tests/formats/dataclass/serializers/test_mixins.py
index e79cd1c1..ca5bc2af 100644
--- a/tests/formats/dataclass/serializers/test_mixins.py
+++ b/tests/formats/dataclass/serializers/test_mixins.py
@@ -1,6 +1,6 @@
+from collections.abc import Generator
 from dataclasses import dataclass, field, make_dataclass
 from io import StringIO
-from typing import Generator, List
 from unittest import TestCase
 from xml.etree.ElementTree import QName
 from xml.sax import ContentHandler
@@ -215,7 +215,7 @@ class EventGeneratorTests(TestCase):
     def test_with_primitive_wrapper(self):
         @dataclass
         class PrimitiveWrapper:
-            primitive_list: List[str] = field(
+            primitive_list: list[str] = field(
                 metadata={
                     "wrapper": "PrimitiveList",
                     "type": "Element",
@@ -246,7 +246,7 @@ class EventGeneratorTests(TestCase):
 
         @dataclass
         class ElementWrapper:
-            elements: List[ElementObject] = field(
+            elements: list[ElementObject] = field(
                 metadata={"wrapper": "Elements", "type": "Element", "name": "Object"}
             )
 
@@ -275,7 +275,7 @@ class EventGeneratorTests(TestCase):
     def test_with_wrapper_namespace(self):
         @dataclass
         class NamespaceWrapper:
-            items: List[str] = field(
+            items: list[str] = field(
                 metadata={
                     "wrapper": "Items",
                     "type": "Element",
diff --git a/tests/formats/dataclass/test_filters.py b/tests/formats/dataclass/test_filters.py
index ba6c1dbd..8aee2d04 100644
--- a/tests/formats/dataclass/test_filters.py
+++ b/tests/formats/dataclass/test_filters.py
@@ -62,8 +62,8 @@ class FiltersTests(FactoryTestCase):
 
         self.assertEqual("XsString", self.filters.class_name("xs:string"))
         self.assertEqual("FooBarBam", self.filters.class_name("foo:bar_bam"))
-        self.assertEqual("ListType", self.filters.class_name("List"))
-        self.assertEqual("TypeType", self.filters.class_name(".*"))
+        self.assertEqual("List", self.filters.class_name("List"))
+        self.assertEqual("Type", self.filters.class_name(".*"))
         self.assertEqual("Cbad", self.filters.class_name("abcd"))
 
     def test_class_bases(self):
@@ -561,7 +561,7 @@ class FiltersTests(FactoryTestCase):
                 "default_factory": "list",
                 "name": "tok",
                 "tokens": True,
-                "type": "Type[List[str]]",
+                "type": "Type[list[str]]",
             },
         )
 
@@ -631,14 +631,11 @@ class FiltersTests(FactoryTestCase):
         )
         attr.restrictions.max_occurs = 2
         self.assertEqual(
-            'List["A.B.C"]',
+            'list["A.B.C"]',
             self.filters.field_type(self.obj, attr),
         )
 
         self.filters.format.frozen = True
-        self.assertEqual('Tuple["A.B.C", ...]', self.filters.field_type(self.obj, attr))
-
-        self.filters.subscriptable_types = True
         self.assertEqual('tuple["A.B.C", ...]', self.filters.field_type(self.obj, attr))
 
         self.filters.format.frozen = False
@@ -652,21 +649,16 @@ class FiltersTests(FactoryTestCase):
             types=AttrTypeFactory.list(1, qname="foo_bar"),
             restrictions=Restrictions(tokens=True),
         )
-        self.assertEqual("List[FooBar]", self.filters.field_type(self.obj, attr))
+        self.assertEqual("list[FooBar]", self.filters.field_type(self.obj, attr))
 
         attr.restrictions.max_occurs = 2
-        self.assertEqual("List[List[FooBar]]", self.filters.field_type(self.obj, attr))
+        self.assertEqual("list[list[FooBar]]", self.filters.field_type(self.obj, attr))
 
         attr.restrictions.max_occurs = 1
         self.filters.format.frozen = True
-        self.assertEqual("Tuple[FooBar, ...]", self.filters.field_type(self.obj, attr))
+        self.assertEqual("tuple[FooBar, ...]", self.filters.field_type(self.obj, attr))
 
         attr.restrictions.max_occurs = 2
-        self.assertEqual(
-            "Tuple[Tuple[FooBar, ...], ...]", self.filters.field_type(self.obj, attr)
-        )
-
-        self.filters.subscriptable_types = True
         self.assertEqual(
             "tuple[tuple[FooBar, ...], ...]", self.filters.field_type(self.obj, attr)
         )
@@ -677,7 +669,7 @@ class FiltersTests(FactoryTestCase):
         )
         attr.restrictions.max_occurs = 2
         self.assertEqual(
-            'List["A.BossLife"]',
+            'list["A.BossLife"]',
             self.filters.field_type(self.obj_nested_nested_nested, attr),
         )
 
@@ -691,16 +683,11 @@ class FiltersTests(FactoryTestCase):
         attr.restrictions.max_occurs = 2
 
         self.assertEqual(
-            'List[Union["A.B.BossLife", int]]',
+            'list[Union["A.B.BossLife", int]]',
             self.filters.field_type(self.obj_nested_nested_nested, attr),
         )
 
         self.filters.union_type = True
-        self.assertEqual(
-            'List["A.B.BossLife" | int]',
-            self.filters.field_type(self.obj_nested_nested_nested, attr),
-        )
-        self.filters.subscriptable_types = True
         self.assertEqual(
             'list["A.B.BossLife" | int]',
             self.filters.field_type(self.obj_nested_nested_nested, attr),
@@ -709,9 +696,6 @@ class FiltersTests(FactoryTestCase):
     def test_field_type_with_any_attribute(self):
         attr = AttrFactory.any_attribute()
 
-        self.assertEqual("Dict[str, str]", self.filters.field_type(self.obj, attr))
-
-        self.filters.subscriptable_types = True
         self.assertEqual("dict[str, str]", self.filters.field_type(self.obj, attr))
 
         self.filters.generic_collections = True
@@ -756,16 +740,16 @@ class FiltersTests(FactoryTestCase):
             restrictions=Restrictions(min_occurs=0, max_occurs=1),
         )
 
-        expected = "Optional[Union[str, int, List[Decimal]]]"
+        expected = "Optional[Union[str, int, list[Decimal]]]"
         self.assertEqual(expected, self.filters.field_type(self.obj, attr))
 
         attr.restrictions.max_occurs = 2
-        expected = "List[Union[str, int, List[Decimal]]]"
+        expected = "list[Union[str, int, list[Decimal]]]"
         self.assertEqual(expected, self.filters.field_type(self.obj, attr))
 
         attr.restrictions.min_occurs = attr.restrictions.max_occurs = 1
         self.filters.format.kw_only = True
-        expected = "Union[str, int, List[Decimal]]"
+        expected = "Union[str, int, list[Decimal]]"
         self.assertEqual(expected, self.filters.field_type(self.obj, attr))
 
     def test_choice_type(self):
@@ -817,14 +801,13 @@ class FiltersTests(FactoryTestCase):
         choice.restrictions.tokens = True
         target = ClassFactory.create()
         actual = self.filters.choice_type(target, choice)
-        self.assertEqual("Type[List[Union[str, bool]]]", actual)
+        self.assertEqual("Type[list[Union[str, bool]]]", actual)
 
         self.filters.format.frozen = True
         actual = self.filters.choice_type(target, choice)
-        self.assertEqual("Type[Tuple[Union[str, bool], ...]]", actual)
+        self.assertEqual("Type[tuple[Union[str, bool], ...]]", actual)
 
         self.filters.union_type = True
-        self.filters.subscriptable_types = True
         actual = self.filters.choice_type(target, choice)
         self.assertEqual("Type[tuple[str | bool, ...]]", actual)
 
@@ -882,18 +865,6 @@ class FiltersTests(FactoryTestCase):
         self.assertNotIn(expected, self.filters.default_imports("class fooXmlDateTime"))
 
     def test_default_imports_with_typing(self):
-        output = ": Dict["
-        expected = "from typing import Dict"
-        self.assertIn(expected, self.filters.default_imports(output))
-
-        output = ": List["
-        expected = "from typing import List"
-        self.assertIn(expected, self.filters.default_imports(output))
-
-        output = ": Tuple["
-        expected = "from typing import Tuple"
-        self.assertIn(expected, self.filters.default_imports(output))
-
         output = "Optional[ "
         expected = "from typing import Optional"
         self.assertIn(expected, self.filters.default_imports(output))
diff --git a/tests/formats/dataclass/test_typing.py b/tests/formats/dataclass/test_typing.py
index ea0d8fac..5832e912 100644
--- a/tests/formats/dataclass/test_typing.py
+++ b/tests/formats/dataclass/test_typing.py
@@ -1,5 +1,3 @@
-from typing import Type
-
 import pytest
 
 from tests.formats.dataclass.cases import (
@@ -20,11 +18,11 @@ from xsdata.formats.dataclass.typing import (
 
 
 def test_evaluate_with_typevar():
-    result = evaluate(Type["str"], None)
+    result = evaluate(type["str"], None)
     assert result is str
 
     with pytest.raises(TypeError):
-        evaluate(Type, None)
+        evaluate(type["str", "int"], None)
 
 
 @pytest.mark.parametrize("case,expected", attribute.tokens)
diff --git a/tests/formats/test_mixins.py b/tests/formats/test_mixins.py
index 399c735f..1fc884ac 100644
--- a/tests/formats/test_mixins.py
+++ b/tests/formats/test_mixins.py
@@ -1,5 +1,5 @@
 import datetime
-from typing import Iterator, List
+from collections.abc import Iterator
 from unittest import mock
 
 from xsdata import __version__
@@ -11,7 +11,7 @@ from xsdata.utils.testing import ClassFactory, FactoryTestCase
 
 
 class NoneGenerator(AbstractGenerator):
-    def render(self, classes: List[Class]) -> Iterator[GeneratorResult]:
+    def render(self, classes: list[Class]) -> Iterator[GeneratorResult]:
         """Do nothing."""
 
 
diff --git a/tests/models/test_config.py b/tests/models/test_config.py
index 4e68f7ad..16536aba 100644
--- a/tests/models/test_config.py
+++ b/tests/models/test_config.py
@@ -29,7 +29,7 @@ class GeneratorConfigTests(TestCase):
         expected = (
             '<?xml version="1.0" encoding="UTF-8"?>\n'
             f'<Config xmlns="http://pypi.org/project/xsdata" version="{__version__}">\n'
-            '  <Output maxLineLength="79" subscriptableTypes="false" genericCollections="false" unionType="false">\n'
+            '  <Output maxLineLength="79" genericCollections="false" unionType="false">\n'
             "    <Package>generated</Package>\n"
             '    <Format repr="true" eq="true" order="false" unsafeHash="false" frozen="false" slots="false" kwOnly="false">dataclasses</Format>\n'
             "    <Structure>filenames</Structure>\n"
@@ -72,7 +72,7 @@ class GeneratorConfigTests(TestCase):
         existing = (
             '<?xml version="1.0" encoding="UTF-8"?>\n'
             '<Config xmlns="http://pypi.org/project/xsdata" version="20.8">\n'
-            '  <Output maxLineLength="79" subscriptableTypes="false" unionType="false">\n'
+            '  <Output maxLineLength="79" unionType="false">\n'
             "    <Package>foo.bar</Package>\n"
             "  </Output>\n"
             "  <Conventions>\n"
@@ -90,7 +90,7 @@ class GeneratorConfigTests(TestCase):
         expected = (
             '<?xml version="1.0" encoding="UTF-8"?>\n'
             f'<Config xmlns="http://pypi.org/project/xsdata" version="{__version__}">\n'
-            '  <Output maxLineLength="79" subscriptableTypes="false" genericCollections="false" unionType="false">\n'
+            '  <Output maxLineLength="79" genericCollections="false" unionType="false">\n'
             "    <Package>foo.bar</Package>\n"
             '    <Format repr="true" eq="true" order="false" unsafeHash="false"'
             ' frozen="false" slots="false" kwOnly="false">dataclasses</Format>\n'
diff --git a/tests/models/test_datatype.py b/tests/models/test_datatype.py
index e10d2458..bd23a63e 100644
--- a/tests/models/test_datatype.py
+++ b/tests/models/test_datatype.py
@@ -1,11 +1,10 @@
 from datetime import date, datetime, time, timedelta, timezone
-from typing import Dict
 from unittest import TestCase
 
 from xsdata.models.datatype import XmlDate, XmlDateTime, XmlDuration, XmlPeriod, XmlTime
 
 
-def filter_none(mapping: Dict) -> Dict:
+def filter_none(mapping: dict) -> dict:
     return {k: v for k, v in mapping.items() if v is not None}
 
 
diff --git a/tests/models/test_mixins.py b/tests/models/test_mixins.py
index bc72edd8..4b0cce63 100644
--- a/tests/models/test_mixins.py
+++ b/tests/models/test_mixins.py
@@ -1,4 +1,4 @@
-from typing import Generator, Iterator
+from collections.abc import Generator, Iterator
 from unittest import TestCase
 
 from xsdata.codegen.exceptions import CodegenError
diff --git a/tests/models/wsdl/test_definitions.py b/tests/models/wsdl/test_definitions.py
index 6f9fc523..b9127344 100644
--- a/tests/models/wsdl/test_definitions.py
+++ b/tests/models/wsdl/test_definitions.py
@@ -1,5 +1,5 @@
 import copy
-from typing import Generator
+from collections.abc import Generator
 from unittest import TestCase
 
 from xsdata.codegen.exceptions import CodegenError
diff --git a/tests/models/xsd/test_restriction.py b/tests/models/xsd/test_restriction.py
index 8e8aeb23..d6773f78 100644
--- a/tests/models/xsd/test_restriction.py
+++ b/tests/models/xsd/test_restriction.py
@@ -1,4 +1,4 @@
-from typing import Iterator
+from collections.abc import Iterator
 from unittest import TestCase
 
 from xsdata.models.xsd import (
diff --git a/tests/models/xsd/test_schema.py b/tests/models/xsd/test_schema.py
index f574cd26..2fcb2279 100644
--- a/tests/models/xsd/test_schema.py
+++ b/tests/models/xsd/test_schema.py
@@ -1,4 +1,4 @@
-from typing import Iterator
+from collections.abc import Iterator
 from unittest import TestCase
 
 from xsdata.models.enums import Namespace
diff --git a/tests/models/xsd/test_union.py b/tests/models/xsd/test_union.py
index fd036a59..ca5fb08e 100644
--- a/tests/models/xsd/test_union.py
+++ b/tests/models/xsd/test_union.py
@@ -1,4 +1,4 @@
-from typing import Iterator
+from collections.abc import Iterator
 from unittest import TestCase
 
 from xsdata.models.xsd import (
diff --git a/tests/utils/test_collections.py b/tests/utils/test_collections.py
index 2d460a7d..b2e385dd 100644
--- a/tests/utils/test_collections.py
+++ b/tests/utils/test_collections.py
@@ -1,5 +1,5 @@
 from collections import namedtuple
-from typing import Iterator
+from collections.abc import Iterator
 from unittest import TestCase
 
 from xsdata.utils import collections
diff --git a/tests/utils/test_namespaces.py b/tests/utils/test_namespaces.py
index 2c371e29..6537348f 100644
--- a/tests/utils/test_namespaces.py
+++ b/tests/utils/test_namespaces.py
@@ -1,4 +1,3 @@
-from typing import Dict
 from unittest import TestCase
 
 from xsdata.models.enums import Namespace
@@ -19,7 +18,7 @@ from xsdata.utils.namespaces import (
 
 class NamespacesTests(TestCase):
     def test_load_prefix(self):
-        ns_map: Dict = {}
+        ns_map: dict = {}
         self.assertEqual("ns0", load_prefix("a", ns_map))
         self.assertEqual("ns0", load_prefix("a", ns_map))
         self.assertEqual("ns0", load_prefix("a", ns_map))
@@ -34,7 +33,7 @@ class NamespacesTests(TestCase):
         self.assertEqual(expected, ns_map)
 
     def test_generate_prefix(self):
-        ns_map: Dict = {}
+        ns_map: dict = {}
         self.assertEqual("ns0", generate_prefix("a", ns_map))
         self.assertEqual("xs", generate_prefix(Namespace.XS.uri, ns_map))
         self.assertEqual("soapenv", generate_prefix(Namespace.SOAP_ENV.uri, ns_map))
diff --git a/xsdata/utils/testing.py b/xsdata/utils/testing.py
index ea9394b7..d089ee26 100644
--- a/xsdata/utils/testing.py
+++ b/xsdata/utils/testing.py
@@ -3,9 +3,10 @@ import copy
 import importlib
 import random
 import unittest
+from collections.abc import Sequence
 from contextlib import suppress
 from dataclasses import is_dataclass
-from typing import Any, Callable, Dict, List, Optional, Sequence, Type, TypeVar
+from typing import Any, Callable, Optional, TypeVar
 
 from xsdata.codegen.models import (
     Attr,
@@ -82,7 +83,7 @@ class FactoryTestCase(unittest.TestCase):
 
 class Factory(abc.ABC):
     counter = 0
-    model: Type
+    model: type
 
     @classmethod
     @abc.abstractmethod
@@ -99,7 +100,7 @@ class Factory(abc.ABC):
         return chr(cls.counter)
 
     @classmethod
-    def list(cls, number: int, **kwargs: Any) -> List:
+    def list(cls, number: int, **kwargs: Any) -> list:
         return [cls.create(**kwargs) for _ in range(number)]
 
 
@@ -118,11 +119,11 @@ class ClassFactory(Factory):
         abstract: bool = False,
         mixed: bool = False,
         nillable: bool = False,
-        extensions: Optional[List[Extension]] = None,
-        substitutions: Optional[List[str]] = None,
-        attrs: Optional[List[Attr]] = None,
-        inner: Optional[List[Class]] = None,
-        ns_map: Optional[Dict] = None,
+        extensions: Optional[list[Extension]] = None,
+        substitutions: Optional[list[str]] = None,
+        attrs: Optional[list[Attr]] = None,
+        inner: Optional[list[Class]] = None,
+        ns_map: Optional[dict] = None,
         location: str = "tests.xsd",
         package: Optional[str] = None,
         module: Optional[str] = "tests",
@@ -269,8 +270,8 @@ class AttrFactory(Factory):
         cls,
         name: Optional[str] = None,
         index: Optional[int] = None,
-        types: Optional[List[AttrType]] = None,
-        choices: Optional[List[Attr]] = None,
+        types: Optional[list[AttrType]] = None,
+        choices: Optional[list[Attr]] = None,
         tag: Optional[str] = None,
         namespace: Optional[str] = None,
         wrapper: Optional[str] = None,
@@ -388,8 +389,8 @@ class XmlVarFactory(Factory):
         local_name: Optional[str] = None,
         wrapper: Optional[str] = None,
         index: int = 0,
-        types: Optional[Sequence[Type]] = None,
-        clazz: Optional[Type] = None,
+        types: Optional[Sequence[type]] = None,
+        clazz: Optional[type] = None,
         init: bool = True,
         mixed: bool = False,
         factory: Optional[Callable] = None,
@@ -403,7 +404,7 @@ class XmlVarFactory(Factory):
         default: Optional[Any] = None,
         xml_type: str = XmlType.ELEMENT,
         namespaces: Optional[Sequence[str]] = None,
-        elements: Optional[Dict[str, XmlVar]] = None,
+        elements: Optional[dict[str, XmlVar]] = None,
         wildcards: Optional[Sequence[XmlVar]] = None,
         prefix: str = "field_",
         **kwargs: Any,
@@ -454,15 +455,15 @@ class XmlMetaFactory(Factory):
     @classmethod
     def create(  # type: ignore
         cls,
-        clazz: Type,
+        clazz: type,
         qname: Optional[str] = None,
         target_qname: Optional[str] = None,
         nillable: bool = False,
         text: Optional[XmlVar] = None,
         choices: Optional[Sequence[XmlVar]] = None,
-        elements: Optional[Dict[str, Sequence[XmlVar]]] = None,
+        elements: Optional[dict[str, Sequence[XmlVar]]] = None,
         wildcards: Optional[Sequence[XmlVar]] = None,
-        attributes: Optional[Dict[str, XmlVar]] = None,
+        attributes: Optional[dict[str, XmlVar]] = None,
         any_attributes: Optional[Sequence[XmlVar]] = None,
         **kwargs: Any,
     ) -> XmlMeta:
@@ -513,7 +514,7 @@ class DtdAttributeFactory(Factory):
         type: Optional[DtdAttributeType] = None,
         default: Optional[DtdAttributeDefault] = None,
         default_value: Optional[str] = None,
-        values: Optional[List[str]] = None,
+        values: Optional[list[str]] = None,
         **kwargs: Any,
     ) -> DtdAttribute:
         if name is None:
@@ -579,8 +580,8 @@ class DtdElementFactory(Factory):
         prefix: Optional[str] = None,
         type: Optional[DtdElementType] = None,
         content: Optional[DtdContent] = None,
-        attributes: Optional[List[DtdAttribute]] = None,
-        ns_map: Optional[Dict] = None,
+        attributes: Optional[list[DtdAttribute]] = None,
+        ns_map: Optional[dict] = None,
         **kwargs: Any,
     ) -> DtdElement:
         if name is None:
@@ -609,7 +610,7 @@ class DtdFactory(Factory):
     @classmethod
     def create(
         cls,
-        elements: Optional[List[DtdElement]] = None,
+        elements: Optional[list[DtdElement]] = None,
         location: Optional[str] = None,
         **kwargs: Any,
     ) -> Dtd: