Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
c9409f7c
Commit
c9409f7c
authored
Nov 28, 2017
by
Victor Stinner
Committed by
GitHub
Nov 28, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "bpo-32107 - Better merge of #4494 (#4576)" (#4593)
This reverts commit
9522a218
.
parent
39f0bb5a
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
28 additions
and
93 deletions
+28
-93
Lib/test/test_uuid.py
Lib/test/test_uuid.py
+17
-30
Lib/uuid.py
Lib/uuid.py
+11
-59
Misc/NEWS.d/next/Library/2017-11-26-18-48-17.bpo-32107.h2ph2K.rst
...S.d/next/Library/2017-11-26-18-48-17.bpo-32107.h2ph2K.rst
+0
-4
No files found.
Lib/test/test_uuid.py
View file @
c9409f7c
...
@@ -512,69 +512,60 @@ eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
...
@@ -512,69 +512,60 @@ eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
self
.
assertEqual
(
mac
,
0x1234567890ab
)
self
.
assertEqual
(
mac
,
0x1234567890ab
)
def
check_node
(
self
,
node
,
requires
=
None
,
*
,
check_bit
=
Tru
e
):
def
check_node
(
self
,
node
,
requires
=
None
,
network
=
Fals
e
):
if
requires
and
node
is
None
:
if
requires
and
node
is
None
:
self
.
skipTest
(
'requires '
+
requires
)
self
.
skipTest
(
'requires '
+
requires
)
hex
=
'%012x'
%
node
hex
=
'%012x'
%
node
if
support
.
verbose
>=
2
:
if
support
.
verbose
>=
2
:
print
(
hex
,
end
=
' '
)
print
(
hex
,
end
=
' '
)
# The MAC address will be universally administered (i.e. the second
if
network
:
# least significant bit of the first octet must be unset) for any
# 47 bit will never be set in IEEE 802 addresses obtained
# physical interface, such as an ethernet port or wireless adapter.
# from network cards.
# There are some cases where this won't be the case. Randomly
self
.
assertFalse
(
node
&
0x010000000000
,
hex
)
# generated MACs may not be universally administered, but they must
# have their multicast bit set, though this is tested in the
# `test_random_getnode()` method specifically. Another case is the
# Travis-CI case, which apparently only has locally administered MAC
# addresses.
if
check_bit
and
not
os
.
getenv
(
'TRAVIS'
):
self
.
assertFalse
(
node
&
(
1
<<
41
),
'%012x'
%
node
)
self
.
assertTrue
(
0
<
node
<
(
1
<<
48
),
self
.
assertTrue
(
0
<
node
<
(
1
<<
48
),
"%s is not an RFC 4122 node ID"
%
hex
)
"%s is not an RFC 4122 node ID"
%
hex
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
def
test_ifconfig_getnode
(
self
):
def
test_ifconfig_getnode
(
self
):
node
=
self
.
uuid
.
_ifconfig_getnode
()
node
=
self
.
uuid
.
_ifconfig_getnode
()
self
.
check_node
(
node
,
'ifconfig'
)
self
.
check_node
(
node
,
'ifconfig'
,
True
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
def
test_ip_getnode
(
self
):
def
test_ip_getnode
(
self
):
node
=
self
.
uuid
.
_ip_getnode
()
node
=
self
.
uuid
.
_ip_getnode
()
self
.
check_node
(
node
,
'ip'
)
self
.
check_node
(
node
,
'ip'
,
True
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
def
test_arp_getnode
(
self
):
def
test_arp_getnode
(
self
):
node
=
self
.
uuid
.
_arp_getnode
()
node
=
self
.
uuid
.
_arp_getnode
()
self
.
check_node
(
node
,
'arp'
)
self
.
check_node
(
node
,
'arp'
,
True
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
def
test_lanscan_getnode
(
self
):
def
test_lanscan_getnode
(
self
):
node
=
self
.
uuid
.
_lanscan_getnode
()
node
=
self
.
uuid
.
_lanscan_getnode
()
self
.
check_node
(
node
,
'lanscan'
)
self
.
check_node
(
node
,
'lanscan'
,
True
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
def
test_netstat_getnode
(
self
):
def
test_netstat_getnode
(
self
):
node
=
self
.
uuid
.
_netstat_getnode
()
node
=
self
.
uuid
.
_netstat_getnode
()
self
.
check_node
(
node
,
'netstat'
)
self
.
check_node
(
node
,
'netstat'
,
True
)
@
unittest
.
skipUnless
(
os
.
name
==
'nt'
,
'requires Windows'
)
@
unittest
.
skipUnless
(
os
.
name
==
'nt'
,
'requires Windows'
)
def
test_ipconfig_getnode
(
self
):
def
test_ipconfig_getnode
(
self
):
node
=
self
.
uuid
.
_ipconfig_getnode
()
node
=
self
.
uuid
.
_ipconfig_getnode
()
self
.
check_node
(
node
,
'ipconfig'
)
self
.
check_node
(
node
,
'ipconfig'
,
True
)
@
unittest
.
skipUnless
(
importable
(
'win32wnet'
),
'requires win32wnet'
)
@
unittest
.
skipUnless
(
importable
(
'win32wnet'
),
'requires win32wnet'
)
@
unittest
.
skipUnless
(
importable
(
'netbios'
),
'requires netbios'
)
@
unittest
.
skipUnless
(
importable
(
'netbios'
),
'requires netbios'
)
def
test_netbios_getnode
(
self
):
def
test_netbios_getnode
(
self
):
node
=
self
.
uuid
.
_netbios_getnode
()
node
=
self
.
uuid
.
_netbios_getnode
()
self
.
check_node
(
node
)
self
.
check_node
(
node
,
network
=
True
)
def
test_random_getnode
(
self
):
def
test_random_getnode
(
self
):
node
=
self
.
uuid
.
_random_getnode
()
node
=
self
.
uuid
.
_random_getnode
()
# The multicast bit, i.e. the least significant bit of first octet,
# Least significant bit of first octet must be set.
# must be set for randomly generated MAC addresses. See RFC 4122,
self
.
assertTrue
(
node
&
0x010000000000
,
'%012x'
%
node
)
# $4.1.6.
self
.
check_node
(
node
)
self
.
assertTrue
(
node
&
(
1
<<
40
),
'%012x'
%
node
)
self
.
check_node
(
node
,
check_bit
=
False
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
@
unittest
.
skipUnless
(
os
.
name
==
'posix'
,
'requires Posix'
)
def
test_unix_getnode
(
self
):
def
test_unix_getnode
(
self
):
...
@@ -584,17 +575,13 @@ eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
...
@@ -584,17 +575,13 @@ eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
node
=
self
.
uuid
.
_unix_getnode
()
node
=
self
.
uuid
.
_unix_getnode
()
except
TypeError
:
except
TypeError
:
self
.
skipTest
(
'requires uuid_generate_time'
)
self
.
skipTest
(
'requires uuid_generate_time'
)
# Since we don't know the provenance of the MAC address, don't check
self
.
check_node
(
node
,
'unix'
)
# whether it is locally or universally administered.
self
.
check_node
(
node
,
'unix'
,
check_bit
=
False
)
@
unittest
.
skipUnless
(
os
.
name
==
'nt'
,
'requires Windows'
)
@
unittest
.
skipUnless
(
os
.
name
==
'nt'
,
'requires Windows'
)
@
unittest
.
skipUnless
(
importable
(
'ctypes'
),
'requires ctypes'
)
@
unittest
.
skipUnless
(
importable
(
'ctypes'
),
'requires ctypes'
)
def
test_windll_getnode
(
self
):
def
test_windll_getnode
(
self
):
node
=
self
.
uuid
.
_windll_getnode
()
node
=
self
.
uuid
.
_windll_getnode
()
# Since we don't know the provenance of the MAC address, don't check
self
.
check_node
(
node
)
# whether it is locally or universally administered.
self
.
check_node
(
node
,
check_bit
=
False
)
class
TestInternalsWithoutExtModule
(
BaseTestInternals
,
unittest
.
TestCase
):
class
TestInternalsWithoutExtModule
(
BaseTestInternals
,
unittest
.
TestCase
):
...
...
Lib/uuid.py
View file @
c9409f7c
...
@@ -342,29 +342,11 @@ def _popen(command, *args):
...
@@ -342,29 +342,11 @@ def _popen(command, *args):
env
=
env
)
env
=
env
)
return
proc
return
proc
# For MAC (a.k.a. IEEE 802, or EUI-48) addresses, the second least significant
# bit of the first octet signifies whether the MAC address is universally (0)
# or locally (1) administered. Network cards from hardware manufacturers will
# always be universally administered to guarantee global uniqueness of the MAC
# address, but any particular machine may have other interfaces which are
# locally administered. An example of the latter is the bridge interface to
# the Touch Bar on MacBook Pros.
#
# This bit works out to be the 42nd bit counting from 1 being the least
# significant, or 1<<41. We'll skip over any locally administered MAC
# addresses, as it makes no sense to use those in UUID calculation.
#
# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
def
_is_universal
(
mac
):
return
not
(
mac
&
(
1
<<
41
))
def
_find_mac
(
command
,
args
,
hw_identifiers
,
get_index
):
def
_find_mac
(
command
,
args
,
hw_identifiers
,
get_index
):
first_local_mac
=
None
try
:
try
:
proc
=
_popen
(
command
,
*
args
.
split
())
proc
=
_popen
(
command
,
*
args
.
split
())
if
not
proc
:
if
not
proc
:
return
None
return
with
proc
:
with
proc
:
for
line
in
proc
.
stdout
:
for
line
in
proc
.
stdout
:
words
=
line
.
lower
().
rstrip
().
split
()
words
=
line
.
lower
().
rstrip
().
split
()
...
@@ -373,9 +355,8 @@ def _find_mac(command, args, hw_identifiers, get_index):
...
@@ -373,9 +355,8 @@ def _find_mac(command, args, hw_identifiers, get_index):
try
:
try
:
word
=
words
[
get_index
(
i
)]
word
=
words
[
get_index
(
i
)]
mac
=
int
(
word
.
replace
(
b':'
,
b''
),
16
)
mac
=
int
(
word
.
replace
(
b':'
,
b''
),
16
)
if
_is_universal
(
mac
)
:
if
mac
:
return
mac
return
mac
first_local_mac
=
first_local_mac
or
mac
except
(
ValueError
,
IndexError
):
except
(
ValueError
,
IndexError
):
# Virtual interfaces, such as those provided by
# Virtual interfaces, such as those provided by
# VPNs, do not have a colon-delimited MAC address
# VPNs, do not have a colon-delimited MAC address
...
@@ -385,7 +366,6 @@ def _find_mac(command, args, hw_identifiers, get_index):
...
@@ -385,7 +366,6 @@ def _find_mac(command, args, hw_identifiers, get_index):
pass
pass
except
OSError
:
except
OSError
:
pass
pass
return
first_local_mac
or
None
def
_ifconfig_getnode
():
def
_ifconfig_getnode
():
"""Get the hardware address on Unix by running ifconfig."""
"""Get the hardware address on Unix by running ifconfig."""
...
@@ -395,7 +375,6 @@ def _ifconfig_getnode():
...
@@ -395,7 +375,6 @@ def _ifconfig_getnode():
mac
=
_find_mac
(
'ifconfig'
,
args
,
keywords
,
lambda
i
:
i
+
1
)
mac
=
_find_mac
(
'ifconfig'
,
args
,
keywords
,
lambda
i
:
i
+
1
)
if
mac
:
if
mac
:
return
mac
return
mac
return
None
def
_ip_getnode
():
def
_ip_getnode
():
"""Get the hardware address on Unix by running ip."""
"""Get the hardware address on Unix by running ip."""
...
@@ -403,7 +382,6 @@ def _ip_getnode():
...
@@ -403,7 +382,6 @@ def _ip_getnode():
mac
=
_find_mac
(
'ip'
,
'link list'
,
[
b'link/ether'
],
lambda
i
:
i
+
1
)
mac
=
_find_mac
(
'ip'
,
'link list'
,
[
b'link/ether'
],
lambda
i
:
i
+
1
)
if
mac
:
if
mac
:
return
mac
return
mac
return
None
def
_arp_getnode
():
def
_arp_getnode
():
"""Get the hardware address on Unix by running arp."""
"""Get the hardware address on Unix by running arp."""
...
@@ -426,10 +404,8 @@ def _arp_getnode():
...
@@ -426,10 +404,8 @@ def _arp_getnode():
# This works on Linux, FreeBSD and NetBSD
# This works on Linux, FreeBSD and NetBSD
mac
=
_find_mac
(
'arp'
,
'-an'
,
[
os
.
fsencode
(
'(%s)'
%
ip_addr
)],
mac
=
_find_mac
(
'arp'
,
'-an'
,
[
os
.
fsencode
(
'(%s)'
%
ip_addr
)],
lambda
i
:
i
+
2
)
lambda
i
:
i
+
2
)
# Return None instead of 0.
if
mac
:
if
mac
:
return
mac
return
mac
return
None
def
_lanscan_getnode
():
def
_lanscan_getnode
():
"""Get the hardware address on Unix by running lanscan."""
"""Get the hardware address on Unix by running lanscan."""
...
@@ -439,36 +415,32 @@ def _lanscan_getnode():
...
@@ -439,36 +415,32 @@ def _lanscan_getnode():
def
_netstat_getnode
():
def
_netstat_getnode
():
"""Get the hardware address on Unix by running netstat."""
"""Get the hardware address on Unix by running netstat."""
# This might work on AIX, Tru64 UNIX.
# This might work on AIX, Tru64 UNIX.
first_local_mac
=
None
try
:
try
:
proc
=
_popen
(
'netstat'
,
'-ia'
)
proc
=
_popen
(
'netstat'
,
'-ia'
)
if
not
proc
:
if
not
proc
:
return
None
return
with
proc
:
with
proc
:
words
=
proc
.
stdout
.
readline
().
rstrip
().
split
()
words
=
proc
.
stdout
.
readline
().
rstrip
().
split
()
try
:
try
:
i
=
words
.
index
(
b'Address'
)
i
=
words
.
index
(
b'Address'
)
except
ValueError
:
except
ValueError
:
return
None
return
for
line
in
proc
.
stdout
:
for
line
in
proc
.
stdout
:
try
:
try
:
words
=
line
.
rstrip
().
split
()
words
=
line
.
rstrip
().
split
()
word
=
words
[
i
]
word
=
words
[
i
]
if
len
(
word
)
==
17
and
word
.
count
(
b':'
)
==
5
:
if
len
(
word
)
==
17
and
word
.
count
(
b':'
)
==
5
:
mac
=
int
(
word
.
replace
(
b':'
,
b''
),
16
)
mac
=
int
(
word
.
replace
(
b':'
,
b''
),
16
)
if
_is_universal
(
mac
)
:
if
mac
:
return
mac
return
mac
first_local_mac
=
first_local_mac
or
mac
except
(
ValueError
,
IndexError
):
except
(
ValueError
,
IndexError
):
pass
pass
except
OSError
:
except
OSError
:
pass
pass
return
first_local_mac
or
None
def
_ipconfig_getnode
():
def
_ipconfig_getnode
():
"""Get the hardware address on Windows by running ipconfig.exe."""
"""Get the hardware address on Windows by running ipconfig.exe."""
import
os
,
re
import
os
,
re
first_local_mac
=
None
dirs
=
[
''
,
r'c:\
wi
ndows\
sys
tem32'
,
r'c:\
wi
nnt\
sys
tem32'
]
dirs
=
[
''
,
r'c:\
wi
ndows\
sys
tem32'
,
r'c:\
wi
nnt\
sys
tem32'
]
try
:
try
:
import
ctypes
import
ctypes
...
@@ -486,23 +458,18 @@ def _ipconfig_getnode():
...
@@ -486,23 +458,18 @@ def _ipconfig_getnode():
for
line
in
pipe
:
for
line
in
pipe
:
value
=
line
.
split
(
':'
)[
-
1
].
strip
().
lower
()
value
=
line
.
split
(
':'
)[
-
1
].
strip
().
lower
()
if
re
.
match
(
'([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]'
,
value
):
if
re
.
match
(
'([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]'
,
value
):
mac
=
int
(
value
.
replace
(
'-'
,
''
),
16
)
return
int
(
value
.
replace
(
'-'
,
''
),
16
)
if
_is_universal
(
mac
):
return
mac
first_local_mac
=
first_local_mac
or
mac
return
first_local_mac
or
None
def
_netbios_getnode
():
def
_netbios_getnode
():
"""Get the hardware address on Windows using NetBIOS calls.
"""Get the hardware address on Windows using NetBIOS calls.
See http://support.microsoft.com/kb/118623 for details."""
See http://support.microsoft.com/kb/118623 for details."""
import
win32wnet
,
netbios
import
win32wnet
,
netbios
first_local_mac
=
None
ncb
=
netbios
.
NCB
()
ncb
=
netbios
.
NCB
()
ncb
.
Command
=
netbios
.
NCBENUM
ncb
.
Command
=
netbios
.
NCBENUM
ncb
.
Buffer
=
adapters
=
netbios
.
LANA_ENUM
()
ncb
.
Buffer
=
adapters
=
netbios
.
LANA_ENUM
()
adapters
.
_pack
()
adapters
.
_pack
()
if
win32wnet
.
Netbios
(
ncb
)
!=
0
:
if
win32wnet
.
Netbios
(
ncb
)
!=
0
:
return
None
return
adapters
.
_unpack
()
adapters
.
_unpack
()
for
i
in
range
(
adapters
.
length
):
for
i
in
range
(
adapters
.
length
):
ncb
.
Reset
()
ncb
.
Reset
()
...
@@ -521,11 +488,7 @@ def _netbios_getnode():
...
@@ -521,11 +488,7 @@ def _netbios_getnode():
bytes
=
status
.
adapter_address
[:
6
]
bytes
=
status
.
adapter_address
[:
6
]
if
len
(
bytes
)
!=
6
:
if
len
(
bytes
)
!=
6
:
continue
continue
mac
=
int
.
from_bytes
(
bytes
,
'big'
)
return
int
.
from_bytes
(
bytes
,
'big'
)
if
_is_universal
(
mac
):
return
mac
first_local_mac
=
first_local_mac
or
mac
return
first_local_mac
or
None
_generate_time_safe
=
_UuidCreate
=
None
_generate_time_safe
=
_UuidCreate
=
None
...
@@ -638,19 +601,9 @@ def _windll_getnode():
...
@@ -638,19 +601,9 @@ def _windll_getnode():
return
UUID
(
bytes
=
bytes_
(
_buffer
.
raw
)).
node
return
UUID
(
bytes
=
bytes_
(
_buffer
.
raw
)).
node
def
_random_getnode
():
def
_random_getnode
():
"""Get a random node ID."""
"""Get a random node ID, with eighth bit set as suggested by RFC 4122."""
# RFC 4122, $4.1.6 says "For systems with no IEEE address, a randomly or
# pseudo-randomly generated value may be used; see Section 4.5. The
# multicast bit must be set in such addresses, in order that they will
# never conflict with addresses obtained from network cards."
#
# The "multicast bit" of a MAC address is defined to be "the least
# significant bit of the first octet". This works out to be the 41st bit
# counting from 1 being the least significant bit, or 1<<40.
#
# See https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
import
random
import
random
return
random
.
getrandbits
(
48
)
|
(
1
<<
40
)
return
random
.
getrandbits
(
48
)
|
0x010000000000
_node
=
None
_node
=
None
...
@@ -673,14 +626,13 @@ def getnode():
...
@@ -673,14 +626,13 @@ def getnode():
getters
=
[
_unix_getnode
,
_ifconfig_getnode
,
_ip_getnode
,
getters
=
[
_unix_getnode
,
_ifconfig_getnode
,
_ip_getnode
,
_arp_getnode
,
_lanscan_getnode
,
_netstat_getnode
]
_arp_getnode
,
_lanscan_getnode
,
_netstat_getnode
]
for
getter
in
getters
:
for
getter
in
getters
+
[
_random_getnode
]
:
try
:
try
:
_node
=
getter
()
_node
=
getter
()
except
:
except
:
continue
continue
if
_node
is
not
None
:
if
_node
is
not
None
:
return
_node
return
_node
return
_random_getnode
()
_last_timestamp
=
None
_last_timestamp
=
None
...
...
Misc/NEWS.d/next/Library/2017-11-26-18-48-17.bpo-32107.h2ph2K.rst
deleted
100644 → 0
View file @
39f0bb5a
Improve the private ``*_getnode()`` methods for UUID1 such that universally
administered MAC addresses are preferred over locally administered MAC
addresses. If only the latter is available, the first such one is returned.
Improve the related tests and fix some bugs there as well.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment