[Python-ideas] Change magic strings to enums

Jacco van Dorp j.van.dorp at deonet.nl
Wed Apr 25 05:12:42 EDT 2018


2018-04-25 10:30 GMT+02:00 Chris Angelico <rosuav at gmail.com>:
> 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?

Which is where the auto-completion comes in. type Encoding.IS - and
you'd have a list of options. If the function is annotated with the
type of the enum, it'll even suggest you that.

I'll freely admit that the amount of encodings might make this a bad
idea. On the other hand....it might make it a good idea as well. See a
list of possibilities, and the IDE can filter it as you type. IIRC
tho, you can add encodings at runtime, while you can't add Enum
members. If you actually can, than this might be unsuitable for Enum
solution.

(looking at the docs 7.2:codecs though, the error handling strings
look...tasty ;p)

>
> 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.

But where would you get a list of these strings, and how'd you define
that list of strings ? It's currently commonly accepted that
annotations are for types, and the later PEP's about the subject seem
to assume this without question. Another annotation-like functionality
? hardcode the list of possibilities inside pycharm ?

Also, perhaps I want to select the string first, store in into a
variable, then pass that variable into a function. How would any
checker ever know what im going to feed that string into ? But an
Enum, I can use that as type annotation myself and then it'll know
without question which are legal arguments.

> 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

Pycharm doesn't execute your code - it scans it. It wont know what you
store on a function object. As whether type annotations can mean "a
string from either of these options" would require a currently not
known to me interpretation of type annotations - and probably
incompatible with what most people currenlty use them for.

Forgive me if I misunderstand you, but aren't you really just trying
to use those strings as enum members when you define a function like
"takes one of these strings as argument" ? Because as far as I know,
except from some fluff, that's exactly what enums are and are intended
for - a unique set of keys that all have special meaning.


More information about the Python-ideas mailing list