Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion mypyc/analysis/ircheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,10 @@ def can_coerce_to(src: RType, dest: RType) -> bool:
if isinstance(src, RPrimitive):
# If either src or dest is a disjoint type, then they must both be.
if src.name in disjoint_types and dest.name in disjoint_types:
return src.name == dest.name
return src.name == dest.name or (
src.name in ("builtins.dict", "builtins.dict[exact]")
and dest.name in ("builtins.dict", "builtins.dict[exact]")
)
return src.size == dest.size
if isinstance(src, RInstance):
return is_object_rprimitive(dest)
Expand Down
16 changes: 14 additions & 2 deletions mypyc/ir/rtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,12 @@ def __hash__(self) -> int:
"builtins.list", is_unboxed=False, is_refcounted=True, may_be_immortal=False
)

# Python dict object (or an instance of a subclass of dict).
# Python dict object.
exact_dict_rprimitive: Final = RPrimitive(
"builtins.dict[exact]", is_unboxed=False, is_refcounted=True
)

# An instance of a subclass of dict.
dict_rprimitive: Final = RPrimitive("builtins.dict", is_unboxed=False, is_refcounted=True)

# Python set object (or an instance of a subclass of set).
Expand Down Expand Up @@ -608,7 +613,14 @@ def is_list_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:


def is_dict_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.dict"
return isinstance(rtype, RPrimitive) and rtype.name in (
"builtins.dict",
"builtins.dict[exact]",
)


def is_exact_dict_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.dict[exact]"


def is_set_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
Expand Down
6 changes: 4 additions & 2 deletions mypyc/irbuild/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
bitmap_rprimitive,
bytes_rprimitive,
c_pyssize_t_rprimitive,
dict_rprimitive,
exact_dict_rprimitive,
int_rprimitive,
is_float_rprimitive,
is_list_rprimitive,
Expand Down Expand Up @@ -437,6 +437,8 @@ def add_to_non_ext_dict(
) -> None:
# Add an attribute entry into the class dict of a non-extension class.
key_unicode = self.load_str(key)
# must use `dict_set_item_op` instead of `exact_dict_set_item_op` because
# it breaks enums, and probably other stuff, if we take the fast path.
self.primitive_op(dict_set_item_op, [non_ext.dict, key_unicode, val], line)

# It's important that accessing class dictionary items from multiple threads
Expand Down Expand Up @@ -1409,7 +1411,7 @@ def load_global_str(self, name: str, line: int) -> Value:
return self.primitive_op(dict_get_item_op, [_globals, reg], line)

def load_globals_dict(self) -> Value:
return self.add(LoadStatic(dict_rprimitive, "globals", self.module_name))
return self.add(LoadStatic(exact_dict_rprimitive, "globals", self.module_name))

def load_module_attr_by_fullname(self, fullname: str, line: int) -> Value:
module, _, name = fullname.rpartition(".")
Expand Down
3 changes: 2 additions & 1 deletion mypyc/primitives/misc_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
c_pyssize_t_rprimitive,
cstring_rprimitive,
dict_rprimitive,
exact_dict_rprimitive,
float_rprimitive,
int_rprimitive,
none_rprimitive,
Expand Down Expand Up @@ -161,7 +162,7 @@
# Get the sys.modules dictionary
get_module_dict_op = custom_op(
arg_types=[],
return_type=dict_rprimitive,
return_type=exact_dict_rprimitive,
c_function_name="PyImport_GetModuleDict",
error_kind=ERR_NEVER,
is_borrowed=True,
Expand Down
4 changes: 4 additions & 0 deletions mypyc/rt_subtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
RVoid,
is_bit_rprimitive,
is_bool_rprimitive,
is_dict_rprimitive,
is_exact_dict_rprimitive,
is_int_rprimitive,
is_short_int_rprimitive,
)
Expand Down Expand Up @@ -58,6 +60,8 @@ def visit_rprimitive(self, left: RPrimitive) -> bool:
return True
if is_bit_rprimitive(left) and is_bool_rprimitive(self.right):
return True
if is_exact_dict_rprimitive(left) and is_dict_rprimitive(self.right):
return True
return left is self.right

def visit_rtuple(self, left: RTuple) -> bool:
Expand Down
5 changes: 5 additions & 0 deletions mypyc/subtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
RVoid,
is_bit_rprimitive,
is_bool_rprimitive,
is_dict_rprimitive,
is_exact_dict_rprimitive,
is_fixed_width_rtype,
is_int_rprimitive,
is_object_rprimitive,
Expand Down Expand Up @@ -67,6 +69,9 @@ def visit_rprimitive(self, left: RPrimitive) -> bool:
elif is_fixed_width_rtype(left):
if is_int_rprimitive(right):
return True
elif is_exact_dict_rprimitive(left):
if is_dict_rprimitive(right):
return True
return left is right

def visit_rtuple(self, left: RTuple) -> bool:
Expand Down
Loading