diff --git a/HACKING.rst b/HACKING.rst index ae080f56cf..bceaba410d 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -4,4 +4,4 @@ Trove Library Specific Commandments - [T101] Validate that LOG messages, except debug ones, are translated - [T102] Validate that debug level logs are not translated - [T103] Exception messages should be translated - +- [T104] Python 3 is not support basestring,replace basestring with six.string_types diff --git a/integration/tests/examples/examples/example_generation.py b/integration/tests/examples/examples/example_generation.py index 7ca8a02c43..54d03d1120 100644 --- a/integration/tests/examples/examples/example_generation.py +++ b/integration/tests/examples/examples/example_generation.py @@ -2,6 +2,7 @@ import httplib2 import json import os import re +import six import sys import time from urlparse import urlparse @@ -727,9 +728,11 @@ class MgmtHosts(object): check.true(instance['name'] == 'json_rack_instance' or instance['name'] == 'xml_rack_instance') #TODO: Check with GUID regex. - check.true(isinstance(instance['id'], basestring)) - check.true(isinstance(instance['server_id'], basestring)) - check.true(isinstance(instance['tenant_id'], basestring)) + check.true(isinstance(instance['id'], six.string_types)) + check.true(isinstance(instance['server_id'], + six.string_types)) + check.true(isinstance(instance['tenant_id'], + six.string_types)) @test def mgmt_host_update_all(self): @@ -827,7 +830,7 @@ class MgmtInstance(object): @for_both def created(self, result): #TODO: use regex - assert_true(isinstance(result.created, basestring)) + assert_true(isinstance(result.created, six.string_types)) @test def deleted(self): @@ -862,26 +865,29 @@ class MgmtInstance(object): assert_true(isinstance(result.links, list)) for link in result.links: assert_true(isinstance(link, dict)) - assert_true(isinstance(link['href'], basestring)) - assert_true(isinstance(link['rel'], basestring)) + assert_true(isinstance(link['href'], six.string_types)) + assert_true(isinstance(link['rel'], six.string_types)) @test def local_id(self): #TODO: regex assert_true(isinstance(self.results[JSON_INDEX].local_id, int)) - assert_true(isinstance(self.results[XML_INDEX].local_id, basestring)) + assert_true(isinstance(self.results[XML_INDEX].local_id, + six.string_types)) @test @for_both def name(self, result): #TODO: regex - assert_true(isinstance(result.name, basestring)) + assert_true(isinstance(result.name, + six.string_types)) @test @for_both def server_id(self, result): #TODO: regex - assert_true(isinstance(result.server_id, basestring)) + assert_true(isinstance(result.server_id, + six.string_types)) @test @for_both @@ -903,7 +909,8 @@ class MgmtInstance(object): @for_both def updated(self, result): #TODO: regex - assert_true(isinstance(result.updated, basestring)) + assert_true(isinstance(result.updated, + six.string_types)) @test @for_both diff --git a/integration/tests/integration/tests/volumes/driver.py b/integration/tests/integration/tests/volumes/driver.py index 221b2a41f4..340b721cab 100644 --- a/integration/tests/integration/tests/volumes/driver.py +++ b/integration/tests/integration/tests/volumes/driver.py @@ -17,6 +17,7 @@ from numbers import Number import os import re import shutil +import six import socket import time import unittest @@ -329,7 +330,7 @@ class SetupVolume(VolumeTest): device = self.story.client._setup_volume(self.story.context, self.story.volume_id, self.story.host) - if not isinstance(device, basestring): + if not isinstance(device, six.string_types): self.fail("Expected device to be a string, but instead it was " + str(type(device)) + ".") self.story.device_path = device diff --git a/tox.ini b/tox.ini index c4b6d15c96..f5bba9c330 100644 --- a/tox.ini +++ b/tox.ini @@ -81,7 +81,7 @@ filename=*.py,trove-* [hacking] import_exceptions = trove.common.i18n -local-check-factory = trove.hacking.translation_checks.factory +local-check-factory = trove.hacking.checks.factory [testenv:api-ref] # This environment is called from CI scripts to test and publish diff --git a/trove/hacking/translation_checks.py b/trove/hacking/checks.py similarity index 89% rename from trove/hacking/translation_checks.py rename to trove/hacking/checks.py index 9cacd5941b..965f0c3d95 100644 --- a/trove/hacking/translation_checks.py +++ b/trove/hacking/checks.py @@ -104,7 +104,19 @@ def check_raised_localized_exceptions(logical_line, filename): yield (logical_line.index(exception_msg), msg) +def check_no_basestring(logical_line): + """T104 - Don't use basestring, use six.string_types instead + basestring is not supported by py3, using six.string_types to ensure + py3 and py2 compatibility + """ + if re.search(r"\, basestring\)", logical_line): + msg = ("T104: basestring is not Python3-compatible, use " + "six.string_types instead.") + yield(0, msg) + + def factory(register): register(validate_log_translations) register(no_translate_debug_logs) register(check_raised_localized_exceptions) + register(check_no_basestring) diff --git a/trove/tests/scenario/runners/configuration_runners.py b/trove/tests/scenario/runners/configuration_runners.py index e1e17ae3b7..8591286fb4 100644 --- a/trove/tests/scenario/runners/configuration_runners.py +++ b/trove/tests/scenario/runners/configuration_runners.py @@ -16,6 +16,7 @@ from datetime import datetime import json from proboscis import SkipTest +import six from trove.common.utils import generate_uuid from trove.tests.scenario.runners.test_runners import TestRunner @@ -139,12 +140,12 @@ class ConfigurationRunner(TestRunner): self.assert_client_code(client, expected_http_code) with TypeCheck('Configuration', result) as configuration: - configuration.has_field('name', basestring) - configuration.has_field('description', basestring) + configuration.has_field('name', six.string_types) + configuration.has_field('description', six.string_types) configuration.has_field('values', dict) - configuration.has_field('datastore_name', basestring) + configuration.has_field('datastore_name', six.string_types) configuration.has_field('datastore_version_id', unicode) - configuration.has_field('datastore_version_name', basestring) + configuration.has_field('datastore_version_name', six.string_types) self.assert_equal(name, result.name) self.assert_equal(description, result.description) @@ -216,12 +217,12 @@ class ConfigurationRunner(TestRunner): # check the result field types with TypeCheck("configuration", result) as check: - check.has_field("id", basestring) - check.has_field("name", basestring) - check.has_field("description", basestring) + check.has_field("id", six.string_types) + check.has_field("name", six.string_types) + check.has_field("description", six.string_types) check.has_field("values", dict) - check.has_field("created", basestring) - check.has_field("updated", basestring) + check.has_field("created", six.string_types) + check.has_field("updated", six.string_types) check.has_field("instance_count", int) # check for valid timestamps @@ -243,7 +244,7 @@ class ConfigurationRunner(TestRunner): if param.type == 'integer': check.has_element(item_key, int) if param.type == 'string': - check.has_element(item_key, basestring) + check.has_element(item_key, six.string_types) if param.type == 'boolean': check.has_element(item_key, bool) diff --git a/trove/tests/unittests/hacking/test_translation_checks.py b/trove/tests/unittests/hacking/test_check.py similarity index 92% rename from trove/tests/unittests/hacking/test_translation_checks.py rename to trove/tests/unittests/hacking/test_check.py index bd539f6ba8..2c764a9946 100644 --- a/trove/tests/unittests/hacking/test_translation_checks.py +++ b/trove/tests/unittests/hacking/test_check.py @@ -10,7 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. -from trove.hacking import translation_checks as tc +from trove.hacking import checks as tc from trove.tests.unittests import trove_testtools @@ -87,3 +87,11 @@ class HackingTestCase(trove_testtools.TestCase): f = tc.check_raised_localized_exceptions self.assertLinePasses(f, "raise KeyError('Error text')", 'neutron_lib/tests/unit/mytest.py') + + def test_no_basestring(self): + self.assertEqual( + 1, + len(list(tc.check_no_basestring("isinstance(x, basestring)")))) + self.assertEqual( + 0, + len(list(tc.check_no_basestring("this basestring is good)"))))