Added python3 support 41/97841/1
authorLianhao Lu <lianhao.lu@intel.com>
Fri, 1 Nov 2019 08:01:34 +0000 (16:01 +0800)
committerLianhao Lu <lianhao.lu@intel.com>
Fri, 1 Nov 2019 08:01:34 +0000 (16:01 +0800)
Change-Id: I7a09d11cc6506e91327d96e06a9d1001c9567380
Issue-ID: VNFSDK-419
Signed-off-by: Lianhao Lu <lianhao.lu@intel.com>
13 files changed:
requirements.txt
setup.py
tests/packager/test_manifest.py
tests/packager/test_utils.py
tests/validator/test_validate_utils.py
tox.ini
vnfsdk_pkgtools/packager/manifest.py
vnfsdk_pkgtools/packager/utils.py
vnfsdk_pkgtools/util.py
vnfsdk_pkgtools/validator/toscaparser_validator.py
vnfsdk_pkgtools/version.py
vnfsdk_pkgtools/vnfreq/__init__.py
vnfsdk_pkgtools/vnfreq/pkg_reqs.py

index fa17a3e..ea3b478 100644 (file)
@@ -2,5 +2,6 @@ ruamel.yaml<0.15
 requests>=2.3.0
 stevedore>=1.9.0
 udatetime<1.0,>=0.0.16
-nfv-toscaparser<2.0,>=1.0.1
+nfv-toscaparser<2.0,>=1.1.2.dev2
 prettytable<1.0
+six<2.0
index 90e7e9b..867cb64 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -22,9 +22,6 @@ import sys
 
 if sys.version_info < (2, 7):
     sys.exit('VNF SDK requires Python 2.7+')
-if sys.version_info >= (3, 0):
-    sys.exit('VNF SDK does not support Python 3')
-
 
 root_dir = os.path.dirname(__file__)
 install_requires = []
@@ -73,6 +70,7 @@ setup(
         'Programming Language :: Python',
         'Programming Language :: Python :: 2',
         'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3',
         'Topic :: Software Development :: Libraries :: Python Modules',
         'Topic :: System :: Networking',
         'Topic :: System :: Systems Administration'],
index 2383284..003e23e 100644 (file)
@@ -126,7 +126,7 @@ def test_update_to_file(tmpdir):
     m2 = manifest.Manifest(mf.dirname, 'test.mf')
     assert m1.metadata['vnf_provider_id'] == m2.metadata['vnf_provider_id']
     assert m1.digests['digest'] == m2.digests['digest2']
-    assert len(m2.digests.keys()) == 2
+    assert len(list(m2.digests.keys())) == 2
     assert m2.signature == CMS
 
 def test_signature(tmpdir):
index 2a2d98c..7456302 100644 (file)
@@ -28,7 +28,7 @@ MSG_FILE  = os.path.join(RESOURCES_DIR, 'manifest.mf')
 CERT_FILE = os.path.join(RESOURCES_DIR, 'test.crt')
 KEY_FILE  = os.path.join(RESOURCES_DIR, 'test.key')
 
-CONTENT = "needToBeHashed"
+CONTENT = b"needToBeHashed"
 SHA256 = "20a480339aa4371099f9503511dcc5a8051ce3884846678ced5611ec64bbfc9c"
 SHA512 = "dbed8672e752d51d0c7ca42050f67faf1534e58470bba96e787df5c4cf6a4f8ecf7ad45fb9307adbc5b9dec8432627d86b3eb1d3d43ee9c5e93f754ff2825320"
 
index 2c36a3b..1d663e5 100644 (file)
@@ -39,4 +39,4 @@ def test_load_bad_definition(tmpdir):
 
 def test_load_defualt_definition(tmpdir):
     p = tmpdir.join("non_exist")
-    assert 1 == utils.load_definitions(str(p),defaults=1)
+    assert 1 == utils.load_definitions(str(p), defaults=1)
diff --git a/tox.ini b/tox.ini
index b4e2212..2567eaf 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -28,13 +28,8 @@ setenv =
 deps =
     -rrequirements.txt
     -rtests/requirements.txt
-basepython =
-  py27: python2.7
-
-[testenv:py27]
 commands =
-        coverage run --module pytest --junitxml xunit-results.xml tests/
-        coverage xml --omit=".tox/py27/*","tests/*"
-        coverage report --omit=".tox/py27/*","tests/*"
-       #pytest tests --cov-report term-missing --cov vnfsdk_pkgtools
-
+    coverage run --module pytest --junitxml xunit-results.xml tests/
+    coverage xml --omit=".tox/*,tests/*"
+    coverage report --omit=".tox/*,tests/*"
+    #pytest tests --cov-report term-missing --cov vnfsdk_pkgtools
index 937f14e..81ac53c 100644 (file)
@@ -17,6 +17,7 @@ from collections import namedtuple
 import os
 import tempfile
 
+import six
 import udatetime
 
 from vnfsdk_pkgtools.packager import utils
@@ -64,7 +65,7 @@ class Manifest(object):
         line or a line with only spaces and tabs.
         '''
         block_content = [ ]
-        with open(os.path.join(self.root, self.path),'rU') as fp:
+        with open(os.path.join(self.root, self.path), 'rU') as fp:
             for line in fp:
                 line = line.strip(' \t\n')
                 if line:
@@ -153,7 +154,7 @@ class Manifest(object):
         ret += "vnf_package_version: %s\n" % (self.metadata['vnf_package_version'])
         ret += "vnf_release_data_time: %s\n" % (self.metadata['vnf_release_data_time'])
         # degist
-        for (key, digest) in self.digests.iteritems():
+        for (key, digest) in six.iteritems(self.digests):
             ret += "\n"
             ret += "Source: %s\n" % key
             ret += "Algorithm: %s\n" % digest[0]
@@ -178,10 +179,9 @@ class Manifest(object):
     def save_to_temp_without_cms(self):
         # we need to strip cms block with out changing the order of the
         # file digest content before we verify the signature
-        tmpfile = tempfile.NamedTemporaryFile(delete=False)
         skip = False
         lines = []
-        with open(os.path.join(self.root, self.path),'rU') as fp:
+        with open(os.path.join(self.root, self.path), 'rU') as fp:
             for line in fp:
                 if '--BEGIN CMS--' in line:
                     skip = True
@@ -192,6 +192,7 @@ class Manifest(object):
         # strip trailing empty lines
         content = ''.join(lines).rstrip(' \n\t')
         content += '\n'
+        tmpfile = tempfile.NamedTemporaryFile(mode='w',delete=False)
         tmpfile.write(content)
         tmpfile.close()
         return tmpfile.name
index 7027e2b..405a65e 100644 (file)
@@ -18,11 +18,13 @@ from io import BytesIO
 import logging
 import os
 import os.path
-import urlparse
 import subprocess
 import tempfile
 
 import requests
+import six
+from six.moves.urllib import parse as urlparse
+
 
 LOG = logging.getLogger(__name__)
 
@@ -59,13 +61,13 @@ def _run_cmd(cmd, **kwargs):
     else:
         raise RuntimeError("cmd must be string or list")
 
-    for key, value in kwargs.iteritems():
+    for key, value in six.iteritems(kwargs):
         args.append(key)
         if value:
             args.append(value)
     try:
         LOG.debug("Executing %s", args)
-        return subprocess.check_output(args)
+        return str(subprocess.check_output(args).decode('utf-8'))
     except subprocess.CalledProcessError as e:
         LOG.error("Executing %s failed with return code %d, output: %s",
                   e.cmd, e.returncode, e.output)
@@ -89,7 +91,7 @@ def verify(msg_file, cert_file, cms, no_verify_cert=False):
     if no_verify_cert:
         args.append("-no_signer_cert_verify")
 
-    with tempfile.NamedTemporaryFile() as f:
+    with tempfile.NamedTemporaryFile(mode='w') as f:
         f.write(cms)
         f.flush()
         kwargs = {
index 78010e2..71344de 100644 (file)
@@ -1,8 +1,9 @@
 import os
+import os.path as path
 
 import vnfsdk_pkgtools
 
 
 def get_project_root():
     """Returns project root folder."""
-    return os.path.abspath(os.path.join(os.path.dirname(vnfsdk_pkgtools.__file__),os.pardir))
+    return path.abspath(path.join(path.dirname(vnfsdk_pkgtools.__file__), os.pardir))
index 533cc00..d1ccd9a 100644 (file)
@@ -20,6 +20,7 @@ import os
 import pkg_resources
 import re
 
+import six
 from toscaparser.common.exception import ValidationError
 from toscaparser.tosca_template import ToscaTemplate
 
@@ -122,7 +123,7 @@ class ToscaparserValidator(validator.ValidatorBase):
         if not isinstance(value, dict):
             msg = "node %s: value %s is not a map of string"
             raise HpaValueError(msg % (refkey, value))
-        for (key, hpa_value) in value.iteritems():
+        for (key, hpa_value) in six.iteritems(value):
             if key not in hpa_schema:
                 msg = "node %s: %s is NOT a valid HPA key"
                 raise HpaValueError(msg  % (refkey, key))
@@ -134,18 +135,18 @@ class ToscaparserValidator(validator.ValidatorBase):
             if not isinstance(hpa_dict, dict):
                 msg = "node %s, HPA key %s: %s is NOT a valid json encoded string of dict"
                 raise HpaValueError(msg % (refkey, key, hpa_value.encode('ascii', 'replace')))
-            for (attr, val) in hpa_dict.iteritems():
+            for (attr, val) in six.iteritems(hpa_dict):
                 if attr not in hpa_schema[key]:
                     msg = "node %s, HPA key %s: %s is NOT valid HPA attribute"
                     raise HpaValueError(msg % (refkey, key, attr))
-                if not isinstance(val, basestring):
+                if not isinstance(val, six.string_types):
                     msg = ("node %s, HPA key %s, attr %s: %s is not a string attr value")
-                    raise HpaValueError(msg % (refkey, key, attr, str(val).encode('ascii','replace')))
+                    raise HpaValueError(msg % (refkey, key, attr, str(val).encode('ascii', 'replace')))
                 attr_schema = hpa_schema[key][attr]
                 if not re.match(attr_schema, str(val)):
                     msg = ("node %s, HPA key %s, attr %s: %s is not a valid HPA "
                           "attr value, expected re pattern is %s")
-                    raise HpaValueError(msg % (refkey, key, attr, val.encode('ascii','replace'), attr_schema))
+                    raise HpaValueError(msg % (refkey, key, attr, val.encode('ascii', 'replace'), attr_schema))
 
     def validate_hpa_value(self, refkey, hpa_schema, values):
         if isinstance(values, list):
index 691a45b..f5708c4 100644 (file)
@@ -1,3 +1,3 @@
 global __version__
 
-__version__='1.2.0'
+__version__='1.3.0'
index 376b519..4c27495 100644 (file)
@@ -52,7 +52,7 @@ def check_and_print(test_reqs, reader, tosca):
         lines = textwrap.wrap(testor.DESC, width=40)
         table.add_row([testor.ID, status, lines.pop(0)])
         for line in lines:
-            table.add_row(['','',line])
+            table.add_row(['', '', line])
     if test_reqs:
         print(table)
     return err
index 5c047bd..b84e80a 100644 (file)
@@ -85,7 +85,7 @@ class R26881(vnfreq.TesterBase):
                 # TODO(llu) nfv-toscaparser now doesn't support artifacts
                 # yet, we have to hack it for now.
                 # See https://jira.opnfv.org/browse/PARSER-184.
-                for name, props in node.entity_tpl.get('artifacts', {}).iteritems():
+                for name, props in six.iteritems(node.entity_tpl.get('artifacts', {})):
                     file = props.get('file', None)
                     if file and \
                        os.path.isfile(os.path.join(entry_path, file)) or \