-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Support factory= in attr plugin. #5005
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
It works pretty much like default=
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Here are some comments.
attr_has_factory = bool(_get_argument(rvalue, 'factory')) | ||
|
||
if attr_has_default and attr_has_factory: | ||
ctx.api.fail("Can't pass both `default` and `factory`.", rvalue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a good idea to always add tests for any newly added error messages.
@attr.s | ||
class A: | ||
x: List[int] = attr.ib(factory=list) | ||
y: int = attr.ib(factory=my_factory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add also a test where this fails due to a wrong return type of the factory function.
mypy/plugins/attrs.py
Outdated
if attr_has_default and attr_has_factory: | ||
ctx.api.fail("Can't pass both `default` and `factory`.", rvalue) | ||
elif attr_has_factory: | ||
attr_has_default = attr_has_factory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think attr_has_default = True
would be shorter and cleaner.
Done and done! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few more comments.
test-data/unit/lib-stub/attr.pyi
Outdated
factory: Optional[Callable[[], _T]] = ..., | ||
) -> _T: ... | ||
# This form catches explicit None or no default but with no other arguments returns Any. | ||
# This form catches explicit None or no default but with no other arguments returns Any. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is repeated twice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops.
|
||
_T = TypeVar('_T') | ||
_C = TypeVar('_C', bound=type) | ||
|
||
_ValidatorType = Callable[[Any, Any, _T], Any] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought validator should return bool
, isn't this the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value of validators is ignored. A validation error is a raised exception. However I don't want to force a "None"
test-data/unit/check-attr.test
Outdated
import attr | ||
@attr.s | ||
class A: | ||
x: int = attr.ib(factory=list) # E: Incompatible types in assignment (expression has type "List[T]", variable has type "int") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message looks a bit cryptic. Why it is List[T]
and not List[Any]
? There is no T
in code. I suppose this might be a bug in using class as factory, is the error better if you use a generic function instead of class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error come from the stubs not from the plugin (i.e. any method that takes a type would give this error message.) I can add a generic function too.
Thanks for the quick review. Your requests have been implemented. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, if there are no concerns, I am going to merge this later today.
This is a new feature in attrs 18.1
The implementation is just like
default=