(self, defn: OverloadedFuncDef)
| 1288 | self.current_overload_item = None |
| 1289 | |
| 1290 | def analyze_overloaded_func_def(self, defn: OverloadedFuncDef) -> None: |
| 1291 | # OverloadedFuncDef refers to any legitimate situation where you have |
| 1292 | # more than one declaration for the same function in a row. This occurs |
| 1293 | # with a @property with a setter or a deleter, and for a classic |
| 1294 | # @overload. |
| 1295 | |
| 1296 | defn._fullname = self.qualified_name(defn.name) |
| 1297 | # TODO: avoid modifying items. |
| 1298 | defn.items = defn.unanalyzed_items.copy() |
| 1299 | |
| 1300 | first_item = defn.items[0] |
| 1301 | first_item.is_overload = True |
| 1302 | with self.overload_item_set(0): |
| 1303 | first_item.accept(self) |
| 1304 | |
| 1305 | bare_setter_type = None |
| 1306 | is_property = False |
| 1307 | if isinstance(first_item, Decorator) and first_item.func.is_property: |
| 1308 | is_property = True |
| 1309 | # This is a property. |
| 1310 | first_item.func.is_overload = True |
| 1311 | bare_setter_type = self.analyze_property_with_multi_part_definition(defn) |
| 1312 | typ = function_type(first_item.func, self.function_type()) |
| 1313 | assert isinstance(typ, CallableType) |
| 1314 | typ.definition = first_item |
| 1315 | types = [typ] |
| 1316 | else: |
| 1317 | # This is a normal overload. Find the item signatures, the |
| 1318 | # implementation (if outside a stub), and any missing @overload |
| 1319 | # decorators. |
| 1320 | types, impl, non_overload_indexes = self.analyze_overload_sigs_and_impl(defn) |
| 1321 | defn.impl = impl |
| 1322 | if non_overload_indexes: |
| 1323 | self.handle_missing_overload_decorators( |
| 1324 | defn, non_overload_indexes, some_overload_decorators=len(types) > 0 |
| 1325 | ) |
| 1326 | # If we found an implementation, remove it from the overload item list, |
| 1327 | # as it's special. |
| 1328 | if impl is not None: |
| 1329 | assert impl is defn.items[-1] |
| 1330 | defn.items = defn.items[:-1] |
| 1331 | elif not non_overload_indexes: |
| 1332 | self.handle_missing_overload_implementation(defn) |
| 1333 | |
| 1334 | if types and not any( |
| 1335 | # If some overload items are decorated with other decorators, then |
| 1336 | # the overload type will be determined during type checking. |
| 1337 | # Note: bare @property is removed in visit_decorator(). |
| 1338 | isinstance(it, Decorator) |
| 1339 | and len(it.decorators) > (1 if i > 0 or not is_property else 0) |
| 1340 | for i, it in enumerate(defn.items) |
| 1341 | ): |
| 1342 | # TODO: should we enforce decorated overloads consistency somehow? |
| 1343 | # Some existing code uses both styles: |
| 1344 | # * Put decorator only on implementation, use "effective" types in overloads |
| 1345 | # * Put decorator everywhere, use "bare" types in overloads. |
| 1346 | defn.type = Overloaded(types) |
| 1347 | defn.type.line = defn.line |
no test coverage detected