{"record":{"id":"db1e87b46b052672","repo":"pandas-dev/pandas","slug":"could-not-convert-name-to-a-valid-python-ident","errorCode":null,"errorMessage":"Could not convert '{name}' to a valid Python identifier.","messagePattern":"Could not convert '(.+?)' to a valid Python identifier\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/parsing.py","lineNumber":77,"sourceCode":"        {\n            \" \": \"_\",\n            \"?\": \"_QUESTIONMARK_\",\n            \"!\": \"_EXCLAMATIONMARK_\",\n            \"$\": \"_DOLLARSIGN_\",\n            \"€\": \"_EUROSIGN_\",\n            \"°\": \"_DEGREESIGN_\",\n            \"'\": \"_SINGLEQUOTE_\",\n            '\"': \"_DOUBLEQUOTE_\",\n            \"#\": \"_HASH_\",\n            \"`\": \"_BACKTICK_\",\n        }\n    )\n\n    name = \"\".join([special_characters_replacements.get(char, char) for char in name])\n    name = f\"BACKTICK_QUOTED_STRING_{name}\"\n\n    if not name.isidentifier():\n        raise SyntaxError(f\"Could not convert '{name}' to a valid Python identifier.\")\n\n    return name\n\n\ndef clean_backtick_quoted_toks(tok: tuple[int, str]) -> tuple[int, str]:\n    \"\"\"\n    Clean up a column name if surrounded by backticks.\n\n    Backtick quoted string are indicated by a certain tokval value. If a string\n    is a backtick quoted token it will processed by\n    :func:`_create_valid_python_identifier` so that the parser can find this\n    string when the query is executed.\n    In this case the tok will get the NAME tokval.\n\n    Parameters\n    ----------\n    tok : tuple of int, str\n        ints correspond to the all caps constants in the tokenize module","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/computation/parsing.py#L59-L95","documentation":"Raised by create_valid_python_identifier in pandas.core.computation.parsing when a backtick-quoted column name (or any identifier fed through the cleaner) cannot be transformed into a legal Python identifier. The function first tries name.isidentifier(), then escapes non-ASCII via backslashreplace, maps special characters using tokenize.EXACT_TOKEN_TYPES plus an explicit table (space, ?, !, $, quotes, etc.), and prefixes the result with 'BACKTICK_QUOTED_STRING_'. If the final string still fails str.isidentifier(), it raises SyntaxError. This is the machinery behind `df.query('`weird col` > 0')`.","triggerScenarios":"Using a backtick-quoted column name whose content, after escaping, still violates identifier rules - e.g. a name consisting solely of characters that map to nothing legal, an empty backtick pair, or names with control characters / leading digits combined with disallowed chars that the escape table cannot rescue.","commonSituations":"DataFrames with column names containing unusual punctuation or control characters; programmatic query construction where the column name is dynamic; CSVs whose headers contain reserved symbols. Most ordinary spaces/punctuation are handled, so this fires only for genuinely pathological names.","solutions":["Rename the column to a clean identifier before querying: df.columns = df.columns.str.replace(r'[^A-Za-z0-9_]', '_', regex=True).","Avoid backtick syntax and select with boolean masks directly: df[df['weird col'] > 0].","Simplify the column name to ASCII alphanumerics + underscore, then re-issue the query.","Inspect the actual column name (print(repr(col))) to find the offending character."],"exampleFix":"# before\nimport pandas as pd\ndf = pd.DataFrame({'a b\\x00c': [1, 2]})\ndf.query('`a b\\x00c` > 1')  # SyntaxError: Could not convert ...\n\n# after (rename)\ndf.columns = ['abc']\ndf.query('abc > 1')\n# or skip query syntax:\ndf[df.iloc[:, 0] > 1]","handlingStrategy":"validation","validationCode":"import re\n\ndef safe_query_column(name: str) -> str:\n    cleaned = re.sub(r'[^A-Za-z0-9_]', '_', name)\n    if not cleaned or cleaned[0].isdigit():\n        cleaned = f'col_{cleaned}'\n    if not cleaned.isidentifier():\n        raise SyntaxError(f'column {name!r} cannot be used in query()')\n    return cleaned","typeGuard":"from keyword import iskeyword\n\ndef is_query_safe_column(name: str) -> bool:\n    return isinstance(name, str) and name.isidentifier() and not iskeyword(name)\n","tryCatchPattern":"try:\n    df.query(f'`{col}` > 0')\nexcept SyntaxError as e:\n    if 'Could not convert' in str(e):\n        # rename column or use boolean mask\n        df[df[col] > 0]\n    raise","preventionTips":["Sanitize column names to valid identifiers before storing data.","Prefer boolean masks df[df[col] > 0] over query() for messy column names.","Inspect problematic names with print(repr(col)) to find control chars."],"tags":["pandas","query","parsing","identifiers","column-names"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}