Skip to content

Commit 5a3d5ff

Browse files
committed
Merge branch 'master' into color-output-option
2 parents ff79d3c + 91487cb commit 5a3d5ff

File tree

10 files changed

+428
-24
lines changed

10 files changed

+428
-24
lines changed

mypyc/irbuild/expression.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
is_int_rprimitive,
7777
is_list_rprimitive,
7878
is_none_rprimitive,
79+
is_object_rprimitive,
7980
object_rprimitive,
8081
set_rprimitive,
8182
)
@@ -98,7 +99,7 @@
9899
from mypyc.irbuild.specialize import apply_function_specialization, apply_method_specialization
99100
from mypyc.primitives.bytes_ops import bytes_slice_op
100101
from mypyc.primitives.dict_ops import dict_get_item_op, dict_new_op, exact_dict_set_item_op
101-
from mypyc.primitives.generic_ops import iter_op
102+
from mypyc.primitives.generic_ops import iter_op, name_op
102103
from mypyc.primitives.list_ops import list_append_op, list_extend_op, list_slice_op
103104
from mypyc.primitives.misc_ops import ellipsis_op, get_module_dict_op, new_slice_op, type_op
104105
from mypyc.primitives.registry import builtin_names
@@ -218,6 +219,13 @@ def transform_member_expr(builder: IRBuilder, expr: MemberExpr) -> Value:
218219
obj = builder.accept(expr.expr, can_borrow=can_borrow)
219220
rtype = builder.node_type(expr)
220221

222+
if (
223+
is_object_rprimitive(obj.type)
224+
and expr.name == "__name__"
225+
and builder.options.capi_version >= (3, 11)
226+
):
227+
return builder.primitive_op(name_op, [obj], expr.line)
228+
221229
# Special case: for named tuples transform attribute access to faster index access.
222230
typ = get_proper_type(builder.types.get(expr.expr))
223231
if isinstance(typ, TupleType) and typ.partial_fallback.type.is_named_tuple:

mypyc/irbuild/ll_builder.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,12 @@
184184
str_ssize_t_size_op,
185185
unicode_compare,
186186
)
187-
from mypyc.primitives.tuple_ops import list_tuple_op, new_tuple_op, new_tuple_with_length_op
187+
from mypyc.primitives.tuple_ops import (
188+
list_tuple_op,
189+
new_tuple_op,
190+
new_tuple_with_length_op,
191+
sequence_tuple_op,
192+
)
188193
from mypyc.rt_subtype import is_runtime_subtype
189194
from mypyc.sametype import is_same_type
190195
from mypyc.subtype import is_subtype
@@ -789,16 +794,25 @@ def _construct_varargs(
789794
for value, kind, name in args:
790795
if kind == ARG_STAR:
791796
if star_result is None:
792-
# fast path if star expr is a tuple:
793-
# we can pass the immutable tuple straight into the function call.
794-
if is_tuple_rprimitive(value.type):
795-
if len(args) == 1:
796-
# fn(*args)
797-
return value, self._create_dict([], [], line)
798-
elif len(args) == 2 and args[1][1] == ARG_STAR2:
799-
# fn(*args, **kwargs)
797+
# star args fastpath
798+
if len(args) == 1:
799+
# fn(*args)
800+
if is_list_rprimitive(value.type):
801+
value = self.primitive_op(list_tuple_op, [value], line)
802+
elif not is_tuple_rprimitive(value.type) and not isinstance(
803+
value.type, RTuple
804+
):
805+
value = self.primitive_op(sequence_tuple_op, [value], line)
806+
return value, self._create_dict([], [], line)
807+
elif len(args) == 2 and args[1][1] == ARG_STAR2:
808+
# fn(*args, **kwargs)
809+
if is_tuple_rprimitive(value.type) or isinstance(value.type, RTuple):
800810
star_result = value
801-
continue
811+
elif is_list_rprimitive(value.type):
812+
star_result = self.primitive_op(list_tuple_op, [value], line)
813+
else:
814+
star_result = self.primitive_op(sequence_tuple_op, [value], line)
815+
continue
802816
# elif ...: TODO extend this to optimize fn(*args, k=1, **kwargs) case
803817
# TODO optimize this case using the length utils - currently in review
804818
star_result = self.new_list_op(star_values, line)

mypyc/lib-rt/CPy.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,10 @@ PyObject *CPy_GetANext(PyObject *aiter);
931931
void CPy_SetTypeAliasTypeComputeFunction(PyObject *alias, PyObject *compute_value);
932932
void CPyTrace_LogEvent(const char *location, const char *line, const char *op, const char *details);
933933

934+
#if CPY_3_11_FEATURES
935+
PyObject *CPy_GetName(PyObject *obj);
936+
#endif
937+
934938
#if CPY_3_14_FEATURES
935939
void CPy_SetImmortal(PyObject *obj);
936940
#endif

mypyc/lib-rt/misc_ops.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,20 @@ PyObject *CPy_GetANext(PyObject *aiter)
10451045
return NULL;
10461046
}
10471047

1048+
#if CPY_3_11_FEATURES
1049+
1050+
// Return obj.__name__ (specialized to type objects, which are the most common target).
1051+
PyObject *CPy_GetName(PyObject *obj) {
1052+
if (PyType_Check(obj)) {
1053+
return PyType_GetName((PyTypeObject *)obj);
1054+
}
1055+
_Py_IDENTIFIER(__name__);
1056+
PyObject *name = _PyUnicode_FromId(&PyId___name__); /* borrowed */
1057+
return PyObject_GetAttr(obj, name);
1058+
}
1059+
1060+
#endif
1061+
10481062
#ifdef MYPYC_LOG_TRACE
10491063

10501064
// This is only compiled in if trace logging is enabled by user

mypyc/lib-rt/mypyc_util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ static inline CPyTagged CPyTagged_ShortFromSsize_t(Py_ssize_t x) {
140140
}
141141

142142
// Are we targeting Python 3.X or newer?
143+
#define CPY_3_11_FEATURES (PY_VERSION_HEX >= 0x030b0000)
143144
#define CPY_3_12_FEATURES (PY_VERSION_HEX >= 0x030c0000)
144145
#define CPY_3_14_FEATURES (PY_VERSION_HEX >= 0x030e0000)
145146

mypyc/primitives/generic_ops.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
ERR_NEG_INT,
2727
binary_op,
2828
custom_op,
29+
custom_primitive_op,
2930
function_op,
3031
method_op,
3132
unary_op,
@@ -382,3 +383,12 @@
382383
c_function_name="CPy_GetANext",
383384
error_kind=ERR_MAGIC,
384385
)
386+
387+
# x.__name__ (requires Python 3.11+)
388+
name_op = custom_primitive_op(
389+
name="__name__",
390+
arg_types=[object_rprimitive],
391+
return_type=object_rprimitive,
392+
c_function_name="CPy_GetName",
393+
error_kind=ERR_MAGIC,
394+
)

mypyc/primitives/tuple_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
)
7777

7878
# Construct tuple from an arbitrary (iterable) object.
79-
function_op(
79+
sequence_tuple_op = function_op(
8080
name="builtins.tuple",
8181
arg_types=[object_rprimitive],
8282
return_type=tuple_rprimitive,

0 commit comments

Comments
 (0)