Skip to content

Make property a type #199

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

Merged
merged 2 commits into from
May 16, 2016
Merged

Make property a type #199

merged 2 commits into from
May 16, 2016

Conversation

beckjake
Copy link
Contributor

This adds partial support for property in the builtins/__builtin__ module, fixing python/mypy#1529

This allows subclassing property and some basic property behavior but it's got a few warts still:

  1. Return values for setter(), getter(), and deleter() on a subclass are by default the subclassed type, but mypy still thinks it's a 'property'. This is usually benign but can be annoying.
  2. You can't use the decorator syntax on your custom property either, because mypy wants you to @override things. I think that's an issue with mypy's understanding of decorators.

You can use the old non-decorator style of declaring your getter/setter/deleter and then calling everything with the constructor though.

@gvanrossum
Copy link
Member

That was fast!

The answer to (1) would be to introduce "SelfType", see python/mypy#1212. So I guess we'll have to live with it for now.

As to (2), can you show the code you tried? I am trying something like you mentioned in python/mypy#1529 but I don't get an error:

class P(property):
    pass
class C:
    @P
    def attr(self) -> int:
        return 42
print(C().attr)

I'm also honestly not sure what good all the type variables do -- since you didn't make the property class itself generic, it looks like you just made the methods all generic functions, but since none of the type variables are used more than once per method you might as well have replaced them all with Any.

Finally, the __init__ signatures are rather long -- they probably should be broken up.

@beckjake
Copy link
Contributor Author

The problem with 2 is in the attr.setter syntax. My code for 2 was:

class fooprop(property):
    pass

class Foo:
    @fooprop
    def bar(self) -> int:
        print('returning bar=3')
        return 3

    @bar.setter
    def bar(self, value: int):
        print('tried to set bar={}'.format(value))

Running mypy, I get:

test.py:7: error: 'overload' decorator expected
test.py:12: error: Name 'bar' is not defined
test.py:12: error: 'overload' decorator expected

I'll make the suggested changes in a moment.

@beckjake
Copy link
Contributor Author

I think the fix for making getter/setter/deleter work correctly would be in mypy rather than here and it seems kind of tricky. It seems you'd have to change the check for property-ness in semanal.py, line 1559. Currently it's part of a long if-elif chain matching against those two names, that would have to become something more complicated.

@gvanrossum gvanrossum merged commit 70389d1 into python:master May 16, 2016
@beckjake beckjake deleted the property-is-a-type branch May 17, 2016 05:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants