MCPcopy
hub / github.com/python/mypy / intersect_instances

Method intersect_instances

mypy/checker.py:6130–6230  ·  view source on GitHub ↗

Try creating an ad-hoc intersection of the given instances. Note that this function does *not* try and create a full-fledged intersection type. Instead, it returns an instance of a new ad-hoc subclass of the given instances. This is mainly useful when you need a way

(
        self, instances: tuple[Instance, Instance], errors: list[tuple[str, str]]
    )

Source from the content-addressed store, hash-verified

6128 return cdef, info
6129
6130 def intersect_instances(
6131 self, instances: tuple[Instance, Instance], errors: list[tuple[str, str]]
6132 ) -> Instance | None:
6133 """Try creating an ad-hoc intersection of the given instances.
6134
6135 Note that this function does *not* try and create a full-fledged
6136 intersection type. Instead, it returns an instance of a new ad-hoc
6137 subclass of the given instances.
6138
6139 This is mainly useful when you need a way of representing some
6140 theoretical subclass of the instances the user may be trying to use
6141 the generated intersection can serve as a placeholder.
6142
6143 This function will create a fresh subclass the first time you call it.
6144 So this means calling `self.intersect_intersection([inst_1, inst_2], ctx)`
6145 twice will return the same subclass of inst_1 and inst_2.
6146
6147 Returns None if creating the subclass is impossible (e.g. due to
6148 MRO errors or incompatible signatures). If we do successfully create
6149 a subclass, its TypeInfo will automatically be added to the global scope.
6150 """
6151 curr_module = self.scope.stack[0]
6152 assert isinstance(curr_module, MypyFile)
6153
6154 # First, retry narrowing while allowing promotions (they are disabled by default
6155 # for isinstance() checks, etc). This way we will still type-check branches like
6156 # x: complex = 1
6157 # if isinstance(x, int):
6158 # ...
6159 left, right = instances
6160 if is_proper_subtype(left, right, ignore_promotions=False):
6161 return left
6162 if is_proper_subtype(right, left, ignore_promotions=False):
6163 return right
6164
6165 def _get_base_classes(instances_: tuple[Instance, Instance]) -> list[Instance]:
6166 base_classes_ = []
6167 for inst in instances_:
6168 if inst.type.is_intersection:
6169 expanded = inst.type.bases
6170 else:
6171 expanded = [inst]
6172
6173 for expanded_inst in expanded:
6174 base_classes_.append(expanded_inst)
6175 return base_classes_
6176
6177 def _make_fake_typeinfo_and_full_name(
6178 base_classes_: list[Instance], curr_module_: MypyFile, options: Options
6179 ) -> tuple[TypeInfo, str]:
6180 names = [format_type_bare(x, options=options, verbosity=2) for x in base_classes_]
6181 name = f"<subclass of {pretty_seq(names, 'and')}>"
6182 if (symbol := curr_module_.names.get(name)) is not None:
6183 assert isinstance(symbol.node, TypeInfo)
6184 return symbol.node, name
6185 cdef, info_ = self.make_fake_typeinfo(curr_module_.fullname, name, name, base_classes_)
6186 return info_, name
6187

Calls 12

is_proper_subtypeFunction · 0.90
pretty_seqFunction · 0.90
format_type_distinctlyFunction · 0.90
SymbolTableNodeClass · 0.90
InstanceClass · 0.90
isinstanceFunction · 0.85
appendMethod · 0.80
extendMethod · 0.80
filter_errorsMethod · 0.80
has_new_errorsMethod · 0.80

Tested by

no test coverage detected