# HG changeset patch # User Andrew Halberstadt # Date 1562102855 0 # Node ID 54ea59c8c99db1796013ddedc00135f9cd0be7f1 # Parent 75da187a5e939a68258660553035ea114cf84cae Bug 1473498 - [mach] Enable test_dispatcher with python 3 r=firefox-build-system-reviewers,chmanchester This test is working with minimal effort. Let's get it running to prevent future regressions. Differential Revision: https://phabricator.services.mozilla.com/D36098 diff --git a/python/mach/mach/config.py b/python/mach/mach/config.py --- a/python/mach/mach/config.py +++ b/python/mach/mach/config.py @@ -17,17 +17,17 @@ settings are available. from __future__ import absolute_import, unicode_literals import collections import os import sys import six from functools import wraps from six.moves.configparser import RawConfigParser, NoSectionError -from six import string_types as str_type +from six import string_types class ConfigException(Exception): pass class ConfigType(object): """Abstract base class for config values.""" @@ -57,17 +57,17 @@ class ConfigType(object): @staticmethod def to_config(value): return value class StringType(ConfigType): @staticmethod def validate(value): - if not isinstance(value, str_type): + if not isinstance(value, string_types): raise TypeError() @staticmethod def from_config(config, section, option): return config.get(section, option) class BooleanType(ConfigType): @@ -104,17 +104,17 @@ class PositiveIntegerType(IntegerType): if value < 0: raise ValueError() class PathType(StringType): @staticmethod def validate(value): - if not isinstance(value, str_type): + if not isinstance(value, string_types): raise TypeError() @staticmethod def from_config(config, section, option): return config.get(section, option) TYPE_CLASSES = { @@ -332,17 +332,17 @@ class ConfigSettings(collections.Mapping Each setting has the following optional parameters: default -- The default value for the setting. If None (the default) there is no default. extra -- A dict of additional key/value pairs to add to the setting metadata. """ - if isinstance(type_cls, basestring): + if isinstance(type_cls, string_types): type_cls = TYPE_CLASSES[type_cls] meta = { 'description': description, 'type_cls': type_cls, } if default != DefaultValue: diff --git a/python/mach/mach/main.py b/python/mach/mach/main.py --- a/python/mach/mach/main.py +++ b/python/mach/mach/main.py @@ -1,43 +1,43 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # This module provides functionality for the command-line build tool # (mach). It is packaged as a module because everything is a library. from __future__ import absolute_import, print_function, unicode_literals -from collections import Iterable import argparse import codecs import errno import imp import logging import os import sys import traceback import uuid +from collections import Iterable + +from six import string_types from .base import ( CommandContext, MachError, MissingFileError, NoCommandError, UnknownCommandError, UnrecognizedArgumentError, FailedCommandError, ) - +from .config import ConfigSettings from .decorators import ( CommandProvider, ) - -from .config import ConfigSettings from .dispatcher import CommandAction from .logging import LoggingManager from .registrar import Registrar MACH_ERROR = r''' The error occurred in mach itself. This is likely a bug in mach itself or a fundamental problem with a loaded module. @@ -252,21 +252,21 @@ To see more help for a specific command, This takes a path to a file and loads it as a Python module under the module name specified. If no name is specified, a random one will be chosen. """ if module_name is None: # Ensure parent module is present otherwise we'll (likely) get # an error due to unknown parent. - if b'mach.commands' not in sys.modules: - mod = imp.new_module(b'mach.commands') - sys.modules[b'mach.commands'] = mod + if 'mach.commands' not in sys.modules: + mod = imp.new_module('mach.commands') + sys.modules['mach.commands'] = mod - module_name = 'mach.commands.%s' % uuid.uuid1().get_hex() + module_name = 'mach.commands.%s' % uuid.uuid4().hex try: imp.load_source(module_name, path) except IOError as e: if e.errno != errno.ENOENT: raise raise MissingFileError('%s does not exist' % path) @@ -537,17 +537,17 @@ To see more help for a specific command, def load_settings(self, paths): """Load the specified settings files. If a directory is specified, the following basenames will be searched for in this order: machrc, .machrc """ - if isinstance(paths, basestring): + if isinstance(paths, string_types): paths = [paths] valid_names = ('machrc', '.machrc') def find_in_dir(base): if os.path.isfile(base): return base diff --git a/python/mach/mach/test/common.py b/python/mach/mach/test/common.py --- a/python/mach/mach/test/common.py +++ b/python/mach/mach/test/common.py @@ -1,18 +1,23 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. from __future__ import unicode_literals -from StringIO import StringIO import os import unittest +try: + from StringIO import StringIO +except ImportError: + # TODO io.StringIO causes failures with Python 2 (needs to be sorted out) + from io import StringIO + from mach.main import Mach here = os.path.abspath(os.path.dirname(__file__)) class TestBase(unittest.TestCase): provider_dir = os.path.join(here, 'providers') diff --git a/python/mach/mach/test/python.ini b/python/mach/mach/test/python.ini --- a/python/mach/mach/test/python.ini +++ b/python/mach/mach/test/python.ini @@ -1,10 +1,14 @@ [DEFAULT] -skip-if = python == 3 subsuite = mach [test_conditions.py] +skip-if = python == 3 [test_config.py] +skip-if = python == 3 [test_dispatcher.py] [test_entry_point.py] +skip-if = python == 3 [test_error_output.py] +skip-if = python == 3 [test_logger.py] +skip-if = python == 3 \ No newline at end of file diff --git a/python/mach/mach/test/test_dispatcher.py b/python/mach/mach/test/test_dispatcher.py --- a/python/mach/mach/test/test_dispatcher.py +++ b/python/mach/mach/test/test_dispatcher.py @@ -1,37 +1,38 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. from __future__ import unicode_literals import os -from cStringIO import StringIO +from io import StringIO + +from mozunit import main +from six import string_types from mach.base import CommandContext from mach.registrar import Registrar from mach.test.common import TestBase -from mozunit import main - here = os.path.abspath(os.path.dirname(__file__)) class TestDispatcher(TestBase): """Tests dispatch related code""" def get_parser(self, config=None): mach = self.get_mach('basic.py') for provider in Registrar.settings_providers: mach.settings.register_provider(provider) if config: - if isinstance(config, basestring): + if isinstance(config, string_types): config = StringIO(config) mach.settings.load_fps([config]) context = CommandContext(settings=mach.settings) return mach.get_argument_parser(context) def test_command_aliases(self): config = """