-
-
Notifications
You must be signed in to change notification settings - Fork 454
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Return Promise for lazy functions. (#689)
* Type the return value of lazy translation functions as Promise. The return value of the lazy translation functions is a proxied `Promise` object. https://github.com/django/django/blob/3.2.6/django/utils/translation/__init__.py#L135-L221. Signed-off-by: Zixuan James Li <[email protected]> * Mark unicode translation functions for deprecation. https://docs.djangoproject.com/en/4.0/releases/4.0/#features-removed-in-4-0. Signed-off-by: Zixuan James Li <[email protected]> * Add proxied functions for Promise. Although there is nothing defined in `Promise` itself, the only instances of `Promise` are created by the `lazy` function, with magic methods defined on it. https://github.com/django/django/blob/3.2.6/django/utils/functional.py#L84-L191. Signed-off-by: Zixuan James Li <[email protected]> * Add _StrPromise as a special type for Promise objects for str. This allows the user to access methods defined on lazy strings while still letting mypy be aware of that they are not instances of `str`. The definitions for some of the magic methods are pulled from typeshed. We need those definitions in the stubs so that `_StrPromise` objects will work properly with operators, as refining operator types is tricky with the mypy plugins API. The rest of the methods will be covered by an attribute hook. Signed-off-by: Zixuan James Li <[email protected]> * Implement _StrPromise attribute hook. This implements an attribute hook that provides type information for methods that are available on `builtins.str` for `_StrPromise` except the supported operators. This allows us to avoid copying stubs from the builtins for all supported methods on `str`. Signed-off-by: Zixuan James Li <[email protected]> * Allow message being a _StrPromise object for RegexValidator. One intended usage of lazystr is to postpone the translation of the error message of a validation error. It is possible that we pass a Promise (specifically _StrPromise) and only evaluate it when a ValidationError is raised. Signed-off-by: Zixuan James Li <[email protected]> * Refactor _StrPromise attribtue hook with analyze_member_access. Signed-off-by: Zixuan James Li <[email protected]> Signed-off-by: Zixuan James Li <[email protected]>
- Loading branch information
Showing
7 changed files
with
122 additions
and
15 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from mypy.checkmember import analyze_member_access | ||
from mypy.errorcodes import ATTR_DEFINED | ||
from mypy.nodes import CallExpr, MemberExpr | ||
from mypy.plugin import AttributeContext | ||
from mypy.types import AnyType, Instance | ||
from mypy.types import Type as MypyType | ||
from mypy.types import TypeOfAny | ||
|
||
from mypy_django_plugin.lib import helpers | ||
|
||
|
||
def resolve_str_promise_attribute(ctx: AttributeContext) -> MypyType: | ||
if isinstance(ctx.context, MemberExpr): | ||
method_name = ctx.context.name | ||
elif isinstance(ctx.context, CallExpr) and isinstance(ctx.context.callee, MemberExpr): | ||
method_name = ctx.context.callee.name | ||
else: | ||
ctx.api.fail(f'Cannot resolve the attribute of "{ctx.type}"', ctx.context, code=ATTR_DEFINED) | ||
return AnyType(TypeOfAny.from_error) | ||
|
||
str_info = helpers.lookup_fully_qualified_typeinfo(helpers.get_typechecker_api(ctx), f"builtins.str") | ||
assert str_info is not None | ||
str_type = Instance(str_info, []) | ||
return analyze_member_access( | ||
method_name, | ||
str_type, | ||
ctx.context, | ||
is_lvalue=False, | ||
is_super=False, | ||
# operators are already handled with magic methods defined in the stubs for _StrPromise | ||
is_operator=False, | ||
msg=ctx.api.msg, | ||
original_type=ctx.type, | ||
chk=helpers.get_typechecker_api(ctx), | ||
) |
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