python3: version neutral API

Using the six library we make version neutral API calls to
dictionary methods and to unicode methods.

partial: https://github.com/vmware/pyvmomi/issues/55
This commit is contained in:
Shawn Hartsock
2014-07-28 13:09:25 -04:00
parent e88f67a4a1
commit de17170440
4 changed files with 53 additions and 29 deletions

View File

@@ -314,7 +314,10 @@ def __Login(host, port, user, pwd, service, adapter, version, path,
# library the fault occurred. Without the traceback we have no idea
# why the connection failed beyond the message string.
(type, value, traceback) = sys.exc_info()
reraise(vim.fault.HostConnectFault(msg=str(e)), None, traceback)
if traceback:
reraise(vim.fault.HostConnectFault(msg=str(e)), None, traceback)
else:
raise vim.fault.HostConnectFault(msg=str(e))
# Get a ticket if we're connecting to localhost and password is not specified
if host == 'localhost' and not pwd:

View File

@@ -21,6 +21,7 @@ This module is for ISO 8601 parsing
"""
__author__ = 'VMware, Inc.'
from six import iteritems
import time
from datetime import datetime, timedelta, tzinfo
import re
@@ -119,7 +120,7 @@ def ParseISO8601(datetimeStr):
if match:
try:
dt = {}
for key, defaultVal in _dtExprKeyDefValMap.iteritems():
for key, defaultVal in iteritems(_dtExprKeyDefValMap):
val = match.group(key)
if val:
if key == 'microsecond':

View File

@@ -13,22 +13,34 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from six.moves import http_client
from six import text_type
from six import u
from six import PY2
from six import PY3
from six.moves import http_client
if PY3:
long = int
basestring = str
from six import u
import sys
import os
import socket
import subprocess
import thread
if PY2:
from thread import allocate_lock
if PY3:
from _thread import allocate_lock
import time
import urlparse
from datetime import datetime
from xml.parsers.expat import ParserCreate
# We have our own escape functionality.
# from xml.sax.saxutils import escape
from cStringIO import StringIO
if PY2:
from cStringIO import StringIO
if PY3:
from io import StringIO
from pyVmomi.VmomiSupport import *
from pyVmomi.StubAdapterAccessorImpl import StubAdapterAccessorMixin
import pyVmomi.Iso8601
@@ -68,7 +80,7 @@ SOAP_BODY_TAG = "{0}:Body".format(SOAP_NSMAP[XMLNS_SOAPENV])
SOAP_ENVELOPE_START = '<{0} '.format(SOAP_ENVELOPE_TAG) + \
' '.join(['xmlns:' + prefix + '="' + urn + '"' \
for urn, prefix in SOAP_NSMAP.iteritems()]) + \
for urn, prefix in iteritems(SOAP_NSMAP)]) + \
'>\n'
SOAP_ENVELOPE_END = "\n</{0}>".format(SOAP_ENVELOPE_TAG)
SOAP_HEADER_START = "<{0}>".format(SOAP_HEADER_TAG)
@@ -181,7 +193,7 @@ class SoapSerializer:
self.version = version
self.nsMap = nsMap and nsMap or {}
self.encoding = encoding and encoding or XML_ENCODING
for ns, prefix in self.nsMap.iteritems():
for ns, prefix in iteritems(self.nsMap):
if prefix == '':
self.defaultNS = ns
break
@@ -385,7 +397,9 @@ class SoapSerializer:
# it means that if you emit output in other encoding than UTF-8,
# you cannot serialize it again once more. That's feature, not
# a bug.
val = str(val).decode('UTF-8')
val = str(val)
if PY2:
val = val.decode('UTF-8')
result = XmlEscape(val)
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr,
result.encode(self.encoding)))
@@ -821,7 +835,7 @@ class SoapStubAdapterBase(StubAdapterBase):
if reqContexts or samlToken:
result.append(SOAP_HEADER_START)
for key, val in reqContexts.iteritems():
for key, val in iteritems(reqContexts):
# Note: Support req context of string type only
if not isinstance(val, basestring):
raise TypeError("Request context key ({0}) has non-string value ({1}) of {2}".format(key, val, type(val)))
@@ -1126,7 +1140,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
# the UnixSocketConnection ctor expects to find it -- see above
self.host = sock
elif url:
scheme, self.host, urlpath = urlparse.urlparse(url)[:3]
scheme, self.host, urlpath = urlparse(url)[:3]
# Only use the URL path if it's sensible, otherwise use the path
# keyword argument as passed in.
if urlpath not in ('', '/'):
@@ -1163,7 +1177,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
self.poolSize = poolSize
self.pool = []
self.connectionPoolTimeout = connectionPoolTimeout
self.lock = thread.allocate_lock()
self.lock = allocate_lock()
self.schemeArgs = {}
if certKeyFile:
self.schemeArgs['key_file'] = certKeyFile
@@ -1490,7 +1504,7 @@ class SessionOrientedStub(StubAdapterBase):
raise obj
# Raise any socket/httplib errors caught above.
raise
raise SystemError()
## Retrieve a managed property
#
@@ -1520,7 +1534,7 @@ class SessionOrientedStub(StubAdapterBase):
raise e
return obj
# Raise any socket/httplib errors caught above.
raise
raise SystemError()
## Handle the login method call
#

View File

@@ -17,8 +17,14 @@
from __future__ import absolute_import
from __future__ import with_statement # 2.5 only
from six import iteritems
from six import iterkeys
from six import itervalues
from six import text_type
from six import u
from six import PY3
if PY3:
long = int
basestring = str
from datetime import datetime
import pyVmomi.Iso8601
@@ -1030,7 +1036,7 @@ def GetWsdlTypes():
with _lazyLock:
for ns, name in _wsdlDefMap:
GetWsdlType(ns, name)
return _wsdlTypeMap.itervalues()
return itervalues(_wsdlTypeMap)
## Get the qualified XML schema name (ns, name) of a type
def GetQualifiedWsdlName(type):
@@ -1117,21 +1123,21 @@ def GetServiceVersions(namespace):
by compatibility (i.e. any version in the list that is compatible with some version
v in the list will preceed v)
"""
versions = dict((v, True) for (v, n) in serviceNsMap.iteritems() if n == namespace)
versions = dict((v, True) for (v, n) in iteritems(serviceNsMap) if n == namespace)
mappings = {}
for v in versions.iterkeys():
mappings[v] = set(parent for parent in parentMap[v].iterkeys()
if parent != v and versions.has_key(parent))
for v in iterkeys(versions):
mappings[v] = set(parent for parent in iterkeys(parentMap[v])
if parent != v and parent in versions.keys())
res = []
while True:
el = [ k for (k, v) in mappings.iteritems() if len(v) == 0 ]
el = [ k for (k, v) in iteritems(mappings) if len(v) == 0 ]
if len(el) == 0:
return res
el.sort()
for k in el:
res.insert(0, k)
del mappings[k]
for values in mappings.itervalues():
for values in itervalues(mappings):
values.discard(k)
@@ -1222,7 +1228,7 @@ def GetCompatibleType(type, version):
## Invert an injective mapping
def InverseMap(map):
return dict([ (v, k) for (k, v) in map.iteritems() ])
return dict([ (v, k) for (k, v) in iteritems(map) ])
types = Object()
nsMap = {}
@@ -1267,7 +1273,7 @@ _wsdlTypeMap = {
}
_wsdlNameMap = InverseMap(_wsdlTypeMap)
for ((ns, name), typ) in _wsdlTypeMap.items():
for ((ns, name), typ) in iteritems(dict(_wsdlTypeMap)):
if typ is not NoneType:
setattr(types, typ.__name__, typ)
_wsdlTypeMapNSs.add(ns)
@@ -1326,7 +1332,7 @@ vmodlTypes = {
vmodlNames = {}
## Add array type into special names
for name, typ in vmodlTypes.copy().iteritems():
for name, typ in iteritems(vmodlTypes.copy()):
if typ is not NoneType:
try:
arrayType = typ.Array
@@ -1458,7 +1464,7 @@ class StringDict(dict):
# Same as dict setdefault, except this will call through our __setitem__
def update(self, *args, **kwargs):
for k, v in dict(*args, **kwargs).iteritems():
for k, v in iteritems(dict(*args, **kwargs)):
self[k] = v
# Same as dict setdefault, except this will call through our __setitem__