-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Keys remember whether to use deprecated syntax #6
Conversation
Heads up Power Team LMS @cpennington @flowerhack @dianakhuang -- this is the start to https://edx-wiki.atlassian.net/browse/LMS-2752 |
@@ -172,7 +175,7 @@ def replace(self, **kwargs): | |||
return type(self)(**existing_values) | |||
|
|||
def __setattr__(self, name, value): | |||
if getattr(self, '_initialized', False): | |||
if name != 'deprecated' and getattr(self, '_initialized', False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we allowing deprecated
to flip after initialization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Globally, |
Pulling in @dmitchell since these changes were originally authored by him. Don, can you look over this and help me respond to comments made? |
wrt
@cpennington I'm not sure I'm following what you intend here - what do you want to handle, and how? |
Heads up that I force-pushed the branch. These changes are now done:
|
def test_hash_equality(self): | ||
self.assertEquals(hash(DummyKey.from_string('hex:0x10')), hash(DummyKey.from_string('hex:0x10'))) | ||
# TODO: These two hash to the same value - is this a feature or a bug? | ||
#self.assertNotEquals(hash(DummyKey.from_string('hex:0x10')), hash(DummyKey.from_string('base10:16'))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was trying to increase test coverage and found that hashing two different keys w/ the same values leads to the same hash. Wanted to know if we consider this a feature (in which case will change this to an assertEquals
) or a bug (in which case I'll change how __hash__
is implemented).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two key objects of the same type with the same values should hash to the same value, so that they can be used in dictionaries as keys in a useful way. Things that compare equal should also hash equal.
Two keys with different implementation types shouldn't hash to the same value, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cpennington thanks, that's what I thought. Right now,
hash(DummyKey.from_string('hex:0x10')) == hash(DummyKey.from_string('base10:16'))
while
DummyKey.from_string('hex:0x10') != DummyKey.from_string('base10:16')
I think the best way to fix the hash method may be to incorporate the CANONICAL_NAMESPACE
into the __hash__
method, as opposed to just using hash(self._key)
. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option would be to include type(self)
in self._key
, and remove the check from __eq__
.
@cpennington @dmitchell @flowerhack @dianakhuang I think this is ready for review |
@@ -184,6 +189,9 @@ def __unicode__(self): | |||
""" | |||
Serialize this :class:`OpaqueKey`, in the form ``<CANONICAL_NAMESPACE>:<value of _to_string>``. | |||
""" | |||
if self.deprecated: | |||
# no namespace on deprecated | |||
return self._to_string() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised we're using _to_string
rather than to_deprecated_string
. By using _to_string
we're requiring the non-deprecated syntax to == the deprecated syntax sans the namespace giving us no flexibility to change serialization syntax. (or does _to_string
also look for the deprecated flag?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I see _to_string()
does consult the deprecated flag; so, this is probably ok, but it's not quite parallel to from_string()
.
Who's removing locators.py, locations.py, & opaque_keys from edx-platform and moving test-locators, test_location to this module? |
and the deprecated key handler registers itself with the base key type LMS-2752
@@ -130,7 +164,7 @@ def _separate_namespace(cls, serialized): | |||
MissingNamespace: Raised when no namespace can be | |||
extracted from `serialized`. | |||
""" | |||
namespace, _, rest = serialized.partition(cls.NAMESPACE_SEPARATOR) | |||
namespace, __, rest = serialized.partition(cls.NAMESPACE_SEPARATOR) | |||
|
|||
# If ':' isn't found in the string, then the source string | |||
# is returned as the first result (i.e. namespace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add a note here that we'd expect this to happen either in the case of (1) a totally borked string, or (2) a deprecated string? Otherwise it's a little confusing, reading through, that deprecated strings would be considered invalid
I think that's my only other comment. Everything else is 👍 |
It wasn't introduced in this PR, but does anyone know the deal with the |
besides that, ⛵ |
@@ -232,7 +285,7 @@ def __lt__(self, other): | |||
return self._key < other._key # pylint: disable=protected-access | |||
|
|||
def __hash__(self): | |||
return hash(self._key) | |||
return hash(self._key) + hash(type(self)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that rather than using +
to add the hashes here, we should include type(self)
in _key
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably at the end of the tuple, so that it's just a tiebreaker for comparisons.
👍 after the hash fix. |
…ed_string parallel constructions
Keys remember whether to use deprecated syntax
and the deprecated key handler registers itself with the base key type
LMS-2752