From f9b8277b920755933031c2b7a408141658501e28 Mon Sep 17 00:00:00 2001 From: Steven Troxler Date: Tue, 29 Oct 2024 09:13:53 -0700 Subject: [PATCH] Prevent users from shadowing `builtins.pyi` in ptt Summary: When using buck-based per-target type checking, we realised that it is possible for users, by setting `base_module = ''` and having an `__init__.py`, to shadow `builtins.py`. This is pretty confusing because there's no user-visible indication that this is happening, and we just get tons of type errors on all the builtin types being undefined. Reviewed By: grievejia Differential Revision: D65076559 fbshipit-source-id: d1ea05c3d0b5c6a8b2e114ba42fb7b81e2f1f1a8 --- source/buck_command/buckBasedSourceCodeApi.ml | 14 +++++++++++--- source/buck_command/test/sourceCodeApiTest.ml | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/source/buck_command/buckBasedSourceCodeApi.ml b/source/buck_command/buckBasedSourceCodeApi.ml index bca83e0ee59..53e595f25c0 100644 --- a/source/buck_command/buckBasedSourceCodeApi.ml +++ b/source/buck_command/buckBasedSourceCodeApi.ml @@ -78,9 +78,17 @@ let create let source_index = build_index ~configuration:dummy_configuration source_module_paths in let dependency_index = build_index ~configuration:dummy_configuration dependency_module_paths in let merged_index = - (* Source files always take priority over dependency files *) - (* TODO: Revisit this decision once we get more results from production *) - let combine ~key:_ source_value _dependency_value = source_value in + (* Source files always take priority over dependency files, except in the special case of the + Reference.empty module name, in which case we make sure that it is not possible for an + `__init__.py` to shadow `builtins.pyi`. *) + let combine ~key:_ source_module_path dependency_module_path = + match + ( String.equal (ModulePath.relative dependency_module_path) "builtins.pyi", + String.equal (ModulePath.relative source_module_path) "builtins.pyi" ) + with + | true, false -> dependency_module_path + | _, _ -> source_module_path + in Map.merge_skewed source_index dependency_index ~combine in let implicit_modules = diff --git a/source/buck_command/test/sourceCodeApiTest.ml b/source/buck_command/test/sourceCodeApiTest.ml index cf166e1226f..8347f25fb3e 100644 --- a/source/buck_command/test/sourceCodeApiTest.ml +++ b/source/buck_command/test/sourceCodeApiTest.ml @@ -186,7 +186,7 @@ let test_source_code_api = in create loader listing in - assert_lookup_relative_path ~context ~api [!"", Some "__init__.py"]; + assert_lookup_relative_path ~context ~api [!"", Some "builtins.pyi"]; ()); ]