Neat way of making urllib work with python 2 and 3
Asked Answered
P

2

6

I'm looking for suggestions on how to combine the two code snippets so that they work with both python 2 and 3. The goal is to make it "neat", ideally keeping it to one line and limiting any if/else/try/except constructs.

For python 3.x

   import xml.etree.ElementTree as ET, urllib.request, gzip, io
   url = "https://github.com/OpenExoplanetCatalogue/oec_gzip/raw/master/systems.xml.gz"
   oec = ET.parse(gzip.GzipFile(fileobj=io.BytesIO(urllib.request.urlopen(url).read())))

For python 2.x

  import xml.etree.ElementTree as ET, urllib, gzip, io
  url = "https://github.com/OpenExoplanetCatalogue/oec_gzip/raw/master/systems.xml.gz"
  oec = ET.parse(gzip.GzipFile(fileobj=io.BytesIO(urllib.urlopen(url).read())))
Pourboire answered 25/6, 2014 at 19:40 Comment(1)
The urllib imports are going to be different. One answer: use requests. Alternately, run a test for py2/py3 and import the proper urllib urlopen as urlopen. You might look at six, which contains a boolean value to test if you're in Python3 or Python2: six.PY3Austin
H
13

If you don't want an extra dependency, you could simply use a try except block to import either module under the same alias...:

try:
    import urllib.request as urlrequest
except ImportError:
    import urllib as urlrequest

url = "https://github.com/OpenExoplanetCatalogue/oec_gzip/raw/master/systems.xml.gz"
oec = ET.parse(gzip.GzipFile(fileobj=io.BytesIO(urlrequest.urlopen(url).read())))
Hibbard answered 25/6, 2014 at 20:8 Comment(0)
C
11

This is exactly what six was created for. It's a library designed to allow your code to work with both Python 2 and 3. (Don't let "library" scare you, it's intentionally just a single .py file to make it very easy to integrate/package.)

Instead of using the built-in urllib module, you'd use six's version which automatically redirects to the built-in module in both Python 2 and 3.

Here's what your code would look like:

import xml.etree.ElementTree as ET, gzip, io
from six.moves.urllib.request import urlopen
url = "https://github.com/OpenExoplanetCatalogue/oec_gzip/raw/master/systems.xml.gz"
oec = ET.parse(gzip.GzipFile(fileobj=io.BytesIO(urlopen(url).read())))

See: https://six.readthedocs.io/#module-six.moves.urllib.request

Circumrotate answered 25/6, 2014 at 19:45 Comment(2)
Nice suggestion: I didn't realize six could do that. I've used it for other stuff.Austin
The only reason anyone would be using urllib over requests is to avoid having any dependencies, six included.Jorge

© 2022 - 2024 — McMap. All rights reserved.