diff --git a/packages/pyright-internal/src/parser/tokenizer.ts b/packages/pyright-internal/src/parser/tokenizer.ts index 562328586787..416532935708 100644 --- a/packages/pyright-internal/src/parser/tokenizer.ts +++ b/packages/pyright-internal/src/parser/tokenizer.ts @@ -142,7 +142,11 @@ const _byteOrderMarker = 0xfeff; const defaultTabSize = 8; const magicsRegEx = /\\\s*$/; -const typeIgnoreCommentRegEx = /((^|#)\s*)type:\s*ignore(\s*\[([\s\w-,]*)\]|\s|$)/; +// The character class for type: ignore rule codes includes ':' so that +// tool-namespaced codes such as "ty:unresolved-reference" are accepted. +// pyright: ignore uses the original class since tool-namespaced codes +// are not expected there. +const typeIgnoreCommentRegEx = /((^|#)\s*)type:\s*ignore(\s*\[([\s\w:,-]*)\]|\s|$)/; const pyrightIgnoreCommentRegEx = /((^|#)\s*)pyright:\s*ignore(\s*\[([\s\w-,]*)\]|\s|$)/; const underscoreRegEx = /_/g; diff --git a/packages/pyright-internal/src/tests/tokenizer.test.ts b/packages/pyright-internal/src/tests/tokenizer.test.ts index d755a972498f..32f92009bbd1 100644 --- a/packages/pyright-internal/src/tests/tokenizer.test.ts +++ b/packages/pyright-internal/src/tests/tokenizer.test.ts @@ -1815,6 +1815,33 @@ test('TypeIgnoreLine2', () => { assert.equal(results.tokens.contains(42), false); }); +// Regression test for https://github.com/microsoft/pyright/issues/11345. +// type: ignore comments containing tool-namespaced codes (e.g. "ty:rule-name") +// must be recognised as type: ignore comments. +test('TypeIgnoreNamespacedCode', () => { + const t = new Tokenizer(); + // Single namespaced code. + const results = t.tokenize('a = 1 # type: ignore[ty:unresolved-reference]'); + assert.equal(results.typeIgnoreLines.size, 1); + assert(results.typeIgnoreLines.has(0)); + const rules = results.typeIgnoreLines.get(0)!.rulesList; + assert(rules !== undefined); + assert.equal(rules.length, 1); + assert.equal(rules[0].text, 'ty:unresolved-reference'); +}); + +test('TypeIgnoreMixedNamespacedCodes', () => { + const t = new Tokenizer(); + // Mix of plain and namespaced codes. + const results = t.tokenize('a = 1 # type: ignore[name-defined, ty:unresolved-reference]'); + assert.equal(results.typeIgnoreLines.size, 1); + const rules = results.typeIgnoreLines.get(0)!.rulesList; + assert(rules !== undefined); + assert.equal(rules.length, 2); + assert.equal(rules[0].text, 'name-defined'); + assert.equal(rules[1].text, 'ty:unresolved-reference'); +}); + test('Constructor', () => { const t = new Tokenizer(); const results = t.tokenize('def constructor');