Skip to content
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

Ensure that underlying value of enum key is used by BaseCache._build_key() across Python versions #633

Closed
padraic-shafer opened this issue Jan 10, 2023 · 3 comments · Fixed by #635

Comments

@padraic-shafer
Copy link
Contributor

padraic-shafer commented Jan 10, 2023

Key builders and tests currently cast key values (notably Enum values) to str to maintain compatibility with Python 3.11 and older versions. This requirement can be eliminated by using f-strings rather than str.__format__.

EDIT: Whoops, that erroneous statement was based on testing in the wrong python environment. Instead of using str(), perhaps we should use a simple guard that check for an enum key. Something like:

def ensure_key(key):
    if isinstance(key, Enum):
        return key.value
    else:
        return key
@padraic-shafer padraic-shafer changed the title f-string removes need to cast to str for 3.11 compatibility Ensure that underlying value of enum key is used by BaseCache._build_key() across Python versions Jan 10, 2023
@Dreamsorcerer
Copy link
Member

Is there any issue with using str() currently? Seems fine to me.

@padraic-shafer
Copy link
Contributor Author

padraic-shafer commented Jan 10, 2023

Is there any issue with using str() currently? Seems fine to me.

The result of using str() with an enum is the name of the enum, rather than its value. Earlier versions of _build_key() used "{}".format(key) which always returned the value of an enum key until Python 3.11 came along.

My impression was that str() is a workaround and that you were trying to get back to earlier functionality. One benefit should be that existing caches would not get invalidated due to key values changing. I might have misunderstood that though.

>>> from enum import Enum
>>> from aiocache.base import ensure_key

>>> class Keys(str, Enum):
...    KEY: str = "key"
...    KEY_1: str = "random"

>>> # Option 1
>>> Keys.KEY
<Keys.KEY: 'key'>

>>> # Option 2
>>> str(Keys.KEY)
'Keys.KEY'

>>> # Option 3
>>> "{}".format(Keys.KEY)
'Keys.KEY'  # 3.11
'key'       # 3.7 -- 3.10

>>> # Option 4
>>> ensure_key(Keys.KEY)
'key'

In resolving the ambiguity of Option 3, the current implementation of _build_key() was switched to Option 2. I'm proposing to use Option 4 instead, to maintain backward compatibility.

EDIT: Corrected typos in the code block

@Dreamsorcerer
Copy link
Member

I missed that it was the value, actually. Thought the difference was whether it was namespaced or not. Seems reasonable then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants