tornadoweb / tornado

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
http://www.tornadoweb.org/
Apache License 2.0
21.75k stars 5.5k forks source link

'HTTPClient' object has no attribute '_closed' in tornado5.0 #2325

Closed DreamHackchosenone closed 6 years ago

DreamHackchosenone commented 6 years ago

about httpclient.HTTPClient() I can't execute http_client = httpclient.HTTPClient() in tornado==5.0 running this will throw Exception this: Traceback (most recent call last): File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/site-packages/tornado/httpclient.py", line 85, in del self.close() File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/site-packages/tornado/httpclient.py", line 89, in close if not self._closed: AttributeError: 'HTTPClient' object has no attribute '_closed'

but in tornado==4.5.2 it works fine, this issue on macOS,can you tell me why?

bdarnell commented 6 years ago

Is this the only error in your logs? It looks like there was an exception in the constructor which kept the _closed attribute from being set, and then this exception occurred in the destructor trying to clean up. The first exception is the real error.

DreamHackchosenone commented 6 years ago

you are right,the whole error log is

/Users/zhonghao/anaconda3/envs/tornado_test/bin/python3.6 /Users/zhonghao/Desktop/tornado_test/async_webserver/5.1.1_sync_rate.py [E 180325 12:21:13 web:1621] Uncaught exception GET / (::1) HTTPServerRequest(protocol='http', host='localhost:8000', method='GET', uri='/', version='HTTP/1.1', remote_ip='::1') Traceback (most recent call last): File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/site-packages/tornado/web.py", line 1541, in _execute result = method(*self.path_args, self.path_kwargs) File "/Users/zhonghao/Desktop/tornado_test/async_webserver/5.1.1_sync_rate.py", line 23, in get client = httpclient.HTTPClient() File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/site-packages/tornado/httpclient.py", line 81, in init gen.coroutine(lambda: async_client_class(kwargs))) File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/site-packages/tornado/ioloop.py", line 577, in run_sync self.start() File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/site-packages/tornado/platform/asyncio.py", line 112, in start self.asyncio_loop.run_forever() File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/asyncio/base_events.py", line 411, in run_forever 'Cannot run the event loop while another loop is running') RuntimeError: Cannot run the event loop while another loop is running [E 180325 12:21:13 web:2106] 500 GET / (::1) 3.77ms Exception ignored in: <bound method HTTPClient.del of <tornado.httpclient.HTTPClient object at 0x106864588>> Traceback (most recent call last): File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/site-packages/tornado/httpclient.py", line 85, in del self.close() File "/Users/zhonghao/anaconda3/envs/tornado_test/lib/python3.6/site-packages/tornado/httpclient.py", line 89, in close if not self._closed: AttributeError: 'HTTPClient' object has no attribute '_closed'

and my demo code is this:

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        client = httpclient.HTTPClient()
        self.write('done')
if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers=[(r"/", IndexHandler)],)
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

note: I use python3.6

bdarnell commented 6 years ago

OK. The real error, "RuntimeError: Cannot run the event loop while another loop is running", is a limitation of asyncio. You can't use the synchronous HTTPClient in an asynchronous Tornado application when asyncio is used. You have to use AsyncHTTPClient instead.

DreamHackchosenone commented 6 years ago

why the error not in tornado4.5? what's the difference between 4.5 and 5, may be I should read 5.0 document seriously. : ( thanks for your reply

bdarnell commented 6 years ago

In Tornado 5.0, asyncio is used automatically when it is available. In 4.5 you had to opt in to asyncio integration separately.

DreamHackchosenone commented 6 years ago

I get it thank you again