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

Add typings for web_response #3317

Closed
wants to merge 13 commits into from
Closed

Add typings for web_response #3317

wants to merge 13 commits into from

Conversation

kornicameister
Copy link
Contributor

Add typings for aiohttp/web_response.py

For now it is not clear.

Related issue number

#1749

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
    • The format is <Name> <Surname>.
    • Please keep alphabetical order, the file is sorted by names.
  • Add a new news fragment into the CHANGES folder
    • name it <issue_id>.<type> for example (588.bugfix)
    • if you don't have an issue_id change it to the pr id after creating the pr
    • ensure type is one of the following:
      • .feature: Signifying a new feature.
      • .bugfix: Signifying a bug fix.
      • .doc: Signifying a documentation improvement.
      • .removal: Signifying a deprecation or removal of public API.
      • .misc: A ticket has been closed, but it is not of interest to users.
    • Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files."

If there isn't a .netrc file specified by an environment variable, it
can be confusing to see warnings about it. If NETRC isn't set, don't
warn. Only warn if: a) can't resolve HOME, b) can load, but can't parse
file, c) can't find file, d) file appears to exist at the default
location but is unreadable for some reason.
Copy link
Contributor Author

@kornicameister kornicameister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asvetlov the PR isn't finished, but the amount of doubts was the reason for my to ask for some early look at this. Hope you have some time to check it out.

@@ -484,13 +484,13 @@ def _format_r(request: 'BaseRequest',
@staticmethod
def _format_s(request: 'BaseRequest',
response: 'StreamResponse',
time: float) -> str:
time: float) -> int:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct if I am wrong, but doing typings in web_response.py reveled that it should be int most likely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right.
As an option, we can return str but should apply str(response.status).
Let's change annotation as you did already.

@@ -101,7 +101,7 @@ def register(self,

class Payload(ABC):

_size = None # type: Optional[float]
_size = None # type: Optional[int]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I am pretty sure that making this float in the beginning was an err on my side.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, 3.5 bytes will never happen.

if params:
ctype = self._content_type + '; ' + params
ctype = self.content_type + '; ' + params
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really sure why variable is Optional[str] and attr getter from super returns str. Can't tell yet which one is correct.

return len(self._state)

def __iter__(self):
return iter(self._state)
def __iter__(self) -> Iterator[Tuple[str, str]]:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try to look into this once again but basically this one says that aiohttp/web_response.py:483: error: Return type of "__iter__" incompatible with supertype "Iterable" . An Iterable is last or the one before last in the chain of inheritance starting from MutableMapping. I can't really say why this one is bad if typings for MutableMapping says exactly MutableMapping[str, str].

if body is None:
self._body = None
self._body_payload = False
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, it turns out that _body can be either bytes or Payload. Seemed more correct to rely on isinstance then keeping extra property in the class.

return self._body.decode(self.charset or 'utf-8')
else:
if isinstance(self._body, payload.Payload):
raise ValueError('Cannot extract text from payload')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most likely this is wrong :/

self._cookies = SimpleCookie()

self._req = None
self._payload_writer = None
self._req = None # type: Optional[Request]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional[BaseRequest] here

return self._payload_writer is not None

@property
def task(self):
def task(self) -> asyncio.Task[_T]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return self._compression

@property
def reason(self):
def reason(self) -> Optional[str]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resp.reason is always str (can be an empty string though).

return self._body_length

@property
def output_length(self):
def output_length(self) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the length is int


def enable_chunked_encoding(self, chunk_size=None):
def enable_chunked_encoding(self, chunk_size: Any=None) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chunk_size: Optional[int].
The parameter will be removed in aiohttp 4.0 but now let's be consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figure that since it is not used in anyway and setting it to anything else other than None will anyway result in an error, we actually don't have to care about that. But if you prefer to have it as Optional[int], let it be so.

@kornicameister
Copy link
Contributor Author

@asvetlov sorry for longer inactive. Didn't exactly had time in the evenings to take a look here.

The current status is that I have two errors for which I can't find the solution:

aiohttp/web_response.py:105: error: Cannot determine type of 'RESPONSES'
aiohttp/web_response.py:356: error: Cannot determine type of 'SERVER_SOFTWARE'

Surprisingly that happens only if I use make mypy. Running mypy directly does not report that. I think I saw the fix for it elsewhere I just can't find it, so any help appreciated.

asvetlov and others added 6 commits October 13, 2018 02:04
* Update async-timeout from 3.0.0 to 3.0.1

* Update cython from 0.28.5 to 0.29

* Update cython from 0.28.5 to 0.29

* Update cython from 0.28.5 to 0.29

* Update gunicorn from 19.8.1 to 19.9.0

* Update tox from 3.5.0 to 3.5.2
@asvetlov
Copy link
Member

I've fixed mypy errors but looks like the logic is broken somehow -- 10 tests are failed.

@asvetlov
Copy link
Member

Done by 22a58e2

@asvetlov asvetlov closed this Oct 17, 2018
@kornicameister kornicameister deleted the add_typings_for_web_response branch October 17, 2018 20:35
@kornicameister
Copy link
Contributor Author

@asvetlov I was aware that logic will be broken somehow. I couldn't actually get around mypy here and wanted to handle tests after that's done. But if you managed to resolve that, I am more than happy ;-)

@kornicameister
Copy link
Contributor Author

BTW: @asvetlov really nice product. Maybe you recall me mentioning performance comparision (or maybe I've mentioned that over in connexion), but comparing aiohttp with ordinary flask based application, well we, roughly speaking, improved performance about 30%-50%. So really great product 👍

@asvetlov
Copy link
Member

Thanks for the feedback.
You know, any benchmarking is cheating because hard to compare the same functionality; synthetic benchmark code is very different than your production one.
That's why I love to see any performance comparisons of real applications.

@kornicameister
Copy link
Contributor Author

Heh, it was real application. Although for the sake of POC I've compared just two endpoints (those destined to work under heaviest load). But application was normally working inside the cluster (i.e. it was normally deployed) and tests were ran also in there. So we've been actually sending bunch of requests, sometimes even spawning the service. And what was nearly a heart attack for older app, new one was still catching up.

@asvetlov
Copy link
Member

Sweet!

@lock
Copy link

lock bot commented Oct 28, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a [new issue] for related bugs.
If you feel like there's important points made in this discussion, please include those exceprts into that [new issue].
[new issue]: https://github.com/aio-libs/aiohttp/issues/new

@lock lock bot added the outdated label Oct 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 28, 2019
@psf-chronographer psf-chronographer bot added the bot:chronographer:provided There is a change note present in this PR label Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bot:chronographer:provided There is a change note present in this PR outdated
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants