Skip to content

Commit 4887eb7

Browse files
authored
Fixed bug that results in confusion between two classes defined in the same file with the same name but in different functions when they are used in protocol matching. This addresses #10418. (#10584)
1 parent 4cd01c6 commit 4887eb7

2 files changed

Lines changed: 16 additions & 4 deletions

File tree

packages/pyright-internal/src/analyzer/protocols.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ export function isProtocolUnsafeOverlap(evaluator: TypeEvaluator, protocol: Clas
229229
return isUnsafeOverlap;
230230
}
231231

232+
function makeProtocolCompatibilityCacheClassKey(classType: ClassType): string {
233+
// Create a unique key based on the full name of the class and its type source ID,
234+
// which is derived from the character offset of the class in the source file.
235+
return `${classType.shared.fullName}.${classType.shared.typeSourceId}`;
236+
}
237+
232238
// Looks up the protocol compatibility in the cache. If it's not found,
233239
// return undefined.
234240
function getProtocolCompatibility(
@@ -238,7 +244,12 @@ function getProtocolCompatibility(
238244
constraints: ConstraintTracker | undefined
239245
): ProtocolCompatibility | undefined {
240246
const map = srcType.shared.protocolCompatibility as Map<string, ProtocolCompatibility[]> | undefined;
241-
const entries = map?.get(destType.shared.fullName);
247+
if (!map) {
248+
return undefined;
249+
}
250+
251+
const classKey = makeProtocolCompatibilityCacheClassKey(destType);
252+
const entries = map.get(classKey);
242253
if (entries === undefined) {
243254
return undefined;
244255
}
@@ -284,10 +295,11 @@ function setProtocolCompatibility(
284295
srcType.shared.protocolCompatibility = map;
285296
}
286297

287-
let entries = map.get(destType.shared.fullName);
298+
const classKey = makeProtocolCompatibilityCacheClassKey(destType);
299+
let entries = map.get(classKey);
288300
if (!entries) {
289301
entries = [];
290-
map.set(destType.shared.fullName, entries);
302+
map.set(classKey, entries);
291303
}
292304

293305
// See if the srcType is always incompatible regardless of how it

packages/pyright-internal/src/analyzer/typeEvaluator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17357,7 +17357,7 @@ export function createTypeEvaluator(
1735717357
fileInfo.moduleName,
1735817358
fileInfo.fileUri,
1735917359
classFlags,
17360-
/* typeSourceId */ 0,
17360+
ParseTreeUtils.getTypeSourceId(node),
1736117361
/* declaredMetaclass */ undefined,
1736217362
/* effectiveMetaclass */ undefined,
1736317363
ParseTreeUtils.getDocString(node.d.suite.d.statements)

0 commit comments

Comments
 (0)