{"action":"created","issue":{"url":"https://api.github.com/repos/huge-success/sanic/issues/1422","repository_url":"https://api.github.com/repos/huge-success/sanic","labels_url":"https://api.github.com/repos/huge-success/sanic/issues/1422/labels{/name}","comments_url":"https://api.github.com/repos/huge-success/sanic/issues/1422/comments","events_url":"https://api.github.com/repos/huge-success/sanic/issues/1422/events","html_url":"https://github.com/huge-success/sanic/pull/1422","id":386626568,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM1MzAzNjA2","number":1422,"title":"Add in some server.py __slots__ attribute names that are missing.","user":{"login":"ashleysommer","id":402468,"node_id":"MDQ6VXNlcjQwMjQ2OA==","avatar_url":"https://avatars3.githubusercontent.com/u/402468?v=4","gravatar_id":"","url":"https://api.github.com/users/ashleysommer","html_url":"https://github.com/ashleysommer","followers_url":"https://api.github.com/users/ashleysommer/followers","following_url":"https://api.github.com/users/ashleysommer/following{/other_user}","gists_url":"https://api.github.com/users/ashleysommer/gists{/gist_id}","starred_url":"https://api.github.com/users/ashleysommer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashleysommer/subscriptions","organizations_url":"https://api.github.com/users/ashleysommer/orgs","repos_url":"https://api.github.com/users/ashleysommer/repos","events_url":"https://api.github.com/users/ashleysommer/events{/privacy}","received_events_url":"https://api.github.com/users/ashleysommer/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":7,"created_at":"2018-12-03T01:29:50Z","updated_at":"2018-12-03T22:14:51Z","closed_at":null,"author_association":"MEMBER","pull_request":{"url":"https://api.github.com/repos/huge-success/sanic/pulls/1422","html_url":"https://github.com/huge-success/sanic/pull/1422","diff_url":"https://github.com/huge-success/sanic/pull/1422.diff","patch_url":"https://github.com/huge-success/sanic/pull/1422.patch"},"body":"While doing some digging in the server.py file this morning, I found that there are a bunch of attributes used in the HTTPProtocol class which are not declared in the `__slots__` tuple at the top of the class.\r\n\r\nNormally not having the attribute name in `__slots__` means the class cannot write to that attribute at runtime (because it doesn't exist) but in this case it never mattered because HTTPProtocol is a subclass of asyncio.Protocol, which itself is a Normal class (no `__slots__`). So having `__slots__` on the HTTPProtocol subclass to restrict its possible attributes is kind-of useless in this case because it doesn't restrict anything.\r\n\r\nBut anyway, for correctness sake this PR adds the missing attribute names to the `__slots__` of Sanic server.py HTTPProtocol."},"comment":{"url":"https://api.github.com/repos/huge-success/sanic/issues/comments/443890905","html_url":"https://github.com/huge-success/sanic/pull/1422#issuecomment-443890905","issue_url":"https://api.github.com/repos/huge-success/sanic/issues/1422","id":443890905,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0Mzg5MDkwNQ==","user":{"login":"vltr","id":1540275,"node_id":"MDQ6VXNlcjE1NDAyNzU=","avatar_url":"https://avatars2.githubusercontent.com/u/1540275?v=4","gravatar_id":"","url":"https://api.github.com/users/vltr","html_url":"https://github.com/vltr","followers_url":"https://api.github.com/users/vltr/followers","following_url":"https://api.github.com/users/vltr/following{/other_user}","gists_url":"https://api.github.com/users/vltr/gists{/gist_id}","starred_url":"https://api.github.com/users/vltr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vltr/subscriptions","organizations_url":"https://api.github.com/users/vltr/orgs","repos_url":"https://api.github.com/users/vltr/repos","events_url":"https://api.github.com/users/vltr/events{/privacy}","received_events_url":"https://api.github.com/users/vltr/received_events","type":"User","site_admin":false},"created_at":"2018-12-03T22:14:51Z","updated_at":"2018-12-03T22:14:51Z","author_association":"MEMBER","body":"Well, it does works - but it is kind of tricky:\r\n\r\n```python\r\n>>> class Foo: pass\r\n... \r\n>>> class Bar(Foo):\r\n...     __slots__ = (\"test\",)\r\n... \r\n>>> x = Bar()\r\n>>> x\r\n<__main__.Bar object at 0x7f7436445848>\r\n>>> dir(x)\r\n['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', 'test']\r\n>>> x.test = \"hello\"\r\n>>> x.not_in_slots = \"world\"\r\n>>> print(x.test)\r\nhello\r\n>>> print(x.__dict__)\r\n{'not_in_slots': 'world'}\r\n>>> import timeit\r\n>>> def get_set_delete_slots():\r\n...     x.test = \"foo\"\r\n...     x.test\r\n...     del x.test\r\n...\r\n>>> def get_set_delete_no_slots():\r\n...     x.foo = \"foo\"\r\n...     x.foo\r\n...     del x.foo\r\n...\r\n>>> min(timeit.repeat(get_set_delete_slots))\r\n0.18530158700014\r\n>>> min(timeit.repeat(get_set_delete_no_slots))\r\n0.22946998499537585\r\n>>> z = Bar()\r\n>>> dir(z)\r\n['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', 'test']\r\n```\r\n\r\nThis means that we can have attributes in the instance that are not listed in the `__slots__`  - that will end up in the `__dict__` - we'll just end up having to take extra care to have all attributes into `__slots__`."}}
{"actor":{"display_login":"vltr"}}