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

AttributeError: object has no attribute 'decode' for PAYLOAD_REGISTRY class #5281

Closed
folt opened this issue Nov 23, 2020 · 6 comments
Closed
Labels

Comments

@folt
Copy link

folt commented Nov 23, 2020

🐞 Describe the bug
While working with PAYLOAD_REGISTRY I came across a problem. After examining the information, I found an error. The fact is that the Response class implements a property that calls the self._body.decode method expecting a string there. But when using PAYLOAD_REGISTRY (I used JsonPayload) in self._body there is an instance of the payload class where there is no implementation of the decode method.

💡 To Reproduce

from typing import Mapping, Optional
from types import MappingProxyType
from http import HTTPStatus

from aiohttp import web
from aiohttp import payload
from aiohttp import web_request
from aiohttp import web_middlewares
from aiohttp import PAYLOAD_REGISTRY
from aiohttp import web_exceptions


def format_http_error(http_error_cls, message: Optional[str] = None,
                      ) -> web_exceptions.HTTPException:
    status = HTTPStatus(http_error_cls.status_code)

    error = {
        'code': status.name.lower(),
        'message': message or status.description
    }

    return http_error_cls(body={'error': error})


async def handle():
    raise web_exceptions.HTTPNotFound()


@web_middlewares.middleware
async def error_middleware(request: web_request.Request, handler):
    try:
        return await handler(request)
    except web_exceptions.HTTPException as err:
        err = format_http_error(err.__class__, err.text)
        raise err


app = web.Application(
    middlewares=[error_middleware]
)

PAYLOAD_REGISTRY.register(payload.JsonPayload, (Mapping, MappingProxyType))

app.add_routes([web.get('/', handle)])

if __name__ == '__main__':
    web.run_app(app)

📋 Logs/tracebacks

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages/aiohttp/web_protocol.py", line 422, in _handle_request
    resp = await self._request_handler(request)
  File "/Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages/aiohttp/web_app.py", line 499, in _handle
    resp = await handler(request)
  File "/Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages/aiohttp/web_middlewares.py", line 118, in impl
    return await handler(request)
  File "/Users/folt/Documents/Work/geodb/qq.py", line 35, in error_middleware
    raise err
aiohttp.web_exceptions.HTTPNotFound: Not Found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages/aiohttp/web_protocol.py", line 485, in start
    resp, reset = await task
  File "/Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages/aiohttp/web_protocol.py", line 427, in _handle_request
    status=exc.status, reason=exc.reason, text=exc.text, headers=exc.headers
  File "/Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages/aiohttp/web_response.py", line 650, in text
    return self._body.decode(self.charset or "utf-8")
AttributeError: 'JsonPayload' object has no attribute 'decode'

📋 Your version of the Python
Python 3.8.5

📋 Your version of the aiohttp/yarl/multidict distributions
$ python -m pip show aiohttp

Name: aiohttp
Version: 3.7.2
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: Nikolay Kim
Author-email: [email protected]
License: Apache 2
Location: /Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages
Requires: async-timeout, multidict, typing-extensions, chardet, attrs, yarl
Required-by: aiohttp-jinja2, aiohttp-debugtoolbar, aiohttp-apispec

$ python -m pip show multidict

Name: multidict
Version: 5.0.0
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages
Requires: 
Required-by: yarl, aiohttp

$ python -m pip show yarl

Name: yarl
Version: 1.6.2
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /Users/folt/Documents/Work/geodb/.venv/lib/python3.8/site-packages
Requires: idna, multidict
Required-by: aiohttp

Also found a related issue #2928 . I solved the error by implementing my JsonPayload.
I see 2 ways to solve this error.

  1. Implement the decode method in the JsonPayload class
  2. In the def text(self) method, check the type of _body and, based on this check, decide whether to call the decode method for _body.

I am ready to contribute, but I would like to discuss possible solutions.

@folt folt added the bug label Nov 23, 2020
folt added a commit to folt/aiohttp that referenced this issue Dec 14, 2020
folt added a commit to folt/aiohttp that referenced this issue Dec 16, 2020
folt added a commit to folt/aiohttp that referenced this issue Dec 16, 2020
folt added a commit to folt/aiohttp that referenced this issue Dec 16, 2020
folt added a commit to folt/aiohttp that referenced this issue Dec 16, 2020
@i3Cheese
Copy link

Can you do pull request?

@folt
Copy link
Author

folt commented Oct 14, 2021

Can you do pull request?

I made a pull request #5350 . But it was not considered.

@Dreamsorcerer
Copy link
Member

I made a pull request #5350 . But it was not considered.

You appear to have closed your own PR on the same day you opened it...

No one is going to review a PR the author has already closed.

folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
@folt
Copy link
Author

folt commented Oct 15, 2021

I made a pull request #5350 . But it was not considered.

You appear to have closed your own PR on the same day you opened it...

No one is going to review a PR the author has already closed.

I have prepared a new pull request

folt added a commit to folt/aiohttp that referenced this issue Oct 15, 2021
@Dreamsorcerer
Copy link
Member

Sorry, I've just had a proper look at this. I think the cause is another unrelated regression. Your original code runs fine on aiohttp 3.6 and 3.8. It's just 3.7 that has this problem.

Also, if you were running with warnings enabled, you'd see that the body argument you are passing to HTTPException is deprecated, so your code will also fail on master.

@Dreamsorcerer
Copy link
Member

If you can create a different reproducer that demonstrates a problem on master, then we can reopen this.

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

No branches or pull requests

3 participants