--- a/testing/mozbase/mozprofile/mozprofile/addons.py
+++ b/testing/mozbase/mozprofile/mozprofile/addons.py
@@ -4,22 +4,22 @@
from __future__ import absolute_import
import json
import os
import sys
import shutil
import tempfile
-import urllib2
import zipfile
import hashlib
from xml.dom import minidom
-from six import reraise
+from six import reraise, string_types
+from six.moves.urllib import request
import mozfile
from mozlog.unstructured import getLogger
# Needed for the AMO's rest API -
# https://developer.mozilla.org/en/addons.mozilla.org_%28AMO%29_API_Developers%27_Guide/The_generic_AMO_API
AMO_API_VERSION = "1.5"
_SALT = os.urandom(32).encode('hex')
@@ -108,17 +108,17 @@ class AddonManager(object):
def download(self, url, target_folder=None):
"""
Downloads an add-on from the specified URL to the target folder
:param url: URL of the add-on (XPI file)
:param target_folder: Folder to store the XPI file in
"""
- response = urllib2.urlopen(url)
+ response = request.urlopen(url)
fd, path = tempfile.mkstemp(suffix='.xpi')
os.write(fd, response.read())
os.close(fd)
if not self.is_addon(path):
mozfile.remove(path)
raise AddonFormatError('Not a valid add-on: %s' % url)
@@ -172,24 +172,24 @@ class AddonManager(object):
Installs all types of addons
:param addons: a list of addon paths to install
:param manifest: a list of addon manifests to install
"""
# install addon paths
if addons:
- if isinstance(addons, basestring):
+ if isinstance(addons, string_types):
addons = [addons]
for addon in set(addons):
self.install_from_path(addon)
# install addon manifests
if manifests:
- if isinstance(manifests, basestring):
+ if isinstance(manifests, string_types):
manifests = [manifests]
for manifest in manifests:
self.install_from_manifest(manifest)
def install_from_manifest(self, filepath):
"""
Installs addons from a manifest
:param filepath: path to the manifest of addons to install
@@ -230,17 +230,17 @@ class AddonManager(object):
def get_amo_install_path(self, query):
"""
Get the addon xpi install path for the specified AMO query.
:param query: query-documentation_
.. _query-documentation: https://developer.mozilla.org/en/addons.mozilla.org_%28AMO%29_API_Developers%27_Guide/The_generic_AMO_API # noqa
"""
- response = urllib2.urlopen(query)
+ response = request.urlopen(query)
dom = minidom.parseString(response.read())
for node in dom.getElementsByTagName('install')[0].childNodes:
if node.nodeType == node.TEXT_NODE:
return node.data
@classmethod
def _gen_iid(cls, addon_path):
hash = hashlib.sha1(_SALT)
@@ -348,17 +348,17 @@ class AddonManager(object):
# Remove the namespace prefix from the tag for comparison
entry = node.nodeName.replace(em, "")
if entry in details.keys():
details.update({entry: get_text(node)})
except Exception as e:
reraise(AddonFormatError(str(e)), None, sys.exc_info()[2])
# turn unpack into a true/false value
- if isinstance(details['unpack'], basestring):
+ if isinstance(details['unpack'], string_types):
details['unpack'] = details['unpack'].lower() == 'true'
# If no ID is set, the add-on is invalid
if details.get('id') is None and not is_webext:
raise AddonFormatError('Add-on id could not be found.')
return details
--- a/testing/mozbase/mozprofile/mozprofile/permissions.py
+++ b/testing/mozbase/mozprofile/mozprofile/permissions.py
@@ -7,17 +7,19 @@
add permissions to the profile
"""
from __future__ import absolute_import
import codecs
import os
import sqlite3
-import urlparse
+
+from six import string_types
+from six.moves.urllib import parse
__all__ = ['MissingPrimaryLocationError', 'MultiplePrimaryLocationsError',
'DEFAULT_PORTS', 'DuplicateLocationError', 'BadPortLocationError',
'LocationsSyntaxError', 'Location', 'ServerLocations',
'Permissions']
# http://hg.mozilla.org/mozilla-central/file/b871dfb2186f/build/automation.py.in#l28
DEFAULT_PORTS = {'http': '8888',
@@ -134,17 +136,17 @@ class ServerLocations(object):
raise MultiplePrimaryLocationsError()
self.hasPrimary = True
self._locations.append(location)
if self.add_callback and not suppress_callback:
self.add_callback([location])
def add_host(self, host, port='80', scheme='http', options='privileged'):
- if isinstance(options, basestring):
+ if isinstance(options, string_types):
options = options.split(',')
self.add(Location(scheme, host, port, options))
def read(self, filename, check_for_primary=True):
"""
Reads the file and adds all valid locations to the ``self._locations`` array.
:param filename: in the format of server-locations.txt_
@@ -177,17 +179,17 @@ class ServerLocations(object):
options = options.split(',')
except ValueError:
server = line
options = []
# parse the server url
if '://' not in server:
server = 'http://' + server
- scheme, netloc, path, query, fragment = urlparse.urlsplit(server)
+ scheme, netloc, path, query, fragment = parse.urlsplit(server)
# get the host and port
try:
host, port = netloc.rsplit(':', 1)
except ValueError:
host = netloc
port = DEFAULT_PORTS.get(scheme, '80')
try:
--- a/testing/mozbase/mozprofile/mozprofile/prefs.py
+++ b/testing/mozbase/mozprofile/mozprofile/prefs.py
@@ -6,18 +6,19 @@
user preferences
"""
from __future__ import absolute_import, print_function
import json
import mozfile
import os
import tokenize
-from ConfigParser import SafeConfigParser as ConfigParser
-from StringIO import StringIO
+
+from six.moves.configparser import SafeConfigParser as ConfigParser
+from six import StringIO, string_types
__all__ = ('PreferencesReadError', 'Preferences')
class PreferencesReadError(Exception):
"""read error for prefrences files"""
@@ -59,17 +60,17 @@ class Preferences(object):
what type the preference value is, as natively it is a string
- integers will get cast to integers
- true/false will get cast to True/False
- anything enclosed in single quotes will be treated as a string
with the ''s removed from both sides
"""
- if not isinstance(value, basestring):
+ if not isinstance(value, string_types):
return value # no op
quote = "'"
if value == 'true':
return True
if value == 'false':
return False
try:
return int(value)
@@ -141,17 +142,17 @@ class Preferences(object):
if isinstance(prefs, list):
if [i for i in prefs if type(i) != list or len(i) != 2]:
raise PreferencesReadError("Malformed preferences: %s" % path)
values = [i[1] for i in prefs]
elif isinstance(prefs, dict):
values = prefs.values()
else:
raise PreferencesReadError("Malformed preferences: %s" % path)
- types = (bool, basestring, int)
+ types = (bool, string_types, int)
if [i for i in values if not [isinstance(i, j) for j in types]]:
raise PreferencesReadError("Only bool, string, and int values allowed")
return prefs
@classmethod
def read_prefs(cls, path, pref_setter='user_pref', interpolation=None):
"""
Read preferences from (e.g.) prefs.js
@@ -181,53 +182,53 @@ class Preferences(object):
if token[0] == tokenize.COMMENT:
continue
processed_tokens.append(token[:2]) # [:2] gets around http://bugs.python.org/issue9974
string = tokenize.untokenize(processed_tokens)
retval = []
def pref(a, b):
- if interpolation and isinstance(b, basestring):
+ if interpolation and isinstance(b, string_types):
b = b.format(**interpolation)
retval.append((a, b))
lines = [i.strip().rstrip(';') for i in string.split('\n') if i.strip()]
_globals = {'retval': retval, 'true': True, 'false': False}
_globals[pref_setter] = pref
for line in lines:
try:
eval(line, _globals, {})
except SyntaxError:
print(line)
raise
# de-magic the marker
for index, (key, value) in enumerate(retval):
- if isinstance(value, basestring) and marker in value:
+ if isinstance(value, string_types) and marker in value:
retval[index] = (key, value.replace(marker, '//'))
return retval
@classmethod
def write(cls, _file, prefs, pref_string='user_pref(%s, %s);'):
"""write preferences to a file"""
- if isinstance(_file, basestring):
- f = file(_file, 'a')
+ if isinstance(_file, string_types):
+ f = open(_file, 'a')
else:
f = _file
if isinstance(prefs, dict):
# order doesn't matter
prefs = prefs.items()
# serialize -> JSON
_prefs = [(json.dumps(k), json.dumps(v))
for k, v in prefs]
# write the preferences
for _pref in _prefs:
print(pref_string % _pref, file=f)
# close the file if opened internally
- if isinstance(_file, basestring):
+ if isinstance(_file, string_types):
f.close()
--- a/testing/mozbase/mozprofile/mozprofile/profile.py
+++ b/testing/mozbase/mozprofile/mozprofile/profile.py
@@ -250,17 +250,17 @@ class Profile(object):
def pop_preferences(self, filename):
"""
pop the last set of preferences added
returns True if popped
"""
path = os.path.join(self.profile, filename)
- with file(path) as f:
+ with open(path) as f:
lines = f.read().splitlines()
def last_index(_list, value):
"""
returns the last index of an item;
this should actually be part of python code but it isn't
"""
for index in reversed(range(len(_list))):
@@ -277,17 +277,17 @@ class Profile(object):
assert s is None, '%s found without %s' % (self.delimeters[0], self.delimeters[1])
# ensure the markers are in the proper order
assert e > s, '%s found at %s, while %s found at %s' % (self.delimeters[1], e,
self.delimeters[0], s)
# write the prefs
cleaned_prefs = '\n'.join(lines[:s] + lines[e + 1:])
- with file(path, 'w') as f:
+ with open(path, 'w') as f:
f.write(cleaned_prefs)
return True
# methods for introspection
def summary(self, return_parts=False):
"""
returns string summarizing profile information.
--- a/testing/mozbase/mozprofile/setup.py
+++ b/testing/mozbase/mozprofile/setup.py
@@ -1,38 +1,35 @@
# 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 absolute_import
-import sys
from setuptools import setup
PACKAGE_NAME = 'mozprofile'
PACKAGE_VERSION = '0.29'
-# we only support python 2 right now
-assert sys.version_info[0] == 2
-
deps = ['mozfile >= 1.0',
'mozlog >= 3.0',
'six >= 1.10.0'
]
setup(name=PACKAGE_NAME,
version=PACKAGE_VERSION,
description="Library to create and modify Mozilla application profiles",
long_description="see https://firefox-source-docs.mozilla.org/mozbase/index.html",
classifiers=['Environment :: Console',
'Intended Audience :: Developers',
'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',
'Natural Language :: English',
'Operating System :: OS Independent',
- 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
'Topic :: Software Development :: Libraries :: Python Modules',
],
keywords='mozilla',
author='Mozilla Automation and Tools team',
author_email='tools@lists.mozilla.org',
url='https://wiki.mozilla.org/Auto-tools/Projects/Mozbase',
license='MPL 2.0',
packages=['mozprofile'],
--- a/testing/mozbase/mozprofile/tests/server_locations.py
+++ b/testing/mozbase/mozprofile/tests/server_locations.py
@@ -60,31 +60,31 @@ http://example.org:80 privileg
f = self.create_temp_file(self.locations)
# read the locations
locations = ServerLocations(f.name)
# ensure that they're what we expect
self.assertEqual(len(locations), 6)
i = iter(locations)
- self.compare_location(i.next(), 'http', 'mochi.test', '8888',
+ self.compare_location(next(i), 'http', 'mochi.test', '8888',
['primary', 'privileged'])
- self.compare_location(i.next(), 'http', '127.0.0.1', '80',
+ self.compare_location(next(i), 'http', '127.0.0.1', '80',
['privileged'])
- self.compare_location(i.next(), 'http', '127.0.0.1', '8888',
+ self.compare_location(next(i), 'http', '127.0.0.1', '8888',
['privileged'])
- self.compare_location(i.next(), 'https', 'test', '80', ['privileged'])
- self.compare_location(i.next(), 'http', 'example.org', '80',
+ self.compare_location(next(i), 'https', 'test', '80', ['privileged'])
+ self.compare_location(next(i), 'http', 'example.org', '80',
['privileged'])
- self.compare_location(i.next(), 'http', 'test1.example.org', '8888',
+ self.compare_location(next(i), 'http', 'test1.example.org', '8888',
['privileged'])
locations.add_host('mozilla.org')
self.assertEqual(len(locations), 7)
- self.compare_location(i.next(), 'http', 'mozilla.org', '80',
+ self.compare_location(next(i), 'http', 'mozilla.org', '80',
['privileged'])
# test some errors
self.assertRaises(MultiplePrimaryLocationsError, locations.add_host,
'primary.test', options='primary')
# We no longer throw these DuplicateLocation Error
try:
--- a/testing/mozbase/mozprofile/tests/test_addons.py
+++ b/testing/mozbase/mozprofile/tests/test_addons.py
@@ -5,28 +5,28 @@
# You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import
import os
import shutil
import tempfile
import unittest
-import urllib2
import zipfile
import mozunit
from manifestparser import ManifestParser
import mozfile
import mozhttpd
import mozlog.unstructured as mozlog
import mozprofile
from addon_stubs import generate_addon, generate_manifest
+from six.moves.urllib import error
here = os.path.dirname(os.path.abspath(__file__))
class TestAddonsManager(unittest.TestCase):
""" Class to test mozprofile.addons.AddonManager """
@@ -99,17 +99,17 @@ class TestAddonsManager(unittest.TestCas
# Download an invalid add-on to a special folder
addon = server.get_url() + 'invalid.xpi'
self.assertRaises(mozprofile.addons.AddonFormatError,
self.am.download, addon, self.tmpdir)
self.assertEqual(os.listdir(self.tmpdir), [])
# Download from an invalid URL
addon = server.get_url() + 'not_existent.xpi'
- self.assertRaises(urllib2.HTTPError,
+ self.assertRaises(error.HTTPError,
self.am.download, addon, self.tmpdir)
self.assertEqual(os.listdir(self.tmpdir), [])
# Download from an invalid URL
addon = 'not_existent.xpi'
self.assertRaises(ValueError,
self.am.download, addon, self.tmpdir)
self.assertEqual(os.listdir(self.tmpdir), [])
@@ -161,17 +161,17 @@ class TestAddonsManager(unittest.TestCas
# Generate installer stubs and install them
for ext in ['test-addon-1@mozilla.org', 'test-addon-2@mozilla.org']:
temp_addon = generate_addon(ext, path=self.tmpdir)
addons_to_install.append(self.am.addon_details(temp_addon)['id'])
self.am.install_from_path(temp_addon)
# Generate a list of addons installed in the profile
- addons_installed = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+ addons_installed = [str(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
self.profile.profile, 'extensions', 'staged'))]
self.assertEqual(addons_to_install.sort(), addons_installed.sort())
def test_install_from_path_folder(self):
# Generate installer stubs for all possible types of addons
addons = []
addons.append(generate_addon('test-addon-1@mozilla.org',
path=self.tmpdir))
@@ -326,17 +326,17 @@ class TestAddonsManager(unittest.TestCas
m.read(temp_manifest)
addons = m.get()
# Obtain details of addons to install from the manifest
addons_to_install = [self.am.addon_details(x['path']).get('id') for x in addons]
self.am.install_from_manifest(temp_manifest)
# Generate a list of addons installed in the profile
- addons_installed = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+ addons_installed = [str(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
self.profile.profile, 'extensions', 'staged'))]
self.assertEqual(addons_installed.sort(), addons_to_install.sort())
# Cleanup the temporary addon and manifest directories
mozfile.rmtree(os.path.dirname(temp_manifest))
def test_addon_details(self):
# Generate installer stubs for a valid and invalid add-on manifest
@@ -366,27 +366,27 @@ class TestAddonsManager(unittest.TestCas
self.am.addon_details, addon_path)
@unittest.skip("Bug 900154")
def test_clean_addons(self):
addon_one = generate_addon('test-addon-1@mozilla.org')
addon_two = generate_addon('test-addon-2@mozilla.org')
self.am.install_addons(addon_one)
- installed_addons = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+ installed_addons = [str(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
self.profile.profile, 'extensions', 'staged'))]
# Create a new profile based on an existing profile
# Install an extra addon in the new profile
# Cleanup addons
duplicate_profile = mozprofile.profile.Profile(profile=self.profile.profile,
addons=addon_two)
duplicate_profile.addon_manager.clean()
- addons_after_cleanup = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
+ addons_after_cleanup = [str(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
duplicate_profile.profile, 'extensions', 'staged'))]
# New addons installed should be removed by clean_addons()
self.assertEqual(installed_addons, addons_after_cleanup)
def test_noclean(self):
"""test `restore=True/False` functionality"""
server = mozhttpd.MozHttpd(docroot=os.path.join(here, 'addons'))
--- a/testing/mozbase/mozprofile/tests/test_preferences.py
+++ b/testing/mozbase/mozprofile/tests/test_preferences.py
@@ -138,48 +138,48 @@ general.warnOnAboutConfig = False
def test_reset_should_remove_added_prefs(self):
"""Check that when we call reset the items we expect are updated"""
profile = Profile()
prefs_file = os.path.join(profile.profile, 'user.js')
# we shouldn't have any initial preferences
initial_prefs = Preferences.read_prefs(prefs_file)
self.assertFalse(initial_prefs)
- initial_prefs = file(prefs_file).read().strip()
+ initial_prefs = open(prefs_file).read().strip()
self.assertFalse(initial_prefs)
# add some preferences
prefs1 = [("mr.t.quotes", "i aint getting on no plane!")]
profile.set_preferences(prefs1)
self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
- lines = file(prefs_file).read().strip().splitlines()
+ lines = open(prefs_file).read().strip().splitlines()
self.assertTrue(any(line.startswith('#MozRunner Prefs Start') for line in lines))
self.assertTrue(any(line.startswith('#MozRunner Prefs End') for line in lines))
profile.reset()
self.assertNotEqual(prefs1,
Preferences.read_prefs(os.path.join(profile.profile, 'user.js')),
"I pity the fool who left my pref")
def test_reset_should_keep_user_added_prefs(self):
"""Check that when we call reset the items we expect are updated"""
profile = Profile()
prefs_file = os.path.join(profile.profile, 'user.js')
# we shouldn't have any initial preferences
initial_prefs = Preferences.read_prefs(prefs_file)
self.assertFalse(initial_prefs)
- initial_prefs = file(prefs_file).read().strip()
+ initial_prefs = open(prefs_file).read().strip()
self.assertFalse(initial_prefs)
# add some preferences
prefs1 = [("mr.t.quotes", "i aint getting on no plane!")]
profile.set_persistent_preferences(prefs1)
self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
- lines = file(prefs_file).read().strip().splitlines()
+ lines = open(prefs_file).read().strip().splitlines()
self.assertTrue(any(line.startswith('#MozRunner Prefs Start') for line in lines))
self.assertTrue(any(line.startswith('#MozRunner Prefs End') for line in lines))
profile.reset()
self.assertEqual(prefs1,
Preferences.read_prefs(os.path.join(profile.profile, 'user.js')),
"I pity the fool who left my pref")
@@ -187,63 +187,63 @@ general.warnOnAboutConfig = False
"""ensure our magic markers are working"""
profile = Profile()
prefs_file = os.path.join(profile.profile, 'user.js')
# we shouldn't have any initial preferences
initial_prefs = Preferences.read_prefs(prefs_file)
self.assertFalse(initial_prefs)
- initial_prefs = file(prefs_file).read().strip()
+ initial_prefs = open(prefs_file).read().strip()
self.assertFalse(initial_prefs)
# add some preferences
prefs1 = [("browser.startup.homepage", "http://planet.mozilla.org/"),
("zoom.minPercent", 30)]
profile.set_preferences(prefs1)
self.assertEqual(prefs1, Preferences.read_prefs(prefs_file))
- lines = file(prefs_file).read().strip().splitlines()
+ lines = open(prefs_file).read().strip().splitlines()
self.assertTrue(bool([line for line in lines
if line.startswith('#MozRunner Prefs Start')]))
self.assertTrue(bool([line for line in lines
if line.startswith('#MozRunner Prefs End')]))
# add some more preferences
prefs2 = [("zoom.maxPercent", 300),
("webgl.verbose", 'false')]
profile.set_preferences(prefs2)
self.assertEqual(prefs1 + prefs2, Preferences.read_prefs(prefs_file))
- lines = file(prefs_file).read().strip().splitlines()
+ lines = open(prefs_file).read().strip().splitlines()
self.assertTrue(len([line for line in lines
if line.startswith('#MozRunner Prefs Start')]) == 2)
self.assertTrue(len([line for line in lines
if line.startswith('#MozRunner Prefs End')]) == 2)
# now clean it up
profile.clean_preferences()
final_prefs = Preferences.read_prefs(prefs_file)
self.assertFalse(final_prefs)
- lines = file(prefs_file).read().strip().splitlines()
+ lines = open(prefs_file).read().strip().splitlines()
self.assertTrue('#MozRunner Prefs Start' not in lines)
self.assertTrue('#MozRunner Prefs End' not in lines)
def test_preexisting_preferences(self):
"""ensure you don't clobber preexisting preferences"""
# make a pretend profile
tempdir = tempfile.mkdtemp()
try:
# make a user.js
contents = """
user_pref("webgl.enabled_for_all_sites", true);
user_pref("webgl.force-enabled", true);
"""
user_js = os.path.join(tempdir, 'user.js')
- f = file(user_js, 'w')
+ f = open(user_js, 'w')
f.write(contents)
f.close()
# make sure you can read it
prefs = Preferences.read_prefs(user_js)
original_prefs = [('webgl.enabled_for_all_sites', True), ('webgl.force-enabled', True)]
self.assertTrue(prefs == original_prefs)