|
24 | 24 | PY_3_10_PLUS, |
25 | 25 | PY_3_11_PLUS, |
26 | 26 | PY_3_13_PLUS, |
| 27 | + PY_3_14_PLUS, |
27 | 28 | _AnnotationExtractor, |
28 | 29 | _get_annotations, |
29 | 30 | get_generic_base, |
@@ -618,6 +619,17 @@ def evolve(*args, **changes): |
618 | 619 | return cls(**changes) |
619 | 620 |
|
620 | 621 |
|
| 622 | +# Hack to the get the underlying dict out of a mappingproxy |
| 623 | +# Use it with: cls.__dict__ | _deproxier |
| 624 | +# See: https://github.com/python/cpython/pull/136893 |
| 625 | +class _Deproxier: |
| 626 | + def __ror__(self, other): |
| 627 | + return other |
| 628 | + |
| 629 | + |
| 630 | +_deproxier = _Deproxier() |
| 631 | + |
| 632 | + |
621 | 633 | class _ClassBuilder: |
622 | 634 | """ |
623 | 635 | Iteratively build *one* class. |
@@ -845,6 +857,20 @@ def _create_slots_class(self): |
845 | 857 | if k not in (*tuple(self._attr_names), "__dict__", "__weakref__") |
846 | 858 | } |
847 | 859 |
|
| 860 | + if PY_3_14_PLUS: |
| 861 | + # Clean up old dict to avoid leaks. |
| 862 | + old_cls_dict = self._cls.__dict__ | _deproxier |
| 863 | + old_cls_dict.pop("__dict__", None) |
| 864 | + if "__weakref__" in self._cls.__dict__: |
| 865 | + del self._cls.__weakref__ |
| 866 | + |
| 867 | + # Manually bump internal version tag. |
| 868 | + try: |
| 869 | + self._cls.__abstractmethods__ = self._cls.__abstractmethods__ |
| 870 | + except AttributeError: |
| 871 | + self._cls.__abstractmethods__ = frozenset({"__init__"}) |
| 872 | + del self._cls.__abstractmethods__ |
| 873 | + |
848 | 874 | # If our class doesn't have its own implementation of __setattr__ |
849 | 875 | # (either from the user or by us), check the bases, if one of them has |
850 | 876 | # an attrs-made __setattr__, that needs to be reset. We don't walk the |
|
0 commit comments