mojo
mojo copied to clipboard
[Feature Request] setitem support for PythonObject
Request
Currently it is not possible to assign to an item/subscript of a Python object (such as a list index or a dictionary entry) from Mojo code using the typical Python syntax of object[key] = value
. Attempting to do so results in an error indicating that the expression is not mutable, even if the dictionary is in a variable defined using var
:
from PythonInterface import Python
from PythonObject import PythonObject
let python_builtins: PythonObject = Python.import_module("builtins")
let dict: PythonObject = python_builtins.dict;
var my_dict: PythonObject = dict()
my_dict["x"] = "hello, world!";
error: Expression [1]:24:12: expression must be mutable in assignment
my_dict["x"] = "hello, world!";
~~~~~~~^~~~~
This same error occurs for any Python value (represented by the PythonObject type in Mojo), such as for lists:
error: Expression [4]:34:12: expression must be mutable in assignment
my_list[0] = "bonjour!"
~~~~~~~^~~
Motivation
Many Python APIs take dictionaries as arguments, either as collections of data, or as parameters/options, so it's valuable to be able to construct these values from Mojo. This is already possible by manually calling the __setitem__
method that Python uses to implement item assignment, but this is a bit clunky and not what Python programmers are used to.
my_dict.__setitem__("x", "hello, world")
my_list.__setitem__(0, "bonjour!")
It would be preferable to be able to populate dictionaries using the typical syntax instead, and generally to use the same syntax as Python for such operations on any Python object.
Description and Requirements
It should be possible to assign to any Python objects that support __setitem__
(including but not limited to dictionary keys and list indices) using the typical Python syntax:
my_dict["x"] = "hello, world!"
my_list[0] = "bonjour!"
This was originally mentioned at https://discord.com/channels/1087530497313357884/1103478447872950312.
(Note that getitem support already appears to be implemented, I'm able to
print(my_dict["x"])
and print(my_list[0])
without a similar error.)
Steffi is on it, thank you!
Thanks for the feature request! This should be straightforward to add @stumpOS
edit: ninja'd
@stumpOS I think you fixed this already?
Yes it is fixed
It seems that it is not fixed with Mojo 0.0.5 and that this issue could be reopened:
let python_builtins: PythonObject = Python.import_module("builtins")
let dict: PythonObject = python_builtins.dict
let d: PythonObject = dict()
# error: expression must be mutable in assignment (with Mojo 0.0.5)
# d["a"] = 0
# works:
d.__setitem__("a", 0)
print(d["a"])
@paugier it's fixed in the next release 0.6.0
@jackos , I'm trying 0.6.0
, and I'm guessing this didn't make it in?
I'm not convinced it's fixed in 0.7 either
let smtp1 = Python.import_module("smtplib")
let emtext1 = Python.import_module("email.mime.text")
var msg = emtext1.MIMEText(body)
msg['Subject'] = "Hello!"
#error: expression must be mutable in assignment
let python_builtins: PythonObject = Python.import_module("builtins")
let dict: PythonObject = python_builtins.dict
let d = dict()
# works:
d.__setitem__("a", 2345)
#warning: 'PythonObject' value is unused
__setitem__
issues a warning, but does work.
In VsCode, only __setattr__
appears in the intelisence
I'm new to Mojo. so sorry if I've misunderstood Does anyone send Emails using Mojo?