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

Permit empty reason strings in ClientResponse.raise_for_status() #3533

Merged
merged 2 commits into from
Jan 14, 2019
Merged

Permit empty reason strings in ClientResponse.raise_for_status() #3533

merged 2 commits into from
Jan 14, 2019

Conversation

rhwlo
Copy link
Contributor

@rhwlo rhwlo commented Jan 13, 2019

What do these changes do?

Are there changes in behavior for the user?

  • Calling raise_for_status on a status with a reason phrase that’s an empty string will raise a ClientResponseError now instead of an AssertionError

Related issue number

#3532

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."

@codecov-io
Copy link

Codecov Report

Merging #3533 into master will decrease coverage by 0.04%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3533      +/-   ##
==========================================
- Coverage   97.94%   97.89%   -0.05%     
==========================================
  Files          44       44              
  Lines        8562     8563       +1     
  Branches     1381     1382       +1     
==========================================
- Hits         8386     8383       -3     
- Misses         71       73       +2     
- Partials      105      107       +2
Impacted Files Coverage Δ
aiohttp/client_reqrep.py 97.12% <0%> (-0.32%) ⬇️
aiohttp/web_fileresponse.py 96.55% <0%> (-1.15%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2d8aa12...1270774. Read the comment docs.

@codecov-io
Copy link

codecov-io commented Jan 13, 2019

Codecov Report

Merging #3533 into master will decrease coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3533      +/-   ##
==========================================
- Coverage   97.94%   97.92%   -0.03%     
==========================================
  Files          44       44              
  Lines        8562     8562              
  Branches     1381     1381              
==========================================
- Hits         8386     8384       -2     
- Misses         71       72       +1     
- Partials      105      106       +1
Impacted Files Coverage Δ
aiohttp/client_reqrep.py 97.43% <100%> (ø) ⬆️
aiohttp/web_fileresponse.py 96.55% <0%> (-1.15%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2d8aa12...3b9d0d3. Read the comment docs.

@@ -931,8 +931,10 @@ def release(self) -> Any:
return noop()

def raise_for_status(self) -> None:
# self.reason is only None if self.start() hasn't been called:
if self.reason is None:
raise TypeError("Expected a Reason-Phrase as a string")
Copy link
Member

Choose a reason for hiding this comment

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

An exception type and especially text is meaningless for an end user.
The text describes a consequence (the reason field is not set) but hides an actual problem.

Moreover, assertion exists only for sake of mypy.
If you don't like the assertion -- please find another way to satisfy mypy.

assert self.reason is not None could be the simplest possible fix, even no test is needed for the case.

Copy link
Member

Choose a reason for hiding this comment

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

Well, a test would be nice but please use a functional test for an empty reason.
https://github.com/aio-libs/aiohttp/blob/master/tests/test_client_functional.py can give an inspiration how a functional client test looks like

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’ll switch it to assert self.reason is not None if that’s the desired outcome.

@asvetlov asvetlov merged commit f590bfd into aio-libs:master Jan 14, 2019
@asvetlov
Copy link
Member

Thanks!

asvetlov pushed a commit that referenced this pull request Jan 14, 2019
#3533)

(cherry picked from commit f590bfd)

Co-authored-by: Joshu Coats <rhwlo@users.noreply.github.com>
asvetlov added a commit that referenced this pull request Jan 15, 2019
#3533) (#3541)

(cherry picked from commit f590bfd)

Co-authored-by: Joshu Coats <rhwlo@users.noreply.github.com>
@ctg3
Copy link

ctg3 commented Feb 7, 2019

Why is reason string required? I have a webserver that doesn't return any reason phrase (None). If self.reason is None, can we just change it to self.reason = '' and still satisfy mypy?

Also see a discussion here: https://stackoverflow.com/questions/17517086/can-an-http-response-omit-the-reason-phrase

@vaultah
Copy link

vaultah commented Apr 4, 2019

Maybe make a release that contains a fix for this? No hurry though, it's only been three months.

@Solvero
Copy link

Solvero commented Apr 8, 2019

I have encountered this problem after aiohttp upgrade to 3.5.4. My server doesn't return Response-Reason too. HTTP/1.1 specification says that:

The Status-Code is intended for use by automata and the Reason-Phrase is intended for the human user. The client is not required to examine or display the Reason- Phrase.

Please see also:
https://stackoverflow.com/questions/17517086/can-an-http-response-omit-the-reason-phrase

@gwerbin
Copy link

gwerbin commented Jun 26, 2019

I appreciate all the work the contributors are doing on this library, but it would have been nice to merge and release this as a 3.5.5 "patch". It looks like you're waiting for 3.6 release or something like that?

In the meantime, I'm using my own implementation of this, basically copy-and-pasted from the source code:

def raise_for_status(response: aiohttp.ClientResponse) -> None:
    if 400 <= response.status:
        response.release()
        raise aiohttp.ClientResponseError(
            response.request_info,
            response.history,
            status=response.status,
            message=response.reason or '',
            headers=response.headers
        )

@webknjaz
Copy link
Member

@gwerbin master branch is for 4.0. If you want, you can submit a backport PR against 3.5 branch.

@gwerbin
Copy link

gwerbin commented Jun 26, 2019

Thanks @webknjaz, My one concern is about this line:

reason should always be not None for a started response

Does some other part of the application or test suite depend on this being true? I don't want to break anything else with my quick or '' fix.

Alternatively, why would reason be None here, rather than defaulting to an empty string? I feel like fixing this at the raise_for_status point doesn't actually address the problem, that reason can be None in the first place instead of an empty string.

@webknjaz
Copy link
Member

@gwerbin you should normally cherry-pick the entire PR and not try to rip off some parts of it. This includes tests.

@fiendish
Copy link

fiendish commented Jan 26, 2023

raise_for_status on a response object is still giving AssertionError instead of ClientResponseError in the latest release?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ClientResponse.raise_for_status() raises an AssertionError for empty reason
10 participants