| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
| _node = None | ||
|
|
||
| def getnode(): | ||
| def getnode(*, getters=None): |
There was a problem hiding this comment.
I added the getters keyword to make testing work without a bunch of mocks, but in principle it could be used to extend getnode and uuid1 for some other platform. uuid1(node=getnode(getters=[my_ifconfig_parser]))
Sorry, something went wrong.
There was a problem hiding this comment.
I think the change is fine in principle, however this is an API change, so it needs to be documented in the getnode() docstring, and in the uuid.getnode() documentation. Don't forget a versionchanged in the latter. Both docs need to also mention that random UUID generation is always included in the list of getters. Are you okay with not providing a way to override that? (I think I am.)
The API change also needs to be documented in your News file entry.
Changing the API will also make this more difficult to backport, since you can't change the API in any previous version of Python. Are you okay with that (i.e. either not backporting it, or implementing the backport differently)?
Sorry, something went wrong.
There was a problem hiding this comment.
I wasn't sure about whether this counts as an API change or whether this needs to be backported, etc. To sidestep the problems that introduces I removed the API change and changed the approach a bit.
Sorry, something went wrong.
|
I'd like @warsaw to take a look at this since he has recently been in those places. |
Sorry, something went wrong.
| # bpo-32502: UUID1 requires a 48-bit identifier, but hardware identifiers | ||
| # need not necessarily be 48 bits (e.g., EUI-64). | ||
| def test_uuid1_eui64(self): | ||
| # Reset any cached node value |
There was a problem hiding this comment.
Minor style nit: please use complete sentences everywhere (e.g. end them with a period).
Sorry, something went wrong.
|
|
||
| # Confirm that uuid.getnode ignores hardware addresses larger than 48 | ||
| # bits | ||
| bad_getter = lambda: 1 << 48 |
There was a problem hiding this comment.
Why not make this 64 bits? First, it more closely mirrors the failure in the bug, and second, it eliminates a minor cognitive hiccup. IOW, you have to think about any off-by-one possibility. Admittedly, it's minor, but think of the next person reading the code.
Maybe also call the variable too_large_getter or some such?
Sorry, something went wrong.
There was a problem hiding this comment.
I've added some more details in the comment to try to clarify this. 1 << 48, is, of course, 49 bits and not 48. My goal was to test something just outside the bounds of acceptability and not something well past it.
Sorry, something went wrong.
| # bits | ||
| bad_getter = lambda: 1 << 48 | ||
| node = self.uuid.getnode(getters=[bad_getter]) | ||
| self.assertTrue(0 < node < (1 << 48), '%012x' % node) |
There was a problem hiding this comment.
Okay, so why is that assertion going to be true? The reason is that the random UUID generator is always appended to getters, and it's that latter one that will return a valid value. I think you should write a comment above line 323 explaining that, otherwise it could be a bit of a head scratcher for someone just reading the test.
Sorry, something went wrong.
There was a problem hiding this comment.
Quite right. Hopefully my new comment explains this.
Sorry, something went wrong.
| try: | ||
| self.uuid.uuid1(node=node) | ||
| except ValueError as e: | ||
| self.fail('uuid1 was given an invalid node ID') |
There was a problem hiding this comment.
This one is a bit of a head scratcher. Why does the comment mention "only a 64-bit hardware address" but you're passing in node which should be 48 bits? It's not easy to follow the logic, so what's going on here?
Sorry, something went wrong.
There was a problem hiding this comment.
As above, I'm actually passing it in something that's 49 bits, which could happen in a 64-bit address space but not in a 48-bit address space.
Sorry, something went wrong.
There was a problem hiding this comment.
To clarify further: I'm having the "hardware" return a number that's from an address space larger than 48 bits. Running this test against master means that getnode() will return that value and this check will fail. On this branch, getnode() rejects the "hardware" address and properly constraints the value of node.
That is, this check is here to make sure that the patch actually addresses the problem in the bug report, which is that uuid.uuid1() fails.
Sorry, something went wrong.
| _node = None | ||
|
|
||
| def getnode(): | ||
| def getnode(*, getters=None): |
There was a problem hiding this comment.
I think the change is fine in principle, however this is an API change, so it needs to be documented in the getnode() docstring, and in the uuid.getnode() documentation. Don't forget a versionchanged in the latter. Both docs need to also mention that random UUID generation is always included in the list of getters. Are you okay with not providing a way to override that? (I think I am.)
The API change also needs to be documented in your News file entry.
Changing the API will also make this more difficult to backport, since you can't change the API in any previous version of Python. Are you okay with that (i.e. either not backporting it, or implementing the backport differently)?
Sorry, something went wrong.
| if (_node is not None) and (0 <= _node < (1 << 48)): | ||
| return _node | ||
| assert False, '_random_getnode() returned None' | ||
| assert False, '_random_getnode() returned an invalid value' |
There was a problem hiding this comment.
What about including the invalid value in the assertion message? (probably with a .format() call)
This case can't possibly happen but if for some odd reason it does, it would be good to know what the value was. Your test to the conditional means it could be something other than None.
Sorry, something went wrong.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request. |
Sorry, something went wrong.
|
I have made the requested changes; please review again. @warsaw, many thanks for the review. I'll make some comments to your inline notes. |
Sorry, something went wrong.
|
Thanks for making the requested changes! @warsaw: please review the changes made to this pull request. |
Sorry, something went wrong.
There was a problem hiding this comment.
This looks great, thanks for making the changes. I really only have some minor comments left, but I think you're really close to landing this. Thanks for your great contribution!
Sorry, something went wrong.
| # need not necessarily be 48 bits (e.g., EUI-64). | ||
| def test_uuid1_eui64(self): | ||
| # Reset any cached node value. | ||
| self.uuid._node = None |
There was a problem hiding this comment.
Should this restore the cached value after the test is done, or at least ensure that it's set back to None, even if the test fails? (E.g. add a self.addCleanup() or mock the global in this test.
Sorry, something went wrong.
| _node_getters_win32 = [_windll_getnode, _netbios_getnode, _ipconfig_getnode] | ||
|
|
||
| _node_getters_unix = [_unix_getnode, _ifconfig_getnode, _ip_getnode, | ||
| _arp_getnode, _lanscan_getnode, _netstat_getnode] |
There was a problem hiding this comment.
Since these are constants, what do you think about capitalizing their names? E.g. _NODE_GETTERS_WIN32 and _NODE_GETTERS_UNIX (or maybe _NODE_GETTERS_POSIX)?
Sorry, something went wrong.
| if (_node is not None) and (0 <= _node < (1 << 48)): | ||
| return _node | ||
| assert False, '_random_getnode() returned None' | ||
|
|
There was a problem hiding this comment.
Probably don't need that extra blank line.
Sorry, something went wrong.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request. |
Sorry, something went wrong.
|
I have made the requested changes; please review again. @warsaw, many thanks again for the guidance. |
Sorry, something went wrong.
|
Thanks for making the requested changes! @warsaw: please review the changes made to this pull request. |
Sorry, something went wrong.
There was a problem hiding this comment.
Looks awesome, thanks!
Sorry, something went wrong.
|
Sorry, @bbayles and @warsaw, I could not cleanly backport this to 3.6 due to a conflict. |
Sorry, something went wrong.
|
@bbayles Do you want to give the cherry picker script a go? |
Sorry, something went wrong.
pythonGH-5254). (cherry picked from commit 6b273f7)
|
GH-5290 is a backport of this pull request to the 3.6 branch. |
Sorry, something went wrong.
|
@warsaw - I took a shot. I think I followed the directions, but please correct me if I tripped up! |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
This PR adds a fix for bug 32502, which causes uuid.uuid1 to fail when uuid.getnode finds a hardware address that's not 48 bits (e.g., a 64-bit FireWire hardware address).
In this fix I'm simply discarding MAC addresses that appear to be outside of [0, 2^48). This means in principle that an EUI-64 address that doesn't have any high bits set could be accepted, but I think that's (a) OK, and (b) better than the status quo.
I'm also not modifying each of the platform-specific *_getnode functions - just the one that organizes them. If I should patch each of the existing ones I can, but in that case it might make sense to enforce that the *_getnode functions check for 48-bits.
https://bugs.python.org/issue32502