Create valid Python identifiers from any string. Check if name contains any special characters. If it contains any special characters, the special characters will be replaced by a special string and a prefix is added. Raises ------ SyntaxError If the returned n
(name: str)
| 22 | |
| 23 | |
| 24 | def create_valid_python_identifier(name: str) -> str: |
| 25 | """ |
| 26 | Create valid Python identifiers from any string. |
| 27 | |
| 28 | Check if name contains any special characters. If it contains any |
| 29 | special characters, the special characters will be replaced by |
| 30 | a special string and a prefix is added. |
| 31 | |
| 32 | Raises |
| 33 | ------ |
| 34 | SyntaxError |
| 35 | If the returned name is not a Python valid identifier, raise an exception. |
| 36 | """ |
| 37 | if name.isidentifier() and not iskeyword(name): |
| 38 | return name |
| 39 | |
| 40 | # Escape characters that fall outside the ASCII range (U+0001..U+007F). |
| 41 | # GH 49633 |
| 42 | gen = ( |
| 43 | (c, "".join(chr(b) for b in c.encode("ascii", "backslashreplace"))) |
| 44 | for c in name |
| 45 | ) |
| 46 | name = "".join( |
| 47 | c_escaped.replace("\\", "_UNICODE_" if c != c_escaped else "_BACKSLASH_") |
| 48 | for c, c_escaped in gen |
| 49 | ) |
| 50 | |
| 51 | # Create a dict with the special characters and their replacement string. |
| 52 | # EXACT_TOKEN_TYPES contains these special characters |
| 53 | # token.tok_name contains a readable description of the replacement string. |
| 54 | special_characters_replacements = { |
| 55 | char: f"_{token.tok_name[tokval]}_" |
| 56 | for char, tokval in (tokenize.EXACT_TOKEN_TYPES.items()) |
| 57 | } |
| 58 | special_characters_replacements.update( |
| 59 | { |
| 60 | " ": "_", |
| 61 | "?": "_QUESTIONMARK_", |
| 62 | "!": "_EXCLAMATIONMARK_", |
| 63 | "$": "_DOLLARSIGN_", |
| 64 | "€": "_EUROSIGN_", |
| 65 | "°": "_DEGREESIGN_", |
| 66 | "'": "_SINGLEQUOTE_", |
| 67 | '"': "_DOUBLEQUOTE_", |
| 68 | "#": "_HASH_", |
| 69 | "`": "_BACKTICK_", |
| 70 | } |
| 71 | ) |
| 72 | |
| 73 | name = "".join([special_characters_replacements.get(char, char) for char in name]) |
| 74 | name = f"BACKTICK_QUOTED_STRING_{name}" |
| 75 | |
| 76 | if not name.isidentifier(): |
| 77 | raise SyntaxError(f"Could not convert '{name}' to a valid Python identifier.") |
| 78 | |
| 79 | return name |
| 80 | |
| 81 |
no test coverage detected