{"action":"closed","number":2415,"pull_request":{"url":"https://api.github.com/repos/python/mypy/pulls/2415","id":92674916,"html_url":"https://github.com/python/mypy/pull/2415","diff_url":"https://github.com/python/mypy/pull/2415.diff","patch_url":"https://github.com/python/mypy/pull/2415.patch","issue_url":"https://api.github.com/repos/python/mypy/issues/2415","number":2415,"state":"closed","locked":false,"title":"Allow instance access to class attributes that are class objects","user":{"login":"ilevkivskyi","id":12005495,"avatar_url":"https://avatars.githubusercontent.com/u/12005495?v=3","gravatar_id":"","url":"https://api.github.com/users/ilevkivskyi","html_url":"https://github.com/ilevkivskyi","followers_url":"https://api.github.com/users/ilevkivskyi/followers","following_url":"https://api.github.com/users/ilevkivskyi/following{/other_user}","gists_url":"https://api.github.com/users/ilevkivskyi/gists{/gist_id}","starred_url":"https://api.github.com/users/ilevkivskyi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ilevkivskyi/subscriptions","organizations_url":"https://api.github.com/users/ilevkivskyi/orgs","repos_url":"https://api.github.com/users/ilevkivskyi/repos","events_url":"https://api.github.com/users/ilevkivskyi/events{/privacy}","received_events_url":"https://api.github.com/users/ilevkivskyi/received_events","type":"User","site_admin":false},"body":"Currently, mypy flags as error access via instances to class attributes that are class objects. For example:\r\n```python\r\nclass C:\r\n    ...\r\nclass D:\r\n    c = C\r\n    def __init__(self) -> None:\r\n        self.c  # Flagged as error, but perfectly valid at runtime\r\n        self.c()  # Flagged as error, but perfectly valid at runtime\r\n\r\nD().c  # Flagged as error, but perfectly valid at runtime\r\nD().c()  # Flagged as error, but perfectly valid at runtime\r\n```\r\n\r\nIn this PR I propose to allow this since it is valid at runtime, valid logically, and is sometimes a useful pattern (in django for example).\r\n\r\nThe fix is very simple -- don't consider ``FunctionLike`` members with ``.is_type_obj()`` returning ``True`` as instance methods.","created_at":"2016-11-07T22:10:36Z","updated_at":"2016-11-08T23:13:27Z","closed_at":"2016-11-08T23:13:27Z","merged_at":"2016-11-08T23:13:27Z","merge_commit_sha":"f8c3550b9405bf419aa1e0d6f7eb56dc10565a89","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/python/mypy/pulls/2415/commits","review_comments_url":"https://api.github.com/repos/python/mypy/pulls/2415/comments","review_comment_url":"https://api.github.com/repos/python/mypy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/python/mypy/issues/2415/comments","statuses_url":"https://api.github.com/repos/python/mypy/statuses/a363f1e9a39306b956f137f28871ee32c33cb2e3","head":{"label":"ilevkivskyi:type-valued-attrs","ref":"type-valued-attrs","sha":"a363f1e9a39306b956f137f28871ee32c33cb2e3","user":{"login":"ilevkivskyi","id":12005495,"avatar_url":"https://avatars.githubusercontent.com/u/12005495?v=3","gravatar_id":"","url":"https://api.github.com/users/ilevkivskyi","html_url":"https://github.com/ilevkivskyi","followers_url":"https://api.github.com/users/ilevkivskyi/followers","following_url":"https://api.github.com/users/ilevkivskyi/following{/other_user}","gists_url":"https://api.github.com/users/ilevkivskyi/gists{/gist_id}","starred_url":"https://api.github.com/users/ilevkivskyi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ilevkivskyi/subscriptions","organizations_url":"https://api.github.com/users/ilevkivskyi/orgs","repos_url":"https://api.github.com/users/ilevkivskyi/repos","events_url":"https://api.github.com/users/ilevkivskyi/events{/privacy}","received_events_url":"https://api.github.com/users/ilevkivskyi/received_events","type":"User","site_admin":false},"repo":{"id":55439770,"name":"mypy","full_name":"ilevkivskyi/mypy","owner":{"login":"ilevkivskyi","id":12005495,"avatar_url":"https://avatars.githubusercontent.com/u/12005495?v=3","gravatar_id":"","url":"https://api.github.com/users/ilevkivskyi","html_url":"https://github.com/ilevkivskyi","followers_url":"https://api.github.com/users/ilevkivskyi/followers","following_url":"https://api.github.com/users/ilevkivskyi/following{/other_user}","gists_url":"https://api.github.com/users/ilevkivskyi/gists{/gist_id}","starred_url":"https://api.github.com/users/ilevkivskyi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ilevkivskyi/subscriptions","organizations_url":"https://api.github.com/users/ilevkivskyi/orgs","repos_url":"https://api.github.com/users/ilevkivskyi/repos","events_url":"https://api.github.com/users/ilevkivskyi/events{/privacy}","received_events_url":"https://api.github.com/users/ilevkivskyi/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ilevkivskyi/mypy","description":"Optional static typing for Python","fork":true,"url":"https://api.github.com/repos/ilevkivskyi/mypy","forks_url":"https://api.github.com/repos/ilevkivskyi/mypy/forks","keys_url":"https://api.github.com/repos/ilevkivskyi/mypy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ilevkivskyi/mypy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ilevkivskyi/mypy/teams","hooks_url":"https://api.github.com/repos/ilevkivskyi/mypy/hooks","issue_events_url":"https://api.github.com/repos/ilevkivskyi/mypy/issues/events{/number}","events_url":"https://api.github.com/repos/ilevkivskyi/mypy/events","assignees_url":"https://api.github.com/repos/ilevkivskyi/mypy/assignees{/user}","branches_url":"https://api.github.com/repos/ilevkivskyi/mypy/branches{/branch}","tags_url":"https://api.github.com/repos/ilevkivskyi/mypy/tags","blobs_url":"https://api.github.com/repos/ilevkivskyi/mypy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ilevkivskyi/mypy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ilevkivskyi/mypy/git/refs{/sha}","trees_url":"https://api.github.com/repos/ilevkivskyi/mypy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ilevkivskyi/mypy/statuses/{sha}","languages_url":"https://api.github.com/repos/ilevkivskyi/mypy/languages","stargazers_url":"https://api.github.com/repos/ilevkivskyi/mypy/stargazers","contributors_url":"https://api.github.com/repos/ilevkivskyi/mypy/contributors","subscribers_url":"https://api.github.com/repos/ilevkivskyi/mypy/subscribers","subscription_url":"https://api.github.com/repos/ilevkivskyi/mypy/subscription","commits_url":"https://api.github.com/repos/ilevkivskyi/mypy/commits{/sha}","git_commits_url":"https://api.github.com/repos/ilevkivskyi/mypy/git/commits{/sha}","comments_url":"https://api.github.com/repos/ilevkivskyi/mypy/comments{/number}","issue_comment_url":"https://api.github.com/repos/ilevkivskyi/mypy/issues/comments{/number}","contents_url":"https://api.github.com/repos/ilevkivskyi/mypy/contents/{+path}","compare_url":"https://api.github.com/repos/ilevkivskyi/mypy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ilevkivskyi/mypy/merges","archive_url":"https://api.github.com/repos/ilevkivskyi/mypy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ilevkivskyi/mypy/downloads","issues_url":"https://api.github.com/repos/ilevkivskyi/mypy/issues{/number}","pulls_url":"https://api.github.com/repos/ilevkivskyi/mypy/pulls{/number}","milestones_url":"https://api.github.com/repos/ilevkivskyi/mypy/milestones{/number}","notifications_url":"https://api.github.com/repos/ilevkivskyi/mypy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ilevkivskyi/mypy/labels{/name}","releases_url":"https://api.github.com/repos/ilevkivskyi/mypy/releases{/id}","deployments_url":"https://api.github.com/repos/ilevkivskyi/mypy/deployments","created_at":"2016-04-04T19:45:28Z","updated_at":"2016-04-04T19:45:30Z","pushed_at":"2016-11-08T16:53:31Z","git_url":"git://github.com/ilevkivskyi/mypy.git","ssh_url":"git@github.com:ilevkivskyi/mypy.git","clone_url":"https://github.com/ilevkivskyi/mypy.git","svn_url":"https://github.com/ilevkivskyi/mypy","homepage":"http://www.mypy-lang.org/","size":16231,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"python:master","ref":"master","sha":"4f7dbfc6307ab4bac5f6f5a7b4c96b1e57129eb5","user":{"login":"python","id":1525981,"avatar_url":"https://avatars.githubusercontent.com/u/1525981?v=3","gravatar_id":"","url":"https://api.github.com/users/python","html_url":"https://github.com/python","followers_url":"https://api.github.com/users/python/followers","following_url":"https://api.github.com/users/python/following{/other_user}","gists_url":"https://api.github.com/users/python/gists{/gist_id}","starred_url":"https://api.github.com/users/python/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/python/subscriptions","organizations_url":"https://api.github.com/users/python/orgs","repos_url":"https://api.github.com/users/python/repos","events_url":"https://api.github.com/users/python/events{/privacy}","received_events_url":"https://api.github.com/users/python/received_events","type":"Organization","site_admin":false},"repo":{"id":7053637,"name":"mypy","full_name":"python/mypy","owner":{"login":"python","id":1525981,"avatar_url":"https://avatars.githubusercontent.com/u/1525981?v=3","gravatar_id":"","url":"https://api.github.com/users/python","html_url":"https://github.com/python","followers_url":"https://api.github.com/users/python/followers","following_url":"https://api.github.com/users/python/following{/other_user}","gists_url":"https://api.github.com/users/python/gists{/gist_id}","starred_url":"https://api.github.com/users/python/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/python/subscriptions","organizations_url":"https://api.github.com/users/python/orgs","repos_url":"https://api.github.com/users/python/repos","events_url":"https://api.github.com/users/python/events{/privacy}","received_events_url":"https://api.github.com/users/python/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/python/mypy","description":"Optional static typing for Python 2 and 3 (PEP484)","fork":false,"url":"https://api.github.com/repos/python/mypy","forks_url":"https://api.github.com/repos/python/mypy/forks","keys_url":"https://api.github.com/repos/python/mypy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/python/mypy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/python/mypy/teams","hooks_url":"https://api.github.com/repos/python/mypy/hooks","issue_events_url":"https://api.github.com/repos/python/mypy/issues/events{/number}","events_url":"https://api.github.com/repos/python/mypy/events","assignees_url":"https://api.github.com/repos/python/mypy/assignees{/user}","branches_url":"https://api.github.com/repos/python/mypy/branches{/branch}","tags_url":"https://api.github.com/repos/python/mypy/tags","blobs_url":"https://api.github.com/repos/python/mypy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/python/mypy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/python/mypy/git/refs{/sha}","trees_url":"https://api.github.com/repos/python/mypy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/python/mypy/statuses/{sha}","languages_url":"https://api.github.com/repos/python/mypy/languages","stargazers_url":"https://api.github.com/repos/python/mypy/stargazers","contributors_url":"https://api.github.com/repos/python/mypy/contributors","subscribers_url":"https://api.github.com/repos/python/mypy/subscribers","subscription_url":"https://api.github.com/repos/python/mypy/subscription","commits_url":"https://api.github.com/repos/python/mypy/commits{/sha}","git_commits_url":"https://api.github.com/repos/python/mypy/git/commits{/sha}","comments_url":"https://api.github.com/repos/python/mypy/comments{/number}","issue_comment_url":"https://api.github.com/repos/python/mypy/issues/comments{/number}","contents_url":"https://api.github.com/repos/python/mypy/contents/{+path}","compare_url":"https://api.github.com/repos/python/mypy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/python/mypy/merges","archive_url":"https://api.github.com/repos/python/mypy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/python/mypy/downloads","issues_url":"https://api.github.com/repos/python/mypy/issues{/number}","pulls_url":"https://api.github.com/repos/python/mypy/pulls{/number}","milestones_url":"https://api.github.com/repos/python/mypy/milestones{/number}","notifications_url":"https://api.github.com/repos/python/mypy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/python/mypy/labels{/name}","releases_url":"https://api.github.com/repos/python/mypy/releases{/id}","deployments_url":"https://api.github.com/repos/python/mypy/deployments","created_at":"2012-12-07T13:30:23Z","updated_at":"2016-11-08T13:41:51Z","pushed_at":"2016-11-08T23:13:27Z","git_url":"git://github.com/python/mypy.git","ssh_url":"git@github.com:python/mypy.git","clone_url":"https://github.com/python/mypy.git","svn_url":"https://github.com/python/mypy","homepage":"http://www.mypy-lang.org/","size":19788,"stargazers_count":1952,"watchers_count":1952,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":229,"mirror_url":null,"open_issues_count":509,"forks":229,"open_issues":509,"watchers":1952,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/python/mypy/pulls/2415"},"html":{"href":"https://github.com/python/mypy/pull/2415"},"issue":{"href":"https://api.github.com/repos/python/mypy/issues/2415"},"comments":{"href":"https://api.github.com/repos/python/mypy/issues/2415/comments"},"review_comments":{"href":"https://api.github.com/repos/python/mypy/pulls/2415/comments"},"review_comment":{"href":"https://api.github.com/repos/python/mypy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/python/mypy/pulls/2415/commits"},"statuses":{"href":"https://api.github.com/repos/python/mypy/statuses/a363f1e9a39306b956f137f28871ee32c33cb2e3"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"gvanrossum","id":2894642,"avatar_url":"https://avatars.githubusercontent.com/u/2894642?v=3","gravatar_id":"","url":"https://api.github.com/users/gvanrossum","html_url":"https://github.com/gvanrossum","followers_url":"https://api.github.com/users/gvanrossum/followers","following_url":"https://api.github.com/users/gvanrossum/following{/other_user}","gists_url":"https://api.github.com/users/gvanrossum/gists{/gist_id}","starred_url":"https://api.github.com/users/gvanrossum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gvanrossum/subscriptions","organizations_url":"https://api.github.com/users/gvanrossum/orgs","repos_url":"https://api.github.com/users/gvanrossum/repos","events_url":"https://api.github.com/users/gvanrossum/events{/privacy}","received_events_url":"https://api.github.com/users/gvanrossum/received_events","type":"User","site_admin":false},"comments":1,"review_comments":1,"commits":1,"additions":69,"deletions":1,"changed_files":2}}
{"actor":{"display_login":"gvanrossum"}}