Skip to content
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

Documentation confusion - implicit vs explicit declaration #226

Open
omry opened this issue Dec 25, 2019 · 2 comments
Open

Documentation confusion - implicit vs explicit declaration #226

omry opened this issue Dec 25, 2019 · 2 comments

Comments

@omry
Copy link

@omry omry commented Dec 25, 2019

The documentation equates two kinds of attribute declarations:

explicit:

 class Derp:
    attribute: int = 1

    @property
    def property(self) -> int: ...

and implicit:

  class Derp:
    def __init__(self):
       self.attribute: int = 1

Those two things are not about explicit vs implicit declaration, but about class membership (static field) vs member field.

I think it's worth changing the doc to avoid confusion.

Example of difference:

In [1]: class Derp:
   ...:     x : int = 10
   ...:

In [2]: Derp.x
Out[2]: 10

In [3]:   class Derp:
   ...:     def __init__(self):
   ...:        self.attribute: int = 1
   ...:

In [4]: Derp.x
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-d80ae71850d9> in <module>
----> 1 Derp.x
@grievejia
Copy link
Contributor

@grievejia grievejia commented Dec 27, 2019

According to PEP 526, the first form of attribute declaration should actually be treated as instance membership as opposed to class membership by the type checker. If you explicitly want class membership, you'll need to use ClassVar:

class Derp:
  instance_attribute: int = 1  # instance membership
  class_attribute: ClassVar[int] = 1  # class membership

I don' t think Pyre currently fully enforce this distinction, but we might eventually go there in the future as I feel there's value in explicitly distinguishing between instance members and class members.

The fact that Derp.instance_attribute exists as class member at runtime is rather unfortunate -- but IMO that's more of a compromise to the legacy Python runtime when PEP 484/526 was introduced, not an intended behavior.

@omry
Copy link
Author

@omry omry commented Dec 28, 2019

Yeah, it does seem unfortunate.
I think a better recommendation for explicit class member typing is:

class Foo:
  x: int
  def __init__():
    self.x = 10

As opposed to the implicit one:

class Foo:
  def __init__():
    self.x : int = 10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.