[Python-ideas] Change magic strings to enums

Chris Angelico rosuav at gmail.com
Wed Apr 25 04:30:32 EDT 2018


On Wed, Apr 25, 2018 at 6:06 PM, Jacco van Dorp <j.van.dorp at deonet.nl> wrote:
>> First, though, can you enumerate (pun intended) the problems with
>> magic strings? You list "no magic strings" as a benefit, as if it's
>> self-evident; I'm not sure that it is.
>>
>> ChrisA
>
> One of my main reasons would be the type-checking from tools like
> Pycharm, which is the one I use. If I don't remember the exact
> strings, I won't have to switch to my browser to look up the
> documentation, but instead I type the enum name, and the typechecker
> will give me the members with correct spelling - all I need to
> remember is a vague idea of what option did what. The option names
> will be reminders instead of the thing to remember.
>
> Perhaps the string encode/decode would be a better case, tho. Is it
> latin 1 or latin-1 ? utf-8 or UTF-8 ? They might be fast to look up if
> you know where to look (probably the top result of googling "python
> string encoding utf 8", and it's the second and first option
> respectively IIRC. But I shouldn't -have- to recall correctly), but
> it's still a lot faster if you can type "Encoding.U" and it gives you
> the option.

There are so many encodings that I don't think an enum would be
practical. Also, their canonical names are not valid identifiers, so
you would have to futz around just as much - is it Encoding.ISO_8859_1
or Encoding.ISO88591 or something else?

Perhaps an alternative tool in PyCharm is the solution. There's no
reason that you can't have tab completion inside string literals;
imagine, for instance, if >> open("/usr/lo << could tab-complete
"/usr/local" and let you fill in a valid path name from your file
system. Tab-completing a set of common encodings would be reasonably
easy. Tab-completing a set of constant strings for the warnings
module, even easier.

Maybe there could be a way to store this info on a function object,
and then PyCharm just has to follow instructions ("this arg of this
function uses these strings")? Possibly as a type annotation, even -
instead of saying "this takes a string", it can say "this takes a
string drawn from these options"? The strings themselves don't have to
be any different.

ChrisA


More information about the Python-ideas mailing list