text: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  # Libcloud Python 2.x and 3.x compatibility layer
  # Some methods below are taken from Django PYK3 port which is licensed under 3
  # clause BSD license
  # https://bitbucket.org/loewis/django-3k
  
  # pylint: disable=import-error
  
  from __future__ import absolute_import
  
  import sys
  import types
  
  DEFAULT_LXML = False
  
  try:
      if DEFAULT_LXML:
          from lxml import etree as ET
      else:
          from xml.etree import ElementTree as ET
  except ImportError:
      from xml.etree import ElementTree as ET
  
  PY2 = sys.version_info[0] == 2
  PY3 = sys.version_info[0] == 3
  PY2_pre_279 = PY2 and sys.version_info < (2, 7, 9)
  
  PY2 = False
  PY27 = False
  PY3 = False
  
  if (2, 0) <= sys.version_info < (3, 0):
      PY2 = True
  
  if (2, 7) <= sys.version_info < (2, 8):
      PY27 = True
  
  if sys.version_info >= (3, 0):
      PY3 = True
  
  if PY2_pre_279:
      try:
          from backports.ssl_match_hostname import match_hostname, CertificateError  # NOQA
      except ImportError:
          import warnings
          warnings.warn("Missing backports.ssl_match_hostname package")
  else:
      # ssl module in Python >= 3.2 includes match hostname function
      from ssl import match_hostname, CertificateError  # NOQA
  
  if PY3:
      import http.client as httplib
      from io import StringIO
      import urllib
      import urllib as urllib2
      # pylint: disable=no-name-in-module
      import urllib.parse as urlparse
      import xmlrpc.client as xmlrpclib
  
      from urllib.parse import quote as urlquote
      from urllib.parse import unquote as urlunquote
      from urllib.parse import urlencode as urlencode
      from os.path import relpath
  
      from imp import reload
  
      from builtins import bytes
      from builtins import next
  
      parse_qs = urlparse.parse_qs
      parse_qsl = urlparse.parse_qsl
  
      basestring = str
  
      def method_type(callable, instance, klass):
          return types.MethodType(callable, instance or klass())
  
      def b(s):
          if isinstance(s, str):
              return s.encode('utf-8')
          elif isinstance(s, bytes):
              return s
          elif isinstance(s, int):
              return bytes([s])
          else:
              raise TypeError("Invalid argument %r for b()" % (s,))
  
      def ensure_string(s):
          if isinstance(s, str):
              return s
          elif isinstance(s, bytes):
              return s.decode('utf-8')
          else:
              raise TypeError("Invalid argument %r for ensure_string()" % (s,))
  
      def byte(n):
          # assume n is a Latin-1 string of length 1
          return ord(n)
  
      _real_unicode = str
      u = str
  
      def bchr(s):
          """Take an integer and make a 1-character byte string."""
          return bytes([s])
  
      def dictvalues(d):
          return list(d.values())
  
      def tostring(node):
          return ET.tostring(node, encoding='unicode')
  
      def hexadigits(s):
          # s needs to be a byte string.
          return [format(x, "x") for x in s]
  
  else:
      import httplib  # NOQA
      from StringIO import StringIO  # NOQA
      import urllib  # NOQA
      import urllib2  # NOQA
      import urlparse  # NOQA
      import xmlrpclib  # NOQA
      from urllib import quote as _urlquote  # NOQA
      from urllib import unquote as urlunquote  # NOQA
      from urllib import urlencode as urlencode  # NOQA
  
      from __builtin__ import reload  # NOQA
  
      parse_qs = urlparse.parse_qs
      parse_qsl = urlparse.parse_qsl
  
      from os.path import relpath  # NOQA
  
      # Save the real value of unicode because urlquote needs it to tell the
      # difference between a unicode string and a byte string.
      _real_unicode = unicode
      basestring = unicode = str
  
      method_type = types.MethodType
  
      b = bytes = ensure_string = str
  
      def byte(n):
          return n
  
      u = unicode
  
      def bchr(s):
          """Take an integer and make a 1-character byte string."""
          return chr(s)
  
      _default_value_next = object()
  
      def next(iterator, default=_default_value_next):
          try:
              return iterator.next()
          except StopIteration:
              if default is _default_value_next:
                  raise
              return default
  
      def dictvalues(d):
          return d.values()
  
      tostring = ET.tostring
  
      def urlquote(s, safe='/'):
          if isinstance(s, _real_unicode):
              # Pretend to be py3 by encoding the URI automatically.
              s = s.encode('utf8')
          return _urlquote(s, safe)
  
      def hexadigits(s):
          # s needs to be a string.
          return [x.encode("hex") for x in s]
  