-
Notifications
You must be signed in to change notification settings - Fork 271
Python: improve default values and use dataclasses to keep mypy happy. #2552
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
"Rust and Foreign Language tests" are failing with the mypy errors. |
059c2bf
to
4625463
Compare
This isn't just builtins: class foo: # unlikely, but looking at the general case...
pass
class Test:
bool: bool
int: int
foo: foo
def __init__(self, bool: bool, foo: foo):
pass
t = Test(True, foo()) mypy complains:
(not clear why So my initial naive idea of just special-casing builtin types and using a fully-qualified name from the |
@crazytonyli @joe-p @akhramov any ideas here? Not a big deal but slightly annoying. |
If the from dataclasses import dataclass
class foo:
pass
@dataclass(init=False)
class Test:
def __init__(self, bool: bool, foo: foo) -> None:
self.bool = bool
self.foo = foo
test = Test(bool=True, foo=foo())
foo_val = test.foo In this case MyPy knows If explicit type hints on the instance vars are desired you could use type aliases, but that was added in 3.10. To be clear I'm not sure why this would be required. I've confirmed both mypy and basedpyright are able to infer the types properly with the above solution. BoolType: TypeAlias = bool
FooType: TypeAlias = foo
@dataclass
class Test:
bool: BoolType
foo: FooType Edit: I realized you could also just not use the TypeAlias type hint and it would still work BoolType = bool
FooType = foo
@dataclass
class Test:
bool: BoolType
foo: FooType Although I still think the first solution is preferable because it avoid the alias type being shown to the user |
dataclass is interesting - it looks like it will generate |
huh - we also use the field as a placeholder for the field docstring :(
|
Oh sorry for some reason I thought uniffi already used dataclass. But yeah the fix for this specific issue still works without dataclasses.
Looks like we can define them like this according to PEP 258. I just noticed that that PEP is rejected but I have confirmed locally that these style docstrings are picked up by basedpyright and sphinx, so probably safe to assume most tooling supports them. class Test:
def __init__(self, bool: bool, foo: foo) -> None:
self.bool = bool
""" This is a boolean field """
self.foo = foo
""" This is a foo field """ |
huh - line 2 of that file is identical - so we are just repeating the record docstring for every field, which can be seen in the docstring test:
and the test is checking only the class -
__doc__ and doesn't appear in help() . The basedpyright playground doesn't seem to show anything about docs, although it is upset at our signatures for __str__ etc. The right thing to do for now is probably to just omit those field docs entirely and tackle that in another issue?
|
4625463
to
774e590
Compare
@joe-p what do you think about this? |
Oh interesting... yeah for now type inference in |
This is failing with:
with error:
|
What is if opt_integer is None:
self.opt_integer = 42
else:
self.opt_integer = opt_integer This should also work: if opt_integer is None or is _DEFAULT:
self.opt_integer = 42
else:
self.opt_integer = opt_integer Alternatively if |
It's a placeholder - mainly to handle the "default value" case rather than null. We can't unconditionally use literals due to list etc. But even in the None case it's a little problematic - |
(I mean I guess we probably could use literals everywhere other than where they cause problems, but that still leaves lists, maps and objects) |
774e590
to
7cf9e55
Compare
That actually worked out really well and made the generated code for default values much much better. |
7cf9e55
to
916a063
Compare
Improved how default values are handled in function signatures etc, and more canonical use of Python dataclasses for records and enums, all towards making mypy happier
916a063
to
6450438
Compare
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 don't understand all the mypy stuff, but I trust you and joe-p on that. Behavior-wise, I can't see anything that's changed so thumbs up from me.
cargo test -p uniffi-fixture-keywords-rust
works, but:This just demonstrates the error but makes no attempt to fix it yet.