Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] setitem support for PythonObject #11

Closed
jeremyBanks opened this issue May 4, 2023 · 8 comments
Closed

[Feature Request] setitem support for PythonObject #11

jeremyBanks opened this issue May 4, 2023 · 8 comments
Assignees
Labels
enhancement New feature or request mojo-repo Tag all issues with this label

Comments

@jeremyBanks
Copy link

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.)

@lattner
Copy link
Collaborator

lattner commented May 4, 2023

Steffi is on it, thank you!

@Mogball
Copy link
Collaborator

Mogball commented May 4, 2023

Thanks for the feature request! This should be straightforward to add @stumpOS

edit: ninja'd

@Mogball Mogball added the enhancement New feature or request label May 4, 2023
@lattner
Copy link
Collaborator

lattner commented May 10, 2023

@stumpOS I think you fixed this already?

@Mogball Mogball closed this as completed May 10, 2023
@modularml modularml deleted a comment from Mogball May 10, 2023
@stumpOS
Copy link
Contributor

stumpOS commented May 11, 2023

Yes it is fixed

@paugier
Copy link

paugier commented Nov 15, 2023

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"])

@jackos
Copy link
Collaborator

jackos commented Nov 15, 2023

@paugier it's fixed in the next release 0.6.0

@fnands
Copy link

fnands commented Dec 11, 2023

@jackos , I'm trying 0.6.0, and I'm guessing this didn't make it in?

@jradxl
Copy link

jradxl commented Jan 27, 2024

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request mojo-repo Tag all issues with this label
Projects
None yet
Development

No branches or pull requests

10 participants