Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

IsoCode639_1, IsoCode639_3 Enums don't support Python access by name #254

Closed
brettrp opened this issue Feb 11, 2025 · 5 comments
Closed
Labels
duplicate This issue or pull request already exists

Comments

@brettrp
Copy link

brettrp commented Feb 11, 2025

A real Python Enum allows you to do this:

from enum import Enum

class IsoCode(Enum):
    EN = 1
    FR = 2
    ES = 3

IsoCode['EN']

<IsoCode639_1.EN: 1>

but, perhaps because they're not real Python Enums but rather Rust bindings, the Enums in lingua don't allow this:

import lingua

lingua.IsoCode639_1['EN']
TypeError: type 'builtins.IsoCode639_1' is not subscriptable

If the languages your app supports are (variable) strings, this makes mapping them to lingua enums very annoying.

@pemistahl pemistahl added the duplicate This issue or pull request already exists label Feb 11, 2025
@pemistahl
Copy link
Owner

I know about this problem and I've already fixed it in the Rust implementation. It just has not been released yet. See #225. But I plan to do so this month.

In release 2.1.0, the following will work:

assert Language.from_str("english") == Language.ENGLISH
assert IsoCode639_1.from_str("en") == IsoCode639_1.EN
assert IsoCode639_3.from_str("eng") == IsoCode639_3.ENG

@brettrp
Copy link
Author

brettrp commented Feb 11, 2025

It would be nice to also implement __getitem__ and maybe __call__ so that IsoCode639_1 works like standard Python enums -- i.e. you can do IsoCode639_1['en'] (name) or IsoCode639_1(1) (value).

It's quite confusing then you see that these are declared as subclasses of Python Enum but they don't support all the methods that an Enum is meant to support.

@pemistahl
Copy link
Owner

Cool, I did not know that one can implement the behavior of Python enums manually. I will gladly do so then. Thanks for the hint. :)

@brettrp
Copy link
Author

brettrp commented Feb 13, 2025

As a workaround until that lands, I discovered that you can do this:

getattr(IsoCode639_1, 'EN')
IsoCode639_1.EN

@pemistahl
Copy link
Owner

It turns out that it is currently not possible to implement __getitem__ and __call__ because PyO3 does not yet support meta classes, see PyO3/pyo3#906. The advantage of my from_str method is that it does not matter whether you pass the argument as upper case or lower case. getattr() only supports upper case.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants