Skip to content

Commit 95fc77b

Browse files
committed
Address review
2 parents 37b2388 + c68acb1 commit 95fc77b

File tree

13 files changed

+156
-1315
lines changed

13 files changed

+156
-1315
lines changed

Doc/library/email.utils.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ module:
1717
arguments, return current time. Otherwise *dt* argument should be a
1818
:class:`~datetime.datetime` instance, and it is converted to the local time
1919
zone according to the system time zone database. If *dt* is naive (that
20-
is, ``dt.tzinfo`` is ``None``), it is assumed to be in local time. The
21-
*isdst* parameter is ignored.
20+
is, ``dt.tzinfo`` is ``None``), it is assumed to be in local time.
2221

2322
.. versionadded:: 3.3
2423

Doc/whatsnew/3.14.rst

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,21 @@ Deprecated
101101
Removed
102102
=======
103103

104+
email
105+
-----
106+
107+
* The *isdst* parameter has been removed from :func:`email.utils.localtime`.
108+
(Contributed by Hugo van Kemenade in :gh:`118798`.)
109+
110+
pty
111+
___
112+
113+
* Remove deprecated ``pty.master_open`` and ``pty.slave_open``.
114+
They had previously raised a :exc:`DeprecationWarning` since Python 3.12.
115+
116+
Others
117+
------
118+
104119
* Using :data:`NotImplemented` in a boolean context will now raise a :exc:`TypeError`.
105120
It had previously raised a :exc:`DeprecationWarning` since Python 3.9. (Contributed
106121
by Jelle Zijlstra in :gh:`118767`.)
@@ -109,8 +124,10 @@ Removed
109124
are removed. They had previously raised a :exc:`DeprecationWarning`
110125
since Python 3.12.
111126

112-
* Remove deprecated ``pty.master_open`` and ``pty.slave_open``.
113-
They had previously raised a :exc:`DeprecationWarning` since Python 3.12.
127+
* :mod:`itertools` support for copy, deepcopy, and pickle operations.
128+
These had previously raised a :exc:`DeprecationWarning` since Python 3.12.
129+
(Contributed by Raymond Hettinger in :gh:`101588`.)
130+
114131

115132
Porting to Python 3.14
116133
======================

Lib/dataclasses.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,10 +1199,17 @@ def _dataclass_setstate(self, state):
11991199

12001200
def _get_slots(cls):
12011201
match cls.__dict__.get('__slots__'):
1202-
# A class which does not define __slots__ at all is equivalent
1203-
# to a class defining __slots__ = ('__dict__', '__weakref__')
1202+
# `__dictoffset__` and `__weakrefoffset__` can tell us whether
1203+
# the base type has dict/weakref slots, in a way that works correctly
1204+
# for both Python classes and C extension types. Extension types
1205+
# don't use `__slots__` for slot creation
12041206
case None:
1205-
yield from ('__dict__', '__weakref__')
1207+
slots = []
1208+
if getattr(cls, '__weakrefoffset__', -1) != 0:
1209+
slots.append('__weakref__')
1210+
if getattr(cls, '__dictrefoffset__', -1) != 0:
1211+
slots.append('__dict__')
1212+
yield from slots
12061213
case str(slot):
12071214
yield slot
12081215
# Slots may be any iterable, but we cannot handle an iterator

Lib/email/utils.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -466,23 +466,15 @@ def collapse_rfc2231_value(value, errors='replace',
466466
# better than not having it.
467467
#
468468

469-
def localtime(dt=None, isdst=None):
469+
def localtime(dt=None):
470470
"""Return local time as an aware datetime object.
471471
472472
If called without arguments, return current time. Otherwise *dt*
473473
argument should be a datetime instance, and it is converted to the
474474
local time zone according to the system time zone database. If *dt* is
475475
naive (that is, dt.tzinfo is None), it is assumed to be in local time.
476-
The isdst parameter is ignored.
477476
478477
"""
479-
if isdst is not None:
480-
import warnings
481-
warnings._deprecated(
482-
"The 'isdst' parameter to 'localtime'",
483-
message='{name} is deprecated and slated for removal in Python {remove}',
484-
remove=(3, 14),
485-
)
486478
if dt is None:
487479
dt = datetime.datetime.now()
488480
return dt.astimezone()

Lib/pty.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,17 @@ def openpty():
3232
except (AttributeError, OSError):
3333
pass
3434
master_fd, slave_name = _open_terminal()
35-
slave_fd = slave_open(slave_name)
35+
36+
slave_fd = os.open(slave_name, os.O_RDWR)
37+
try:
38+
from fcntl import ioctl, I_PUSH
39+
except ImportError:
40+
return master_fd, slave_fd
41+
try:
42+
ioctl(result, I_PUSH, "ptem")
43+
ioctl(result, I_PUSH, "ldterm")
44+
except OSError:
45+
pass
3646
return master_fd, slave_fd
3747

3848
def _open_terminal():

Lib/test/test_dataclasses/__init__.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3515,8 +3515,114 @@ class A:
35153515
class B(A):
35163516
pass
35173517

3518+
self.assertEqual(B.__slots__, ())
35183519
B()
35193520

3521+
def test_dataclass_derived_generic(self):
3522+
T = typing.TypeVar('T')
3523+
3524+
@dataclass(slots=True, weakref_slot=True)
3525+
class A(typing.Generic[T]):
3526+
pass
3527+
self.assertEqual(A.__slots__, ('__weakref__',))
3528+
self.assertTrue(A.__weakref__)
3529+
A()
3530+
3531+
@dataclass(slots=True, weakref_slot=True)
3532+
class B[T2]:
3533+
pass
3534+
self.assertEqual(B.__slots__, ('__weakref__',))
3535+
self.assertTrue(B.__weakref__)
3536+
B()
3537+
3538+
def test_dataclass_derived_generic_from_base(self):
3539+
T = typing.TypeVar('T')
3540+
3541+
class RawBase: ...
3542+
3543+
@dataclass(slots=True, weakref_slot=True)
3544+
class C1(typing.Generic[T], RawBase):
3545+
pass
3546+
self.assertEqual(C1.__slots__, ())
3547+
self.assertTrue(C1.__weakref__)
3548+
C1()
3549+
@dataclass(slots=True, weakref_slot=True)
3550+
class C2(RawBase, typing.Generic[T]):
3551+
pass
3552+
self.assertEqual(C2.__slots__, ())
3553+
self.assertTrue(C2.__weakref__)
3554+
C2()
3555+
3556+
@dataclass(slots=True, weakref_slot=True)
3557+
class D[T2](RawBase):
3558+
pass
3559+
self.assertEqual(D.__slots__, ())
3560+
self.assertTrue(D.__weakref__)
3561+
D()
3562+
3563+
def test_dataclass_derived_generic_from_slotted_base(self):
3564+
T = typing.TypeVar('T')
3565+
3566+
class WithSlots:
3567+
__slots__ = ('a', 'b')
3568+
3569+
@dataclass(slots=True, weakref_slot=True)
3570+
class E1(WithSlots, Generic[T]):
3571+
pass
3572+
self.assertEqual(E1.__slots__, ('__weakref__',))
3573+
self.assertTrue(E1.__weakref__)
3574+
E1()
3575+
@dataclass(slots=True, weakref_slot=True)
3576+
class E2(Generic[T], WithSlots):
3577+
pass
3578+
self.assertEqual(E2.__slots__, ('__weakref__',))
3579+
self.assertTrue(E2.__weakref__)
3580+
E2()
3581+
3582+
@dataclass(slots=True, weakref_slot=True)
3583+
class F[T2](WithSlots):
3584+
pass
3585+
self.assertEqual(F.__slots__, ('__weakref__',))
3586+
self.assertTrue(F.__weakref__)
3587+
F()
3588+
3589+
def test_dataclass_derived_generic_from_slotted_base(self):
3590+
T = typing.TypeVar('T')
3591+
3592+
class WithWeakrefSlot:
3593+
__slots__ = ('__weakref__',)
3594+
3595+
@dataclass(slots=True, weakref_slot=True)
3596+
class G1(WithWeakrefSlot, Generic[T]):
3597+
pass
3598+
self.assertEqual(G1.__slots__, ())
3599+
self.assertTrue(G1.__weakref__)
3600+
G1()
3601+
@dataclass(slots=True, weakref_slot=True)
3602+
class G2(Generic[T], WithWeakrefSlot):
3603+
pass
3604+
self.assertEqual(G2.__slots__, ())
3605+
self.assertTrue(G2.__weakref__)
3606+
G2()
3607+
3608+
@dataclass(slots=True, weakref_slot=True)
3609+
class H[T2](WithWeakrefSlot):
3610+
pass
3611+
self.assertEqual(H.__slots__, ())
3612+
self.assertTrue(H.__weakref__)
3613+
H()
3614+
3615+
def test_dataclass_slot_dict(self):
3616+
class WithDictSlot:
3617+
__slots__ = ('__dict__',)
3618+
3619+
@dataclass(slots=True)
3620+
class A(WithDictSlot): ...
3621+
3622+
self.assertEqual(A.__slots__, ())
3623+
self.assertEqual(A().__dict__, {})
3624+
A()
3625+
35203626

35213627
class TestDescriptors(unittest.TestCase):
35223628
def test_set_name(self):

Lib/test/test_email/test_utils.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,6 @@ def test_variable_tzname(self):
154154
t1 = utils.localtime(t0)
155155
self.assertEqual(t1.tzname(), 'EET')
156156

157-
def test_isdst_deprecation(self):
158-
with self.assertWarns(DeprecationWarning):
159-
t0 = datetime.datetime(1990, 1, 1)
160-
t1 = utils.localtime(t0, isdst=True)
161157

162158
# Issue #24836: The timezone files are out of date (pre 2011k)
163159
# on Mac OS X Snow Leopard.

0 commit comments

Comments
 (0)