Skip to content

Commit 8835b47

Browse files
authored
Merge pull request #444 from skinny121/object_format
Add object.__format__
2 parents 9177252 + d14aeef commit 8835b47

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

tests/snippets/builtin_format.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,12 @@
66
pass
77
else:
88
assert False, "TypeError not raised when format is called with a number"
9+
10+
assert format({}) == "{}"
11+
12+
try:
13+
format({}, 'b')
14+
except TypeError:
15+
pass
16+
else:
17+
assert False, "TypeError not raised when format_spec not empty for dict"

vm/src/builtins.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,13 @@ fn builtin_format(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
281281
arg_check!(
282282
vm,
283283
args,
284-
required = [(obj, None), (format_spec, Some(vm.ctx.str_type()))]
284+
required = [(obj, None)],
285+
optional = [(format_spec, Some(vm.ctx.str_type()))]
285286
);
286-
287-
vm.call_method(obj, "__format__", vec![format_spec.clone()])
287+
let format_spec = format_spec
288+
.cloned()
289+
.unwrap_or_else(|| vm.new_str("".to_string()));
290+
vm.call_method(obj, "__format__", vec![format_spec])
288291
}
289292

290293
fn builtin_getattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

vm/src/obj/objobject.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,22 @@ fn object_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
8383
Ok(vm.new_str(format!("<{} object at 0x{:x}>", type_name, address)))
8484
}
8585

86+
fn object_format(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
87+
arg_check!(
88+
vm,
89+
args,
90+
required = [
91+
(obj, Some(vm.ctx.object())),
92+
(format_spec, Some(vm.ctx.str_type()))
93+
]
94+
);
95+
if objstr::get_value(format_spec).is_empty() {
96+
vm.to_str(obj)
97+
} else {
98+
Err(vm.new_type_error("unsupported format string passed to object.__format__".to_string()))
99+
}
100+
}
101+
86102
pub fn init(context: &PyContext) {
87103
let object = &context.object;
88104
let object_doc = "The most base type";
@@ -100,6 +116,7 @@ pub fn init(context: &PyContext) {
100116
context.set_attr(&object, "__hash__", context.new_rustfunc(object_hash));
101117
context.set_attr(&object, "__str__", context.new_rustfunc(object_str));
102118
context.set_attr(&object, "__repr__", context.new_rustfunc(object_repr));
119+
context.set_attr(&object, "__format__", context.new_rustfunc(object_format));
103120
context.set_attr(
104121
&object,
105122
"__getattribute__",

0 commit comments

Comments
 (0)