Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SyntaxError: keyword can't be an expression while creating a dictionary

I got two strings retrieved from a cookie

name = 'rack.session'
val = 'CookieVal'

Using them I would like to build a dictionary

cookies = dict(rack.session=val)

but SyntaxError: keyword can't be an expression

So I tried to escape the (.) dot

re.escape(name)

... but it raises the same error

How is this possible? According to Python type() name is a string:

type(name)
 <class 'str'>

Why is Python mixing up strings and expressions?

like image 526
user2610645 Avatar asked Feb 01 '26 04:02

user2610645


1 Answers

The problem with rack.session is that python thinks that you're trying to use the value of expression rack.session and pass it to dict(), which is incorrect because dict() expects you to pass variables names when you're using keyword arguments, these variables name are then converted to strings when the dict is created.

Simple example:

>>> dict('val' = 'a')     
  File "<ipython-input-21-1cdf9688c191>", line 1
SyntaxError: keyword can't be an expression

So, you can't use an object on the left side of =, you can only use a valid identifier.

Byte code makes it even more clear what happens with rack.session:

>>> import dis
>>> dis.dis(lambda : dict(rack.session , val))
  1           0 LOAD_GLOBAL              0 (dict)
              3 LOAD_GLOBAL              1 (rack)   # load the object `rack`
              6 LOAD_ATTR                2 (session)# use the value of it's attribute
                                                    # `session`
              9 LOAD_GLOBAL              3 (val)
             12 CALL_FUNCTION            2
             15 RETURN_VALUE   

So, with rack.session = val, python will think that you're trying to use the value returned from rack.session and pass it to dict, which is incorrect. Secondly rack.session isn't a valid identifier as dots(.) are not allowed in python identifiers.

This is applicable to any function in python not even dict, a keyword argument must be a valid identifier.

From the docs:

keyword_item   ::=  identifier "=" expression

Valid examples:

>>> dict(foo = 1, bar = '2')
{'foo': 1, 'bar': '2'}

For your example you can simply do:

>>> val = 'CookieVal'
>>> name = 'rack.session'
>>> dict(((name,val),))
{'rack.session': 'CookieVal'}
#or
>>> {name:val}
{'rack.session': 'CookieVal'}
like image 135
Ashwini Chaudhary Avatar answered Feb 03 '26 17:02

Ashwini Chaudhary