Does Python forbid two similarly looking Unicode identifiers?

Viewed 6405

I was playing around with Unicode identifiers and stumbled upon this:

>>> , x = 1, 2
>>> , x
(1, 2)
>>> , f = 1, 2
>>> , f
(2, 2)

What's going on here? Why does Python replace the object referenced by , but only sometimes? Where is that behavior described?

2 Answers

PEP 3131 -- Supporting Non-ASCII Identifiers says

All identifiers are converted into the normal form NFKC while parsing; comparison of identifiers is based on NFKC.

You can use unicodedata to test the conversions:

import unicodedata

unicodedata.normalize('NFKC', '')
# f

which would indicate that '' gets converted to 'f' in parsing. Leading to the expected:

  = "Some String"
print(f)
# "Some String"

Here's a small example, just to show how horrible this "feature" is:

ᵢ_fᵣₑ_ₕ_dₑᵢiℓy___ᵘg = 42
print(Tℹ_eᵣe_ₛº_eᵢⁱtᵉ_ℯ__)
# => 42

Try it online! (But please don't use it)

And as mentioned by @MarkMeyer, two identifiers might be distinct even though they look just the same ("CYRILLIC CAPITAL LETTER A" and "LATIN CAPITAL LETTER A")

А = 42
print(A)
# => NameError: name 'A' is not defined
Related