From 45f88c16268ccf8a6c106b1ea20e84515c74e476 Mon Sep 17 00:00:00 2001 From: Clint Byrum Date: Fri, 15 May 2015 11:40:37 -0700 Subject: [PATCH] Use six.string_types instead of basestring In python3 strings are different, so basestring isn't available anymore. While examining these uses, all of them still work fine with six.string_types and should not need any new special handling to deal with bytes. --- setup.py | 3 ++- src/saml2/__init__.py | 5 +++-- src/saml2/assertion.py | 5 +++-- src/saml2/authn.py | 7 ++++--- src/saml2/client.py | 5 +++-- src/saml2/client_base.py | 7 ++++--- src/saml2/httputil.py | 3 ++- src/saml2/mdie.py | 6 ++++-- src/saml2/metadata.py | 17 +++++++++-------- src/saml2/mongo_store.py | 9 +++++---- src/saml2/population.py | 3 ++- src/saml2/s_utils.py | 5 +++-- src/saml2/saml.py | 3 ++- src/saml2/server.py | 5 +++-- src/saml2/time_util.py | 7 ++++--- tests/test_51_client.py | 5 +++-- tools/parse_xsd2.py | 6 +++--- 17 files changed, 59 insertions(+), 42 deletions(-) diff --git a/setup.py b/setup.py index 97bc582..25006c8 100755 --- a/setup.py +++ b/setup.py @@ -31,7 +31,8 @@ install_requires = [ 'pytz', 'pyOpenSSL', 'python-dateutil', - 'argparse' + 'argparse', + 'six' ] tests_require = [ diff --git a/src/saml2/__init__.py b/src/saml2/__init__.py index b3c3bee..87bfafa 100644 --- a/src/saml2/__init__.py +++ b/src/saml2/__init__.py @@ -19,6 +19,7 @@ import logging +import six from saml2.validate import valid_instance try: @@ -727,7 +728,7 @@ class SamlBase(ExtensionContainer): setattr(self, "text", "false") elif isinstance(val, int): setattr(self, "text", "%d" % val) - elif isinstance(val, basestring): + elif isinstance(val, six.string_types): setattr(self, "text", val) elif val is None: pass @@ -809,7 +810,7 @@ class SamlBase(ExtensionContainer): continue svals = self.__dict__[key] ovals = other.__dict__[key] - if isinstance(svals, basestring): + if isinstance(svals, six.string_types): if svals != ovals: return False elif isinstance(svals, list): diff --git a/src/saml2/assertion.py b/src/saml2/assertion.py index 77106a0..58d61ae 100644 --- a/src/saml2/assertion.py +++ b/src/saml2/assertion.py @@ -5,6 +5,7 @@ import logging import re from saml2.saml import NAME_FORMAT_URI +import six import xmlenc from saml2 import saml @@ -31,7 +32,7 @@ def _filter_values(vals, vlist=None, must=False): if not vlist: # No value specified equals any value return vals - if isinstance(vlist, basestring): + if isinstance(vlist, six.string_types): vlist = [vlist] res = [] @@ -237,7 +238,7 @@ def filter_attribute_value_assertions(ava, attribute_restrictions=None): else: if _rests is None: continue - if isinstance(vals, basestring): + if isinstance(vals, six.string_types): vals = [vals] rvals = [] for restr in _rests: diff --git a/src/saml2/authn.py b/src/saml2/authn.py index 804feee..a189157 100644 --- a/src/saml2/authn.py +++ b/src/saml2/authn.py @@ -2,6 +2,7 @@ import logging from urllib import urlencode from urlparse import parse_qs from urlparse import urlsplit +import six import time import ldap from saml2 import SAMLError @@ -77,7 +78,7 @@ def create_return_url(base, query, **kwargs): for key, values in parse_qs(query).items(): if key in kwargs: - if isinstance(kwargs[key], basestring): + if isinstance(kwargs[key], six.string_types): kwargs[key] = [kwargs[key]] kwargs[key].extend(values) else: @@ -86,7 +87,7 @@ def create_return_url(base, query, **kwargs): if part.query: for key, values in parse_qs(part.query).items(): if key in kwargs: - if isinstance(kwargs[key], basestring): + if isinstance(kwargs[key], six.string_types): kwargs[key] = [kwargs[key]] kwargs[key].extend(values) else: @@ -160,7 +161,7 @@ class UsernamePasswordMako(UserAuthnMethod): """ #logger.debug("verify(%s)" % request) - if isinstance(request, basestring): + if isinstance(request, six.string_types): _dict = parse_qs(request) elif isinstance(request, dict): _dict = request diff --git a/src/saml2/client.py b/src/saml2/client.py index 6ee5ef3..cdb66e0 100644 --- a/src/saml2/client.py +++ b/src/saml2/client.py @@ -1,6 +1,7 @@ # !/usr/bin/env python # -*- coding: utf-8 -*- # +import six """Contains classes and functions that a SAML2.0 Service Provider (SP) may use to conclude its tasks. @@ -149,7 +150,7 @@ class Saml2Client(Base): conversation. """ - if isinstance(name_id, basestring): + if isinstance(name_id, six.string_types): name_id = decode(name_id) logger.info("logout request for: %s" % name_id) @@ -363,7 +364,7 @@ class Saml2Client(Base): raise NoServiceDefined("%s: %s" % (entity_id, "assertion_id_request_service")) - if isinstance(assertion_ids, basestring): + if isinstance(assertion_ids, six.string_types): assertion_ids = [assertion_ids] _id_refs = [AssertionIDRef(_id) for _id in assertion_ids] diff --git a/src/saml2/client_base.py b/src/saml2/client_base.py index 4e9cbdf..009d438 100644 --- a/src/saml2/client_base.py +++ b/src/saml2/client_base.py @@ -8,6 +8,7 @@ to conclude its tasks. import threading from urllib import urlencode from urlparse import urlparse +import six from saml2.entity import Entity @@ -382,7 +383,7 @@ class Base(Entity): pass else: raise AttributeError("Missing required parameter") - elif isinstance(name_id, basestring): + elif isinstance(name_id, six.string_types): name_id = saml.NameID(text=name_id) for key in ["sp_name_qualifier", "name_qualifier", "format"]: try: @@ -453,7 +454,7 @@ class Base(Entity): """ if action: - if isinstance(action, basestring): + if isinstance(action, six.string_types): _action = [saml.Action(text=action)] else: _action = [saml.Action(text=a) for a in action] @@ -473,7 +474,7 @@ class Base(Entity): :return: One ID ref """ - if isinstance(assertion_id_refs, basestring): + if isinstance(assertion_id_refs, six.string_types): return 0, assertion_id_refs else: return 0, assertion_id_refs[0] diff --git a/src/saml2/httputil.py b/src/saml2/httputil.py index 78a2713..88c8f39 100644 --- a/src/saml2/httputil.py +++ b/src/saml2/httputil.py @@ -3,6 +3,7 @@ import hmac import logging import time import cgi +import six from urllib import quote from urlparse import parse_qs @@ -61,7 +62,7 @@ class Response(object): mte = self.mako_lookup.get_template(self.mako_template) return [mte.render(**argv)] else: - if isinstance(message, basestring): + if isinstance(message, six.string_types): return [message] else: return message diff --git a/src/saml2/mdie.py b/src/saml2/mdie.py index 645700b..8919731 100644 --- a/src/saml2/mdie.py +++ b/src/saml2/mdie.py @@ -1,4 +1,6 @@ #!/usr/bin/env python +import six + from saml2 import element_to_extension_element from saml2 import extension_elements_to_elements from saml2 import SamlBase @@ -22,7 +24,7 @@ def _eval(val, onts, mdb_safe): :param onts: Schemas to be used in the conversion :return: The basic dictionary """ - if isinstance(val, basestring): + if isinstance(val, six.string_types): val = val.strip() if not val: return None @@ -140,7 +142,7 @@ def from_dict(val, onts, mdb_safe=False): key = key.replace("__", ".") res[key] = from_dict(v, onts) return res - elif isinstance(val, basestring): + elif isinstance(val, six.string_types): return val elif isinstance(val, list): return [from_dict(v, onts) for v in val] diff --git a/src/saml2/metadata.py b/src/saml2/metadata.py index 99bcf89..980a7b8 100644 --- a/src/saml2/metadata.py +++ b/src/saml2/metadata.py @@ -20,6 +20,7 @@ from saml2 import samlp from saml2 import class_name from saml2 import xmldsig as ds +import six from saml2.sigver import pre_signature_part @@ -137,7 +138,7 @@ def do_organization_info(ava): for dkey, (ckey, klass) in ORG_ATTR_TRANSL.items(): if ckey not in ava: continue - if isinstance(ava[ckey], basestring): + if isinstance(ava[ckey], six.string_types): setattr(org, dkey, [_localized_name(ava[ckey], klass)]) elif isinstance(ava[ckey], list): setattr(org, dkey, @@ -163,7 +164,7 @@ def do_contact_person_info(lava): data = [] if isinstance(classpec, list): # What if value is not a list ? - if isinstance(value, basestring): + if isinstance(value, six.string_types): data = [classpec[0](text=value)] else: for val in value: @@ -253,7 +254,7 @@ def do_uiinfo(_uiinfo): aclass = uii.child_class(attr) inst = getattr(uii, attr) - if isinstance(val, basestring): + if isinstance(val, six.string_types): ainst = aclass(text=val) inst.append(ainst) elif isinstance(val, dict): @@ -263,7 +264,7 @@ def do_uiinfo(_uiinfo): inst.append(ainst) else: for value in val: - if isinstance(value, basestring): + if isinstance(value, six.string_types): ainst = aclass(text=value) inst.append(ainst) elif isinstance(value, dict): @@ -299,11 +300,11 @@ def do_uiinfo(_uiinfo): _attr = "keywords" val = _uiinfo[_attr] inst = getattr(uii, _attr) - # list of basestrings, dictionary or list of dictionaries + # list of six.string_types, dictionary or list of dictionaries if isinstance(val, list): for value in val: keyw = mdui.Keywords() - if isinstance(value, basestring): + if isinstance(value, six.string_types): keyw.text = value elif isinstance(value, dict): keyw.text = " ".join(value["text"]) @@ -398,7 +399,7 @@ def do_extensions(mname, item): def _do_nameid_format(cls, conf, typ): namef = conf.getattr("name_id_format", typ) if namef: - if isinstance(namef, basestring): + if isinstance(namef, six.string_types): ids = [md.NameIDFormat(namef)] else: ids = [md.NameIDFormat(text=form) for form in namef] @@ -413,7 +414,7 @@ def do_endpoints(conf, endpoints): servs = [] i = 1 for args in conf[endpoint]: - if isinstance(args, basestring): # Assume it's the location + if isinstance(args, six.string_types): # Assume it's the location args = {"location": args, "binding": DEFAULT_BINDING[endpoint]} elif isinstance(args, tuple) or isinstance(args, list): diff --git a/src/saml2/mongo_store.py b/src/saml2/mongo_store.py index 86c5607..7190882 100644 --- a/src/saml2/mongo_store.py +++ b/src/saml2/mongo_store.py @@ -21,6 +21,7 @@ from saml2.extension import mdattr from saml2.extension import ui from saml2 import xmldsig from saml2 import xmlenc +import six ONTS = { @@ -324,14 +325,14 @@ def protect(dic): res = {} for key, val in dic.items(): key = key.replace(".", "__") - if isinstance(val, basestring): + if isinstance(val, six.string_types): pass elif isinstance(val, dict): val = protect(val) elif isinstance(val, list): li = [] for va in val: - if isinstance(va, basestring): + if isinstance(va, six.string_types): pass elif isinstance(va, dict): va = protect(va) @@ -349,14 +350,14 @@ def unprotect(dic): pass else: key = key.replace("__", ".") - if isinstance(val, basestring): + if isinstance(val, six.string_types): pass elif isinstance(val, dict): val = unprotect(val) elif isinstance(val, list): li = [] for va in val: - if isinstance(va, basestring): + if isinstance(va, six.string_types): pass elif isinstance(val, dict): va = unprotect(va) diff --git a/src/saml2/population.py b/src/saml2/population.py index 75d505e..2362136 100644 --- a/src/saml2/population.py +++ b/src/saml2/population.py @@ -1,5 +1,6 @@ import logging from saml2.cache import Cache +import six logger = logging.getLogger(__name__) @@ -7,7 +8,7 @@ logger = logging.getLogger(__name__) class Population(object): def __init__(self, cache=None): if cache: - if isinstance(cache, basestring): + if isinstance(cache, six.string_types): self.cache = Cache(cache) else: self.cache = cache diff --git a/src/saml2/s_utils.py b/src/saml2/s_utils.py index 5339125..3aae0be 100644 --- a/src/saml2/s_utils.py +++ b/src/saml2/s_utils.py @@ -4,6 +4,7 @@ import random import time import base64 +import six import sys import hmac import string @@ -282,7 +283,7 @@ def _attrval(val, typ=""): def do_ava(val, typ=""): - if isinstance(val, basestring): + if isinstance(val, six.string_types): ava = saml.AttributeValue() ava.set_text(val) attrval = [ava] @@ -310,7 +311,7 @@ def do_attribute(val, typ, key): if attrval: attr.attribute_value = attrval - if isinstance(key, basestring): + if isinstance(key, six.string_types): attr.name = key elif isinstance(key, tuple): # 3-tuple or 2-tuple try: diff --git a/src/saml2/saml.py b/src/saml2/saml.py index 07f3c3e..d151383 100644 --- a/src/saml2/saml.py +++ b/src/saml2/saml.py @@ -11,6 +11,7 @@ from saml2.validate import valid_domain_name import saml2 from saml2 import SamlBase +import six from saml2 import xmldsig as ds from saml2 import xmlenc as xenc @@ -192,7 +193,7 @@ class AttributeValueBase(SamlBase): val = base64.encodestring(val) self.set_type("xs:base64Binary") else: - if isinstance(val, basestring): + if isinstance(val, six.string_types): if not typ: self.set_type("xs:string") else: diff --git a/src/saml2/server.py b/src/saml2/server.py index ce703cd..58017b1 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -10,6 +10,7 @@ import os import importlib import shelve +import six import threading from saml2 import saml @@ -89,7 +90,7 @@ class Server(Entity): _spec = self.config.getattr("session_storage", "idp") if not _spec: return SessionStorage() - elif isinstance(_spec, basestring): + elif isinstance(_spec, six.string_types): if _spec.lower() == "memory": return SessionStorage() else: # Should be tuple @@ -116,7 +117,7 @@ class Server(Entity): typ = "" if not dbspec: idb = {} - elif isinstance(dbspec, basestring): + elif isinstance(dbspec, six.string_types): idb = shelve.open(dbspec, writeback=True) else: # database spec is a a 2-tuple (type, address) #print(>> sys.stderr, "DBSPEC: %s" % (dbspec,)) diff --git a/src/saml2/time_util.py b/src/saml2/time_util.py index 2a40370..03f97b1 100644 --- a/src/saml2/time_util.py +++ b/src/saml2/time_util.py @@ -14,6 +14,7 @@ import sys from datetime import timedelta from datetime import datetime +import six TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" TIME_FORMAT_WITH_FRAGMENT = re.compile( @@ -274,7 +275,7 @@ def before(point): if not point: return True - if isinstance(point, basestring): + if isinstance(point, six.string_types): point = str_to_time(point) elif isinstance(point, int): point = time.gmtime(point) @@ -302,12 +303,12 @@ valid = before def later_than(after, before): """ True if then is later or equal to that """ - if isinstance(after, basestring): + if isinstance(after, six.string_types): after = str_to_time(after) elif isinstance(after, int): after = time.gmtime(after) - if isinstance(before, basestring): + if isinstance(before, six.string_types): before = str_to_time(before) elif isinstance(before, int): before = time.gmtime(before) diff --git a/tests/test_51_client.py b/tests/test_51_client.py index 905aeff..576171c 100644 --- a/tests/test_51_client.py +++ b/tests/test_51_client.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import base64 +import six import urllib import urlparse from saml2.xmldsig import SIG_RSA_SHA256 @@ -623,7 +624,7 @@ class TestClientWithDummy(): IDP, "http://www.example.com/relay_state", binding=binding, response_binding=response_binding) - assert isinstance(sid, basestring) + assert isinstance(sid, six.string_types) assert len(http_args) == 4 assert http_args["headers"][0][0] == "Location" assert http_args["data"] == [] @@ -643,7 +644,7 @@ class TestClientWithDummy(): binding=binding, response_binding=response_binding) assert binding == auth_binding - assert isinstance(sid, basestring) + assert isinstance(sid, six.string_types) assert len(http_args) == 4 assert http_args["headers"][0][0] == "Location" assert http_args["data"] == [] diff --git a/tools/parse_xsd2.py b/tools/parse_xsd2.py index 43c69c3..a5a2275 100755 --- a/tools/parse_xsd2.py +++ b/tools/parse_xsd2.py @@ -355,7 +355,7 @@ class PyObj(object): line.append("%sc_namespace = NAMESPACE" % (INDENT,)) try: if self.value_type: - if isinstance(self.value_type, basestring): + if isinstance(self.value_type, six.string_types): line.append("%sc_value_type = '%s'" % (INDENT, self.value_type)) else: @@ -593,7 +593,7 @@ def _do(obj, target_namespace, cdict, prep): else: obj.done = True if req: - if isinstance(req, basestring): + if isinstance(req, six.string_types): prep.append(req) else: prep.extend(req) @@ -1643,7 +1643,7 @@ def output(elem, target_namespace, eldict, ignore=None): for prep in preps: if prep: done = 1 - if isinstance(prep, basestring): + if isinstance(prep, six.string_types): print(prep) else: for item in prep: