Skip to content

Allowing using external typeshed - #11485

Open
mochaaP wants to merge 1 commit into
microsoft:mainfrom
mcha-forks:mochaa/external-typeshed
Open

Allowing using external typeshed#11485
mochaaP wants to merge 1 commit into
microsoft:mainfrom
mcha-forks:mochaa/external-typeshed

Conversation

@mochaaP

@mochaaP mochaaP commented Jun 11, 2026

Copy link
Copy Markdown

Adds an environment variable PYRIGHT_TYPESHED_PATH for overriding builtin typeshed with an external one.

@rchiodo

rchiodo commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Might be nice to add a test to verify this works. Like what if the env variable doesn't end with a '/'. Does it still work?

@github-actions

Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

attrs (https://github.com/python-attrs/attrs)
- 0 errors, 0 warnings, 0 informations
+ TypeError: Cannot read properties of undefined (reading 'getDirectory')
+     at r._findClosestMatch (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:224:32)
+     at r._getMappedEntry (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:257:35)
+     at r._isOriginalPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:268:21)
+     at r.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:34:18)
+     at s.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolverFileSystem.ts:134:33)
+     at Object.t.getTypeShedFallbackPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/pythonPathUtils.ts:30:12)
+     at d._computeTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:249:42)
+     at d.getTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:41:27)
+     at d.getTypeshedSubdirectory (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:57:35)
+     at e._getStdlibTypeshedPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:1948:62)
+     at e.getImportRoots (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:349:34)
+     at ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:416:66)
+     at t.BackgroundAnalysisProgram._ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:279:37)
+     at ...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:75
+     at Array.forEach (<anonymous>)
+     at t.BackgroundAnalysisProgram.setImportResolver (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:55)
+     at e.applyConfigOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:698:41)
+     at e.setOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:335:14)
+     at L (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:567:13)
+     at V (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:451:12)
+     at Q (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:1393:28)

packaging (https://github.com/pypa/packaging)
+ TypeError: Cannot read properties of undefined (reading 'getDirectory')
+     at r._findClosestMatch (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:224:32)
+     at r._getMappedEntry (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:257:35)
+     at r._isOriginalPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:268:21)
+     at r.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:34:18)
+     at s.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolverFileSystem.ts:134:33)
+     at Object.t.getTypeShedFallbackPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/pythonPathUtils.ts:30:12)
+     at d._computeTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:249:42)
+     at d.getTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:41:27)
+     at d.getTypeshedSubdirectory (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:57:35)
+     at e._getStdlibTypeshedPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:1948:62)
+     at e.getImportRoots (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:349:34)
+     at ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:416:66)
+     at t.BackgroundAnalysisProgram._ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:279:37)
+     at ...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:75
+     at Array.forEach (<anonymous>)
+     at t.BackgroundAnalysisProgram.setImportResolver (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:55)
+     at e.applyConfigOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:698:41)
+     at e.setOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:335:14)
+     at L (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:567:13)
+     at V (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:451:12)
+     at Q (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:1393:28)
- .../projects/packaging/src/packaging/_manylinux.py
-   .../projects/packaging/src/packaging/_manylinux.py:195:29 - error: "manylinux_compatible" is not a known attribute of module "_manylinux" (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/_manylinux.py:200:32 - error: "manylinux1_compatible" is not a known attribute of module "_manylinux" (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/_manylinux.py:204:32 - error: "manylinux2010_compatible" is not a known attribute of module "_manylinux" (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/_manylinux.py:208:32 - error: "manylinux2014_compatible" is not a known attribute of module "_manylinux" (reportAttributeAccessIssue)
- .../projects/packaging/src/packaging/_parser.py
-   .../projects/packaging/src/packaging/_parser.py:311:28 - error: Argument of type "tuple[str, MarkerAtom]" cannot be assigned to parameter "iterable" of type "Iterable[MarkerAtom]" in function "extend"
-     Type "str" is not assignable to type "MarkerAtom"
-       "str" is not assignable to "tuple[MarkerVar, Op, MarkerVar]"
-       "str" is not assignable to "Sequence[MarkerAtom]"
-         Type parameter "_T_co@Sequence" is covariant, but "str" is not a subtype of "MarkerAtom"
-           Type "str" is not assignable to type "MarkerAtom"
-             "str" is not assignable to "tuple[MarkerVar, Op, MarkerVar]"
-             "str" is not assignable to "Sequence[MarkerAtom]" (reportArgumentType)
-   .../projects/packaging/src/packaging/_parser.py:312:12 - error: Type "list[MarkerAtom]" is not assignable to return type "MarkerList"
-     "list[MarkerAtom]" is not assignable to "list[MarkerAtom | MarkerLogical | MarkerList]"
-       Type parameter "_T@list" is invariant, but "MarkerAtom" is not the same as "MarkerAtom | MarkerLogical | MarkerList"
-       Consider switching from "list" to "Sequence" which is covariant (reportReturnType)
-   .../projects/packaging/src/packaging/_parser.py:329:34 - error: Type "MarkerList" is not assignable to declared type "MarkerAtom"
-     Type "MarkerList" is not assignable to type "MarkerAtom"
-       "list[MarkerAtom | MarkerLogical | MarkerList]" is not assignable to "tuple[MarkerVar, Op, MarkerVar]"
-       "list[MarkerAtom | MarkerLogical | MarkerList]" is not assignable to "Sequence[MarkerAtom]"
-         Type parameter "_T_co@Sequence" is covariant, but "MarkerAtom | MarkerLogical | MarkerList" is not a subtype of "MarkerAtom"
-           Type "MarkerAtom | MarkerLogical | MarkerList" is not assignable to type "MarkerAtom"
-             Type "Literal['and']" is not assignable to type "MarkerAtom" (reportAssignmentType)
- .../projects/packaging/src/packaging/markers.py
-   .../projects/packaging/src/packaging/markers.py:164:50 - error: Cannot access attribute "value" for class "MarkerItem"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:164:50 - error: Cannot access attribute "value" for class "Sequence[MarkerAtom]"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:167:50 - error: Cannot access attribute "value" for class "tuple[MarkerVar, Op, MarkerVar]"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:167:50 - error: Cannot access attribute "value" for class "Sequence[MarkerAtom]"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:169:12 - error: Type "tuple[MarkerVar | MarkerAtom, MarkerAtom | Op, MarkerVar | MarkerAtom]" is not assignable to return type "MarkerAtom | MarkerList | str"
-     Type "tuple[MarkerVar | MarkerAtom, MarkerAtom | Op, MarkerVar | MarkerAtom]" is not assignable to type "MarkerAtom | MarkerList | str"
-       "tuple[MarkerVar | MarkerAtom, MarkerAtom | Op, MarkerVar | MarkerAtom]" is not assignable to "list[MarkerAtom | MarkerLogical | MarkerList]"
-       "tuple[MarkerVar | MarkerAtom, MarkerAtom | Op, MarkerVar | MarkerAtom]" is not assignable to "tuple[MarkerVar, Op, MarkerVar]"
-         Tuple entry 1 is incorrect type
-           Type "MarkerVar | MarkerAtom" is not assignable to type "MarkerVar"
-             Type "Sequence[MarkerAtom]" is not assignable to type "MarkerVar"
-       "tuple[MarkerVar | MarkerAtom, MarkerAtom | Op, MarkerVar | MarkerAtom]" is not assignable to "Sequence[MarkerAtom]"
-         Type parameter "_T_co@Sequence" is covariant, but "MarkerVar | MarkerAtom | Op" is not a subtype of "MarkerAtom"
-     ... (reportReturnType)
-   .../projects/packaging/src/packaging/markers.py:177:12 - error: Type "list[MarkerAtom | MarkerList | str]" is not assignable to return type "MarkerList" (reportReturnType)
-   .../projects/packaging/src/packaging/markers.py:203:28 - error: Cannot access attribute "serialize" for class "MarkerItem"
-     Attribute "serialize" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:203:28 - error: Cannot access attribute "serialize" for class "Sequence[MarkerAtom]"
-     Attribute "serialize" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:265:49 - error: Argument of type "list[MarkerAtom | MarkerLogical | MarkerList] | list[MarkerAtom]" cannot be assigned to parameter "markers" of type "MarkerList" in function "_evaluate_markers"
-     Type "list[MarkerAtom | MarkerLogical | MarkerList] | list[MarkerAtom]" is not assignable to type "MarkerList"
-       "list[MarkerAtom]" is not assignable to "list[MarkerAtom | MarkerLogical | MarkerList]"
-         Type parameter "_T@list" is invariant, but "MarkerAtom" is not the same as "MarkerAtom | MarkerLogical | MarkerList"
-         Consider switching from "list" to "Sequence" which is covariant (reportArgumentType)
-   .../projects/packaging/src/packaging/markers.py:272:33 - error: Cannot access attribute "value" for class "MarkerItem"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:272:33 - error: Cannot access attribute "value" for class "Sequence[MarkerAtom]"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:274:33 - error: Cannot access attribute "value" for class "tuple[MarkerVar, Op, MarkerVar]"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:274:33 - error: Cannot access attribute "value" for class "Sequence[MarkerAtom]"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:275:39 - error: Cannot access attribute "value" for class "MarkerItem"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:275:39 - error: Cannot access attribute "value" for class "Sequence[MarkerAtom]"
-     Attribute "value" is unknown (reportAttributeAccessIssue)
-   .../projects/packaging/src/packaging/markers.py:280:51 - error: Argument of type "MarkerAtom | Op" cannot be assigned to parameter "op" of type "Op" in function "_eval_op"

... (truncated 28 lines) ...

async-utils (https://github.com/mikeshardmind/async-utils)
- 0 errors, 0 warnings, 0 informations
+ TypeError: Cannot read properties of undefined (reading 'getDirectory')
+     at r._findClosestMatch (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:224:32)
+     at r._getMappedEntry (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:257:35)
+     at r._isOriginalPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:268:21)
+     at r.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:34:18)
+     at s.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolverFileSystem.ts:134:33)
+     at Object.t.getTypeShedFallbackPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/pythonPathUtils.ts:30:12)
+     at d._computeTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:249:42)
+     at d.getTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:41:27)
+     at d.getTypeshedSubdirectory (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:57:35)
+     at e._getStdlibTypeshedPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:1948:62)
+     at e.getImportRoots (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:349:34)
+     at ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:416:66)
+     at t.BackgroundAnalysisProgram._ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:279:37)
+     at ...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:75
+     at Array.forEach (<anonymous>)
+     at t.BackgroundAnalysisProgram.setImportResolver (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:55)
+     at e.applyConfigOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:698:41)
+     at e.setOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:335:14)
+     at L (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:567:13)
+     at V (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:451:12)
+     at Q (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:1393:28)

nionutils (https://github.com/nion-software/nionutils)
+ TypeError: Cannot read properties of undefined (reading 'getDirectory')
+     at r._findClosestMatch (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:224:32)
+     at r._getMappedEntry (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:257:35)
+     at r._isOriginalPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:268:21)
+     at r.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:34:18)
+     at s.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolverFileSystem.ts:134:33)
+     at Object.t.getTypeShedFallbackPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/pythonPathUtils.ts:30:12)
+     at d._computeTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:249:42)
+     at d.getTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:41:27)
+     at d.getTypeshedSubdirectory (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:57:35)
+     at e._getStdlibTypeshedPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:1948:62)
+     at e.getImportRoots (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:349:34)
+     at ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:416:66)
+     at t.BackgroundAnalysisProgram._ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:279:37)
+     at ...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:75
+     at Array.forEach (<anonymous>)
+     at t.BackgroundAnalysisProgram.setImportResolver (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:55)
+     at e.applyConfigOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:698:41)
+     at e.setOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:335:14)
+     at L (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:567:13)
+     at V (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:451:12)
+     at Q (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:1393:28)
- .../projects/nionutils/nion/utils/Converter.py
-   .../projects/nionutils/nion/utils/Converter.py:112:9 - error: Method "convert_back" overrides class "ConverterLike" in an incompatible manner
-     Parameter 2 name mismatch: base parameter is named "formatted_value", override parameter is named "value_int" (reportIncompatibleMethodOverride)
-   .../projects/nionutils/nion/utils/Converter.py:161:9 - error: Method "convert_back" overrides class "ConverterLike" in an incompatible manner
-     Parameter 2 name mismatch: base parameter is named "formatted_value", override parameter is named "value" (reportIncompatibleMethodOverride)
-   .../projects/nionutils/nion/utils/Converter.py:172:9 - error: Method "convert_back" overrides class "ConverterLike" in an incompatible manner
-     Parameter 2 name mismatch: base parameter is named "formatted_value", override parameter is named "value" (reportIncompatibleMethodOverride)
-   .../projects/nionutils/nion/utils/Converter.py:181:9 - error: Method "convert_back" overrides class "ConverterLike" in an incompatible manner
-     Parameter 2 name mismatch: base parameter is named "formatted_value", override parameter is named "value" (reportIncompatibleMethodOverride)
-   .../projects/nionutils/nion/utils/Converter.py:192:9 - error: Method "convert_back" overrides class "ConverterLike" in an incompatible manner
-     Parameter 2 name mismatch: base parameter is named "formatted_value", override parameter is named "value" (reportIncompatibleMethodOverride)
-   .../projects/nionutils/nion/utils/Converter.py:220:9 - error: Method "convert_back" overrides class "ConverterLike" in an incompatible manner
-     Parameter 2 name mismatch: base parameter is named "formatted_value", override parameter is named "value" (reportIncompatibleMethodOverride)
-   .../projects/nionutils/nion/utils/Converter.py:254:9 - error: Method "convert_back" overrides class "ConverterLike" in an incompatible manner
-     Parameter 2 name mismatch: base parameter is named "formatted_value", override parameter is named "index" (reportIncompatibleMethodOverride)
- .../projects/nionutils/nion/utils/ListModel.py
-   .../projects/nionutils/nion/utils/ListModel.py:632:76 - error: Cannot access attribute "begin_changes_event" for class "Observable"
-     Attribute "begin_changes_event" is unknown (reportAttributeAccessIssue)
-   .../projects/nionutils/nion/utils/ListModel.py:633:74 - error: Cannot access attribute "end_changes_event" for class "Observable"
-     Attribute "end_changes_event" is unknown (reportAttributeAccessIssue)
-   .../projects/nionutils/nion/utils/ListModel.py:661:56 - error: "item_changed_event" is not a known attribute of "None" (reportOptionalMemberAccess)
-   .../projects/nionutils/nion/utils/ListModel.py:792:72 - error: Cannot access attribute "begin_changes_event" for class "Observable"
-     Attribute "begin_changes_event" is unknown (reportAttributeAccessIssue)
-   .../projects/nionutils/nion/utils/ListModel.py:793:70 - error: Cannot access attribute "end_changes_event" for class "Observable"
-     Attribute "end_changes_event" is unknown (reportAttributeAccessIssue)
- .../projects/nionutils/nion/utils/Stream.py
-   .../projects/nionutils/nion/utils/Stream.py:552:75 - error: TypeVar "T" is already in use by an outer scope (reportGeneralTypeIssues)
- .../projects/nionutils/nion/utils/StructuredModel.py
-   .../projects/nionutils/nion/utils/StructuredModel.py:91:16 - error: Type "RecordModel" is not assignable to return type "ModelLike"
-     "RecordModel" is incompatible with protocol "ModelLike"
-       "ModelLike" is not assignable to "RecordModel"
-       "from_dict_value" is an incompatible type
-         Type "(values: DictValue) -> None" is not assignable to type "(value: DictValue) -> None"
-           Parameter name mismatch: "value" versus "values"
-       "copy_from" is an incompatible type
-         Type "(record: RecordModel) -> None" is not assignable to type "(m: Any) -> Any"
-           Parameter name mismatch: "m" versus "record" (reportReturnType)
-   .../projects/nionutils/nion/utils/StructuredModel.py:93:16 - error: Type "ArrayModel" is not assignable to return type "ModelLike"
-     "ArrayModel" is incompatible with protocol "ModelLike"
-       "ModelLike" is not assignable to "ArrayModel"
-       "from_dict_value" is an incompatible type
-         Type "(values: DictValue) -> None" is not assignable to type "(value: DictValue) -> None"
-           Parameter name mismatch: "value" versus "values"
-       "copy_from" is an incompatible type
-         Type "(array: ArrayModel) -> None" is not assignable to type "(m: Any) -> Any"
-           Parameter name mismatch: "m" versus "array" (reportReturnType)
- 15 errors, 0 warnings, 0 informations

pyinstrument (https://github.com/joerick/pyinstrument)
- .../projects/pyinstrument/pyinstrument/magic/magic.py
-   .../projects/pyinstrument/pyinstrument/magic/magic.py:10:8 - error: Import "IPython" could not be resolved (reportMissingImports)
-   .../projects/pyinstrument/pyinstrument/magic/magic.py:12:6 - error: Import "IPython.core.magic" could not be resolved (reportMissingImports)
-   .../projects/pyinstrument/pyinstrument/magic/magic.py:13:6 - error: Import "IPython.core.magic_arguments" could not be resolved (reportMissingImports)
-   .../projects/pyinstrument/pyinstrument/magic/magic.py:14:6 - error: Import "IPython.display" could not be resolved (reportMissingImports)
- .../projects/pyinstrument/pyinstrument/middleware.py
-   .../projects/pyinstrument/pyinstrument/middleware.py:6:6 - error: Import "django.conf" could not be resolved (reportMissingImports)
-   .../projects/pyinstrument/pyinstrument/middleware.py:7:6 - error: Import "django.http" could not be resolved (reportMissingImports)
-   .../projects/pyinstrument/pyinstrument/middleware.py:8:6 - error: Import "django.utils.module_loading" could not be resolved (reportMissingImports)
-   .../projects/pyinstrument/pyinstrument/middleware.py:15:10 - error: Import "django.utils.deprecation" could not be resolved (reportMissingImports)
- .../projects/pyinstrument/pyinstrument/renderers/html.py
-   .../projects/pyinstrument/pyinstrument/renderers/html.py:146:25 - error: The function "open" is deprecated
-     Deprecated since Python 3.14. Use `open()` instead. (reportDeprecated)
- .../projects/pyinstrument/pyinstrument/stack_sampler.py
-   .../projects/pyinstrument/pyinstrument/stack_sampler.py:12:6 - warning: Import "pyinstrument.low_level.stat_profile" could not be resolved from source (reportMissingModuleSource)
- .../projects/pyinstrument/pyinstrument/typing.py
-   .../projects/pyinstrument/pyinstrument/typing.py:5:10 - warning: Import "typing_extensions" could not be resolved from source (reportMissingModuleSource)
-   .../projects/pyinstrument/pyinstrument/typing.py:6:10 - warning: Import "typing_extensions" could not be resolved from source (reportMissingModuleSource)
- 9 errors, 3 warnings, 0 informations
+ TypeError: Cannot read properties of undefined (reading 'getDirectory')
+     at r._findClosestMatch (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:224:32)
+     at r._getMappedEntry (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:257:35)
+     at r._isOriginalPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:268:21)
+     at r.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:34:18)
+     at s.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolverFileSystem.ts:134:33)
+     at Object.t.getTypeShedFallbackPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/pythonPathUtils.ts:30:12)
+     at d._computeTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:249:42)
+     at d.getTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:41:27)
+     at d.getTypeshedSubdirectory (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:57:35)
+     at e._getStdlibTypeshedPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:1948:62)
+     at e.getImportRoots (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:349:34)
+     at ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:416:66)
+     at t.BackgroundAnalysisProgram._ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:279:37)
+     at ...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:75
+     at Array.forEach (<anonymous>)
+     at t.BackgroundAnalysisProgram.setImportResolver (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:55)
+     at e.applyConfigOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:698:41)
+     at e.setOptions (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/service.ts:335:14)
+     at L (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:567:13)
+     at V (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:451:12)
+     at Q (...pyright_to_test/packages/pyright/dist/pyright-internal/src/pyright.ts:1393:28)

mypy_primer (https://github.com/hauntsaninja/mypy_primer)
- 0 errors, 0 warnings, 0 informations
+ TypeError: Cannot read properties of undefined (reading 'getDirectory')
+     at r._findClosestMatch (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:224:32)
+     at r._getMappedEntry (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:257:35)
+     at r._isOriginalPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:268:21)
+     at r.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/readonlyAugmentedFileSystem.ts:34:18)
+     at s.existsSync (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolverFileSystem.ts:134:33)
+     at Object.t.getTypeShedFallbackPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/pythonPathUtils.ts:30:12)
+     at d._computeTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:249:42)
+     at d.getTypeshedRoot (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:41:27)
+     at d.getTypeshedSubdirectory (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/typeshedInfoProvider.ts:57:35)
+     at e._getStdlibTypeshedPath (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:1948:62)
+     at e.getImportRoots (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:349:34)
+     at ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/importResolver.ts:416:66)
+     at t.BackgroundAnalysisProgram._ensurePartialStubPackages (...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:279:37)
+     at ...pyright_to_test/packages/pyright/dist/pyright-internal/src/analyzer/backgroundAnalysisProgram.ts:100:75
+     at Array.forEach (<anonymous>)

... (truncated 10975 lines) ...```

Comment thread packages/pyright-internal/src/analyzer/pythonPathUtils.ts Outdated
@mochaaP
mochaaP force-pushed the mochaa/external-typeshed branch from 2aaa7c2 to 257be41 Compare June 11, 2026 18:14
Signed-off-by: Zephyr Lykos <git@mochaa.ws>
@mochaaP

mochaaP commented Jun 11, 2026

Copy link
Copy Markdown
Author

Might be nice to add a test to verify this works. Like what if the env variable doesn't end with a '/'. Does it still work?

Updated, catching this with fs.statSync now. Errors are intentionally not caught to indicate a configuration error

@mochaaP
mochaaP force-pushed the mochaa/external-typeshed branch from 257be41 to 800efe5 Compare June 11, 2026 18:17
const envTypeshedUri = UriEx.file(envTypeshedPath);
const stats = fs.statSync(envTypeshedUri);
if (stats.isDirectory()) {
return fs.realCasePath(envTypeshedUri);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📍 packages/pyright-internal/src/analyzer/pythonPathUtils.ts:32

fs.statSync(envTypeshedUri) has no existence guard and no try/catch, so a missing/typo'd/stale PYRIGHT_TYPESHED_PATH throws ENOENT out of getTypeShedFallbackPath. Nothing on the call path wraps this, so instead of falling back to bundled typeshed the analyzer's stub resolution breaks. This file already imports tryStat/isDirectory precisely because statSync throws. Replace with the safe idiom: if (isDirectory(fs, envTypeshedUri)) { return fs.realCasePath(envTypeshedUri); }.

export function getTypeShedFallbackPath(
fs: Pick<FileSystem, 'getModulePath' | 'existsSync' | 'realCasePath' | 'statSync'>
) {
const envTypeshedPath = process.env.PYRIGHT_TYPESHED_PATH;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📍 packages/pyright-internal/src/analyzer/pythonPathUtils.ts:30

The precedent PYRIGHT_TMPDIR reads process.env.PYRIGHT_TMPDIR?.trim(), but this code omits .trim(). A trailing newline/space (common in shell/CI env exports) becomes part of the path and is then fed into the stat. Read the value as process.env.PYRIGHT_TYPESHED_PATH?.trim() to match the existing convention and avoid surprising failures.

return fs.realCasePath(envTypeshedUri);
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📍 packages/pyright-internal/src/analyzer/pythonPathUtils.ts:30

No tests cover the new behavior. Add a focused regression test for the three cases: valid dir → override used; path is a file → silently ignored; non-existent path → no throw, graceful fallback to bundled typeshed. The missing-path test would catch the crash above directly. Restore/delete process.env.PYRIGHT_TYPESHED_PATH in afterEach to avoid leaking global state into other suites.

@rchiodo

rchiodo commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Core idea is fine, but the env-var path must use the safe stat idiom already present in this file (isDirectory/tryStat) so a bad PYRIGHT_TYPESHED_PATH falls back gracefully instead of throwing. Please also add regression tests for the valid-dir / file / missing-path cases.

@rchiodo

rchiodo commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Core concern: the env-var override uses an unguarded fs.statSync, which can throw and break stub resolution instead of gracefully falling back. Please use the existing isDirectory/tryStat idiom, trim the env value, and add regression tests for the valid-dir / file / missing-path cases.

@rchiodo

rchiodo commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Main blocker: guard the env-path lookup using the existing isDirectory/tryStat idiom already imported in this file, since statSync throws on missing paths. Adding a small regression test and trimming the env value would round it out.

@rchiodo

rchiodo commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

🔒 Automated review in progress — @rchiodo is auto-reviewing this PR.

return fs.realCasePath(envTypeshedUri);
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The raw fs.statSync(envTypeshedUri) throws ENOENT when PYRIGHT_TYPESHED_PATH points to a non-existent path — a very likely misconfiguration (typo, stale export, moved checkout). That throw propagates through getTypeShedFallbackPath into typeshed/import resolution with no try/catch in the chain, turning the intended graceful fallback into broken analysis. This file already imports tryStat and isDirectory for exactly this stat-with-guard pattern (and the rest of the function uses existsSync guards). Fix: const stats = tryStat(fs, envTypeshedUri); if (stats?.isDirectory()) { return fs.realCasePath(envTypeshedUri); }. This also lets you drop 'statSync' from the widened Pick<FileSystem, …> signature.

return fs.realCasePath(envTypeshedUri);
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No tests were added. The analogous PYRIGHT_TMPDIR override ships with realTempFile.test.ts covering set/unset cases. Add coverage for: (1) valid external directory → returned via realCasePath; (2) non-existent path → does NOT throw and falls back to bundled typeshed (this case would have caught the statSync throw above); (3) file-instead-of-directory → ignored. Since process.env is global mutable state, save/restore it in afterEach to avoid leaking into other suites.

return fs.realCasePath(envTypeshedUri);
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new user-facing PYRIGHT_TYPESHED_PATH override is undocumented, making it undiscoverable. Add a one-line mention in docs/ alongside the existing typeshedPath config. Optionally, log via importLogger when the override is applied so users can confirm it took effect when debugging a wrong external typeshed.

@rchiodo

rchiodo commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Core concern: the PYRIGHT_TYPESHED_PATH override should fail gracefully. Use the already-imported tryStat/isDirectory guard instead of a raw statSync, and add basic coverage for the valid/missing/not-a-directory cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants