Path: csiph.com!aioe.org!.POSTED!not-for-mail From: Fabien Newsgroups: comp.lang.python Subject: urlopen, six, and py2 Date: Wed, 2 Mar 2016 15:05:46 +0100 Organization: Aioe.org NNTP Server Lines: 40 Message-ID: NNTP-Posting-Host: +L+NlaBbFxmjN1Tx9NZnQA.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 X-Notice: Filtered by postfilter v. 0.8.2 X-Mozilla-News-Host: news://news.aioe.org:119 Xref: csiph.com comp.lang.python:103869 Hi, it seems that urlopen had no context manager for versions < 3. The following code therefore will crash on py2 but not on py3. from six.moves.urllib.request import urlopen with urlopen('http://www.google.com') as resp: _ = resp.read() Error: AttributeError: addinfourl instance has no attribute '__exit__' I actually wonder if this is not something that the six library should take care of upstream, but in the meantime I could simply do what is suggested on this stackoverflow post: http://stackoverflow.com/questions/30627937/tracebaclk-attributeerroraddinfourl-instance-has-no-attribute-exit My question is: why does the python3 version need a "with" block while the python2 version doesn't? Can I skip the "with" entirely, or should I rather do the following: from six.moves.urllib.request import urlopen try: with urlopen('http://www.google.com') as resp: _ = resp.read() except AttributeError: # python 2 resp = urlopen('http://www.google.com') _ = resp.read() (which is quite ugly). Thanks! Fabien