Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5475253

Browse files
authored
bpo-30977: rework code changes according to post-merge code review (GH-9106)
also mention the change and its consequences in What's New
1 parent1f36bf6 commit5475253

File tree

3 files changed

+146
-68
lines changed

3 files changed

+146
-68
lines changed

‎Doc/whatsnew/3.8.rst‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ Optimizations
131131
objects (e.g. tuple, list, dict) size is reduced 4 or 8 bytes.
132132
(Contributed by Inada Naoki in:issue:`33597`)
133133

134+
*:class:`uuid.UUID` now uses ``__slots__`` to reduce its memory footprint.
135+
Note that this means that instances can no longer be weak-referenced and
136+
that arbitrary attributes can no longer be added to them.
137+
134138

135139
Build and C API Changes
136140
=======================
@@ -275,6 +279,9 @@ Changes in the Python API
275279
* The function:func:`math.factorial` no longer accepts arguments that are not
276280
int-like. (Contributed by Pablo Galindo in:issue:`33083`.)
277281

282+
*:class:`uuid.UUID` now uses ``__slots__``, therefore instances can no longer
283+
be weak-referenced and attributes can no longer be added.
284+
278285

279286
CPython bytecode changes
280287
------------------------

‎Lib/test/test_uuid.py‎

Lines changed: 129 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
fromtestimportsupport
33
importbuiltins
44
importcontextlib
5+
importcopy
6+
fromfunctoolsimportpartial
57
importio
68
importos
79
importpickle
@@ -313,63 +315,139 @@ def test_getnode(self):
313315
node2=self.uuid.getnode()
314316
self.assertEqual(node1,node2,'%012x != %012x'% (node1,node2))
315317

316-
def_setup_for_pickle(self):
317-
orig_uuid=sys.modules.get('uuid')
318-
sys.modules['uuid']=self.uuid
319-
320-
defrestore_uuid_module():
321-
iforig_uuidisnotNone:
322-
sys.modules['uuid']=orig_uuid
323-
else:
324-
delsys.modules['uuid']
325-
self.addCleanup(restore_uuid_module)
326-
327318
deftest_pickle_roundtrip(self):
328-
self._setup_for_pickle()
329-
330-
u=self.uuid.UUID('12345678123456781234567812345678')
331-
self.assertEqual(u,pickle.loads(pickle.dumps(u)))
319+
defcheck(actual,expected):
320+
self.assertEqual(actual,expected)
321+
self.assertEqual(actual.is_safe,expected.is_safe)
322+
323+
withsupport.swap_item(sys.modules,'uuid',self.uuid):
324+
foris_safeinself.uuid.SafeUUID:
325+
u=self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5',
326+
is_safe=is_safe)
327+
check(copy.copy(u),u)
328+
check(copy.deepcopy(u),u)
329+
forprotoinrange(pickle.HIGHEST_PROTOCOL+1):
330+
withself.subTest(protocol=proto):
331+
check(pickle.loads(pickle.dumps(u,proto)),u)
332332

333333
deftest_unpickle_previous_python_versions(self):
334-
self._setup_for_pickle()
335-
336-
u=self.uuid.UUID('12345678123456781234567812345678')
337-
338-
# Python 2.7 protocol 0-2 pickles of u
339-
py27_pickles= [
340-
b'ccopy_reg\n_reconstructor\np0\n(cuuid\nUUID\np1\nc__builtin__\nob'
341-
b'ject\np2\nNtp3\nRp4\n(dp5\nS\'int\'\np6\nL24197857161011715162171'
342-
b'839636988778104L\nsb.',
343-
b'ccopy_reg\n_reconstructor\nq\x00(cuuid\nUUID\nq\x01c__builtin__\n'
344-
b'object\nq\x02Ntq\x03Rq\x04}q\x05U\x03intq\x06L2419785716101171516'
345-
b'2171839636988778104L\nsb.',
346-
b'\x80\x02cuuid\nUUID\nq\x00)\x81q\x01}q\x02U\x03intq\x03\x8a\x10xV'
347-
b'4\x12xV4\x12xV4\x12xV4\x12sb.',
334+
defcheck(actual,expected):
335+
self.assertEqual(actual,expected)
336+
self.assertEqual(actual.is_safe,expected.is_safe)
337+
338+
pickled_uuids= [
339+
# Python 2.7, protocol 0
340+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
341+
b'tR(dS\'int\'\nL287307832597519156748809049798316161701L\nsb.',
342+
# Python 2.7, protocol 1
343+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
344+
b'tR}U\x03intL287307832597519156748809049798316161701L\nsb.',
345+
# Python 2.7, protocol 2
346+
b'\x80\x02cuuid\nUUID\n)\x81}U\x03int\x8a\x11\xa5z\xecz\nI\xdf}'
347+
b'\xde\xa0Bf\xcey%\xd8\x00sb.',
348+
# Python 3.6, protocol 0
349+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
350+
b'tR(dVint\nL287307832597519156748809049798316161701L\nsb.',
351+
# Python 3.6, protocol 1
352+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
353+
b'tR}X\x03\x00\x00\x00intL287307832597519156748809049798316161701L'
354+
b'\nsb.',
355+
# Python 3.6, protocol 2
356+
b'\x80\x02cuuid\nUUID\n)\x81}X\x03\x00\x00\x00int\x8a\x11\xa5z\xec'
357+
b'z\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00sb.',
358+
# Python 3.6, protocol 3
359+
b'\x80\x03cuuid\nUUID\n)\x81}X\x03\x00\x00\x00int\x8a\x11\xa5z\xec'
360+
b'z\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00sb.',
361+
# Python 3.6, protocol 4
362+
b'\x80\x04\x95+\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x8c\x04UUI'
363+
b'D\x93)\x81}\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0Bf\xcey%'
364+
b'\xd8\x00sb.',
365+
# Python 3.7, protocol 0
366+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
367+
b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n'
368+
b'cuuid\nSafeUUID\n(NtRsb.',
369+
# Python 3.7, protocol 1
370+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
371+
b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701'
372+
b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(NtRub.',
373+
# Python 3.7, protocol 2
374+
b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
375+
b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
376+
b'id\nSafeUUID\nN\x85Rub.',
377+
# Python 3.7, protocol 3
378+
b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
379+
b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
380+
b'id\nSafeUUID\nN\x85Rub.',
381+
# Python 3.7, protocol 4
382+
b'\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c'
383+
b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0'
384+
b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93N\x85Rub'
385+
b'.',
386+
]
387+
pickled_uuids_safe= [
388+
# Python 3.7, protocol 0
389+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
390+
b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n'
391+
b'cuuid\nSafeUUID\n(I0\ntRsb.',
392+
# Python 3.7, protocol 1
393+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
394+
b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701'
395+
b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(K\x00tRub.',
396+
# Python 3.7, protocol 2
397+
b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
398+
b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
399+
b'id\nSafeUUID\nK\x00\x85Rub.',
400+
# Python 3.7, protocol 3
401+
b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
402+
b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
403+
b'id\nSafeUUID\nK\x00\x85Rub.',
404+
# Python 3.7, protocol 4
405+
b'\x80\x04\x95G\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c'
406+
b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0'
407+
b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93K\x00'
408+
b'\x85Rub.',
348409
]
349-
# Python 3.6 protocol 0-4 pickles of u
350-
py36_pickles= [
351-
b'ccopy_reg\n_reconstructor\np0\n(cuuid\nUUID\np1\nc__builtin__\nob'
352-
b'ject\np2\nNtp3\nRp4\n(dp5\nVint\np6\nL241978571610117151621718396'
353-
b'36988778104L\nsb.',
354-
b'ccopy_reg\n_reconstructor\nq\x00(cuuid\nUUID\nq\x01c__builtin__\n'
355-
b'object\nq\x02Ntq\x03Rq\x04}q\x05X\x03\x00\x00\x00intq\x06L2419785'
356-
b'7161011715162171839636988778104L\nsb.',
357-
b'\x80\x02cuuid\nUUID\nq\x00)\x81q\x01}q\x02X\x03\x00\x00\x00intq'
358-
b'\x03\x8a\x10xV4\x12xV4\x12xV4\x12xV4\x12sb.',
359-
b'\x80\x03cuuid\nUUID\nq\x00)\x81q\x01}q\x02X\x03\x00\x00\x00intq'
360-
b'\x03\x8a\x10xV4\x12xV4\x12xV4\x12xV4\x12sb.',
361-
b'\x80\x04\x950\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c\x04'
362-
b'UUID\x94\x93\x94)\x81\x94}\x94\x8c\x03int\x94\x8a\x10xV4\x12xV4'
363-
b'\x12xV4\x12xV4\x12sb.',
410+
pickled_uuids_unsafe= [
411+
# Python 3.7, protocol 0
412+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
413+
b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n'
414+
b'cuuid\nSafeUUID\n(I-1\ntRsb.',
415+
# Python 3.7, protocol 1
416+
b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
417+
b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701'
418+
b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(J\xff\xff\xff\xfftR'
419+
b'ub.',
420+
# Python 3.7, protocol 2
421+
b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
422+
b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
423+
b'id\nSafeUUID\nJ\xff\xff\xff\xff\x85Rub.',
424+
# Python 3.7, protocol 3
425+
b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
426+
b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
427+
b'id\nSafeUUID\nJ\xff\xff\xff\xff\x85Rub.',
428+
# Python 3.7, protocol 4
429+
b'\x80\x04\x95J\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c'
430+
b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0'
431+
b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93J\xff'
432+
b'\xff\xff\xff\x85Rub.',
364433
]
365434

366-
forpickledinpy27_pickles+py36_pickles:
367-
unpickled=pickle.loads(pickled)
368-
self.assertEqual(unpickled,u)
369-
# is_safe was added in 3.7. When unpickling values from older
370-
# versions, is_safe will be missing, so it should be set to
371-
# SafeUUID.unknown.
372-
self.assertEqual(unpickled.is_safe,self.uuid.SafeUUID.unknown)
435+
u=self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5')
436+
u_safe=self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5',
437+
is_safe=self.uuid.SafeUUID.safe)
438+
u_unsafe=self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5',
439+
is_safe=self.uuid.SafeUUID.unsafe)
440+
441+
withsupport.swap_item(sys.modules,'uuid',self.uuid):
442+
forpickledinpickled_uuids:
443+
# is_safe was added in 3.7. When unpickling values from older
444+
# versions, is_safe will be missing, so it should be set to
445+
# SafeUUID.unknown.
446+
check(pickle.loads(pickled),u)
447+
forpickledinpickled_uuids_safe:
448+
check(pickle.loads(pickled),u_safe)
449+
forpickledinpickled_uuids_unsafe:
450+
check(pickle.loads(pickled),u_unsafe)
373451

374452
# bpo-32502: UUID1 requires a 48-bit identifier, but hardware identifiers
375453
# need not necessarily be 48 bits (e.g., EUI-64).

‎Lib/uuid.py‎

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -207,26 +207,19 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
207207
object.__setattr__(self,'is_safe',is_safe)
208208

209209
def__getstate__(self):
210-
d= {attr:getattr(self,attr)forattrinself.__slots__}
211-
# is_safe is a SafeUUID instance. Return just its value, so that
212-
# it can be unpickled in older Python versions without SafeUUID.
213-
d['is_safe']=d['is_safe'].value
210+
d= {'int':self.int}
211+
ifself.is_safe!=SafeUUID.unknown:
212+
# is_safe is a SafeUUID instance. Return just its value, so that
213+
# it can be un-pickled in older Python versions without SafeUUID.
214+
d['is_safe']=self.is_safe.value
214215
returnd
215216

216217
def__setstate__(self,state):
217-
# is_safe was added in 3.7
218-
state.setdefault('is_safe',SafeUUID.unknown.value)
219-
220-
forattrinself.__slots__:
221-
value=state[attr]
222-
223-
# for is_safe, restore the SafeUUID from the stored value
224-
ifattr=='is_safe':
225-
try:
226-
value=SafeUUID(value)
227-
exceptValueError:
228-
value=SafeUUID.unknown
229-
object.__setattr__(self,attr,value)
218+
object.__setattr__(self,'int',state['int'])
219+
# is_safe was added in 3.7; it is also omitted when it is "unknown"
220+
object.__setattr__(self,'is_safe',
221+
SafeUUID(state['is_safe'])
222+
if'is_safe'instateelseSafeUUID.unknown)
230223

231224
def__eq__(self,other):
232225
ifisinstance(other,UUID):

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp