I need to set a default value within a Mojo function call which has an argument of type PythonObject. I managed to cause the compiler to die horribly, and found a different compiler error using an inline if-else
. In the repro below, Scenario 2.0 is preferred (most Pythonic), but Scenario 3.0 would work too if the compiler didn’t die. Using Optional[PythonObject]
as the argument type won’t work because a value is required to be passed by the caller.
Suggestions/alternatives? TIA!
main.mojo
from python import Python, PythonObject
fn main() raises:
Foo = Python.import_module("py.foo").Foo
bar = PyBar(Foo())
print(String(bar)) # Wizard
bar = PyBar(Foo("Warlock"))
print(String(bar)) # Warlock
# IMPORTANT: Comment next line to hide compiler error
# bar = PyBar()
# print(String(bar)) # Witch
@value
struct PyBar:
alias DEFAULT_NAME = "Witch"
var foo: PythonObject
# fn __init__(out self, foo: PythonObject) raises: # Requires foo argument
# fn __init__(out self, foo: Optional[PythonObject]) raises: # Requires foo argument
fn __init__(out self, foo: PythonObject = None) raises: # Compiler error
Foo = Python.import_module("py.foo").Foo
# Scenario_1.0
# OK if foo
# when `foo: PythonObject = None` in `fn __init__()`
# KO if foo = None [compiler dies horribly]
# self.foo = foo # Uncomment
# Scenario_2.0 [This is required to create a new Foo if not passed into __init__]
# KO if foo [does not handle inline if-else]
# when `foo: PythonObject = None` in `fn __init__()`
# error: failed to lower module to LLVM IR for archive compilation, translate module to LLVMIR failed
self.foo = foo if foo else Foo(self.DEFAULT_NAME) # Uncomment
# Scenario_2.1
# OK
# when `foo: Optional[PythonObject]` in `fn __init__()`
# self.foo = foo.value() if foo else Foo(self.DEFAULT_NAME) # Uncomment
# Scenario_3.0 [This is required to create a new Foo if not passed into __init__]
# OK if foo
# when `foo: PythonObject = None` in `fn __init__()`
# KO if foo = None [compiler dies horribly]
# if foo: # Uncomment if-else
# self.foo = foo
# else:
# self.foo = Foo(self.DEFAULT_NAME)
fn __str__(self, out result: String):
result = "Name = " + String(self.foo)
foo.py
class Foo:
DEFAULT_NAME = "Wizard"
name: str
def __init__(self, name=DEFAULT_NAME) -> None:
self.name = name
def __str__(self) -> str:
return self.name