-
Notifications
You must be signed in to change notification settings - Fork 611
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Resolve circular references in user code
Summary: # What? Tests failed due to circular references that prevented buck's ability to build python binaries. # Why? The use of the "self-import" to set `_fbthrift_current_module` in the various types modules was the trigger. While the root cause might be elsewhere, I didn't see a strong enough reason to determine if we could make the `_fbthrift_current_module` solution work when there was previously proved workable solution available. # Solution? The original problem to solve was {D66664174}. Use a reserved identifier as an alias for the types in the modules and use this alias as the type annotation rather than the original type. This prevents the problem that user functions, which, when named the same as a type, redefine the type as a function, and render that name unusable as a type annotation. (Side Note: This was a change in a previous iteration before the use of the current module import, which we considered less attractive than the use of the fully qualified name with the current module at that time. Now we have different constraints, which changes our answer.) # Reject options - Obtain the current module via `sys.modules[__name__]`. - Rejected because this works at run-time. It does not work at type-check time. - Use `__fbthrift_` as the alias prefix. - Rejected because this leads to an undefined symbol due to the way that Python mangles the name. ``` class TestStruct(...): ... __fbthrift_TestStruct = TestStruct class TestFieldNameSameAsTypeName(...): @_fbthrift_property def FieldNameSameAsTypeName(def) -> __fbthrift_TestStruct: ... ``` The type-checker sees `__fbthrift_TestStruct` as `_TestFieldNameSameAsTypeName_fbthrift_TestStruct`, which is not defined. Reviewed By: prakashgayasen Differential Revision: D66932282 fbshipit-source-id: dd143ecd351ff3172a5b9efbac33affa6c57471d
- Loading branch information
1 parent
6000643
commit a8a40b1
Showing
234 changed files
with
3,584 additions
and
3,222 deletions.
There are no files selected for viewing
77 changes: 77 additions & 0 deletions
77
thrift/compiler/generate/templates/python/private/alias_prefix.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
{{! | ||
Copyright (c) Meta Platforms, Inc. and affiliates. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
}}_fbthrift_{{! | ||
Why this huge comment for an 10 character string? | ||
It is to give someone pause before they decide it is unnecessary | ||
without the knowledge of the reasons for this partial. | ||
What is the purpose of the alias prefix? | ||
This resolves the type check error below. | ||
Annotation `TestFieldNameSameAsTypeName.SomeTypeName` is not defined as a type. | ||
When a thrift field name (TestFieldNameSameAsTypeName.SomeTypeName in this example) | ||
is exactly the same as a thrift type name (SomeTypeName in this example) | ||
and the type name is used as the type for a field within the same type | ||
that contains that field, then type check fails because the type name, | ||
which is now bound to a function, is not considered a valid type annotation. | ||
Why use a partial for the prefix, which has way more characters, than the | ||
prefix directly? | ||
The goal of partial was NOT to reduce the length of the identifier at the | ||
sites that reference it. It is | ||
1. to reveal intent | ||
2. make it easier to find the places that use this prefix. | ||
3. It is easier to explain the reason for the choice of the prefix in one | ||
place, as you can see from the comment in this file. | ||
4. In cases where the prefix is a common string and harder to search for | ||
just the instances with this specific intent, like `_fbthrift`, | ||
this makes it easier to change the name in all the sites with | ||
just the change to the partial. | ||
( | ||
More detail: The prefix went through a few iterations of changes. | ||
When I changed the name each time, especially, when it was a name like | ||
`_fbthrift_`, which appears in places other than just as this alias_prefix | ||
just a search and replace was not easily possible. | ||
I had to rely on the tests to ensure I addressed | ||
all the locations where I needed to make this change, | ||
which increase the number of cycles before the change completed. | ||
) | ||
Why _fbthrift_ and not __fbthrift_, which would deter unintentional use of that symbol? | ||
As you might already know, Python mangles the double underscore version | ||
and it becomes more difficult to infer the correct name of the type hint, | ||
if that is even possible, and brittle as well, is case Python changes how | ||
it mangles that name. | ||
The single underscore version, _fbthrift_, does not prevent use by | ||
client-sites unless the module deletes this symbol within the context of | ||
the module. The delete caused the call to typing.get_type_hints by the test for | ||
property type hints in the abstract types test to fail because that call | ||
did not have access to the deleted symbol. | ||
I briefly considered _fbthrift_WILL_NOT_FIX_BREAKAGES_IF_YOU_USE_THIS_. | ||
That makes the generated code hard to read. | ||
I decided to stay simple to unblock this fix. I added the DO_BEFORE below | ||
to revisit this issue. | ||
DO_BEFORE(satishvk, 20241231): Determine if it is acceptable to accept | ||
the risk that user code will use the _fbthrift_actual_symbol or | ||
it is important enough to find a different approach to solve the problem | ||
of fieldname matches the typename. | ||
}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 0 additions & 31 deletions
31
thrift/compiler/generate/templates/python/types/set_current_module.mustache
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.