From 007f500c4e192df2f79d721203637b50e2c7911a Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Tue, 5 Dec 2023 01:30:06 +0000 Subject: [PATCH 01/15] 35913574 pkg code base shouldn't use deprecated functionality --- src/depot.py | 5 +---- src/modules/client/history.py | 12 ------------ src/modules/config.py | 29 ++++++----------------------- src/modules/lint/base.py | 25 +++++-------------------- src/modules/lint/config.py | 13 +++---------- src/modules/misc.py | 29 +++++++++++++++-------------- src/modules/portable/util.py | 6 +----- src/tests/api/t_async_rpc.py | 16 ++++++++-------- src/tests/api/t_elf.py | 6 +++--- src/tests/api/t_plat.py | 4 ++-- src/tests/pkg5unittest.py | 35 ++++++----------------------------- 11 files changed, 50 insertions(+), 130 deletions(-) diff --git a/src/depot.py b/src/depot.py index 836c6406e..8078b9fa2 100755 --- a/src/depot.py +++ b/src/depot.py @@ -119,10 +119,7 @@ # to let the dispatcher to find the correct page handler, we need to skip # converting the hyphen symbol. punc = string.punctuation.replace("-", "_") -if six.PY2: - translate = string.maketrans(punc, "_" * len(string.punctuation)) -else: - translate = str.maketrans(punc, "_" * len(string.punctuation)) +translate = str.maketrans(punc, "_" * len(string.punctuation)) class Pkg5Dispatcher(Dispatcher): diff --git a/src/modules/client/history.py b/src/modules/client/history.py index be5cd95bd..198f0f1c3 100644 --- a/src/modules/client/history.py +++ b/src/modules/client/history.py @@ -383,18 +383,6 @@ def __setattr__(self, name, value): # of just referencing self to avoid any of the special logic in # place interfering with logic here. if name == "operation_name": - # Before a new operation starts, clear exception state - # for the current one so that when this one ends, the - # last operation's exception won't be recorded to this - # one. If the error hasn't been recorded by now, it - # doesn't matter anyway, so should be safe to clear. - # sys.exc_clear() isn't supported in Python 3, and - # couldn't find a replacement. - try: - sys.exc_clear() - except: - pass - # Mark the operation as having started and record # other, relevant information. op.start_time = misc.time_to_timestamp(None) diff --git a/src/modules/config.py b/src/modules/config.py index 109c20dc5..d7d3cf3a4 100644 --- a/src/modules/config.py +++ b/src/modules/config.py @@ -722,10 +722,7 @@ def _parse_str(self, value): value = value.split(",") for v in value: try: - if six.PY2: - v = v.encode("ascii") - else: - v = misc.force_str(v) + v = misc.force_str(v) except ValueError: if not isinstance(v, six.text_type): try: @@ -1518,16 +1515,11 @@ def __read(self, overrides=misc.EmptyDict): raise else: try: - # readfp() will be removed in futher Python - # versions, use read_file() instead. - if six.PY2: - cp.readfp(efile) - else: - cp.read_file(efile) + cp.read_file(efile) except ( configparser.ParsingError, configparser.MissingSectionHeaderError, - ) as e: + ): raise api_errors.InvalidConfigFile(self._target) # Attempt to determine version from contents. try: @@ -1644,14 +1636,8 @@ def write(self): else: os.fchmod(fd, misc.PKG_FILE_MODE) - if six.PY2: - with os.fdopen(fd, "wb") as f: - with codecs.EncodedFile(f, "utf-8") as ef: - cp.write(ef) - else: - # it becomes easier to open the file - with open(fd, "w", encoding="utf-8") as f: - cp.write(f) + with open(fd, "w", encoding="utf-8") as f: + cp.write(f) portable.rename(fn, self._target) self._dirty = False except EnvironmentError as e: @@ -1885,10 +1871,7 @@ def __read(self, overrides=misc.EmptyDict): nvalue = [] for v in shlex.split(value): try: - if six.PY2: - v = v.encode("ascii") - else: - v = misc.force_str(v, "ascii") + v = misc.force_str(v, "ascii") except ValueError: try: v = v.decode("utf-8") diff --git a/src/modules/lint/base.py b/src/modules/lint/base.py index 67398e4ab..6e75da248 100644 --- a/src/modules/lint/base.py +++ b/src/modules/lint/base.py @@ -88,10 +88,7 @@ def get_pkglint_id(method): # the short name for this checker class, Checker.name name = method.__self__.__class__.name - if six.PY2: - arg_spec = inspect.getargspec(method) - else: - arg_spec = inspect.getfullargspec(method) + arg_spec = inspect.getfullargspec(method) # arg_spec.args is a tuple of the method args, # populating the tuple with both arg values for @@ -115,10 +112,7 @@ def get_pkglint_id(method): method = item[1] # register the methods in the object that correspond # to lint checks - if six.PY2: - m = inspect.getargspec(method) - else: - m = inspect.getfullargspec(method) + m = inspect.getfullargspec(method) if "pkglint_id" in m[0]: value = "{0}.{1}.{2}".format( self.__module__, self.__class__.__name__, method.__name__ @@ -323,18 +317,9 @@ def __init__(self, config): if os.path.exists(self.classification_path): try: - if six.PY2: - self.classification_data = configparser.SafeConfigParser() - self.classification_data.readfp( - open(self.classification_path) - ) - else: - # SafeConfigParser has been renamed to - # ConfigParser in Python 3.2. - self.classification_data = configparser.ConfigParser() - self.classification_data.read_file( - open(self.classification_path) - ) + self.classification_data = configparser.ConfigParser() + with open(self.classification_path) as ifile: + self.classification_data.read_file(ifile) except Exception as err: # any exception thrown here results in a null # classification_data object. We deal with that diff --git a/src/modules/lint/config.py b/src/modules/lint/config.py index 0f27b02e7..5f664f904 100644 --- a/src/modules/lint/config.py +++ b/src/modules/lint/config.py @@ -71,17 +71,10 @@ def __init__(self, config_file=None): _("unable to read config file: {0} ").format(err) ) try: - if six.PY2: - self.config = configparser.SafeConfigParser(defaults) - else: - # SafeConfigParser has been renamed to - # ConfigParser in Python 3.2. - self.config = configparser.ConfigParser(defaults) + self.config = configparser.ConfigParser(defaults) if not config_file: - if six.PY2: - self.config.readfp(open("/usr/share/lib/pkg/pkglintrc")) - else: - self.config.read_file(open("/usr/share/lib/pkg/pkglintrc")) + with open("/usr/share/lib/pkg/pkglintrc") as ifile: + self.config.read_file(ifile) self.config.read([os.path.expanduser("~/.pkglintrc")]) else: self.config.read(config_file) diff --git a/src/modules/misc.py b/src/modules/misc.py index b1db09f78..49559737f 100644 --- a/src/modules/misc.py +++ b/src/modules/misc.py @@ -549,20 +549,21 @@ def setlocale(category, loc=None, printer=None): try: locale.setlocale(category, loc) - # Because of Python bug 813449, getdefaultlocale may fail - # with a ValueError even if setlocale succeeds. So we call - # it here to prevent having this error raised if it is - # called later by other non-pkg(7) code. - locale.getdefaultlocale() - except (locale.Error, ValueError): - try: - dl = " '{0}.{1}'".format(*locale.getdefaultlocale()) - except ValueError: - dl = "" - printer( - "Unable to set locale{0}; locale package may be broken " - "or\nnot installed. Reverting to C locale.".format(dl) - ) + except locale.Error: + if loc: + dl = locale.normalize(loc) + else: + # Since no locale was given, try to determine what global + # locale setting setlocale used. + for variable in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'): + localename = os.environ.get(variable, None) + if localename: + dl = locale.normalize(localename) + break + else: + dl = "" + printer(f"Unable to set locale {dl}; locale package may be broken or\n" + "not installed. Reverting to C locale.") locale.setlocale(category, "C") diff --git a/src/modules/portable/util.py b/src/modules/portable/util.py index 3505def6e..98124f6b6 100644 --- a/src/modules/portable/util.py +++ b/src/modules/portable/util.py @@ -49,13 +49,9 @@ def get_canonical_os_name(): """ psl = platform.system().lower() - if psl in ["sunos", "darwin", "windows", "aix"]: + if psl in ["sunos", "darwin", "windows", "aix", "linux"]: return psl - if psl == "linux": - # add distro information for Linux - return "linux_{0}".format(platform.dist()[0]) - # Workaround for python bug 1082, on Vista, platform.system() # returns 'Microsoft' prl = platform.release().lower() diff --git a/src/tests/api/t_async_rpc.py b/src/tests/api/t_async_rpc.py index 4d5abda75..03de065c8 100644 --- a/src/tests/api/t_async_rpc.py +++ b/src/tests/api/t_async_rpc.py @@ -86,21 +86,21 @@ def test_async_basics(self): ac = AsyncCall() ac.start(self.__add, 1, 2, 3) if six.PY2: - self.assertRaisesRegexp( + self.assertRaisesRegex( AsyncCallException, "takes exactly 2 arguments", ac.result ) else: - self.assertRaisesRegexp( + self.assertRaisesRegex( AsyncCallException, "takes 2 positional arguments", ac.result ) ac = AsyncCall() ac.start(self.__add, x=1, y=2, z=3) - self.assertRaisesRegexp( + self.assertRaisesRegex( AsyncCallException, "got an unexpected keyword argument", ac.result ) ac = AsyncCall() ac.start(self.__add, y=2, z=3) - self.assertRaisesRegexp( + self.assertRaisesRegex( AsyncCallException, "got an unexpected keyword argument", ac.result ) @@ -109,7 +109,7 @@ def test_async_thread_errors(self): DebugValues["async_thread_error"] = 1 ac = AsyncCall() ac.start(self.__nop) - self.assertRaisesRegexp( + self.assertRaisesRegex( AsyncCallException, "async_thread_error", ac.result ) @@ -200,7 +200,7 @@ def __test_rpc_basics(self, http_enc=True, use_proc=True): self.assertEqual(rv, 3) # test rpc call with an invalid number of arguments - self.assertRaisesRegexp( + self.assertRaisesRegex( AsyncCallException, "Invalid parameters.", self.__server_setup_and_call, @@ -213,7 +213,7 @@ def __test_rpc_basics(self, http_enc=True, use_proc=True): ) # test rpc call of a non-existant method - self.assertRaisesRegexp( + self.assertRaisesRegex( AsyncCallException, "Method foo not supported.", self.__server_setup_and_call, @@ -223,7 +223,7 @@ def __test_rpc_basics(self, http_enc=True, use_proc=True): ) # test rpc call of a server function that raises an exception - self.assertRaisesRegexp( + self.assertRaisesRegex( AsyncCallException, "Server error: .* Exception: raise_ex()", self.__server_setup_and_call, diff --git a/src/tests/api/t_elf.py b/src/tests/api/t_elf.py index 1706c2b45..dd553cc1a 100644 --- a/src/tests/api/t_elf.py +++ b/src/tests/api/t_elf.py @@ -60,16 +60,16 @@ def test_non_elf(self): self.make_misc_files({file: "this is only a test"}) os.chdir(self.test_root) self.assertEqual(elf.is_elf_object(file), False) - self.assertRaisesRegexp( + self.assertRaisesRegex( elf.ElfError, "Request error: class file/memory mismatch", elf.get_dynamic, file, ) - self.assertRaisesRegexp( + self.assertRaisesRegex( elf.ElfError, "invalid file type", elf.get_hashes, file ) - self.assertRaisesRegexp( + self.assertRaisesRegex( elf.ElfError, "Request error: class file/memory mismatch", elf.get_info, diff --git a/src/tests/api/t_plat.py b/src/tests/api/t_plat.py index 5c7a52657..91c3cfbd4 100644 --- a/src/tests/api/t_plat.py +++ b/src/tests/api/t_plat.py @@ -82,7 +82,7 @@ def testRenameOfRunningExecutable(self): return import pkg.portable.os_windows as os_windows - cwd = os.getcwdu() + cwd = os.getcwd() exefilesrc = "C:\\Windows\\system32\\more.com" self.assertTrue(os.path.exists(exefilesrc)) @@ -135,7 +135,7 @@ def testRemoveOfRunningExecutable(self): return import pkg.portable.os_windows as os_windows - cwd = os.getcwdu() + cwd = os.getcwd() exefilesrc = "C:\\Windows\\system32\\more.com" self.assertTrue(os.path.exists(exefilesrc)) diff --git a/src/tests/pkg5unittest.py b/src/tests/pkg5unittest.py index dbb9e2677..f02041faf 100644 --- a/src/tests/pkg5unittest.py +++ b/src/tests/pkg5unittest.py @@ -327,7 +327,7 @@ def assertRegexp(self, text, regexp): '"{0}" does not match "{1}"'.format(regexp, text) ) - def assertRaisesRegexp( + def assertRaisesRegex( self, excClass, regexp, callableObj, *args, **kwargs ): """Perform the same logic as assertRaises, but then verify @@ -926,17 +926,11 @@ def make_file(self, path, content, mode=0o644, copy=False): if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path), 0o777) self.debugfilecreate(content, path) - if six.PY2: - if isinstance(content, six.text_type): - content = content.encode("utf-8") - with open(path, "wb") as fh: - fh.write(content) + if copy: + shutil.copy(content, path) else: - if copy: - shutil.copy(content, path) - else: - with open(path, "w", encoding="utf-8") as fh: - fh.write(content) + with open(path, "w", encoding="utf-8") as fh: + fh.write(content) os.chmod(path, mode) def make_misc_files(self, files, prefix=None, mode=0o644, copy=False): @@ -1193,10 +1187,7 @@ def configure_rcfile( ) as new_rcfile: conf = configparser.RawConfigParser() with open(rcfile) as f: - if six.PY2: - conf.readfp(f) - else: - conf.read_file(f) + conf.read_file(f) for key in config: conf.set(section, key, config[key]) @@ -2340,20 +2331,6 @@ def run(self, result): # No tests; that's ok. return - # This is needed because the import of some modules (such as - # pygtk or pango) causes the default encoding for Python to be - # changed which can can cause tests to succeed when they should - # fail due to unicode issues: - # https://bugzilla.gnome.org/show_bug.cgi?id=132040 - if six.PY2: - default_utf8 = getattr(self._tests[0], "default_utf8", False) - if not default_utf8: - # Now reset to the default a standard Python - # distribution uses. - sys.setdefaultencoding("ascii") - else: - sys.setdefaultencoding("utf-8") - def setUp_donothing(): pass From 7aca226d24b58d762966f795d25bc107c5ed0924 Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Fri, 3 Nov 2023 02:44:09 -0700 Subject: [PATCH 02/15] 33045609 Crash in PyUnicode_AsUTF8AndSize 35922003 _varcet extension has insufficient error handling --- src/modules/_varcet.c | 102 ++++++++++++++++++++++++---------- src/tests/cli/t_pkg_varcet.py | 71 +++++++++++++++++++++++ 2 files changed, 144 insertions(+), 29 deletions(-) diff --git a/src/modules/_varcet.c b/src/modules/_varcet.c index d62f117b3..bc5d36717 100644 --- a/src/modules/_varcet.c +++ b/src/modules/_varcet.c @@ -20,12 +20,12 @@ */ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. - * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. + * Copyright (c) 2012, 2023, Oracle and/or its affiliates. */ #include + /*ARGSUSED*/ static PyObject * __attribute__((hot)) @@ -77,12 +77,19 @@ _allow_facet(PyObject *self, PyObject *args, PyObject *kwargs) while (PyDict_Next(act_attrs, &fpos, &attr, &value)) { const char *as = PyUnicode_AsUTF8(attr); + if (as == NULL) { + CLEANUP_FREFS; + return (NULL); + } if (strncmp(as, "facet.", 6) != 0) continue; - PyObject *facet = PyDict_GetItem(facets, attr); + PyObject *facet = PyDict_GetItemWithError(facets, attr); if (facet != NULL) { facet_ret = facet; + } else if (PyErr_Occurred()) { + CLEANUP_FREFS; + return (NULL); } else { Py_ssize_t idx = 0; @@ -92,12 +99,27 @@ _allow_facet(PyObject *self, PyObject *args, PyObject *kwargs) */ for (idx = 0; idx < klen; idx++) { PyObject *key = PyList_GET_ITEM(keylist, idx); - PyObject *re = PyDict_GetItem(res, key); + PyObject *re = PyDict_GetItemWithError( + res, key); + if (re == NULL && PyErr_Occurred()) { + CLEANUP_FREFS; + return (NULL); + } PyObject *match = PyObject_CallMethod(re, "match", "O", attr); + if (match == NULL) { + CLEANUP_FREFS; + return (NULL); + } + if (match != Py_None) { - PyObject *fval = PyDict_GetItem( + PyObject *fval = + PyDict_GetItemWithError( facets, key); + if (fval == NULL && PyErr_Occurred()) { + CLEANUP_FREFS; + return (NULL); + } Py_DECREF(match); @@ -132,16 +154,25 @@ _allow_facet(PyObject *self, PyObject *args, PyObject *kwargs) prep_ret: if (facet_ret != NULL) { - const char *vs = PyUnicode_AsUTF8(value); - if (vs == NULL) { - /* - * value is not a string; probably a list, so - * don't allow the action since older clients - * would fail anyway. - */ - PyErr_Clear(); - all_ret = Py_False; - break; + const char *vs = NULL; + PyObject *strvalue = PyObject_Str(value); + if (strvalue != NULL) { + vs = PyUnicode_AsUTF8(strvalue); + } + if (strvalue == NULL || vs == NULL) { + if (PyErr_ExceptionMatches(PyExc_Exception)) { + /* + * value is not a string; probably a + * list, so don't allow the action since + * older clients would fail anyway. + */ + PyErr_Clear(); + all_ret = Py_False; + break; + } else { + CLEANUP_FREFS; + return (NULL); + } } if (strcmp(vs, "all") == 0) { @@ -209,24 +240,34 @@ _allow_variant(PyObject *self, PyObject *args, PyObject *kwargs) while (PyDict_Next(act_attrs, &pos, &attr, &value)) { const char *as = PyUnicode_AsUTF8(attr); + if (as == NULL) { + Py_DECREF(act_attrs); + return (NULL); + } if (strncmp(as, "variant.", 8) == 0) { const char *av = PyUnicode_AsUTF8(value); - const char *sysav = NULL; - PyObject *sysv = NULL; - if (av == NULL) { - /* - * value is not a string; probably a list, so - * don't allow the action since older clients - * would fail anyway. - */ - PyErr_Clear(); - Py_DECREF(act_attrs); - Py_RETURN_FALSE; + if (PyErr_ExceptionMatches(PyExc_Exception)) { + /* + * value is not a string; probably a + * list, so don't allow the action since + * older clients would fail anyway. + */ + PyErr_Clear(); + Py_DECREF(act_attrs); + Py_RETURN_FALSE; + } else { + Py_DECREF(act_attrs); + return (NULL); + } } - sysv = PyDict_GetItem(vars, attr); + PyObject *sysv = PyDict_GetItemWithError(vars, attr); if (sysv == NULL) { + if (PyErr_Occurred()) { + Py_DECREF(act_attrs); + return (NULL); + } /* * If system variant value doesn't exist, then * allow the action if it is a variant that is @@ -240,7 +281,11 @@ _allow_variant(PyObject *self, PyObject *args, PyObject *kwargs) continue; } - sysav = PyUnicode_AsUTF8(sysv); + const char *sysav = PyUnicode_AsUTF8(sysv); + if (sysav == NULL) { + Py_DECREF(act_attrs); + return (NULL); + } if (strcmp(av, sysav) != 0) { /* * If system variant value doesn't match action @@ -277,4 +322,3 @@ PyInit__varcet(void) { return (PyModule_Create(&varcetmodule)); } - diff --git a/src/tests/cli/t_pkg_varcet.py b/src/tests/cli/t_pkg_varcet.py index 168ed839b..77c2a5498 100644 --- a/src/tests/cli/t_pkg_varcet.py +++ b/src/tests/cli/t_pkg_varcet.py @@ -39,6 +39,9 @@ import tempfile import unittest +import pkg.facet as facet +import pkg.variant as variant + from pkg.client.pkgdefs import EXIT_OOPS @@ -885,6 +888,74 @@ def test_03_variant_globbing(self): ) + +class TestPkgVarcetErrors(pkg5unittest.Pkg5TestCase): + """This test class verifies that errors raised while within the _varcet + extension are handled gracefully and won't cause segmentation faults.""" + + def test_01_facet_error_checking(self): + """Verify that _allow_facet extension function has + sufficient error checking.""" + + class Inner: + def __init__(self, problem): + self.problem = problem + + def __str__(self): + if self.problem == 0: + return "fine" + elif self.problem == 1: # Exception + raise ValueError + elif self.problem == 2: # BaseException + raise KeyboardInterrupt + + class Action: + def __init__(self, problem, inproblem): + if problem == 0: + self.attrs = {"facet.debug.test": Inner(inproblem)} + elif problem == 1: + # Not an Unicode object + self.attrs = {b"facet.debug.test": Inner(inproblem)} + + facets = facet.Facets({"facet.debug.test": True}) + facets.allow_action(Action(0, 0), None) + + # attr encoding failure handling + self.assertRaises(TypeError, facets.allow_action, Action(1, 0), None) + + # value encoding failure handling + self.assertEquals(facets.allow_action(Action(0, 1), None), False) + self.assertRaises( + KeyboardInterrupt, facets.allow_action, Action(0, 2), None + ) + + def test_02_variant_error_checking(self): + """Verify that _allow_variant extension function has + sufficient error checking.""" + + class Action: + def __init__(self, problem): + if problem == 0: + self.attrs = {"variant.icecream": "strawberry"} + elif problem == 1: + # Non Unicode key + self.attrs = {b"variant.icecream": "strawberry"} + elif problem == 2: + # Non Unicode value + self.attrs = {"variant.icecream": b"strawberry"} + + variants = variant.Variants({"variant.icecream": "strawberry"}) + variants.allow_action(Action(0), None) + + # attr and value encoding failure handling + self.assertRaises(TypeError, variants.allow_action, Action(1), None) + self.assertEquals(variants.allow_action(Action(2), None), False) + + # variant value encoding failure handling + variants = variant.Variants({"variant.icecream": b"strawberry"}) + self.assertRaises(TypeError, variants.allow_action, Action(0), None) + + if __name__ == "__main__": unittest.main() From 210e063f91edc1c0ade9945fe004b44496c6e402 Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Tue, 5 Dec 2023 01:39:07 +0000 Subject: [PATCH 03/15] 32618088 Incorrect comment in pkglint_action.py in arch64() check 35873604 pkg avoid output order is non-deterministic 34734648 Removed packages message uses two lines to not tell me about one package it removed 34234883 Pkg search Framework error: TypeError: '<' not supported between instances of 'tuple' and 'NoneType' 35808782 pkg does not properly convert all b'ascii' on output --- src/client.py | 13 +++++++------ src/modules/actions/driver.py | 6 ++++-- src/modules/client/publisher.py | 8 ++++---- src/modules/lint/pkglint_action.py | 19 +++++++------------ 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/client.py b/src/client.py index e5d7b82f8..051fa35bc 100755 --- a/src/client.py +++ b/src/client.py @@ -1085,9 +1085,11 @@ def cond_show(s1, s2, v): if not verbose and r and op in [PKG_OP_INSTALL, PKG_OP_UPDATE]: logger.info(_("\nRemoved Packages:\n")) removals = [src.pkg_stem for src, dest in r] - if len(r) <= 5: + if len(r) <= 7: logger.info(" " + "\n ".join(removals)) else: + # Display 7 lines at maximum, which is the first 5 removed + # packages and two additional lines below. logger.info(" " + "\n ".join(removals[:5])) logger.info(" ...") logger.info( @@ -4048,16 +4050,15 @@ def unavoid(api_inst, args): def __display_avoids(api_inst): """Display the current avoid list, and the pkgs that are tracking that pkg""" - for a in api_inst.get_avoid_list(): + for avoid, tracking in sorted(api_inst.get_avoid_list()): tracking = " ".join(a[1]) if tracking: logger.info( - _( - " {avoid_pkg} (group dependency of " "'{tracking_pkg}')" - ).format(avoid_pkg=a[0], tracking_pkg=tracking) + " {avoid_pkg} (group dependency of '{tracking_pkg}')") + .format(avoid_pkg=avoid, tracking_pkg=" ".join(tracking))) ) else: - logger.info(" {0}".format(a[0])) + logger.info(" {0}".format(avoid)) return EXIT_OK diff --git a/src/modules/actions/driver.py b/src/modules/actions/driver.py index 39502759e..624293402 100644 --- a/src/modules/actions/driver.py +++ b/src/modules/actions/driver.py @@ -120,7 +120,7 @@ def __usr_sbin_init(): @staticmethod def __call(args, fmt, fmtargs): proc = subprocess.Popen( - args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT + args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True ) buf = proc.stdout.read() ret = proc.wait() @@ -134,7 +134,9 @@ def __call(args, fmt, fmtargs): print(("command run was:"), " ".join(args)) print("command output was:") print("-" * 60) - print(buf, end=" ") + if not buf.endswith("\n"): + buf += "\n" + print(buf, end="") print("-" * 60) @staticmethod diff --git a/src/modules/client/publisher.py b/src/modules/client/publisher.py index 81476fbc4..7ad4ea961 100644 --- a/src/modules/client/publisher.py +++ b/src/modules/client/publisher.py @@ -682,14 +682,14 @@ def __eq__(self, other): if isinstance(other, TransportRepoURI): return self.uri == other.uri and self.proxy == other.proxy if isinstance(other, six.string_types): - return self.uri == other and self.proxy == None + return self.uri == other and self.proxy is None return False def __ne__(self, other): if isinstance(other, TransportRepoURI): return self.uri != other.uri or self.proxy != other.proxy if isinstance(other, six.string_types): - return self.uri != other or self.proxy != None + return self.uri != other or self.proxy is not None return True __hash__ = object.__hash__ @@ -1949,7 +1949,7 @@ def get_origin_sets(self): for origin, opath in self.__gen_origin_paths(): cat = pkg.catalog.Catalog(meta_root=opath, read_only=True) if not cat.exists: - key = None + key = ("0", "0") else: key = (str(cat.created), str(cat.last_modified)) osets[key].append(origin) @@ -2408,7 +2408,7 @@ def __refresh_v1( flist = [] if not full_refresh and v1_cat.exists: flist = v1_cat.get_updates_needed(tempdir) - if flist == None: + if flist is None: return False, True else: attrs = pkg.catalog.CatalogAttrs(meta_root=tempdir) diff --git a/src/modules/lint/pkglint_action.py b/src/modules/lint/pkglint_action.py index ba6daeef0..18897a350 100644 --- a/src/modules/lint/pkglint_action.py +++ b/src/modules/lint/pkglint_action.py @@ -408,7 +408,7 @@ def duplicate_refcount_path_attrs( continue action_types.add(a.name) - if not key in a.attrs: + if key not in a.attrs: continue for val in a.attrlist(key): @@ -1745,12 +1745,12 @@ def supported_pkg_actuator( start_pattern + "uninstall-on-uninstall", ] - if not "name" in action.attrs or not action.attrs["name"].startswith( + if "name" not in action.attrs or not action.attrs["name"].startswith( start_pattern ): return - if not action.attrs["name"] in supported_actuators: + if action.attrs["name"] not in supported_actuators: engine.warning( _( "invalid package actuator name {attr} in {fmri}\n" @@ -1799,17 +1799,12 @@ def arch64(self, action, manifest, engine, pkglint_id="014"): """ELF files should be delivered as 64-bit objects, other than libraries. - The pkglint paramater pkglint.action0014.report_type can change - whether this check issues errors or warnings. The value of - this parameter should be "error" or "warning". Any other value - defaults to "warning" + The boolean pkglint parameter pkglint.action014.report_errors can be + set to True to force this check to issue errors instead of warnings. + This is done via the pkglintrc config file: + pkglint.action014.report_errors = True """ - # Note that this check is intentionally delivered as disabled - # by default in the pkglintrc config file. The check exists - # so that we can move packages towards best-practises, - # but this may not be appropriate in all cases. - if action.name != "file": return if "elfbits" not in action.attrs: From 6cee015eefc61a81c20e4e0a75a86f7a4d606699 Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Tue, 5 Dec 2023 01:41:03 +0000 Subject: [PATCH 04/15] 34768613 TestPkgFWDependencies is not cleaning dumped global core files --- src/tests/cli/t_origin_fw.py | 39 ++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/tests/cli/t_origin_fw.py b/src/tests/cli/t_origin_fw.py index caec9bb68..ca233d400 100644 --- a/src/tests/cli/t_origin_fw.py +++ b/src/tests/cli/t_origin_fw.py @@ -27,10 +27,11 @@ if __name__ == "__main__": testutils.setup_environment("../../../proto") +import glob import os import pkg5unittest -import unittest - +import re +import subprocess import pkg.portable as portable @@ -119,6 +120,40 @@ def setUp(self): close""" ] + def tearDown(self): + """Try to clean core files dumped by fwenum dump_core=1""" + + res = subprocess.run(["coreadm"], capture_output=True) + if b"global core dumps: enabled" not in res.stdout: + # Global core dumps are not enabled, there won't be any core files. + return + + pattern = None + for line in res.stdout.splitlines(): + if b"global core file pattern:" in line: + pattern = line.strip().split(b" ")[-1] + pattern = re.sub(rb"%.", b"*", pattern) + break + + if pattern is None: + # Couldn't determine the file pattern for global cores. + return + + cores = glob.glob(pattern) + for core in cores: + res = subprocess.run( + [b"/bin/mdb", core], input=b"::status\n", capture_output=True + ) + # Make sure that only fwenum cores with dump_core=1 are deleted. + if ( + res.returncode == 0 + and b"/usr/bin/python" in res.stdout + and b"smf_cmds/fwenum" in res.stdout + and b"dump_core=1" in res.stdout + and b"SIGABRT" in res.stdout + ): + portable.remove(core) + def test_fw_dependency(self): """test origin firmware dependency""" """firmware test simulator uses alphabetic comparison""" From bff6cd6a8cbc0c23c541413dad44a746bd52563f Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Tue, 5 Dec 2023 01:42:29 +0000 Subject: [PATCH 05/15] 35972050 Improve performance of string formatting in transform_main_dict_line --- src/modules/search_storage.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/modules/search_storage.py b/src/modules/search_storage.py index 4b30561a9..76bc4810b 100644 --- a/src/modules/search_storage.py +++ b/src/modules/search_storage.py @@ -320,23 +320,25 @@ def transform_main_dict_line(token, entries): "quote". The details of the contents on entries are described in _write_main_dict_line in indexer.py. """ - sep_chars = IndexStoreMainDict.sep_chars - res = "{0}".format(quote(str(token))) - for ati, atl in enumerate(entries): - action_type, atl = atl - res += "{0}{1}".format(sep_chars[0], action_type) - for sti, stl in enumerate(atl): - subtype, stl = stl - res += "{0}{1}".format(sep_chars[1], subtype) - for fvi, fvl in enumerate(stl): - full_value, fvl = fvl - res += "{0}{1}".format(sep_chars[2], quote(str(full_value))) - for pfi, pfl in enumerate(fvl): - pfmri_index, pfl = pfl - res += "{0}{1}".format(sep_chars[3], pfmri_index) + res = quote(str(token)) + for action_type, atl in entries: + # For performance reasons, 'sep_chars' symbols + # are placed directly into the code. + # uses sep_chars[0] == ' ' + res += f" {action_type}" + for subtype, stl in atl: + # uses sep_chars[1] == '!' + res += f"!{subtype}" + for full_value, fvl in stl: + # uses sep_chars[2] == '@' + res += f"@{quote(str(full_value))}" + for pfmri_index, pfl in fvl: + # uses sep_chars[3] == '#' + res += f"#{pfmri_index}" for offset in pfl: - res += "{0}{1}".format(sep_chars[4], offset) - return res + "\n" + # uses sep_chars[4] == ',' + res += f",{offset}" + return f"{res}\n" def count_entries_removed_during_partial_indexing(self): """Returns the number of entries removed during a second phase From 4dab9361a32370a95c5e3f5eb02e2df26800b9e2 Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Tue, 5 Dec 2023 09:15:24 +0000 Subject: [PATCH 06/15] 36004855 start_expected_fail failures are not very debuggable --- src/modules/depotcontroller.py | 27 +++++++++++++++++++++------ src/tests/cli/t_pkg_depotd.py | 18 ++++++++++-------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/modules/depotcontroller.py b/src/modules/depotcontroller.py index 543410479..a25c97178 100755 --- a/src/modules/depotcontroller.py +++ b/src/modules/depotcontroller.py @@ -483,26 +483,41 @@ def start(self): raise def start_expected_fail(self, exit=2): + """Start the depot, and make sure that it responds in a reasonable time + and that it exits immediately with the expected exit code.""" + try: self.__initial_start() sleeptime = 0.05 - died = False rc = None while sleeptime <= 10.0: rc = self.__depot_handle.poll() if rc is not None: - died = True break time.sleep(sleeptime) sleeptime *= 2 - if died and rc == exit: - self.__state = self.HALTED - return True else: + # in case the break above wasn't executed self.stop() - return False + with open(self.__logpath, "rb", buffering=0) as errf: + err = errf.read() + raise DepotStateException( + "Depot did not respond to repeated attempts " + f"to make contact. Output follows:\n{err}\n" + ) + + if rc != exit: + self.stop() + with open(self.__logpath, "rb", buffering=0) as errf: + err = errf.read() + raise DepotStateException( + f"Depot exited with unexpected exit code {rc} " + f"(expected {exit}). Output follows:\n{err}\n" + ) + + self.__state = self.HALTED except KeyboardInterrupt: if self.__depot_handle: self.kill(now=True) diff --git a/src/tests/cli/t_pkg_depotd.py b/src/tests/cli/t_pkg_depotd.py index 15a21b916..3c1d2152a 100644 --- a/src/tests/cli/t_pkg_depotd.py +++ b/src/tests/cli/t_pkg_depotd.py @@ -382,13 +382,14 @@ def test_repo_create(self): # First, test readonly mode with a repo_dir that doesn't exist. self.dc.set_readonly() self.dc.stop() - self.dc.start_expected_fail() + # expect exit code 1 - "an error occurred" + self.dc.start_expected_fail(exit=1) self.assertTrue(not self.dc.is_alive()) # Next, test readonly mode with a repo_dir that is empty. os.makedirs(dpath, misc.PKG_DIR_MODE) self.dc.set_readonly() - self.dc.start_expected_fail() + self.dc.start_expected_fail(exit=1) self.assertTrue(not self.dc.is_alive()) # Next, test readwrite (publishing) mode with a non-existent @@ -668,37 +669,38 @@ def testBadArgs(self): self.__dc.set_rebuild() self.__dc.set_norefresh_index() - self.assertTrue(self.__dc.start_expected_fail()) + # # expect (default) exit code 2 - "invalid command line options" + self.__dc.start_expected_fail() self.__dc.set_readonly() self.__dc.set_norebuild() self.__dc.set_refresh_index() - self.assertTrue(self.__dc.start_expected_fail()) + self.__dc.start_expected_fail() self.__dc.set_readonly() self.__dc.set_rebuild() self.__dc.set_refresh_index() - self.assertTrue(self.__dc.start_expected_fail()) + self.__dc.start_expected_fail() self.__dc.set_readwrite() self.__dc.set_rebuild() self.__dc.set_refresh_index() - self.assertTrue(self.__dc.start_expected_fail()) + self.__dc.start_expected_fail() self.__dc.set_mirror() self.__dc.set_rebuild() self.__dc.set_norefresh_index() - self.assertTrue(self.__dc.start_expected_fail()) + self.__dc.start_expected_fail() self.__dc.set_mirror() self.__dc.set_norebuild() self.__dc.set_refresh_index() - self.assertTrue(self.__dc.start_expected_fail()) + self.__dc.start_expected_fail() def test_disable_ops(self): """Verify that disable-ops works as expected.""" From c150a512d24bea2dbef1580332fe4c32bb8a691e Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Wed, 29 Nov 2023 03:40:40 -0800 Subject: [PATCH 07/15] 36027870 urllib.parse quote function has poor performance --- src/modules/_misc.c | 169 ++++++++++++++++++++++++++++++ src/modules/search_storage.py | 5 +- src/pkg/manifests/package:pkg.p5m | 1 + src/setup.py | 18 ++++ src/tests/api/t_fast_quote.py | 73 +++++++++++++ 5 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 src/modules/_misc.c create mode 100644 src/tests/api/t_fast_quote.py diff --git a/src/modules/_misc.c b/src/modules/_misc.c new file mode 100644 index 000000000..0b5ab3fd7 --- /dev/null +++ b/src/modules/_misc.c @@ -0,0 +1,169 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2023, Oracle and/or its affiliates. + */ + +/* + * The following is a C reimplementation of urllib.parse.quote function. IPS + * uses quote so extensively that the standard pure Python implementation has + * significant performance drawbacks. + */ + +#include + +#define MAX_STACK_QUOTE_SIZE 1024 + +/*ARGSUSED*/ +static PyObject * +fast_quote(PyObject *self, PyObject *args) +{ + const static char quote_map[256][3] = { + "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", + "%08", "%09", "%0A", "%0B", "%0C", "%0D", "%0E", "%0F", + "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17", + "%18", "%19", "%1A", "%1B", "%1C", "%1D", "%1E", "%1F", + "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27", + "%28", "%29", "%2A", "%2B", "%2C", "-", ".", "/", + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", "%3A", "%3B", "%3C", "%3D", "%3E", "%3F", + "%40", "A", "B", "C", "D", "E", "F", "G", + "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "%5B", "%5C", "%5D", "%5E", "_", + "%60", "a", "b", "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "%7B", "%7C", "%7D", "~", "%7F", + "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87", + "%88", "%89", "%8A", "%8B", "%8C", "%8D", "%8E", "%8F", + "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97", + "%98", "%99", "%9A", "%9B", "%9C", "%9D", "%9E", "%9F", + "%A0", "%A1", "%A2", "%A3", "%A4", "%A5", "%A6", "%A7", + "%A8", "%A9", "%AA", "%AB", "%AC", "%AD", "%AE", "%AF", + "%B0", "%B1", "%B2", "%B3", "%B4", "%B5", "%B6", "%B7", + "%B8", "%B9", "%BA", "%BB", "%BC", "%BD", "%BE", "%BF", + "%C0", "%C1", "%C2", "%C3", "%C4", "%C5", "%C6", "%C7", + "%C8", "%C9", "%CA", "%CB", "%CC", "%CD", "%CE", "%CF", + "%D0", "%D1", "%D2", "%D3", "%D4", "%D5", "%D6", "%D7", + "%D8", "%D9", "%DA", "%DB", "%DC", "%DD", "%DE", "%DF", + "%E0", "%E1", "%E2", "%E3", "%E4", "%E5", "%E6", "%E7", + "%E8", "%E9", "%EA", "%EB", "%EC", "%ED", "%EE", "%EF", + "%F0", "%F1", "%F2", "%F3", "%F4", "%F5", "%F6", "%F7", + "%F8", "%F9", "%FA", "%FB", "%FC", "%FD", "%FE", "%FF"}; + + int i, j; + PyObject* string = NULL; + if (!PyArg_ParseTuple(args, "O", &string)) { + return (NULL); + } + + if (PyBytes_Check(string)) { + /* do nothing */ + } else if (PyUnicode_Check(string)) { + /* convert to bytes like encode() would. */ + string = PyUnicode_AsEncodedString(string, NULL, NULL); + } else { + PyErr_SetString(PyExc_TypeError, + "argument 1 must be bytes or str"); + return (NULL); + } + + Py_ssize_t size = PyBytes_GET_SIZE(string); + const char *bstring = PyBytes_AS_STRING(string); + + if (size <= MAX_STACK_QUOTE_SIZE) { + /* + * Short strings are handled directly on stack without + * the need to allocate additional memory. + */ + char buffer[MAX_STACK_QUOTE_SIZE * 3 + 1]; + + for (i = 0, j = 0; i < size; i++) { + const char *val = quote_map[(unsigned char)bstring[i]]; + buffer[j++] = val[0]; + if (val[1]) { + buffer[j++] = val[1]; + buffer[j++] = val[2]; + } + } + buffer[j] = 0; + return (PyUnicode_FromString(buffer)); + } + + /* + * This assumes that strings are mostly safe ASCII and won't + * be much longer when quoted. + */ + int mbuffer_size = size * 1.5; + char *mbuffer; + + if ((mbuffer = (char *)PyMem_RawMalloc(mbuffer_size)) == NULL) { + return (NULL); + } + + for (i = 0, j = 0; i < size; i++) { + /* Ensure enough space for a quoted value and trailing 0. */ + if (j >= mbuffer_size - 4) { + mbuffer_size *= 1.5; + if ((mbuffer = (char *)PyMem_RawRealloc( + mbuffer, mbuffer_size)) == NULL) { + PyMem_RawFree(mbuffer); + return (NULL); + } + } + const char *val = quote_map[(unsigned char)bstring[i]]; + mbuffer[j++] = val[0]; + if (val[1]) { + mbuffer[j++] = val[1]; + mbuffer[j++] = val[2]; + } + } + mbuffer[j] = 0; + + PyObject *res = PyUnicode_FromString(mbuffer); + PyMem_RawFree(mbuffer); + return (res); +} + +static PyMethodDef methods[] = { + { "fast_quote", (PyCFunction)fast_quote, + METH_VARARGS }, + { NULL, NULL, 0, NULL } +}; + +static struct PyModuleDef miscmodule = { + PyModuleDef_HEAD_INIT, + "_misc", + NULL, + -1, + methods +}; + +PyMODINIT_FUNC +PyInit__misc(void) +{ + PyObject *module = PyModule_Create(&miscmodule); + PyModule_AddIntConstant( + module, "MAX_STACK_QUOTE_SIZE", MAX_STACK_QUOTE_SIZE); + return (module); +} diff --git a/src/modules/search_storage.py b/src/modules/search_storage.py index 76bc4810b..6e33b6c85 100644 --- a/src/modules/search_storage.py +++ b/src/modules/search_storage.py @@ -34,6 +34,7 @@ import pkg.search_errors as search_errors import pkg.portable as portable from pkg.misc import PKG_FILE_BUFSIZ, force_bytes +from pkg._misc import fast_quote FAST_ADD = "fast_add.v1" FAST_REMOVE = "fast_remove.v1" @@ -320,7 +321,7 @@ def transform_main_dict_line(token, entries): "quote". The details of the contents on entries are described in _write_main_dict_line in indexer.py. """ - res = quote(str(token)) + res = fast_quote(str(token)) for action_type, atl in entries: # For performance reasons, 'sep_chars' symbols # are placed directly into the code. @@ -331,7 +332,7 @@ def transform_main_dict_line(token, entries): res += f"!{subtype}" for full_value, fvl in stl: # uses sep_chars[2] == '@' - res += f"@{quote(str(full_value))}" + res += f"@{fast_quote(str(full_value))}" for pfmri_index, pfl in fvl: # uses sep_chars[3] == '#' res += f"#{pfmri_index}" diff --git a/src/pkg/manifests/package:pkg.p5m b/src/pkg/manifests/package:pkg.p5m index f2825c133..0aadc0c7e 100644 --- a/src/pkg/manifests/package:pkg.p5m +++ b/src/pkg/manifests/package:pkg.p5m @@ -61,6 +61,7 @@ file path=$(PYDIRVP)/pkg-0.1-py$(PYVERS).egg-info/dependency_links.txt file path=$(PYDIRVP)/pkg-0.1-py$(PYVERS).egg-info/top_level.txt file path=$(PYDIRVP)/pkg/__init__.py file path=$(PYDIRVP)/pkg/_arch.cpython$(PYPKGVERS).so +file path=$(PYDIRVP)/pkg/_misc.cpython$(PYPKGVERS).so file path=$(PYDIRVP)/pkg/_pspawn.cpython$(PYPKGVERS).so file path=$(PYDIRVP)/pkg/_sha512_t.cpython$(PYPKGVERS).so file path=$(PYDIRVP)/pkg/_sysattr.cpython$(PYPKGVERS).so diff --git a/src/setup.py b/src/setup.py index fe393743e..0696acfe9 100755 --- a/src/setup.py +++ b/src/setup.py @@ -370,6 +370,7 @@ _actions_srcs = ["modules/actions/_actions.c"] _actcomm_srcs = ["modules/actions/_common.c"] _varcet_srcs = ["modules/_varcet.c"] +_misc_srcs = ["modules/_misc.c"] solver_srcs = ["modules/solver/solver.c", "modules/solver/py_solver.c"] solver_link_args = ["-lm", "-lc"] if osname == "sunos": @@ -559,6 +560,13 @@ def run(self): + ["-I" + self.escape(get_python_inc())] + _varcet_srcs ) + _misccmd = ( + lint + + lint_flags + + ["{0}{1}".format("-I", k) for k in include_dirs] + + ["-I" + self.escape(get_python_inc())] + + _misc_srcs + ) pspawncmd = ( lint + lint_flags @@ -604,6 +612,8 @@ def run(self): os.system(" ".join(_actcommcmd)) print(" ".join(_varcetcmd)) os.system(" ".join(_varcetcmd)) + print(" ".join(_misccmd)) + os.system(" ".join(_misccmd)) print(" ".join(pspawncmd)) os.system(" ".join(pspawncmd)) print(" ".join(syscallatcmd)) @@ -1573,6 +1583,14 @@ def __init__(self, name, sources, build_64=False, **kwargs): extra_link_args=link_args, build_64=True, ), + Extension( + "_misc", + _misc_srcs, + include_dirs=include_dirs, + extra_compile_args=compile_args, + extra_link_args=link_args, + build_64=True, + ), Extension( "solver", solver_srcs, diff --git a/src/tests/api/t_fast_quote.py b/src/tests/api/t_fast_quote.py new file mode 100644 index 000000000..976d66ff2 --- /dev/null +++ b/src/tests/api/t_fast_quote.py @@ -0,0 +1,73 @@ +#!/usr/bin/python3 +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2023, Oracle and/or its affiliates. +# + +from . import testutils +if __name__ == "__main__": + testutils.setup_environment("../../../proto") +import pkg5unittest + +import random +import string +import unittest +from urllib.parse import quote + +from pkg._misc import fast_quote, MAX_STACK_QUOTE_SIZE + + +class TestFastQuote(pkg5unittest.Pkg5TestCase): + + def test_basic(self): + """Verify that fast_quote returns the same values as standard quote.""" + for i in range(1024): + symb = chr(i) + # verify both strings and bytes + self.assertEqual(quote(symb), fast_quote(symb)) + self.assertEqual(quote(symb).encode(), fast_quote(symb).encode()) + + def test_long(self): + """Verify that fast_quote handles long strings as well.""" + teststr = "a" * MAX_STACK_QUOTE_SIZE * 2 + self.assertEqual(quote(teststr), fast_quote(teststr)) + + teststr = "ž" * MAX_STACK_QUOTE_SIZE * 2 + self.assertEqual(quote(teststr), fast_quote(teststr)) + + teststr = "こ" * MAX_STACK_QUOTE_SIZE * 2 + self.assertEqual(quote(teststr), fast_quote(teststr)) + + def test_random(self): + """Test fast_quote with string of random length and symbols.""" + for _ in range(1024): + length = random.randrange(2048) + teststr = "".join(random.choices(string.printable, k=length)) + self.assertEqual(quote(teststr), fast_quote(teststr)) + + +if __name__ == "__main__": + unittest.main() + +# Vim hints +# vim:ts=4:sw=4:et:fdm=marker From 2e53c394b3b0fc9c6da3836357ab0904022e25bd Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Thu, 30 Nov 2023 06:41:12 -0800 Subject: [PATCH 08/15] 36058819 test_action_errors fails in Python 3.x due to module import issue --- src/tests/api/t_action.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/tests/api/t_action.py b/src/tests/api/t_action.py index dfddd1bcc..fb84f3a59 100644 --- a/src/tests/api/t_action.py +++ b/src/tests/api/t_action.py @@ -523,14 +523,8 @@ def test_action_errors(self): # Missing key attribute 'fmri'. self.assertInvalid("depend type=require") - # XXX Fails in Python 3.4 due to module import issue; see - # set_invalid_action_error in actions/_common.c. - if six.PY2: - # Multiple values not allowed for 'fmri' if 'type' is - # multi-valued. - self.assertInvalid( - "depend type=require " "type=require-any fmri=foo fmri=bar" - ) + # Multiple values not allowed for 'fmri' if 'type' is multi-valued. + self.assertInvalid("depend type=require type=require-any fmri=foo fmri=bar") # 'path' attribute specified multiple times self.assertInvalid( From 2b4ca0acfc5005a165de2b4d65250caa272ec48f Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Tue, 5 Dec 2023 09:25:07 +0000 Subject: [PATCH 09/15] Re-sync actions/_common with upstream --- src/modules/actions/_common.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/modules/actions/_common.c b/src/modules/actions/_common.c index bca38355c..3ff603b1f 100644 --- a/src/modules/actions/_common.c +++ b/src/modules/actions/_common.c @@ -20,8 +20,7 @@ */ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. - * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright (c) 2012, 2023, Oracle and/or its affiliates. */ /* @@ -32,6 +31,7 @@ static PyObject *nohash; + static void set_invalid_action_error(const char *name, PyObject *action, PyObject *key_aname) @@ -39,23 +39,15 @@ set_invalid_action_error(const char *name, PyObject *action, PyObject *exc = NULL; PyObject *val = NULL; PyObject *pkg_actions = NULL; - PyObject *sys = NULL; - PyObject *sys_modules = NULL; - - if ((sys = PyImport_ImportModule("sys")) == NULL) - return; - if ((sys_modules = PyObject_GetAttrString(sys, "modules")) == NULL) - return; + /* PyImport_ImportModule cannot be called with set exception. */ + PyErr_Clear(); - if ((pkg_actions = PyDict_GetItemString(sys_modules, "pkg.actions")) - == NULL) { + if ((pkg_actions = PyImport_ImportModule("pkg.actions")) == NULL) { /* No exception is set */ - PyErr_SetString(PyExc_KeyError, "siae.pkg.actions"); - Py_DECREF(sys_modules); + PyErr_SetString(PyExc_KeyError, "pkg.actions"); return; } - Py_DECREF(sys_modules); /* * Obtain a reference to the action exception type so that SetObject can @@ -308,7 +300,7 @@ moduleinit(void) if ((pkg_actions = PyImport_ImportModule("pkg.actions")) == NULL) { /* No exception is set */ - PyErr_SetString(PyExc_KeyError, "_common.pkg.actions"); + PyErr_SetString(PyExc_KeyError, "pkg.actions"); return (NULL); } @@ -326,4 +318,3 @@ PyInit__common(void) { return (moduleinit()); } - From 03e1bfb4fdd52885f2479ea03c05aa549030f14e Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Tue, 5 Dec 2023 11:07:56 +0000 Subject: [PATCH 10/15] Build with gcc 13 --- src/Makefile.com | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.com b/src/Makefile.com index 03aac55e7..3d3d183ed 100644 --- a/src/Makefile.com +++ b/src/Makefile.com @@ -24,7 +24,7 @@ ROOTUSRLIB = $(ROOT)/usr/lib ROOTBRAND = $(ROOTUSRLIB)/brand ROOTPKGLIB = $(ROOTUSRLIB)/pkg -CC = /usr/bin/gcc-12 +CC = /usr/bin/gcc-13 CFLAGS = -m64 -Wall -Werror -Wextra -gdwarf-2 -gstrict-dwarf \ -fno-aggressive-loop-optimizations CPPFLAGS = -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS From c3f479c823eb8570ff9b10c61db83417c960f625 Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Tue, 5 Dec 2023 09:31:50 +0000 Subject: [PATCH 11/15] 36066495 remove all trivial use of six library from pkg(7) and related tools --- src/brand/ipkg/fmri_compare.py | 1 - src/client.py | 20 +- src/depot-config.py | 6 +- src/depot.py | 4 +- src/modules/actions/attribute.py | 3 +- src/modules/actions/depend.py | 4 +- src/modules/actions/driver.py | 1 - src/modules/actions/file.py | 9 +- src/modules/actions/generic.py | 18 +- src/modules/actions/license.py | 2 +- src/modules/api_common.py | 2 +- src/modules/bundle/SolarisPackageDirBundle.py | 5 +- src/modules/bundle/__init__.py | 1 - src/modules/catalog.py | 1 - src/modules/cfgfiles.py | 1 - src/modules/client/api.py | 10 +- src/modules/client/api_errors.py | 6 +- src/modules/client/client_api.py | 18 +- src/modules/client/history.py | 2 +- src/modules/client/image.py | 2 +- src/modules/client/imageconfig.py | 2 +- src/modules/client/imageplan.py | 23 +-- src/modules/client/linkedimage/common.py | 2 - src/modules/client/pkg_solver.py | 2 - src/modules/client/pkgplan.py | 2 +- src/modules/client/pkgremote.py | 18 +- src/modules/client/printengine.py | 3 +- src/modules/client/progress.py | 3 - src/modules/client/publisher.py | 21 +- src/modules/client/sigpolicy.py | 3 +- src/modules/client/transport/engine.py | 6 +- src/modules/client/transport/exception.py | 14 +- src/modules/client/transport/fileobj.py | 1 - src/modules/client/transport/mdetect.py | 1 - src/modules/client/transport/repo.py | 68 +++---- src/modules/client/transport/stats.py | 2 +- src/modules/client/transport/transport.py | 16 +- src/modules/config.py | 52 ++--- src/modules/cpiofile.py | 2 - src/modules/depotcontroller.py | 13 +- src/modules/digest.py | 3 +- src/modules/facet.py | 9 +- src/modules/flavor/smf_manifest.py | 3 +- src/modules/fmri.py | 2 +- src/modules/indexer.py | 2 +- src/modules/lint/base.py | 7 +- src/modules/lint/config.py | 3 +- src/modules/lint/engine.py | 7 +- src/modules/lint/log.py | 1 - src/modules/lint/pkglint_action.py | 2 +- src/modules/lint/pkglint_manifest.py | 7 +- src/modules/manifest.py | 21 +- src/modules/mediator.py | 9 +- src/modules/misc.py | 119 +++--------- src/modules/mogrify.py | 13 +- src/modules/p5i.py | 6 +- src/modules/p5p.py | 11 +- src/modules/p5s.py | 2 +- src/modules/pipeutils.py | 15 +- src/modules/portable/os_sunos.py | 1 - src/modules/pspawn.py | 9 +- src/modules/publish/dependencies.py | 8 +- src/modules/publish/transaction.py | 2 +- src/modules/query_parser.py | 2 - src/modules/search_storage.py | 2 +- src/modules/server/depot.py | 179 +++++++++--------- src/modules/server/face.py | 21 +- src/modules/server/feed.py | 6 +- src/modules/server/repository.py | 30 ++- src/modules/server/transaction.py | 12 +- src/modules/sha512_t.py | 10 +- src/modules/smf.py | 15 +- src/modules/sysattr.py | 7 +- src/modules/syscallat.py | 11 +- src/modules/sysvpkg.py | 1 - src/modules/variant.py | 13 +- src/modules/version.py | 2 - src/pkgdep.py | 5 +- src/pkgrepo.py | 7 +- src/publish.py | 11 +- src/pull.py | 9 +- src/setup.py | 1 - src/sysrepo.py | 20 +- src/tests/api/t_action.py | 4 +- src/tests/api/t_api.py | 4 +- src/tests/api/t_api_search.py | 7 +- src/tests/api/t_async_rpc.py | 12 +- src/tests/api/t_catalog.py | 1 - src/tests/api/t_client.py | 6 +- src/tests/api/t_config.py | 110 +++-------- src/tests/api/t_dependencies.py | 1 - src/tests/api/t_fast_quote.py | 2 +- src/tests/api/t_manifest.py | 12 +- src/tests/api/t_p5i.py | 12 +- src/tests/api/t_p5p.py | 5 +- src/tests/api/t_pkg_api_install.py | 4 +- src/tests/api/t_printengine.py | 11 +- src/tests/api/t_progress.py | 16 +- src/tests/api/t_sha512_t.py | 18 +- src/tests/api/t_smf.py | 1 - src/tests/bandit-baseline.json | 5 +- src/tests/baseline.py | 1 - src/tests/cli/t_actuators.py | 47 ++--- src/tests/cli/t_depot_config.py | 19 +- src/tests/cli/t_https.py | 3 +- src/tests/cli/t_origin_fw.py | 1 - src/tests/cli/t_pkg_composite.py | 6 +- src/tests/cli/t_pkg_depotd.py | 51 ++--- src/tests/cli/t_pkg_help.py | 1 - src/tests/cli/t_pkg_history.py | 1 - src/tests/cli/t_pkg_info.py | 13 +- src/tests/cli/t_pkg_install.py | 10 +- src/tests/cli/t_pkg_linked.py | 5 +- src/tests/cli/t_pkg_mediated.py | 4 +- src/tests/cli/t_pkg_nasty.py | 1 - src/tests/cli/t_pkg_search.py | 6 +- src/tests/cli/t_pkg_sysrepo.py | 4 +- src/tests/cli/t_pkg_temp_sources.py | 6 +- src/tests/cli/t_pkg_varcet.py | 9 +- src/tests/cli/t_pkgdep.py | 2 +- src/tests/cli/t_pkgrecv.py | 4 +- src/tests/cli/t_pkgrepo.py | 1 - src/tests/cli/t_pkgsend.py | 5 +- src/tests/cli/t_pkgsign.py | 1 - src/tests/cli/t_publish_api.py | 4 +- src/tests/cli/t_sysrepo.py | 10 +- src/tests/cli/t_util_merge.py | 3 +- src/tests/interactive/runprintengine.py | 1 - src/tests/interactive/runprogress.py | 1 - src/tests/perf/actionbench.py | 1 - src/tests/perf/fmribench.py | 1 - src/tests/perf/manbench.py | 1 - src/tests/perf/membench.py | 1 - src/tests/pkg5testenv.py | 1 - src/tests/pkg5unittest.py | 41 ++-- .../ro_data/signing_certs/generate_certs.py | 1 - src/tests/run.py | 1 - src/util/apache2/depot/depot_index.py | 28 ++- src/util/apache2/sysrepo/sysrepo_p5p.py | 38 ++-- src/util/log-scripts/an2_ip_active.py | 1 - src/util/log-scripts/an_catalog.py | 1 - src/util/log-scripts/an_filelist.py | 1 - src/util/log-scripts/an_first_timestamp.py | 1 - src/util/log-scripts/an_manifest.py | 3 +- src/util/log-scripts/an_report.py | 2 - src/util/log-scripts/an_search.py | 3 +- src/util/log-scripts/config.py | 1 - src/util/log-scripts/in_footer.py | 1 - src/util/log-scripts/in_header.py | 1 - src/util/log-scripts/log.py | 1 - src/util/log-scripts/translate.py | 1 - src/util/publish/pkgdiff.py | 7 +- src/util/publish/pkgfmt.py | 14 +- src/util/publish/pkglint.py | 6 +- src/util/publish/pkgmerge.py | 8 +- src/util/publish/pkgmogrify.py | 7 +- src/util/publish/pkgsurf.py | 8 +- src/util/qual-simulator/scenario.py | 1 - src/web/config.shtml | 2 +- src/web/en/advanced_search.shtml | 2 +- src/web/en/catalog.shtml | 2 +- src/web/en/search.shtml | 13 +- 162 files changed, 601 insertions(+), 1047 deletions(-) diff --git a/src/brand/ipkg/fmri_compare.py b/src/brand/ipkg/fmri_compare.py index efb9fb27d..02d30039f 100644 --- a/src/brand/ipkg/fmri_compare.py +++ b/src/brand/ipkg/fmri_compare.py @@ -24,7 +24,6 @@ # Use is subject to license terms. # -from __future__ import print_function import pkg.fmri import sys diff --git a/src/client.py b/src/client.py index 051fa35bc..8c6c888fc 100755 --- a/src/client.py +++ b/src/client.py @@ -84,7 +84,7 @@ import pycurl import atexit import shutil - from six.moves.urllib.parse import urlparse, unquote + from urllib.parse import urlparse, unquote import pkg import pkg.actions as actions @@ -204,7 +204,7 @@ def format_update_error(e): def error(text, cmd=None): """Emit an error message prefixed by the command name""" - if not isinstance(text, six.string_types): + if not isinstance(text, str): # Assume it's an object that can be stringified. text = str(text) @@ -1998,10 +1998,7 @@ def __api_execute_plan(operation, api_inst): raise if exc_value or exc_tb: - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + raise exc_value return rval @@ -4051,12 +4048,10 @@ def __display_avoids(api_inst): """Display the current avoid list, and the pkgs that are tracking that pkg""" for avoid, tracking in sorted(api_inst.get_avoid_list()): - tracking = " ".join(a[1]) if tracking: - logger.info( + logger.info(_( " {avoid_pkg} (group dependency of '{tracking_pkg}')") .format(avoid_pkg=avoid, tracking_pkg=" ".join(tracking))) - ) else: logger.info(" {0}".format(avoid)) @@ -5686,7 +5681,7 @@ def display_ssl_info(uri_data): if not properties_displayed: msg(_(" Properties:")) properties_displayed = True - if not isinstance(v, six.string_types): + if not isinstance(v, str): v = ", ".join(sorted(v)) msg(property_padding, k + " =", str(v)) return retcode @@ -8007,9 +8002,8 @@ def handle_sighupterm(signum, frame): import warnings warnings.simplefilter("error") - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) # Attempt to handle SIGHUP/SIGTERM gracefully. import signal diff --git a/src/depot-config.py b/src/depot-config.py index 103ac4055..1b506a5af 100755 --- a/src/depot-config.py +++ b/src/depot-config.py @@ -36,7 +36,6 @@ import os import re import shutil -import six import socket import sys import traceback @@ -1182,9 +1181,8 @@ def handle_errors(func, *args, **kwargs): # Make all warnings be errors. warnings.simplefilter("error") - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) __retval = handle_errors(main_func) try: diff --git a/src/depot.py b/src/depot.py index 8078b9fa2..2675ede90 100755 --- a/src/depot.py +++ b/src/depot.py @@ -22,7 +22,6 @@ # Copyright (c) 2007, 2022, Oracle and/or its affiliates. # -from __future__ import print_function import pkg.site_paths pkg.site_paths.init() @@ -75,7 +74,6 @@ import OpenSSL.crypto as crypto import string import shlex -import six import string import subprocess import sys @@ -83,7 +81,7 @@ import portend from importlib import reload -from six.moves.urllib.parse import urlparse, urlunparse +from urllib.parse import urlparse, urlunparse try: import cherrypy diff --git a/src/modules/actions/attribute.py b/src/modules/actions/attribute.py index d1574d1c0..aa5125e12 100644 --- a/src/modules/actions/attribute.py +++ b/src/modules/actions/attribute.py @@ -33,7 +33,6 @@ from . import generic import pkg.fmri import pkg.actions -import six class AttributeAction(generic.Action): @@ -90,7 +89,7 @@ def generate_indices(self): if isinstance(self.attrs["value"], list): tmp = [] for v in self.attrs["value"]: - assert isinstance(v, six.string_types) + assert isinstance(v, str) if " " in v: words = v.split() for w in words: diff --git a/src/modules/actions/depend.py b/src/modules/actions/depend.py index eac4d1859..f82001cf8 100644 --- a/src/modules/actions/depend.py +++ b/src/modules/actions/depend.py @@ -378,7 +378,7 @@ def generate_indices(self): # release and without it creating a dummy timestamp. # Instead we have to split it apart manually. # - if isinstance(pfmris, six.string_types): + if isinstance(pfmris, str): pfmris = [pfmris] inds = [] pat = re.compile(r"pkg:///|pkg://[^/]*/|pkg:/") @@ -528,7 +528,7 @@ def validate(self, fmri=None): single_attrs=single_attrs, ) - if isinstance(dtype, six.string_types) and dtype not in known_types: + if isinstance(dtype, str) and dtype not in known_types: errors.append( ( "type", diff --git a/src/modules/actions/driver.py b/src/modules/actions/driver.py index 624293402..4223fe1b6 100644 --- a/src/modules/actions/driver.py +++ b/src/modules/actions/driver.py @@ -30,7 +30,6 @@ packaging object. """ -from __future__ import print_function import os from . import generic import six diff --git a/src/modules/actions/file.py b/src/modules/actions/file.py index 33d13cded..dba1505ae 100644 --- a/src/modules/actions/file.py +++ b/src/modules/actions/file.py @@ -1032,14 +1032,9 @@ def validate(self, fmri=None): self, errors, fmri=fmri ) - if six.PY3: + def __init__(self, data, **attrs): + _common._file_init(self, data, **attrs) - def __init__(self, data, **attrs): - _common._file_init(self, data, **attrs) - - -if six.PY2: - FileAction.__init__ = types.MethodType(_common._file_init, None, FileAction) # Vim hints # vim:ts=4:sw=4:et:fdm=marker diff --git a/src/modules/actions/generic.py b/src/modules/actions/generic.py index 7f3c2869e..64cf49c18 100644 --- a/src/modules/actions/generic.py +++ b/src/modules/actions/generic.py @@ -208,7 +208,7 @@ def set_data(self, data): self.data = None return - if isinstance(data, six.string_types): + if isinstance(data, str): if not os.path.exists(data): raise pkg.actions.ActionDataError( _("No such file: '{0}'.").format(data), path=data @@ -1289,9 +1289,7 @@ def _validate( for attr in required_attrs: val = self.attrs.get(attr) - if not val or ( - isinstance(val, six.string_types) and not val.strip() - ): + if not val or (isinstance(val, str) and not val.strip()): errors.append((attr, _("{0} is required").format(attr))) if raise_errors and errors: @@ -1345,16 +1343,10 @@ def fsobj_checkpath(self, pkgplan, final_path): ).format(**locals()) raise apx.ActionExecutionError(self, details=err_txt, fmri=fmri) - if six.PY3: - - def __init__(self, data=None, **attrs): - # create a bound method (no unbound method in Python 3) - _common._generic_init(self, data, **attrs) - + def __init__(self, data=None, **attrs): + # create a bound method (no unbound method in Python 3) + _common._generic_init(self, data, **attrs) -if six.PY2: - # create an unbound method - Action.__init__ = types.MethodType(_common._generic_init, None, Action) # Vim hints # vim:ts=4:sw=4:et:fdm=marker diff --git a/src/modules/actions/license.py b/src/modules/actions/license.py index 68e162865..c870d2e02 100644 --- a/src/modules/actions/license.py +++ b/src/modules/actions/license.py @@ -42,7 +42,7 @@ import zlib from pkg.client.api_errors import ActionExecutionError -from six.moves.urllib.parse import quote +from urllib.parse import quote class LicenseAction(generic.Action): diff --git a/src/modules/api_common.py b/src/modules/api_common.py index 2dfd07bab..c6fbea439 100644 --- a/src/modules/api_common.py +++ b/src/modules/api_common.py @@ -235,7 +235,7 @@ def get_attr_values(self, name, modifiers=()): modifiers = tuple( ( k, - isinstance(modifiers[k], six.string_types) + isinstance(modifiers[k], str) and tuple([sorted(modifiers[k])]) or tuple(sorted(modifiers[k])), ) diff --git a/src/modules/bundle/SolarisPackageDirBundle.py b/src/modules/bundle/SolarisPackageDirBundle.py index 365865c26..586364901 100644 --- a/src/modules/bundle/SolarisPackageDirBundle.py +++ b/src/modules/bundle/SolarisPackageDirBundle.py @@ -25,7 +25,6 @@ # import os -import six import pkg.bundle import pkg.misc as misc @@ -195,7 +194,7 @@ def action(self, mapline, data): if ( act.hash == "NOHASH" - and isinstance(data, six.string_types) + and isinstance(data, str) and data.startswith(self.filename) ): act.hash = data[len(self.filename) + 1 :] @@ -218,7 +217,7 @@ def action(self, mapline, data): ) if ( act.hash == "NOHASH" - and isinstance(data, six.string_types) + and isinstance(data, str) and data.startswith(self.filename) ): act.hash = data[len(self.filename) + 1 :] diff --git a/src/modules/bundle/__init__.py b/src/modules/bundle/__init__.py index 208d11045..fdd3bc58f 100644 --- a/src/modules/bundle/__init__.py +++ b/src/modules/bundle/__init__.py @@ -24,7 +24,6 @@ # Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function # The ordering is important -- SolarisPackageDirBundle must come before # DirectoryBundle, or the latter class will recognize a Solaris package diff --git a/src/modules/catalog.py b/src/modules/catalog.py index c1222c269..f3526de6d 100644 --- a/src/modules/catalog.py +++ b/src/modules/catalog.py @@ -25,7 +25,6 @@ """Interfaces and implementation for the Catalog object, as well as functions that operate on lists of package FMRIs.""" -from __future__ import print_function import copy import calendar import collections diff --git a/src/modules/cfgfiles.py b/src/modules/cfgfiles.py index 5544923c8..91fd2fe95 100644 --- a/src/modules/cfgfiles.py +++ b/src/modules/cfgfiles.py @@ -27,7 +27,6 @@ # NOTE: This module is inherently posix specific. Care is taken in the modules # that use this module to not use it on other operating systems. -from __future__ import print_function import datetime import errno import os diff --git a/src/modules/client/api.py b/src/modules/client/api.py index 935d1e697..2f3ac13b7 100644 --- a/src/modules/client/api.py +++ b/src/modules/client/api.py @@ -69,7 +69,7 @@ import time from functools import cmp_to_key -from six.moves.urllib.parse import unquote +from urllib.parse import unquote import pkg.actions as actions import six @@ -386,7 +386,7 @@ def __init__( in the environment or by setting simulate_cmdpath in DebugValues.""" ) - if isinstance(img_path, six.string_types): + if isinstance(img_path, str): # Store this for reset(). self._img_path = img_path self._img = image.Image( @@ -1379,9 +1379,9 @@ def __verify_args(self, args): # arg name type nullable "_act_timeout": (int, False), "_be_activate": ("activate", False), - "_be_name": (six.string_types, True), + "_be_name": (str, True), "_backup_be": (bool, True), - "_backup_be_name": (six.string_types, True), + "_backup_be_name": (str, True), "_ignore_missing": (bool, False), "_ipkg_require_latest": (bool, False), "_li_erecurse": (iter, True), @@ -3908,7 +3908,7 @@ def __get_temp_repo_pubs(self, repos): ret_pubs = [] for repo_uri in repos: - if isinstance(repo_uri, six.string_types): + if isinstance(repo_uri, str): repo = publisher.RepositoryURI(repo_uri) else: # Already a RepositoryURI. diff --git a/src/modules/client/api_errors.py b/src/modules/client/api_errors.py index 25e726181..9fe80aa1a 100644 --- a/src/modules/client/api_errors.py +++ b/src/modules/client/api_errors.py @@ -31,7 +31,7 @@ import six import xml.parsers.expat as expat from functools import total_ordering -from six.moves.urllib.parse import urlsplit +from urllib.parse import urlsplit # pkg classes import pkg.client.pkgdefs as pkgdefs @@ -2452,7 +2452,7 @@ class UnsupportedRepositoryURI(PublisherError): unsupported scheme.""" def __init__(self, uris=[]): - if isinstance(uris, six.string_types): + if isinstance(uris, str): uris = [uris] assert isinstance(uris, (list, tuple, set)) @@ -2463,7 +2463,7 @@ def __str__(self): illegals = [] for u in self.uris: - assert isinstance(u, six.string_types) + assert isinstance(u, str) scheme = urlsplit(u, allow_fragments=0)[0] illegals.append((u, scheme)) diff --git a/src/modules/client/client_api.py b/src/modules/client/client_api.py index f5007456c..b16ba7086 100644 --- a/src/modules/client/client_api.py +++ b/src/modules/client/client_api.py @@ -42,7 +42,6 @@ import time import traceback -from six.moves import filter, map, range import pkg import pkg.actions as actions @@ -102,7 +101,7 @@ def _strify(input): ) elif isinstance(input, list): return [_strify(element) for element in input] - elif isinstance(input, (six.string_types, bytes)): + elif isinstance(input, (str, bytes)): return misc.force_str(input, "utf-8") else: return input @@ -471,7 +470,7 @@ def _format_update_error(e, errors_json=None): def _error_json(text, cmd=None, errors_json=None, errorType=None): """Prepare an error message for json output.""" - if not isinstance(text, six.string_types): + if not isinstance(text, str): # Assume it's an object that can be stringified. text = str(text) @@ -1257,10 +1256,7 @@ def __api_execute_plan(operation, api_inst): raise if exc_value or exc_tb: - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + raise exc_value return rval @@ -2678,7 +2674,7 @@ def get_cert_info(ssl_cert): ) entry = [] for e in values: - if isinstance(e, six.string_types): + if isinstance(e, str): entry.append(e) else: entry.append(str(e)) @@ -2715,7 +2711,7 @@ def get_cert_info(ssl_cert): ) entry = [] for e in values: - if isinstance(e, six.string_types): + if isinstance(e, str): entry.append(e) else: entry.append(str(e)) @@ -2734,7 +2730,7 @@ def get_cert_info(ssl_cert): ) entry = [] for e in values: - if isinstance(e, six.string_types): + if isinstance(e, str): entry.append(e) else: entry.append(str(e)) @@ -3582,7 +3578,7 @@ def __pkg( else: pargs = json.loads(pargs_json) if not isinstance(pargs, list): - if not isinstance(pargs, six.string_types): + if not isinstance(pargs, str): err = {"reason": "{0} is invalid.".format(arg_name)} errors_json.append(err) return None, __prepare_json(EXIT_OOPS, errors=errors_json) diff --git a/src/modules/client/history.py b/src/modules/client/history.py index 198f0f1c3..610e70ed4 100644 --- a/src/modules/client/history.py +++ b/src/modules/client/history.py @@ -882,7 +882,7 @@ def log_operation_error(self, error): output = traceback.format_exc() use_current_stack = False - if isinstance(error, six.string_types): + if isinstance(error, str): output = error elif use_current_stack: # Assume the current stack is more useful if diff --git a/src/modules/client/image.py b/src/modules/client/image.py index 48c064573..8029aa3e9 100644 --- a/src/modules/client/image.py +++ b/src/modules/client/image.py @@ -45,7 +45,7 @@ from contextlib import contextmanager from cryptography import x509 from cryptography.hazmat.backends import default_backend -from six.moves.urllib.parse import quote, unquote +from urllib.parse import quote, unquote import pkg.actions import pkg.catalog diff --git a/src/modules/client/imageconfig.py b/src/modules/client/imageconfig.py index 691a9a77c..59de07875 100644 --- a/src/modules/client/imageconfig.py +++ b/src/modules/client/imageconfig.py @@ -32,7 +32,7 @@ import re import six -from six.moves.urllib.parse import quote, unquote +from urllib.parse import quote, unquote import pkg.client.api_errors as apx import pkg.client.publisher as publisher diff --git a/src/modules/client/imageplan.py b/src/modules/client/imageplan.py index 3ac01adc2..3116d9e93 100644 --- a/src/modules/client/imageplan.py +++ b/src/modules/client/imageplan.py @@ -25,7 +25,6 @@ # Copyright (c) 2007, 2021, Oracle and/or its affiliates. # -from __future__ import print_function from collections import defaultdict, namedtuple import contextlib import errno @@ -3073,7 +3072,7 @@ def __process_conflicts(self, key, func, actions, oactions, errclass, errs): else: msg, actions = ret - if not isinstance(msg, six.string_types): + if not isinstance(msg, str): return False if msg == "nothing": @@ -5988,16 +5987,11 @@ def execute(self): except: # Ensure the real cause of failure is raised. pass - if six.PY2: - six.reraise( - api_errors.InvalidPackageErrors([exc_value]), None, exc_tb - ) - else: - # six.reraise requires the first argument - # callable if the second argument is None. - # Also the traceback is automatically attached, - # in Python 3, so we can simply raise it. - raise api_errors.InvalidPackageErrors([exc_value]) + # six.reraise requires the first argument + # callable if the second argument is None. + # Also the traceback is automatically attached, + # in Python 3, so we can simply raise it. + raise api_errors.InvalidPackageErrors([exc_value]) except: exc_type, exc_value, exc_tb = sys.exc_info() self.pd.state = plandesc.EXECUTED_ERROR @@ -6007,10 +6001,7 @@ def execute(self): # This ensures that the original exception and # traceback are used if exec_fail_actuators # fails. - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + raise exc_value else: self.pd._actuators.exec_post_actuators(self.image) diff --git a/src/modules/client/linkedimage/common.py b/src/modules/client/linkedimage/common.py index 5aec41525..ef2a23907 100644 --- a/src/modules/client/linkedimage/common.py +++ b/src/modules/client/linkedimage/common.py @@ -49,10 +49,8 @@ import os import select -# Redefining built-in 'reduce', 'zip'; pylint: disable=W0622 # Imports from package six are not grouped: pylint: disable=C0412 from functools import reduce -from six.moves import zip import six diff --git a/src/modules/client/pkg_solver.py b/src/modules/client/pkg_solver.py index c7b9865b4..c3150fc38 100644 --- a/src/modules/client/pkg_solver.py +++ b/src/modules/client/pkg_solver.py @@ -33,13 +33,11 @@ from collections import defaultdict -# Redefining built-in; pylint: disable=W0622 from functools import reduce import six # Imports from package six are not grouped: pylint: disable=C0412 -from six.moves import range from itertools import chain import pkg.actions diff --git a/src/modules/client/pkgplan.py b/src/modules/client/pkgplan.py index 6b710886f..88ada8413 100644 --- a/src/modules/client/pkgplan.py +++ b/src/modules/client/pkgplan.py @@ -109,7 +109,7 @@ class PkgPlan(object): __state__desc = { "_autofix_pkgs": [pkg.fmri.PkgFmri], "_license_status": { - six.string_types[0]: { + str: { "src": pkg.actions.generic.NSG, "dest": pkg.actions.generic.NSG, }, diff --git a/src/modules/client/pkgremote.py b/src/modules/client/pkgremote.py index 6439c75f8..4ba527ee5 100644 --- a/src/modules/client/pkgremote.py +++ b/src/modules/client/pkgremote.py @@ -37,7 +37,6 @@ import tempfile import traceback -import six # pkg classes import pkg.client.api_errors as apx @@ -147,17 +146,12 @@ def __rpc_server_fork( # unexpected-keyword-arg 'pass_fds'; # pylint: disable=E1123 # Redefinition of p type - if six.PY2: - p = pkg.pkgsubprocess.Popen( - pkg_cmd, stdout=fstdout, stderr=fstderr - ) - else: - p = subprocess.Popen( - pkg_cmd, - stdout=fstdout, - stderr=fstderr, - pass_fds=(server_cmd_pipe, server_prog_pipe_fobj.fileno()), - ) + p = subprocess.Popen( + pkg_cmd, + stdout=fstdout, + stderr=fstderr, + pass_fds=(server_cmd_pipe, server_prog_pipe_fobj.fileno()), + ) except OSError as e: # Access to protected member; pylint: disable=W0212 diff --git a/src/modules/client/printengine.py b/src/modules/client/printengine.py index 7693352f1..d3a7b1c6f 100644 --- a/src/modules/client/printengine.py +++ b/src/modules/client/printengine.py @@ -30,6 +30,7 @@ import curses import errno +import io import logging import os import re @@ -223,7 +224,7 @@ def __init__(self, logger, loglevel): PrintEngine.__init__(self) self._logger = logger self._loglevel = loglevel - self._stringio = six.StringIO() + self._stringio = io.StringIO() self._pxpe = POSIXPrintEngine(self._stringio, False) def isslow(self): diff --git a/src/modules/client/progress.py b/src/modules/client/progress.py index e0f8684aa..69ee8d811 100644 --- a/src/modules/client/progress.py +++ b/src/modules/client/progress.py @@ -30,7 +30,6 @@ # from __future__ import division -from __future__ import print_function import inspect import itertools @@ -40,8 +39,6 @@ from collections import deque from functools import wraps -# Redefining built-in 'range'; pylint: disable=W0622 -from six.moves import range import six diff --git a/src/modules/client/publisher.py b/src/modules/client/publisher.py index 7ad4ea961..51e656d8c 100644 --- a/src/modules/client/publisher.py +++ b/src/modules/client/publisher.py @@ -34,7 +34,6 @@ # modules/client/api.py:__init__. # -from __future__ import print_function import calendar import collections @@ -55,14 +54,14 @@ from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import padding from io import BytesIO -from six.moves.urllib.parse import ( +from urllib.parse import ( quote, urlsplit, urlparse, urlunparse, ParseResult, ) -from six.moves.urllib.request import url2pathname +from urllib.request import url2pathname import pkg.catalog import pkg.client.api_errors as api_errors @@ -357,7 +356,7 @@ def __set_ssl_cert(self, filename): "ssl_cert", scheme=self.scheme ) if filename: - if not isinstance(filename, six.string_types): + if not isinstance(filename, str): raise api_errors.BadRepositoryAttributeValue( "ssl_cert", value=filename ) @@ -372,7 +371,7 @@ def __set_ssl_key(self, filename): "ssl_key", scheme=self.scheme ) if filename: - if not isinstance(filename, six.string_types): + if not isinstance(filename, str): raise api_errors.BadRepositoryAttributeValue( "ssl_key", value=filename ) @@ -681,14 +680,14 @@ def __init__( def __eq__(self, other): if isinstance(other, TransportRepoURI): return self.uri == other.uri and self.proxy == other.proxy - if isinstance(other, six.string_types): + if isinstance(other, str): return self.uri == other and self.proxy is None return False def __ne__(self, other): if isinstance(other, TransportRepoURI): return self.uri != other.uri or self.proxy != other.proxy - if isinstance(other, six.string_types): + if isinstance(other, str): return self.uri != other or self.proxy is not None return True @@ -697,7 +696,7 @@ def __ne__(self, other): def __lt__(self, other): if not other: return False - if isinstance(other, six.string_types): + if isinstance(other, str): other = TransportRepoURI(other) elif not isinstance(other, TransportRepoURI): return False @@ -710,7 +709,7 @@ def __lt__(self, other): def __gt__(self, other): if not other: return True - if isinstance(other, six.string_types): + if isinstance(other, str): other = TransportRepoURI(other) elif not isinstance(other, TransportRepoURI): return True @@ -3593,7 +3592,7 @@ def __set_prop(self, name, values): if name == SIGNATURE_POLICY: self.__sig_policy = None - if isinstance(values, six.string_types): + if isinstance(values, str): values = [values] policy_name = values[0] if policy_name not in sigpolicy.Policy.policies(): @@ -3627,7 +3626,7 @@ def __set_prop(self, name, values): self.__properties[SIGNATURE_POLICY] = policy_name return if name == "signature-required-names": - if isinstance(values, six.string_types): + if isinstance(values, str): values = self.__read_list(values) self.__properties[name] = values diff --git a/src/modules/client/sigpolicy.py b/src/modules/client/sigpolicy.py index 73a821a12..bb2d4814b 100644 --- a/src/modules/client/sigpolicy.py +++ b/src/modules/client/sigpolicy.py @@ -24,7 +24,6 @@ # Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. # -import six import pkg.client.api_errors as apx from functools import total_ordering @@ -169,7 +168,7 @@ def __init__(self, req_names, *args, **kwargs): "to be passed to the constructor." ) Policy.__init__(self, *args, **kwargs) - if isinstance(req_names, six.string_types): + if isinstance(req_names, str): req_names = [req_names] self.required_names = frozenset(req_names) diff --git a/src/modules/client/transport/engine.py b/src/modules/client/transport/engine.py index 75b5fbdd3..b21a13a0f 100644 --- a/src/modules/client/transport/engine.py +++ b/src/modules/client/transport/engine.py @@ -28,13 +28,13 @@ from __future__ import division import errno +import http.client import os import pycurl import six import time -from six.moves import http_client -from six.moves.urllib.parse import urlsplit +from urllib.parse import urlsplit # Need to ignore SIGPIPE if using pycurl in NOSIGNAL mode. try: @@ -408,7 +408,7 @@ def __cleanup_requests(self): respcode = h.getinfo(pycurl.RESPONSE_CODE) - if proto not in response_protocols or respcode == http_client.OK: + if proto not in response_protocols or respcode == http.client.OK: h.success = True repostats.clear_consecutive_errors() success.append(url) diff --git a/src/modules/client/transport/exception.py b/src/modules/client/transport/exception.py index ee69fda51..538ee7ada 100644 --- a/src/modules/client/transport/exception.py +++ b/src/modules/client/transport/exception.py @@ -25,17 +25,17 @@ # import errno +import http.client import pycurl from functools import total_ordering -from six.moves import http_client retryable_http_errors = set( ( - http_client.REQUEST_TIMEOUT, - http_client.BAD_GATEWAY, - http_client.GATEWAY_TIMEOUT, - http_client.NOT_FOUND, + http.client.REQUEST_TIMEOUT, + http.client.BAD_GATEWAY, + http.client.GATEWAY_TIMEOUT, + http.client.NOT_FOUND, ) ) retryable_file_errors = set( @@ -45,7 +45,7 @@ import pkg.client.api_errors as api_errors # Errors that stats.py may include in a decay-able error rate -decayable_http_errors = set((http_client.NOT_FOUND,)) +decayable_http_errors = set((http.client.NOT_FOUND,)) decayable_file_errors = set( (pycurl.E_FILE_COULDNT_READ_FILE, errno.EAGAIN, errno.ENOENT) ) @@ -68,7 +68,7 @@ "https": decayable_http_errors, } -proto_code_map = {"http": http_client.responses, "https": http_client.responses} +proto_code_map = {"http": http.client.responses, "https": http.client.responses} retryable_pycurl_errors = set( ( diff --git a/src/modules/client/transport/fileobj.py b/src/modules/client/transport/fileobj.py index 28070e1e2..ff8e44adc 100644 --- a/src/modules/client/transport/fileobj.py +++ b/src/modules/client/transport/fileobj.py @@ -24,7 +24,6 @@ # Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import uuid as uuidm import pkg.client.transport.exception as tx diff --git a/src/modules/client/transport/mdetect.py b/src/modules/client/transport/mdetect.py index 7e5ce6f8c..0d20af154 100644 --- a/src/modules/client/transport/mdetect.py +++ b/src/modules/client/transport/mdetect.py @@ -25,7 +25,6 @@ # import random -from six.moves import range import pkg.misc as misc import pkg.client.publisher as pub diff --git a/src/modules/client/transport/repo.py b/src/modules/client/transport/repo.py index 8b136f81e..996757181 100644 --- a/src/modules/client/transport/repo.py +++ b/src/modules/client/transport/repo.py @@ -26,6 +26,8 @@ # import errno +import http.client +import io import itertools import os import shutil @@ -34,8 +36,7 @@ import tempfile from email.utils import formatdate -from six.moves import cStringIO, http_client -from six.moves.urllib.parse import ( +from urllib.parse import ( quote, urlencode, urlsplit, @@ -43,7 +44,7 @@ urlunparse, urljoin, ) -from six.moves.urllib.request import url2pathname, pathname2url +from urllib.request import url2pathname, pathname2url import pkg import pkg.p5i as p5i @@ -297,7 +298,7 @@ def _parse_html_error(content): from xml.dom.minidom import Document, parse - dom = parse(cStringIO(content)) + dom = parse(io.StringIO(content)) msg = "" paragraphs = [] @@ -513,7 +514,7 @@ def __check_response_body(self, fobj): fobj.free_buffer = False fobj.read() except tx.TransportProtoError as e: - if e.code == http_client.BAD_REQUEST: + if e.code == http.client.BAD_REQUEST: exc_type, exc_value, exc_tb = sys.exc_info() try: e.details = self._parse_html_error(fobj.read()) @@ -524,10 +525,7 @@ def __check_response_body(self, fobj): except: # If parse fails, raise original # exception. - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + raise exc_value raise finally: fobj.close() @@ -887,19 +885,15 @@ def get_versions(self, header=None, ccancel=None): # use .read() since this will empty the data buffer. fobj.getheader("octopus", None) except tx.TransportProtoError as e: - if e.code == http_client.UNAUTHORIZED: + if e.code == http.client.UNAUTHORIZED: exc_type, exc_value, exc_tb = sys.exc_info() try: e.details = self._analyze_server_error( fobj.getheader("X-IPkg-Error", None) ) except: - # If analysis fails, raise original - # exception. - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + # If analysis fails, raise original exception. + raise exc_value raise return fobj @@ -1027,17 +1021,13 @@ def publish_abandon(self, header=None, trans_id=None): state = fobj.getheader("State", None) pkgfmri = fobj.getheader("Package-FMRI", None) except tx.TransportProtoError as e: - if e.code == http_client.BAD_REQUEST: + if e.code == http.client.BAD_REQUEST: exc_type, exc_value, exc_tb = sys.exc_info() try: e.details = self._parse_html_error(fobj.read()) except: - # If parse fails, raise original - # exception. - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + # If parse fails, raise original exception. + raise exc_value raise finally: fobj.close() @@ -1067,17 +1057,13 @@ def publish_close(self, header=None, trans_id=None, add_to_catalog=False): state = fobj.getheader("State", None) pkgfmri = fobj.getheader("Package-FMRI", None) except tx.TransportProtoError as e: - if e.code == http_client.BAD_REQUEST: + if e.code == http.client.BAD_REQUEST: exc_type, exc_value, exc_tb = sys.exc_info() try: e.details = self._parse_html_error(fobj.read()) except: - # If parse fails, raise original - # exception. - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + # If parse fails, raise original exception. + raise exc_value raise finally: @@ -1111,17 +1097,13 @@ def __start_trans(self, baseurl, header, client_release, pkg_name): fobj.read() trans_id = fobj.getheader("Transaction-ID", None) except tx.TransportProtoError as e: - if e.code == http_client.BAD_REQUEST: + if e.code == http.client.BAD_REQUEST: exc_type, exc_value, exc_tb = sys.exc_info() try: e.details = self._parse_html_error(fobj.read()) except: - # If parse fails, raise original - # exception. - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + # If parse fails, raise original exception. + raise exc_value raise finally: fobj.close() @@ -1703,7 +1685,7 @@ def get_publisherinfo(self, header=None, ccancel=None): try: pubs = self._frepo.get_publishers() - buf = cStringIO() + buf = io.StringIO() p5i.write(buf, pubs) except Exception as e: reason = ( @@ -1721,7 +1703,7 @@ def get_publisherinfo(self, header=None, ccancel=None): def get_status(self, header=None, ccancel=None): """Get status/0 information from the repository.""" - buf = cStringIO() + buf = io.StringIO() try: rstatus = self._frepo.get_status() json.dump( @@ -1963,7 +1945,7 @@ def get_versions(self, header=None, ccancel=None): """Query the repo for versions information. Returns a file-like object.""" - buf = cStringIO() + buf = io.StringIO() vops = { "abandon": ["0"], "add": ["0"], @@ -2357,7 +2339,7 @@ def get_status(self, header=None, ccancel=None): # Remove temporary directory if possible. shutil.rmtree(tmpdir, ignore_errors=True) - buf = cStringIO() + buf = io.StringIO() try: json.dump( arcdata, buf, ensure_ascii=False, indent=2, sort_keys=True @@ -2461,7 +2443,7 @@ def get_publisherinfo(self, header=None, ccancel=None): try: pubs = self._arc.get_publishers() - buf = cStringIO() + buf = io.StringIO() p5i.write(buf, pubs) except Exception as e: reason = ( @@ -2598,7 +2580,7 @@ def get_versions(self, header=None, ccancel=None): """Query the repo for versions information. Returns a file-like object.""" - buf = cStringIO() + buf = io.StringIO() vops = { "catalog": ["1"], "file": ["0"], diff --git a/src/modules/client/transport/stats.py b/src/modules/client/transport/stats.py index 7d154f217..ea2a991df 100644 --- a/src/modules/client/transport/stats.py +++ b/src/modules/client/transport/stats.py @@ -29,7 +29,7 @@ import os import datetime import random -from six.moves.urllib.parse import urlsplit +from urllib.parse import urlsplit import pkg.misc as misc diff --git a/src/modules/client/transport/transport.py b/src/modules/client/transport/transport.py index 0e6c70f21..b0ac9fd2d 100644 --- a/src/modules/client/transport/transport.py +++ b/src/modules/client/transport/transport.py @@ -25,21 +25,19 @@ # Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # -from __future__ import print_function import copy import datetime as dt import errno +import http.client import os -import six import tempfile import zlib from collections import defaultdict from functools import cmp_to_key from io import BytesIO -from six.moves import http_client, range from cryptography import x509 from cryptography.hazmat.backends import default_backend -from six.moves.urllib.parse import ( +from urllib.parse import ( quote, urlsplit, urlparse, @@ -180,7 +178,7 @@ def get_caches(self, pub=None, readonly=True): if isinstance(pub, publisher.Publisher): pub = pub.prefix - elif not pub or not isinstance(pub, six.string_types): + elif not pub or not isinstance(pub, str): pub = None caches = [ @@ -728,11 +726,11 @@ def do_search(self, pub, data, ccancel=None, alt_repo=None): failures.extend(ex.failures) except tx.TransportProtoError as e: - if e.code in (http_client.NOT_FOUND, errno.ENOENT): + if e.code in (http.client.NOT_FOUND, errno.ENOENT): raise apx.UnsupportedSearchError(e.url, "search/1") - elif e.code == http_client.NO_CONTENT: + elif e.code == http.client.NO_CONTENT: no_result_url = e.url - elif e.code in (http_client.BAD_REQUEST, errno.EINVAL): + elif e.code in (http.client.BAD_REQUEST, errno.EINVAL): raise apx.MalformedSearchRequest(e.url) elif e.retryable: failures.append(e) @@ -823,7 +821,7 @@ def get_catalog(self, pub, ts=None, ccancel=None, path=None, alt_repo=None): # failures that it contains failures.extend(ex.failures) except tx.TransportProtoError as e: - if e.code == http_client.NOT_MODIFIED: + if e.code == http.client.NOT_MODIFIED: return elif e.retryable: failures.append(e) diff --git a/src/modules/config.py b/src/modules/config.py index d7d3cf3a4..077f71073 100644 --- a/src/modules/config.py +++ b/src/modules/config.py @@ -46,9 +46,9 @@ manipulation of configuration data is needed. """ -from __future__ import print_function import ast import codecs +import configparser import copy import errno import os @@ -60,8 +60,6 @@ import tempfile import uuid from collections import OrderedDict -from six import python_2_unicode_compatible -from six.moves import configparser from pkg import misc, portable import pkg.version @@ -224,7 +222,6 @@ def __str__(self): return _("Unknown property section: {0}.").format(self.section) -@python_2_unicode_compatible class Property(object): """Base class for properties.""" @@ -235,9 +232,7 @@ class Property(object): _value_map = misc.EmptyDict def __init__(self, name, default="", value_map=misc.EmptyDict): - if not isinstance(name, six.string_types) or not self.__name_re.match( - name - ): + if not isinstance(name, str) or not self.__name_re.match(name): raise InvalidPropertyNameError(prop=name) try: name.encode("ascii") @@ -296,7 +291,7 @@ def _is_allowed(self, value): """Raises an InvalidPropertyValueError if 'value' is not allowed for this property. """ - if not isinstance(value, six.string_types): + if not isinstance(value, str): # Only string values are allowed. raise InvalidPropertyValueError(prop=self.name, value=value) @@ -329,7 +324,7 @@ def value(self): @value.setter def value(self, value): """Sets the property's value.""" - if isinstance(value, six.string_types): + if isinstance(value, str): value = self._value_map.get(value, value) if value is None: value = "" @@ -357,7 +352,7 @@ def __init__( value_map=None, ): assert prop_type - if not isinstance(name_pattern, six.string_types) or not name_pattern: + if not isinstance(name_pattern, str) or not name_pattern: raise InvalidPropertyTemplateNameError(prop=name_pattern) self.__name = name_pattern try: @@ -417,12 +412,12 @@ def __init__(self, name, default=False, value_map=misc.EmptyDict): @Property.value.setter def value(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): value = self._value_map.get(value, value) if value is None or value == "": self._value = False return - elif isinstance(value, six.string_types): + elif isinstance(value, str): if value.lower() == "true": self._value = True return @@ -465,7 +460,7 @@ def maximum(self): @Property.value.setter def value(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): value = self._value_map.get(value, value) if value is None or value == "": value = 0 @@ -491,15 +486,13 @@ class PropPublisher(Property): @Property.value.setter def value(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): value = self._value_map.get(value, value) if value is None or value == "": self._value = "" return - if not isinstance(value, six.string_types) or not misc.valid_pub_prefix( - value - ): + if not isinstance(value, str) or not misc.valid_pub_prefix(value): # Only string values are allowed. raise InvalidPropertyValueError(prop=self.name, value=value) self._value = value @@ -580,11 +573,11 @@ def _parse_str(self, value): @PropDefined.value.setter def value(self, value): # the value can be arbitrary 8-bit data, so we allow bytes here - if isinstance(value, (six.string_types, bytes)): + if isinstance(value, (str, bytes)): value = self._value_map.get(value, value) if value is None or value == "": value = [] - elif isinstance(value, (six.string_types, bytes)): + elif isinstance(value, (str, bytes)): value = self._parse_str(value) if not isinstance(value, list): # Only accept lists for literal string form. @@ -601,7 +594,7 @@ def value(self, value): v = "" elif isinstance(v, (bool, int)): v = str(v) - elif not isinstance(v, six.string_types): + elif not isinstance(v, str): # Only string values are allowed. raise InvalidPropertyValueError(prop=self.name, value=value) self._is_allowed(v) @@ -621,11 +614,11 @@ class PropDictionaryList(PropList): @PropDefined.value.setter def value(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): value = self._value_map.get(value, value) if value is None or value == "": value = [] - elif isinstance(value, six.string_types): + elif isinstance(value, str): value = self._parse_str(value) if not isinstance(value, list): # Only accept lists for literal string form. @@ -682,7 +675,6 @@ def _is_allowed(self, value): Property._is_allowed(self, val) -@python_2_unicode_compatible class PropSimpleList(PropList): """Class representing a property with a list of string values that are simple in nature. Output is in a comma-separated format that may not @@ -724,7 +716,7 @@ def _parse_str(self, value): try: v = misc.force_str(v) except ValueError: - if not isinstance(v, six.text_type): + if not isinstance(v, str): try: v = v.decode("utf-8") except ValueError: @@ -857,7 +849,7 @@ def __str__(self): @Property.value.setter def value(self, value): - if isinstance(value, six.string_types): + if isinstance(value, str): value = self._value_map.get(value, value) if value is None or value == "": value = "0" @@ -873,7 +865,6 @@ def value(self, value): self._value = nvalue -@python_2_unicode_compatible class PropertySection(object): """A class representing a section of the configuration that also provides an interface for adding and managing properties and sections @@ -887,7 +878,7 @@ class PropertySection(object): def __init__(self, name, properties=misc.EmptyI): if ( - not isinstance(name, six.string_types) + not isinstance(name, str) or not self.__name_re.match(name) or name == "CONFIGURATION" ): @@ -929,7 +920,7 @@ def __copy__(self): return propsec def __str__(self): - return six.text_type(self.name) + return str(self.name) def add_property(self, prop): """Adds the specified property object to the section. The @@ -980,7 +971,7 @@ class PropertySectionTemplate(object): """ def __init__(self, name_pattern, properties=misc.EmptyI): - if not isinstance(name_pattern, six.string_types) or not name_pattern: + if not isinstance(name_pattern, str) or not name_pattern: raise InvalidSectionTemplateNameError(section=name_pattern) self.__name = name_pattern try: @@ -1022,7 +1013,6 @@ def name(self): return self.__name -@python_2_unicode_compatible class Config(object): """The Config class provides basic in-memory management of configuration data.""" @@ -1069,7 +1059,7 @@ def __str__(self): for sec, props in self.get_properties(): out += "[{0}]\n".format(sec.name) for p in props: - out += "{0} = {1}\n".format(p.name, six.text_type(p)) + out += "{0} = {1}\n".format(p.name, str(p)) out += "\n" return out diff --git a/src/modules/cpiofile.py b/src/modules/cpiofile.py index 5ef4e613f..88f341f41 100644 --- a/src/modules/cpiofile.py +++ b/src/modules/cpiofile.py @@ -31,7 +31,6 @@ # Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function # --------- # Imports @@ -44,7 +43,6 @@ import stat import time import struct -from six.moves import range import pkg.pkgsubprocess as subprocess # cpio magic numbers diff --git a/src/modules/depotcontroller.py b/src/modules/depotcontroller.py index a25c97178..c8dd30ec0 100755 --- a/src/modules/depotcontroller.py +++ b/src/modules/depotcontroller.py @@ -22,7 +22,7 @@ # Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function +import http.client import os import platform import shlex @@ -32,10 +32,9 @@ import sys import time -from six.moves import http_client, range -from six.moves.urllib.error import HTTPError, URLError -from six.moves.urllib.request import pathname2url, urlopen -from six.moves.urllib.parse import urlunparse, urljoin +from urllib.error import HTTPError, URLError +from urllib.request import pathname2url, urlopen +from urllib.parse import urlunparse, urljoin import pkg.pkgsubprocess as subprocess import pkg.server.repository as sr @@ -295,7 +294,7 @@ def __network_ping(self): except HTTPError as e: # Server returns NOT_MODIFIED if catalog is up # to date - if e.code == http_client.NOT_MODIFIED: + if e.code == http.client.NOT_MODIFIED: return True else: return False @@ -484,7 +483,7 @@ def start(self): def start_expected_fail(self, exit=2): """Start the depot, and make sure that it responds in a reasonable time - and that it exits immediately with the expected exit code.""" + and that it exits immediately with the expected exit code.""" try: self.__initial_start() diff --git a/src/modules/digest.py b/src/modules/digest.py index 0ee30847d..66fdbb903 100644 --- a/src/modules/digest.py +++ b/src/modules/digest.py @@ -25,7 +25,6 @@ # import hashlib -import six try: import pkg.sha512_t @@ -247,7 +246,7 @@ class ContentHash(dict): def __init__(self, vals): dict.__init__(self) - if isinstance(vals, six.string_types): + if isinstance(vals, str): vals = (vals,) for v in vals: diff --git a/src/modules/facet.py b/src/modules/facet.py index 43bce8c17..1f9cd6085 100644 --- a/src/modules/facet.py +++ b/src/modules/facet.py @@ -524,14 +524,9 @@ def inherited(self): self.__inherited_ro = ImmutableDict(self.__inherited) return self.__inherited_ro - if six.PY3: + def allow_action(self, action, publisher=None): + return _allow_facet(self, action, publisher=publisher) - def allow_action(self, action, publisher=None): - return _allow_facet(self, action, publisher=publisher) - - -if six.PY2: - Facets.allow_action = types.MethodType(_allow_facet, None, Facets) # Vim hints # vim:ts=4:sw=4:et:fdm=marker diff --git a/src/modules/flavor/smf_manifest.py b/src/modules/flavor/smf_manifest.py index 82c2da0db..cb0e155c0 100644 --- a/src/modules/flavor/smf_manifest.py +++ b/src/modules/flavor/smf_manifest.py @@ -25,7 +25,6 @@ # import os.path -import six import xml.dom.minidom as minidom import xml.parsers import xml.parsers.expat @@ -51,7 +50,7 @@ def __init__(self, action, path, pkg_vars, proto_dir): """See __init__ for PublishingDependency.""" self.manifest = path full_paths = None - if isinstance(path, six.string_types): + if isinstance(path, str): base_names = [os.path.basename(path)] paths = [os.path.dirname(path)] diff --git a/src/modules/fmri.py b/src/modules/fmri.py index cf961bc2a..0a8bd2c7f 100644 --- a/src/modules/fmri.py +++ b/src/modules/fmri.py @@ -26,7 +26,7 @@ import fnmatch import re -from six.moves.urllib.parse import quote +from urllib.parse import quote from pkg.version import Version, VersionError diff --git a/src/modules/indexer.py b/src/modules/indexer.py index 7dfd37d33..1180171f0 100644 --- a/src/modules/indexer.py +++ b/src/modules/indexer.py @@ -29,7 +29,7 @@ import os import platform import shutil -from six.moves.urllib.parse import unquote +from urllib.parse import unquote import pkg.fmri as fmri import pkg.misc as misc diff --git a/src/modules/lint/base.py b/src/modules/lint/base.py index 6e75da248..143615bf4 100644 --- a/src/modules/lint/base.py +++ b/src/modules/lint/base.py @@ -24,11 +24,10 @@ # Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. # +import configparser import inspect import os.path -import six import traceback -from six.moves import configparser import pkg.variant as variant import pkg.fmri as fmri @@ -418,7 +417,7 @@ def _linted_action(action, lint_id): for key in action.attrs.keys(): if key.startswith("pkg.linted") and linted.startswith(key): val = action.attrs.get(key, "false") - if isinstance(val, six.string_types): + if isinstance(val, str): if val.lower() == "true": return True else: @@ -436,7 +435,7 @@ def _linted_manifest(manifest, lint_id): for key in manifest.attributes.keys(): if key.startswith("pkg.linted") and linted.startswith(key): val = manifest.attributes.get(key, "false") - if isinstance(val, six.string_types): + if isinstance(val, str): if val.lower() == "true": return True else: diff --git a/src/modules/lint/config.py b/src/modules/lint/config.py index 5f664f904..15ac2d098 100644 --- a/src/modules/lint/config.py +++ b/src/modules/lint/config.py @@ -28,10 +28,9 @@ # aspects of pkglint configuration import os -import six +import configparser from collections import OrderedDict -from six.moves import configparser defaults = { "log_level": "INFO", diff --git a/src/modules/lint/engine.py b/src/modules/lint/engine.py index 72681ffc9..13c4125bf 100644 --- a/src/modules/lint/engine.py +++ b/src/modules/lint/engine.py @@ -34,13 +34,12 @@ from pkg.client.api_errors import ApiException from pkg.version import DotSequence, Version +import configparser import logging import os import shutil -import six import sys -from six.moves import configparser -from six.moves.urllib.parse import urlparse, quote +from urllib.parse import urlparse, quote PKG_CLIENT_NAME = "pkglint" CLIENT_API_VERSION = 82 @@ -1239,7 +1238,7 @@ def get_param(self, key, action=None, manifest=None): if manifest and param_key in manifest: val = manifest[param_key] if val: - if isinstance(val, six.string_types): + if isinstance(val, str): return val else: return " ".join(val) diff --git a/src/modules/lint/log.py b/src/modules/lint/log.py index 1b33389cb..301128819 100644 --- a/src/modules/lint/log.py +++ b/src/modules/lint/log.py @@ -26,7 +26,6 @@ import logging import os -import six import sys from pkg.lint.base import DuplicateLintedAttrException, linted diff --git a/src/modules/lint/pkglint_action.py b/src/modules/lint/pkglint_action.py index 18897a350..5e7618da3 100644 --- a/src/modules/lint/pkglint_action.py +++ b/src/modules/lint/pkglint_action.py @@ -1554,7 +1554,7 @@ def valid_fmri(self, action, manifest, engine, pkglint_id="006"): if "fmri" not in action.attrs: return fmris = action.attrs["fmri"] - if isinstance(fmris, six.string_types): + if isinstance(fmris, str): fmris = [fmris] for fmri in fmris: diff --git a/src/modules/lint/pkglint_manifest.py b/src/modules/lint/pkglint_manifest.py index dde8181c2..4b50cb1d8 100644 --- a/src/modules/lint/pkglint_manifest.py +++ b/src/modules/lint/pkglint_manifest.py @@ -28,8 +28,7 @@ # Some pkg(7) specific lint manifest checks import os.path -import six -from six.moves import configparser +import configparser import pkg.fmri as fmri import pkg.lint.base as base @@ -77,7 +76,7 @@ def seed_depend_dict(mf, dic): continue dep = action.attrs["fmri"] try: - if isinstance(dep, six.string_types): + if isinstance(dep, str): f = fmri.PkgFmri(dep) dic.setdefault(f.get_name(), []).append(name) elif isinstance(dep, list): @@ -459,7 +458,7 @@ def duplicate_deps(self, manifest, engine, pkglint_id="005"): continue deps = action.attrs["fmri"] - if isinstance(deps, six.string_types): + if isinstance(deps, str): deps = [deps] for dep in deps: diff --git a/src/modules/manifest.py b/src/modules/manifest.py index 96de0c797..7b11f8cd0 100644 --- a/src/modules/manifest.py +++ b/src/modules/manifest.py @@ -25,7 +25,6 @@ # Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # -from __future__ import print_function from collections import namedtuple, defaultdict from functools import reduce @@ -38,7 +37,6 @@ import tempfile from itertools import groupby, chain, product, repeat from operator import itemgetter -from six.moves import zip import pkg.actions as actions import pkg.client.api_errors as apx @@ -1060,7 +1058,7 @@ def __content_to_actions(self, content): lineno = 0 errors = [] - if isinstance(content, six.string_types): + if isinstance(content, str): # Get an iterable for the string. content = content.splitlines() @@ -1134,10 +1132,10 @@ def set_content( except EnvironmentError as e: raise apx._convert_error(e) - if six.PY3 and isinstance(content, bytes): + if isinstance(content, bytes): raise TypeError("content must be str, not bytes") - if isinstance(content, six.string_types): + if isinstance(content, str): if signatures: # Generate manifest signature based upon # input content, but only if signatures @@ -1516,16 +1514,9 @@ def _get_varcets(self, excludes=EmptyI): # allow you to be selective and various bits in # pkg.manifest assume you always filter on both so we # have to fake up a filter for facets. - if six.PY2: - nexcludes = [ - x for x in excludes if x.__func__ != facet._allow_facet - ] - else: - nexcludes = [ - x - for x in excludes - if x.__func__ != facet.Facets.allow_action - ] + nexcludes = [ + x for x in excludes if x.__func__ != facet.Facets.allow_action + ] # Excludes list must always have zero or 2+ items; so # fake second entry. nexcludes.append(lambda x, publisher: True) diff --git a/src/modules/mediator.py b/src/modules/mediator.py index 22a3ed49d..4a48d5482 100644 --- a/src/modules/mediator.py +++ b/src/modules/mediator.py @@ -23,7 +23,6 @@ # Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. import re -import six import pkg.misc as misc import pkg.version as version @@ -34,7 +33,7 @@ def valid_mediator(value): string is a valid name for a link mediation. 'valid' is a boolean and 'error' is None or a string containing the error.""" - if isinstance(value, six.string_types): + if isinstance(value, str): if re.match(r"^[a-zA-Z0-9\-]+$", value): return True, None return False, _( @@ -49,7 +48,7 @@ def valid_mediator_version(value): a boolean and 'error' is None or a string containing the error.""" error = "" - if isinstance(value, six.string_types): + if isinstance(value, str): try: version.Version(value) return True, None @@ -70,7 +69,7 @@ def parse_mediator_implementation(value): object representing the version. If the implementation is not valid a tuple of (None, None) will be returned.""" - if not isinstance(value, six.string_types): + if not isinstance(value, str): return None, None if "@" in value: @@ -102,7 +101,7 @@ def valid_mediator_implementation(value, allow_empty_version=False): error = "" iname = iver = None - if isinstance(value, six.string_types): + if isinstance(value, str): if "@" in value: iname, iver = value.rsplit("@", 1) else: diff --git a/src/modules/misc.py b/src/modules/misc.py index 49559737f..fa43ac3f1 100644 --- a/src/modules/misc.py +++ b/src/modules/misc.py @@ -59,6 +59,7 @@ from collections import defaultdict from io import BytesIO from io import StringIO +from itertools import zip_longest from operator import itemgetter from stat import ( @@ -80,14 +81,11 @@ S_IXOTH, ) -# Redefining built-in 'range'; pylint: disable=W0622 -# Module 'urllib' has no 'parse' member; pylint: disable=E1101 -from six.moves import range, zip_longest -from six.moves.urllib.parse import urlsplit, urlparse, urlunparse -from six.moves.urllib.request import pathname2url, url2pathname - import six +from urllib.parse import urlsplit, urlparse, urlunparse +from urllib.request import pathname2url, url2pathname + import pkg.client.api_errors as api_errors import pkg.json as json import pkg.portable as portable @@ -555,15 +553,17 @@ def setlocale(category, loc=None, printer=None): else: # Since no locale was given, try to determine what global # locale setting setlocale used. - for variable in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'): + for variable in ("LC_ALL", "LC_CTYPE", "LANG", "LANGUAGE"): localename = os.environ.get(variable, None) if localename: dl = locale.normalize(localename) break else: dl = "" - printer(f"Unable to set locale {dl}; locale package may be broken or\n" - "not installed. Reverting to C locale.") + printer( + "Unable to set locale{0}; locale package may be broken or\n" + "not installed. Reverting to C locale.".format(dl) + ) locale.setlocale(category, "C") @@ -673,7 +673,7 @@ def get_data_digest( bufsz = PKG_FILE_BUFSIZ closefobj = False - if isinstance(data, six.string_types): + if isinstance(data, str): f = open(data, "rb", bufsz) closefobj = True else: @@ -835,7 +835,7 @@ def compute_compressed_attrs( fobj = _GZWriteWrapper(opath, chashes) ofile = PkgGzipFile(mode="wb", fileobj=fobj) - if isinstance(data, (six.string_types, bytes)): + if isinstance(data, (str, bytes)): # caller passed data in string nbuf = size // bufsz for n in range(0, nbuf): @@ -1964,7 +1964,7 @@ def set_value(entry): # any explicitly named fields are only included if 'json' # is explicitly listed. def fmt_val(v): - if isinstance(v, six.string_types): + if isinstance(v, str): return v if isinstance(v, (list, tuple, set, frozenset)): return [fmt_val(e) for e in v] @@ -2064,8 +2064,8 @@ def flush_output(): json_types_immediates = ( bool, float, - six.integer_types, - six.string_types, + int, + str, type(None), ) json_types_collections = (dict, list) @@ -2206,16 +2206,6 @@ def je_return(name, data, finish, je_state): data_type, name, desc_type, data ) - # The following situation is only true for Python 2. - # We should not see unicode strings getting passed in. The assert is - # necessary since we use the PkgDecoder hook function during json_decode - # to convert unicode objects back into escaped str objects, which would - # otherwise do that conversion unintentionally. - if six.PY2: - assert not isinstance( - data_type, six.text_type - ), "unexpected unicode string: {0}".format(data) - # we don't need to do anything for basic types for t in json_types_immediates: if issubclass(desc_type, t): @@ -2655,9 +2645,9 @@ def json_hook(dct): rvdct = {} for k, v in six.iteritems(dct): - if isinstance(k, six.string_types): + if isinstance(k, str): k = force_str(k) - if isinstance(v, six.string_types): + if isinstance(v, str): v = force_str(v) rvdct[k] = v @@ -2927,15 +2917,6 @@ def get_runtime_proxy(proxy, uri): def decode(s): """convert non-ascii strings to unicode; replace non-convertable chars""" - if six.PY3: - return s - try: - # this will fail if any 8 bit chars in string - # this is a nop if string is ascii. - s = s.encode("ascii") - except ValueError: - # this will encode 8 bit strings into unicode - s = s.decode("utf-8", "replace") return s @@ -3139,45 +3120,6 @@ def suggest_known_words(text, known_words): return [c[0] for c in sorted(candidates, key=itemgetter(1))] -def force_bytes(s, encoding="utf-8", errors="strict"): - """Force the string into bytes.""" - - if isinstance(s, bytes): - if encoding == "utf-8": - return s - return s.decode("utf-8", errors).encode(encoding, errors) - elif isinstance(s, six.string_types): - # this case is: unicode in Python 2 and str in Python 3 - return s.encode(encoding, errors) - elif six.PY3: - # type not a string and Python 3's bytes() requires - # a string argument - return six.text_type(s).encode(encoding) - # type not a string - return bytes(s) - - -def force_text(s, encoding="utf-8", errors="strict"): - """Force the string into text.""" - - if isinstance(s, six.text_type): - return s - if isinstance(s, six.string_types): - # this case is: str(bytes) in Python 2 - return s.decode(encoding, errors) - elif isinstance(s, bytes): - # this case is: bytes in Python 3 - return s.decode(encoding, errors) - # type not a string - return six.text_type(s) - - -if six.PY3: - force_str = force_text -else: - force_str = force_bytes - - def open_image_file(root, path, flag, mode=None): """Open 'path' ensuring that we don't follow a symlink which may lead outside of the specified image. @@ -3291,45 +3233,32 @@ def force_bytes(s, encoding="utf-8", errors="strict"): if isinstance(s, bytes): return s try: - if isinstance(s, six.string_types): - # this case is: unicode in Python 2 and str in Python 3 + if isinstance(s, str): return s.encode(encoding, errors) - elif six.PY3: - # type not a string and Python 3's bytes() requires - # a string argument - return six.text_type(s).encode(encoding) - # type not a string - s = bytes(s) + else: + # type not a string + return str(s).encode(encoding) except UnicodeEncodeError: raise - return s def force_text(s, encoding="utf-8", errors="strict"): """Force the string into text.""" - if isinstance(s, six.text_type): + if isinstance(s, str): return s try: - if isinstance(s, (six.string_types, bytes)): - # this case is: str(bytes) in Python 2 and bytes in - # Python 3 + if isinstance(s, bytes): s = s.decode(encoding, errors) else: # type not a string - s = six.text_type(s) + s = str(s) except UnicodeDecodeError as e: raise api_errors.PkgUnicodeDecodeError(s, *e.args) return s -# force_str minimizes the work for compatible string handling between Python -# 2 and 3 because we will have the native string type in its runtime, that is, -# bytes in Python 2 and unicode string in Python 3. -if six.PY2: - force_str = force_bytes -else: - force_str = force_text +force_str = force_text FILE_DESCRIPTOR_LIMIT = 4096 diff --git a/src/modules/mogrify.py b/src/modules/mogrify.py index ee3875b00..56fb6880f 100755 --- a/src/modules/mogrify.py +++ b/src/modules/mogrify.py @@ -24,7 +24,6 @@ # -from __future__ import print_function import os import re import shlex @@ -257,7 +256,7 @@ def replace_func(action, matches, pkg_attrs, filename, lineno): # It's now appropriate to compile the regexp, if there # are substitutions to be made. So do the substitution # and compile the result. - if isinstance(regexp, six.string_types): + if isinstance(regexp, str): rx = re.compile( substitute_values( regexp, action, matches, pkg_attrs, filename, lineno @@ -468,7 +467,7 @@ def q(s): if not d["quote"]: q = lambda x: x - if isinstance(attr, six.string_types): + if isinstance(attr, str): newmsg += ( msg[prevend : i.start()] + d.get("prefix", "") @@ -606,7 +605,7 @@ def apply_transforms( if verbose: if ( not action - or not isinstance(action, six.string_types) + or not isinstance(action, str) and orig_attrs != action.attrs ): comments.append( @@ -615,13 +614,13 @@ def apply_transforms( ) ) comments.append("# Result: {0}".format(action)) - if not action or isinstance(action, six.string_types): + if not action or isinstance(action, str): break # Any newly-created actions need to have the transforms applied, too. newnewactions = [] for act in newactions: - if not isinstance(act, six.string_types): + if not isinstance(act, str): c, al = apply_transforms( transforms, act, pkg_attrs, verbose, act_filename, act_lineno ) @@ -884,7 +883,7 @@ def process_mog( if act.name == "set": name = act.attrs["name"] value = act.attrs["value"] - if isinstance(value, six.string_types): + if isinstance(value, str): pkg_attrs.setdefault(name, []).append(value) else: pkg_attrs.setdefault(name, []).extend(value) diff --git a/src/modules/p5i.py b/src/modules/p5i.py index 8581170e6..59343f9e1 100644 --- a/src/modules/p5i.py +++ b/src/modules/p5i.py @@ -27,9 +27,9 @@ import os -from six.moves.urllib.error import HTTPError -from six.moves.urllib.parse import urlunparse -from six.moves.urllib.request import urlopen, pathname2url +from urllib.error import HTTPError +from urllib.parse import urlunparse +from urllib.request import urlopen, pathname2url import pkg.client.api_errors as api_errors import pkg.client.publisher as publisher diff --git a/src/modules/p5p.py b/src/modules/p5p.py index 4cc9c8a1a..bccdf8047 100644 --- a/src/modules/p5p.py +++ b/src/modules/p5p.py @@ -30,10 +30,9 @@ import tarfile as tf import os import shutil -import six import sys import tempfile -from six.moves.urllib.parse import unquote +from urllib.parse import unquote import pkg import pkg.client.api_errors as apx @@ -746,7 +745,7 @@ def add_package(self, pfmri, mpath, fpath): """ assert pfmri and mpath and fpath - if isinstance(pfmri, six.string_types): + if isinstance(pfmri, str): pfmri = pkg.fmri.PkgFmri(pfmri) assert pfmri.publisher self.__add_package(pfmri, mpath, fpath=fpath) @@ -766,7 +765,7 @@ def add_repo_package(self, pfmri, repo): """ assert pfmri and repo - if isinstance(pfmri, six.string_types): + if isinstance(pfmri, str): pfmri = pkg.fmri.PkgFmri(pfmri) assert pfmri.publisher self.__add_package(pfmri, repo.manifest(pfmri), repo=repo) @@ -943,7 +942,7 @@ def extract_package_manifest(self, pfmri, path, filename=""): assert not self.__closed and "r" in self.__mode assert pfmri and path - if isinstance(pfmri, six.string_types): + if isinstance(pfmri, str): pfmri = pkg.fmri.PkgFmri(pfmri) assert pfmri.publisher @@ -1137,7 +1136,7 @@ def get_package_manifest(self, pfmri, raw=False): assert not self.__closed and "r" in self.__mode assert pfmri - if isinstance(pfmri, six.string_types): + if isinstance(pfmri, str): pfmri = pkg.fmri.PkgFmri(pfmri) assert pfmri.publisher diff --git a/src/modules/p5s.py b/src/modules/p5s.py index 8ace6b13e..e3176cdd3 100644 --- a/src/modules/p5s.py +++ b/src/modules/p5s.py @@ -27,7 +27,7 @@ import copy import os -from six.moves.urllib.parse import urlparse, urlunparse +from urllib.parse import urlparse, urlunparse import pkg.client.api_errors as api_errors import pkg.client.publisher as publisher diff --git a/src/modules/pipeutils.py b/src/modules/pipeutils.py index e06c04a9b..8f41b2654 100644 --- a/src/modules/pipeutils.py +++ b/src/modules/pipeutils.py @@ -68,12 +68,13 @@ del client_rpc """ -from __future__ import print_function import errno +import http.client import fcntl import logging import os import socket +import socketserver import stat import struct import sys @@ -97,9 +98,7 @@ # # Unused import; pylint: disable=W0611 from jsonrpclib import ProtocolError as ProtocolError1 - -from six.moves import socketserver, http_client -from six.moves.xmlrpc_client import ProtocolError as ProtocolError2 +from xmlrpc.client import ProtocolError as ProtocolError2 # Unused import; pylint: enable=W0611 @@ -373,7 +372,7 @@ def setsockopt(self, *args): # PipedHTTP: Class has no __init__ method; pylint: disable=W0232 # PipedHTTPResponse.begin: Attribute 'will_close' defined outside __init__; # pylint: disable=W0201 -class PipedHTTPResponse(http_client.HTTPResponse): +class PipedHTTPResponse(http.client.HTTPResponse): """Create a httplib.HTTPResponse like object that can be used with a pipe as a transport. We override the minimum number of parent routines necessary.""" @@ -382,12 +381,12 @@ def begin(self): """Our connection will never be automatically closed, so set will_close to False.""" - http_client.HTTPResponse.begin(self) + http.client.HTTPResponse.begin(self) self.will_close = False return -class PipedHTTPConnection(http_client.HTTPConnection): +class PipedHTTPConnection(http.client.HTTPConnection): """Create a httplib.HTTPConnection like object that can be used with a pipe as a transport. We override the minimum number of parent routines necessary.""" @@ -399,7 +398,7 @@ def __init__(self, fd, port=None): assert port is None # invoke parent constructor - http_client.HTTPConnection.__init__(self, "localhost") + http.client.HTTPConnection.__init__(self, "localhost") # self.sock was initialized by httplib.HTTPConnection # to point to a socket, overwrite it with a pipe. diff --git a/src/modules/portable/os_sunos.py b/src/modules/portable/os_sunos.py index 2b2082499..fae7494a5 100644 --- a/src/modules/portable/os_sunos.py +++ b/src/modules/portable/os_sunos.py @@ -31,7 +31,6 @@ """ import os -import six import subprocess import tempfile diff --git a/src/modules/pspawn.py b/src/modules/pspawn.py index 040bf85f8..44e493a8d 100644 --- a/src/modules/pspawn.py +++ b/src/modules/pspawn.py @@ -27,7 +27,6 @@ from __future__ import unicode_literals, print_function import os -import six from pkg._pspawn import lib, ffi @@ -97,7 +96,7 @@ def add_open(self, fd, path, oflag, mode): if not isinstance(fd, int): raise TypeError("fd must be int type") - if not isinstance(path, six.string_types): + if not isinstance(path, str): raise TypeError("path must be a string") if not isinstance(oflag, int): raise TypeError("oflag must be int type") @@ -154,7 +153,7 @@ def posix_spawnp(filename, args, fileactions=None, env=None): 'env', the enviroment, if provided, it must be a sequence object.""" - if not isinstance(filename, six.string_types): + if not isinstance(filename, str): raise TypeError("filename must be a string") pid = ffi.new("pid_t *") @@ -163,7 +162,7 @@ def posix_spawnp(filename, args, fileactions=None, env=None): # This essentially does force_bytes in pkg.misc, but importing pkg.misc has # a circular import issue, so we implement the conversion here. for arg in args: - if six.PY3 and isinstance(arg, six.string_types): + if isinstance(arg, str): arg = arg.encode() spawn_args.append(ffi.new("char []", arg)) spawn_args.append(ffi.NULL) @@ -173,7 +172,7 @@ def posix_spawnp(filename, args, fileactions=None, env=None): if env: for arg in env: try: - if six.PY3 and isinstance(arg, six.string_types): + if isinstance(arg, str): arg = arg.encode() spawn_env.append(ffi.new("char []", arg)) except: diff --git a/src/modules/publish/dependencies.py b/src/modules/publish/dependencies.py index b7520af8c..90128d35f 100644 --- a/src/modules/publish/dependencies.py +++ b/src/modules/publish/dependencies.py @@ -32,7 +32,7 @@ import six from collections import namedtuple -from six.moves.urllib.parse import unquote +from urllib.parse import unquote import pkg.actions as actions import pkg.client.api as api @@ -764,9 +764,9 @@ def make_paths(file_dep): rps = file_dep.attrs.get(paths_prefix, [""]) files = file_dep.attrs[files_prefix] - if isinstance(files, six.string_types): + if isinstance(files, str): files = [files] - if isinstance(rps, six.string_types): + if isinstance(rps, str): rps = [rps] return [os.path.join(rp, f) for rp in rps for f in files] @@ -1164,7 +1164,7 @@ def merge_deps(dest, src): elif v != dest.attrs[k]: # For now, just merge the values. Duplicate values # will be removed in a later step. - if isinstance(v, six.string_types): + if isinstance(v, str): v = [v] if isinstance(dest.attrs[k], list): dest.attrs[k].extend(v) diff --git a/src/modules/publish/transaction.py b/src/modules/publish/transaction.py index 8aa30eb02..6b00ef9e0 100644 --- a/src/modules/publish/transaction.py +++ b/src/modules/publish/transaction.py @@ -31,7 +31,7 @@ import os import shutil import six -from six.moves.urllib.parse import quote, unquote, urlparse, urlunparse +from urllib.parse import quote, unquote, urlparse, urlunparse import tempfile from pkg.misc import EmptyDict diff --git a/src/modules/query_parser.py b/src/modules/query_parser.py index ca8a8b8b2..339c988d0 100644 --- a/src/modules/query_parser.py +++ b/src/modules/query_parser.py @@ -24,11 +24,9 @@ # Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import os import fnmatch import re -import six import sys import threading import copy diff --git a/src/modules/search_storage.py b/src/modules/search_storage.py index 6e33b6c85..db7769a4f 100644 --- a/src/modules/search_storage.py +++ b/src/modules/search_storage.py @@ -28,7 +28,7 @@ import errno import time import hashlib -from six.moves.urllib.parse import quote, unquote +from urllib.parse import quote, unquote import pkg.fmri as fmri import pkg.search_errors as search_errors diff --git a/src/modules/server/depot.py b/src/modules/server/depot.py index 99dc496ac..63f93c3dc 100644 --- a/src/modules/server/depot.py +++ b/src/modules/server/depot.py @@ -44,11 +44,13 @@ import atexit import ast import errno +import http.client import inspect import io import itertools import math import os +import queue import random import re import shutil @@ -59,8 +61,7 @@ import threading import time -from six.moves import cStringIO, http_client, queue -from six.moves.urllib.parse import quote, urlunsplit +from urllib.parse import quote, urlunsplit # Without the below statements, tarfile will trigger calls to getpwuid and # getgrgid for every file downloaded. This in turn leads to nscd usage which @@ -429,7 +430,7 @@ def default(self, *tokens, **params): if op in self.REPO_OPS_DEFAULT and op not in self.vops: raise cherrypy.HTTPError( - http_client.NOT_FOUND, + http.client.NOT_FOUND, "Operation not supported in current server mode.", ) elif op not in self.vops: @@ -448,17 +449,17 @@ def default(self, *tokens, **params): ver = int(tokens[2]) except IndexError: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, "Missing version\n" + http.client.BAD_REQUEST, "Missing version\n" ) except ValueError: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, "Non-integer version\n" + http.client.BAD_REQUEST, "Non-integer version\n" ) if ver not in self.vops[op]: # 'version' is not supported for the operation. raise cherrypy.HTTPError( - http_client.NOT_FOUND, + http.client.NOT_FOUND, "Version '{0}' not supported for operation '{1}'\n".format( ver, op ), @@ -466,7 +467,7 @@ def default(self, *tokens, **params): elif op == "open" and pub not in self.repo.publishers: if not misc.valid_pub_prefix(pub): raise cherrypy.HTTPError( - http_client.BAD_REQUEST, + http.client.BAD_REQUEST, "Invalid publisher prefix: {0}\n".format(pub), ) @@ -482,13 +483,13 @@ def default(self, *tokens, **params): raise cherrypy.InternalRedirect(rel_uri) elif pub: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, "Unknown publisher: {0}\n".format(pub) + http.client.BAD_REQUEST, "Unknown publisher: {0}\n".format(pub) ) # Assume 'version' is not supported for the operation for some # other reason. raise cherrypy.HTTPError( - http_client.NOT_FOUND, + http.client.NOT_FOUND, "Version '{0}' not " "supported for operation '{1}'\n".format(ver, op), ) @@ -539,13 +540,13 @@ def search_0(self, *tokens): try: res_list = self.repo.search(query_args_lst, pub=self._get_req_pub()) except srepo.RepositorySearchUnavailableError as e: - raise cherrypy.HTTPError(http_client.SERVICE_UNAVAILABLE, str(e)) + raise cherrypy.HTTPError(http.client.SERVICE_UNAVAILABLE, str(e)) except srepo.RepositoryError as e: # Treat any remaining repository error as a 404, but # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) # Translate the results from v1 format into what a v0 # searcher expects as results. @@ -583,25 +584,25 @@ def search_1(self, *args, **params): query_str_lst = list(params.values()) elif list(params.values()): raise cherrypy.HTTPError( - http_client.BAD_REQUEST, + http.client.BAD_REQUEST, "args:{0}, params:{1}".format(args, params), ) if not query_str_lst: - raise cherrypy.HTTPError(http_client.BAD_REQUEST) + raise cherrypy.HTTPError(http.client.BAD_REQUEST) try: res_list = self.repo.search(query_str_lst, pub=self._get_req_pub()) except (ParseError, BooleanQueryException) as e: - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) except srepo.RepositorySearchUnavailableError as e: - raise cherrypy.HTTPError(http_client.SERVICE_UNAVAILABLE, str(e)) + raise cherrypy.HTTPError(http.client.SERVICE_UNAVAILABLE, str(e)) except srepo.RepositoryError as e: # Treat any remaining repository error as a 404, but # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) # In order to be able to have a return code distinguish between # no results and search unavailable, we need to use a different @@ -615,7 +616,7 @@ def search_1(self, *args, **params): tmp = next(res_list[0]) res_list = [itertools.chain([tmp], res_list[0])] except StopIteration: - cherrypy.response.status = http_client.NO_CONTENT + cherrypy.response.status = http.client.NO_CONTENT return response = cherrypy.response @@ -665,7 +666,7 @@ def catalog_0(self, *tokens): cat = self.repo.get_catalog(pub=self._get_req_pub()) except srepo.RepositoryError as e: cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) response = cherrypy.response response.headers["Content-type"] = "text/plain; charset=utf-8" @@ -700,7 +701,7 @@ def catalog_1(self, *tokens): name = tokens[0] except IndexError: raise cherrypy.HTTPError( - http_client.FORBIDDEN, _("Directory listing not allowed.") + http.client.FORBIDDEN, _("Directory listing not allowed.") ) try: @@ -710,7 +711,7 @@ def catalog_1(self, *tokens): # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) self.__set_response_expires("catalog", 86400, 86400) return serve_file(fpath, "text/plain; charset=utf-8") @@ -727,14 +728,14 @@ def manifest_0(self, *tokens): pubs = self.repo.publishers except Exception as e: cherrypy.log("Request failed: {0}".format(e)) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) # A broken proxy (or client) has caused a fully-qualified FMRI # to be split up. comps = [t for t in tokens] if not comps: raise cherrypy.HTTPError( - http_client.FORBIDDEN, _("Directory listing not allowed.") + http.client.FORBIDDEN, _("Directory listing not allowed.") ) if len(comps) > 1 and comps[0] == "pkg:" and comps[1] in pubs: @@ -751,13 +752,13 @@ def manifest_0(self, *tokens): pfmri = fmri.PkgFmri(pfmri, None) fpath = self.repo.manifest(pfmri, pub=self._get_req_pub()) except (IndexError, fmri.FmriError) as e: - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) except srepo.RepositoryError as e: # Treat any remaining repository error as a 404, but # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) # Send manifest self.__set_response_expires("manifest", 86400 * 365, 86400 * 365) @@ -775,7 +776,7 @@ def manifest_1(self, *tokens): elif method in ("POST", "PUT"): return self.__upload_manifest(*tokens) raise cherrypy.HTTPError( - http_client.METHOD_NOT_ALLOWED, "{0} is not allowed".format(method) + http.client.METHOD_NOT_ALLOWED, "{0} is not allowed".format(method) ) # We need to prevent cherrypy from processing the request body so that @@ -825,13 +826,13 @@ def file_0(self, *tokens): try: fpath = self.repo.file(fhash, pub=self._get_req_pub()) except srepo.RepositoryFileNotFoundError as e: - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) except srepo.RepositoryError as e: # Treat any remaining repository error as a 404, but # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) self.__set_response_expires("file", 86400 * 365, 86400 * 365) return serve_file(fpath, "application/data") @@ -848,7 +849,7 @@ def file_1(self, *tokens): elif method in ("POST", "PUT"): return self.__upload_file(*tokens) raise cherrypy.HTTPError( - http_client.METHOD_NOT_ALLOWED, "{0} is not allowed".format(method) + http.client.METHOD_NOT_ALLOWED, "{0} is not allowed".format(method) ) # We need to prevent cherrypy from processing the request body so that @@ -875,13 +876,13 @@ def file_2(self, *tokens): try: fpath = self.repo.file(fhash, pub=self._get_req_pub()) except srepo.RepositoryFileNotFoundError as e: - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) except srepo.RepositoryError as e: # Treat any remaining repository error as a 404, # but log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) csize, chashes = misc.compute_compressed_attrs( fhash, file_path=fpath @@ -925,7 +926,7 @@ def open_0(self, *tokens): # signed certificate (or a more elaborate system). if not pfmri: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, + http.client.BAD_REQUEST, _("A valid package FMRI must be specified."), ) @@ -938,7 +939,7 @@ def open_0(self, *tokens): # that to mean that the server doesn't support this # operation. cherrypy.log("Request failed: {0}".format(e)) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) if pfmri.publisher and not self._get_req_pub(): self.__map_pub_ops(pfmri.publisher) @@ -971,7 +972,7 @@ def append_0(self, *tokens): # signed certificate (or a more elaborate system). if not pfmri: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, + http.client.BAD_REQUEST, _("A valid package FMRI must be specified."), ) @@ -984,7 +985,7 @@ def append_0(self, *tokens): # that to mean that the server doesn't support this # operation. cherrypy.log("Request failed: {0}".format(e)) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) if pfmri.publisher and not self._get_req_pub(): self.__map_pub_ops(pfmri.publisher) @@ -1029,7 +1030,7 @@ def close_0(self, *tokens): add_to_catalog = False except ValueError as e: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, "X-IPkg-Add-To-Catalog".format(e) + http.client.BAD_REQUEST, "X-IPkg-Add-To-Catalog".format(e) ) try: @@ -1041,7 +1042,7 @@ def close_0(self, *tokens): # returned here as misc.versioned_urlopen will interpret # that to mean that the server doesn't support this # operation. - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) response = cherrypy.response response.headers["Package-FMRI"] = pfmri @@ -1132,12 +1133,12 @@ def admin_0(self, *tokens, **params): ) else: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, + http.client.BAD_REQUEST, "Unknown or unsupported operation: '{0}'".format(cmd), ) except queue.Full: raise cherrypy.HTTPError( - http_client.SERVICE_UNAVAILABLE, + http.client.SERVICE_UNAVAILABLE, "Another operation is already in progress; try " "again later.", ) @@ -1165,7 +1166,7 @@ def abandon_0(self, *tokens): # returned here as misc.versioned_urlopen will interpret # that to mean that the server doesn't support this # operation. - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) def add_0(self, *tokens): """Adds an action and its content to an in-flight transaction @@ -1186,7 +1187,7 @@ def add_0(self, *tokens): if entry_type not in actions.types: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, + http.client.BAD_REQUEST, _("The " "specified Action Type, '{0}', is not valid.").format( entry_type ), @@ -1211,7 +1212,7 @@ def add_0(self, *tokens): attrs[a] = val except ValueError: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, + http.client.BAD_REQUEST, _( "The " "specified Action attribute value, " @@ -1230,9 +1231,9 @@ def add_0(self, *tokens): action = actions.types[entry_type](data, **attrs) except actions.ActionError as e: cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) - # XXX Once actions are labelled with critical nature. + # XXX Once actions are labeled with critical nature. # if entry_type in critical_actions: # self.critical = True @@ -1244,7 +1245,7 @@ def add_0(self, *tokens): # that to mean that the server doesn't support this # operation. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) # We need to prevent cherrypy from processing the request body so that # add can parse the request body itself. In addition, we also need to @@ -1279,7 +1280,7 @@ def __upload_file(self, *tokens): size = int(request.headers.get("Content-Length", 0)) if size < 0: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, _("file/1 must be sent a file.") + http.client.BAD_REQUEST, _("file/1 must be sent a file.") ) data = request.rfile attrs = dict( @@ -1295,7 +1296,7 @@ def __upload_file(self, *tokens): # returned here as misc.versioned_urlopen will interpret # that to mean that the server doesn't support this # operation. - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) response.headers["Content-Length"] = "0" return response.body @@ -1317,7 +1318,7 @@ def __upload_manifest(self, *tokens): size = int(request.headers.get("Content-Length", 0)) if size < 0: raise cherrypy.HTTPError( - http_client.BAD_REQUEST, _("manifest/1 must be sent a file.") + http.client.BAD_REQUEST, _("manifest/1 must be sent a file.") ) data = request.rfile @@ -1328,7 +1329,7 @@ def __upload_manifest(self, *tokens): # returned here as misc.versioned_urlopen will interpret # that to mean that the server doesn't support this # operation. - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) response.headers["Content-Length"] = "0" return response.body @@ -1364,10 +1365,10 @@ def index_0(self, *tokens): else: err = "Unknown index subcommand: {0}".format(cmd) cherrypy.log(err) - raise cherrypy.HTTPError(http_client.NOT_FOUND, err) + raise cherrypy.HTTPError(http.client.NOT_FOUND, err) except queue.Full: raise cherrypy.HTTPError( - http_client.SERVICE_UNAVAILABLE, + http.client.SERVICE_UNAVAILABLE, "Another operation is already in progress; try " "again later.", ) @@ -1386,7 +1387,7 @@ def info_0(self, *tokens): pubs = self.repo.publishers except Exception as e: cherrypy.log("Request failed: {0}".format(e)) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) # A broken proxy (or client) has caused a fully-qualified FMRI # to be split up. @@ -1411,16 +1412,16 @@ def info_0(self, *tokens): pfmri.publisher = pub fpath = self.repo.manifest(pfmri, pub=pub) except (IndexError, fmri.FmriError) as e: - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) except srepo.RepositoryError as e: # Treat any remaining repository error as a 404, but # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) if not os.path.exists(fpath): - raise cherrypy.HTTPError(http_client.NOT_FOUND) + raise cherrypy.HTTPError(http.client.NOT_FOUND) m = manifest.Manifest(pfmri) m.set_content(pathname=fpath) @@ -1493,16 +1494,16 @@ def publisher_0(self, *tokens): # Publisher specified in request is unknown. e = srepo.RepositoryUnknownPublisher(prefix) cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) - buf = cStringIO() + buf = io.StringIO() try: p5i.write(buf, pubs) except Exception as e: # Treat any remaining error as a 404, but log it and # include the real failure information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) buf.seek(0) self.__set_response_expires("publisher", 86400 * 365, 86400 * 365) # Page handlers MUST return bytes. @@ -1527,16 +1528,16 @@ def publisher_1(self, *tokens): # a not found error to the client so it will # treat it as an unsupported operation. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) - buf = cStringIO() + buf = io.StringIO() try: p5i.write(buf, pubs) except Exception as e: # Treat any remaining error as a 404, but log it and # include the real failure information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) buf.seek(0) self.__set_response_expires("publisher", 86400 * 365, 86400 * 365) return buf.getvalue() @@ -1568,7 +1569,7 @@ def __get_matching_p5i_data(self, rstore, pfmri): # If this fails, it's ok to raise an exception since bad # input was likely provided. cherrypy.log("Request failed: {0}".format(e)) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) if not matches: return "" @@ -1584,7 +1585,7 @@ def __get_matching_p5i_data(self, rstore, pfmri): m.get_fmri(anarchy=True, include_scheme=False) for m in matches ] - buf = cStringIO() + buf = io.StringIO() pkg_names = {pub.prefix: matches} p5i.write(buf, [pub], pkg_names=pkg_names) buf.seek(0) @@ -1602,7 +1603,7 @@ def p5i_0(self, *tokens): pubs = self.repo.publishers except Exception as e: cherrypy.log("Request failed: {0}".format(e)) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) # A broken proxy (or client) has caused a fully-qualified FMRI # to be split up. @@ -1618,7 +1619,7 @@ def p5i_0(self, *tokens): # proxy behaviour. pfmri = "/".join(comps) except IndexError: - raise cherrypy.HTTPError(http_client.BAD_REQUEST) + raise cherrypy.HTTPError(http.client.BAD_REQUEST) # XXX This is a hack to deal with the fact that packagemanager # brokenly expects all p5i URIs or files to have a .p5i @@ -1640,7 +1641,7 @@ def p5i_0(self, *tokens): if output == "": raise cherrypy.HTTPError( - http_client.NOT_FOUND, + http.client.NOT_FOUND, _("No " "matching package found in repository."), ) @@ -1665,7 +1666,7 @@ def status_0(self, *tokens): ) except Exception as e: raise cherrypy.HTTPError( - http_client.NOT_FOUND, _("Unable to generate statistics.") + http.client.NOT_FOUND, _("Unable to generate statistics.") ) return misc.force_bytes(out + "\n") @@ -1769,12 +1770,12 @@ def __init__(self, repo, dconf): # are weighted by how often we want them to happen; the loop # below then puts them into a pick-list. errors = { - http_client.REQUEST_TIMEOUT: 10, - http_client.BAD_GATEWAY: 10, - http_client.GATEWAY_TIMEOUT: 10, - http_client.FORBIDDEN: 2, - http_client.NOT_FOUND: 2, - http_client.BAD_REQUEST: 2, + http.client.REQUEST_TIMEOUT: 10, + http.client.BAD_GATEWAY: 10, + http.client.GATEWAY_TIMEOUT: 10, + http.client.FORBIDDEN: 2, + http.client.NOT_FOUND: 2, + http.client.BAD_REQUEST: 2, } self.errlist = [] @@ -1852,9 +1853,9 @@ def nasty(self, *tokens): try: nasty_level = int(tokens[0]) except (IndexError, ValueError): - raise cherrypy.HTTPError(http_client.BAD_REQUEST) + raise cherrypy.HTTPError(http.client.BAD_REQUEST) if nasty_level < 0 or nasty_level > 100: - raise cherrypy.HTTPError(http_client.BAD_REQUEST) + raise cherrypy.HTTPError(http.client.BAD_REQUEST) cherrypy.log( "Nastiness set to {0:d} by client request".format(nasty_level) ) @@ -1875,7 +1876,7 @@ def versions_0(self, *tokens): if self.need_nasty_3(): cherrypy.log("NASTY versions_0: X-Ipkg-Error") response = cherrypy.response - response.status = http_client.UNAUTHORIZED + response.status = http.client.UNAUTHORIZED response.headers["X-Ipkg-Error"] = random.choice( ["ENT", "LIC", "SVR", "MNT", "YYZ", ""] ) @@ -1946,7 +1947,7 @@ def catalog_0(self, *tokens): # are toxic to clients who are facing a nasty antagonist-- # the client has no way to verify that the content, and # things go badly off the rails. - raise cherrypy.HTTPError(http_client.BAD_REQUEST) + raise cherrypy.HTTPError(http.client.BAD_REQUEST) catalog_0._cp_config = { "response.stream": True, @@ -1970,14 +1971,14 @@ def manifest_0(self, *tokens): pubs = self.repo.publishers except Exception as e: cherrypy.log("Request failed: {0}".format(e)) - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) # A broken proxy (or client) has caused a fully-qualified FMRI # to be split up. comps = [t for t in tokens] if not comps: raise cherrypy.HTTPError( - http_client.FORBIDDEN, _("Directory listing not allowed.") + http.client.FORBIDDEN, _("Directory listing not allowed.") ) if len(comps) > 1 and comps[0] == "pkg:" and comps[1] in pubs: @@ -1994,13 +1995,13 @@ def manifest_0(self, *tokens): pfmri = fmri.PkgFmri(pfmri, None) fpath = self.repo.manifest(pfmri, pub=self._get_req_pub()) except (IndexError, fmri.FmriError) as e: - raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e)) + raise cherrypy.HTTPError(http.client.BAD_REQUEST, str(e)) except srepo.RepositoryError as e: # Treat any remaining repository error as a 404, but # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) # NASTY # Stash manifest entry for later use. @@ -2042,13 +2043,13 @@ def file_0(self, *tokens): try: fpath = self.repo.file(fhash, pub=self._get_req_pub()) except srepo.RepositoryFileNotFoundError as e: - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) except srepo.RepositoryError as e: # Treat any remaining repository error as a 404, but # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) # NASTY # Stash filename for later use. @@ -2062,7 +2063,7 @@ def file_0(self, *tokens): if self.need_nasty_4(): # Forget that the file is here cherrypy.log("NASTY file_0: 404 NOT_FOUND") - raise cherrypy.HTTPError(http_client.NOT_FOUND) + raise cherrypy.HTTPError(http.client.NOT_FOUND) # NASTY # Send the wrong file @@ -2090,7 +2091,7 @@ def catalog_1(self, *tokens): name = tokens[0] except IndexError: raise cherrypy.HTTPError( - http_client.FORBIDDEN, _("Directory listing not allowed.") + http.client.FORBIDDEN, _("Directory listing not allowed.") ) try: @@ -2100,7 +2101,7 @@ def catalog_1(self, *tokens): # log the error and include the real failure # information. cherrypy.log("Request failed: {0}".format(str(e))) - raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e)) + raise cherrypy.HTTPError(http.client.NOT_FOUND, str(e)) # NASTY # Stash catalog entry for later use. @@ -2129,9 +2130,9 @@ def search_1(self, *args, **params): # Raise assorted errors; if not, call superclass search_1. if self.need_nasty(): errs = [ - http_client.NOT_FOUND, - http_client.BAD_REQUEST, - http_client.SERVICE_UNAVAILABLE, + http.client.NOT_FOUND, + http.client.BAD_REQUEST, + http.client.SERVICE_UNAVAILABLE, ] code = random.choice(errs) cherrypy.log("NASTY search_1: HTTP {0:d}".format(code)) @@ -2152,7 +2153,7 @@ def nasty_serve_file(self, filepath, content_type): filesz = fst.st_size nfile = open(filepath, "rb") except EnvironmentError: - raise cherrypy.HTTPError(http_client.NOT_FOUND) + raise cherrypy.HTTPError(http.client.NOT_FOUND) # NASTY # Send incorrect content length diff --git a/src/modules/server/face.py b/src/modules/server/face.py index feed16353..d196ae024 100644 --- a/src/modules/server/face.py +++ b/src/modules/server/face.py @@ -26,14 +26,13 @@ """face - provides the BUI (Browser User Interface) for the image packaging server""" -from __future__ import print_function import cherrypy import cherrypy.lib.static +import http.client import os import sys -from six.moves import http_client -from six.moves.urllib.parse import unquote +from urllib.parse import unquote import pkg.misc as misc import pkg.server.api as api @@ -65,12 +64,12 @@ def init(depot): def feed(depot, request, response, pub): if depot.repo.mirror: raise cherrypy.HTTPError( - http_client.NOT_FOUND, + http.client.NOT_FOUND, "Operation not supported in current server mode.", ) if not depot.repo.get_catalog(pub).updates: raise cherrypy.HTTPError( - http_client.SERVICE_UNAVAILABLE, + http.client.SERVICE_UNAVAILABLE, "No update history; unable to generate feed.", ) return pkg.server.feed.handle(depot, request, response, pub) @@ -92,7 +91,7 @@ def __handle_error(path, error): # All errors are treated as a 404 since reverse proxies such as Apache # don't handle 500 errors in a desirable way. For any error but a 404, # an error is logged. - if error != http_client.NOT_FOUND: + if error != http.client.NOT_FOUND: cherrypy.log( "Error encountered while processing " "template: {0}\n".format(path), @@ -144,7 +143,7 @@ def respond(depot, request, response, pub, http_depot=None): os.path.normpath(depot.web_root) ): # Ignore requests for files outside of the web root. - return __handle_error(path, http_client.NOT_FOUND) + return __handle_error(path, http.client.NOT_FOUND) else: return cherrypy.lib.static.serve_file( os.path.join(depot.web_root, spath) @@ -170,18 +169,18 @@ def respond(depot, request, response, pub, http_depot=None): "Ensure that the correct --content-root has been " "provided to pkg.depotd." ) - return __handle_error(request.path_info, http_client.NOT_FOUND) + return __handle_error(request.path_info, http.client.NOT_FOUND) except IOError as e: - return __handle_error(path, http_client.INTERNAL_SERVER_ERROR) + return __handle_error(path, http.client.INTERNAL_SERVER_ERROR) except mako.exceptions.TemplateLookupException as e: # The above exception indicates that mako could not locate the # template (in most cases, Mako doesn't seem to always clearly # differentiate). - return __handle_error(path, http_client.NOT_FOUND) + return __handle_error(path, http.client.NOT_FOUND) except sae.RedirectException as e: raise cherrypy.HTTPRedirect(e.data) except: - return __handle_error(path, http_client.INTERNAL_SERVER_ERROR) + return __handle_error(path, http.client.INTERNAL_SERVER_ERROR) # Vim hints diff --git a/src/modules/server/feed.py b/src/modules/server/feed.py index b285be08c..14c8b2707 100644 --- a/src/modules/server/feed.py +++ b/src/modules/server/feed.py @@ -33,6 +33,7 @@ import cherrypy import copy import datetime +import http.client import os import shutil import six @@ -40,8 +41,7 @@ import xml.dom.minidom as xmini from cherrypy.lib.static import serve_file -from six.moves import http_client -from six.moves.urllib.parse import quote, unquote, urlparse +from urllib.parse import quote, unquote, urlparse import pkg.catalog as catalog import pkg.misc as misc @@ -330,7 +330,7 @@ def __clear_cache(depot, pub): os.remove(pathname) except IOError: raise cherrypy.HTTPError( - http_client.INTERNAL_SERVER_ERROR, "Unable to clear feed cache." + http.client.INTERNAL_SERVER_ERROR, "Unable to clear feed cache." ) diff --git a/src/modules/server/repository.py b/src/modules/server/repository.py index 70f6c3a97..5d2ce12ad 100644 --- a/src/modules/server/repository.py +++ b/src/modules/server/repository.py @@ -37,8 +37,8 @@ import zlib from cryptography import x509 from cryptography.hazmat.backends import default_backend -from io import BytesIO -from six.moves.urllib.parse import unquote +from io import BytesIO, StringIO +from urllib.parse import unquote import pkg.actions as actions import pkg.catalog as catalog @@ -1411,7 +1411,7 @@ def catalog_0(self): c = old_catalog.ServerCatalog( self.catalog_root, read_only=True, publisher=self.publisher ) - output = cStringIO.StringIO() + output = StringIO() c.send(output) output.seek(0) for l in output: @@ -2034,18 +2034,13 @@ def update_publisher(self, pub): else: os.fchmod(fd, misc.PKG_FILE_MODE) - if six.PY2: - with os.fdopen(fd, "wb") as f: - with codecs.EncodedFile(f, "utf-8") as ef: - p5i.write(ef, [pub]) - else: - # we use json.dump() in p5i.write(), - # json module will produce str objects - # in Python 3, therefore fp.write() - # must support str input. + # we use json.dump() in p5i.write(), + # json module will produce str objects + # in Python 3, therefore fp.write() + # must support str input. - with open(fd, "w", encoding="utf-8") as fp: - p5i.write(fp, [pub]) + with open(fd, "w", encoding="utf-8") as fp: + p5i.write(fp, [pub]) portable.rename(fn, p5ipath) except EnvironmentError as e: if e.errno == errno.EACCES: @@ -3249,10 +3244,7 @@ def add_publisher(self, pub, skip_config=False): finally: # This ensures that the original exception and # traceback are used. - if six.PY2: - six.reraise(exc_value, None, exc_tb) - else: - raise exc_value + raise exc_value def remove_publisher(self, pfxs, repo_path, synch=False): """Removes a repository storage area and configuration @@ -4610,7 +4602,7 @@ def repository_create(repo_uri, properties=misc.EmptyDict, version=None): raised. Other errors can raise exceptions of class ApiException. """ - if isinstance(repo_uri, six.string_types): + if isinstance(repo_uri, str): repo_uri = publisher.RepositoryURI(misc.parse_uri(repo_uri)) path = repo_uri.get_pathname() diff --git a/src/modules/server/transaction.py b/src/modules/server/transaction.py index 27b1fd6eb..c87095ceb 100644 --- a/src/modules/server/transaction.py +++ b/src/modules/server/transaction.py @@ -24,17 +24,15 @@ # Copyright (c) 2007, 2023, Oracle and/or its affiliates. # -from __future__ import print_function import calendar import datetime import errno import os import re import shutil -import six import time import zlib -from six.moves.urllib.parse import quote, unquote +from urllib.parse import quote, unquote import pkg.actions as actions import pkg.digest as digest @@ -177,7 +175,7 @@ def open(self, rstore, client_release, pfmri): if pfmri is None: raise TransactionOperationError(pfmri=None) - if not isinstance(pfmri, six.string_types): + if not isinstance(pfmri, str): pfmri = str(pfmri) self.client_release = client_release @@ -286,7 +284,7 @@ def append(self, rstore, client_release, pfmri): if pfmri is None: raise TransactionOperationError(pfmri=None) - if not isinstance(pfmri, six.string_types): + if not isinstance(pfmri, str): pfmri = str(pfmri) self.client_release = client_release @@ -647,7 +645,7 @@ def add_file(self, f, basename=None, size=None): if not fileneeded: return - if isinstance(f, six.string_types): + if isinstance(f, str): portable.copyfile(f, dst_path) return @@ -704,7 +702,7 @@ def add_file(self, f, basename=None, size=None): def add_manifest(self, f): """Adds the manifest to the Transaction.""" - if isinstance(f, six.string_types): + if isinstance(f, str): f = open(f, "rb") opened = True else: diff --git a/src/modules/sha512_t.py b/src/modules/sha512_t.py index 95bac7fc2..610478974 100644 --- a/src/modules/sha512_t.py +++ b/src/modules/sha512_t.py @@ -21,7 +21,7 @@ # # -# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2023, Oracle and/or its affiliates. # Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # @@ -77,12 +77,8 @@ def __init__(self, message=None, t=256): def update(self, message): """Update the hash object with the string arguments.""" - if six.PY3 and isinstance(message, str): - raise TypeError("Unicode-objects must be encoded before hashing") - if not isinstance(message, (six.string_types, bytes)): - raise TypeError("Message must be string or buffer.") - if isinstance(message, six.text_type): - message = message.encode("utf-8") + if not isinstance(message, bytes): + raise TypeError(f"Message must be bytes, not {type(message)}") lib.SHA2Update(self.ctx, message, len(message)) def digest(self): diff --git a/src/modules/smf.py b/src/modules/smf.py index 63f8ab145..eecfb7505 100644 --- a/src/modules/smf.py +++ b/src/modules/smf.py @@ -28,14 +28,13 @@ import locale import os -import six import pkg.misc as misc import pkg.pkgsubprocess as subprocess from pkg.client import global_settings from pkg.client.debugvalues import DebugValues -from six.moves.urllib.parse import urlparse +from urllib.parse import urlparse logger = global_settings.logger @@ -138,7 +137,7 @@ def check_fmris(attr, fmris, zone=None): from the set that is returned and an error message is logged. """ - if isinstance(fmris, six.string_types): + if isinstance(fmris, str): fmris = set([fmris]) chars = "*?[!^" for fmri in fmris.copy(): @@ -207,7 +206,7 @@ def get_prop(fmri, prop, zone=None): def enable(fmris, temporary=False, sync_timeout=0, zone=None): if not fmris: return - if isinstance(fmris, six.string_types): + if isinstance(fmris, str): fmris = (fmris,) args = [svcadm_path, "enable"] @@ -224,7 +223,7 @@ def enable(fmris, temporary=False, sync_timeout=0, zone=None): def disable(fmris, temporary=False, sync_timeout=0, zone=None): if not fmris: return - if isinstance(fmris, six.string_types): + if isinstance(fmris, str): fmris = (fmris,) args = [svcadm_path, "disable", "-s"] # if sync_timeout > 0: @@ -238,7 +237,7 @@ def disable(fmris, temporary=False, sync_timeout=0, zone=None): def mark(state, fmris, zone=None): if not fmris: return - if isinstance(fmris, six.string_types): + if isinstance(fmris, str): fmris = (fmris,) args = [svcadm_path, "mark", state] # fmris could be a list so explicit cast is necessary @@ -248,7 +247,7 @@ def mark(state, fmris, zone=None): def refresh(fmris, sync_timeout=0, zone=None): if not fmris: return - if isinstance(fmris, six.string_types): + if isinstance(fmris, str): fmris = (fmris,) args = [svcadm_path, "refresh"] if sync_timeout: @@ -262,7 +261,7 @@ def refresh(fmris, sync_timeout=0, zone=None): def restart(fmris, sync_timeout=0, zone=None): if not fmris: return - if isinstance(fmris, six.string_types): + if isinstance(fmris, str): fmris = (fmris,) args = [svcadm_path, "restart"] if sync_timeout: diff --git a/src/modules/sysattr.py b/src/modules/sysattr.py index 7dcd39c12..e6c7c4fd5 100644 --- a/src/modules/sysattr.py +++ b/src/modules/sysattr.py @@ -26,7 +26,6 @@ from __future__ import unicode_literals import os -import six from pkg._sysattr import lib, ffi F_ATTR_ALL = lib.F_ATTR_ALL @@ -59,7 +58,7 @@ def fgetattr(filename, compact=False): from pkg.misc import force_text - if not isinstance(filename, six.string_types): + if not isinstance(filename, str): raise TypeError("filename must be string type") cattrs = ffi.new("char[F_ATTR_ALL]") @@ -130,7 +129,7 @@ def fsetattr(filename, attr): from pkg.misc import force_bytes - if not isinstance(filename, six.string_types): + if not isinstance(filename, str): raise TypeError("filename must be string type") if not attr: raise TypeError("{0} is not a valid system attribute".format(attr)) @@ -145,7 +144,7 @@ def fsetattr(filename, attr): # A single string indicates system attributes are passed in compact # form (e.g. AHi), verbose attributes are read as a list of strings. - if isinstance(attr, six.string_types): + if isinstance(attr, str): compact = True for c in attr: diff --git a/src/modules/syscallat.py b/src/modules/syscallat.py index 679819078..434b7c510 100644 --- a/src/modules/syscallat.py +++ b/src/modules/syscallat.py @@ -26,7 +26,6 @@ from __future__ import unicode_literals import os -import six from pkg._syscallat import lib, ffi from pkg.misc import force_bytes @@ -36,7 +35,7 @@ def mkdirat(fd, path, mode): if not isinstance(fd, int): raise TypeError("fd must be int type") - if not isinstance(path, six.string_types): + if not isinstance(path, str): raise TypeError("path must be a string") if not isinstance(mode, int): raise TypeError("mode must be int type") @@ -51,7 +50,7 @@ def openat(fildes, path, oflag, mode): if not isinstance(fildes, int): raise TypeError("fildes must be int type") - if not isinstance(path, six.string_types): + if not isinstance(path, str): raise TypeError("path must be a string") if not isinstance(oflag, int): raise TypeError("oflag must be int type") @@ -69,11 +68,11 @@ def renameat(fromfd, old, tofd, new): if not isinstance(fromfd, int): raise TypeError("fromfd must be int type") - if not isinstance(old, six.string_types): + if not isinstance(old, str): raise TypeError("old must be a string") if not isinstance(tofd, int): raise TypeError("tofd must be int type") - if not isinstance(new, six.string_types): + if not isinstance(new, str): raise TypeError("new must be a string") rv = lib.renameat(fromfd, force_bytes(old), tofd, force_bytes(new)) @@ -86,7 +85,7 @@ def unlinkat(dirfd, path, flag): if not isinstance(dirfd, int): raise TypeError("dirfd must be int type") - if not isinstance(path, six.string_types): + if not isinstance(path, str): raise TypeError("path must be a string") if not isinstance(flag, int): raise TypeError("flag must be int type") diff --git a/src/modules/sysvpkg.py b/src/modules/sysvpkg.py index 3ecc3fb6d..fa164ecd3 100644 --- a/src/modules/sysvpkg.py +++ b/src/modules/sysvpkg.py @@ -36,7 +36,6 @@ datastream. """ -from __future__ import print_function import errno import gzip import os diff --git a/src/modules/variant.py b/src/modules/variant.py index 7e2cba46d..e651ff1c6 100644 --- a/src/modules/variant.py +++ b/src/modules/variant.py @@ -28,7 +28,6 @@ import copy import itertools -import six import types from collections import namedtuple @@ -48,16 +47,8 @@ def __init__(self, init=EmptyI): def copy(self): return Variants(self) - # allow_action is provided as a native function (see end of class - # declaration). - if six.PY3: - - def allow_action(self, action, publisher=None): - return _allow_variant(self, action, publisher=publisher) - - -if six.PY2: - _Variants.allow_action = types.MethodType(_allow_variant, None, _Variants) + def allow_action(self, action, publisher=None): + return _allow_variant(self, action, publisher=publisher) class Variants(_Variants): diff --git a/src/modules/version.py b/src/modules/version.py index 7edb4e66f..86e1ee75a 100644 --- a/src/modules/version.py +++ b/src/modules/version.py @@ -29,8 +29,6 @@ import time import weakref -from six.moves import zip - CONSTRAINT_NONE = 0 CONSTRAINT_AUTO = 50 diff --git a/src/pkgdep.py b/src/pkgdep.py index 8aef21fdc..a5d76cd1f 100644 --- a/src/pkgdep.py +++ b/src/pkgdep.py @@ -675,9 +675,8 @@ def main_func(): # Make all warnings be errors. warnings.simplefilter("error") - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: __ret = main_func() diff --git a/src/pkgrepo.py b/src/pkgrepo.py index 8b2b3f4c6..a86e89834 100755 --- a/src/pkgrepo.py +++ b/src/pkgrepo.py @@ -2468,7 +2468,7 @@ def __diff_pub_helper(pub, symbol): for idx, cell in enumerate(td): if not cell: t_row.append("-") - elif isinstance(cell, six.string_types): + elif isinstance(cell, str): t_row.append(cell) elif isinstance(cell, dict): t_row.append( @@ -2750,9 +2750,8 @@ def handle_errors(func, *args, **kwargs): # Make all warnings be errors. warnings.simplefilter("error") - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) __retval = handle_errors(main_func) try: diff --git a/src/publish.py b/src/publish.py index 85950e494..f49a7dbe4 100755 --- a/src/publish.py +++ b/src/publish.py @@ -24,7 +24,6 @@ # Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import pkg.site_paths pkg.site_paths.init() @@ -33,7 +32,6 @@ import gettext import locale import os -import six import sys import traceback import warnings @@ -72,7 +70,7 @@ def error(text, cmd=None): """Emit an error message prefixed by the command name""" - if not isinstance(text, six.string_types): + if not isinstance(text, str): # Assume it's an object that can be stringified. text = str(text) @@ -502,7 +500,7 @@ def trans_publish(repo_uri, fargs): basename = os.path.basename(a.attrs["path"]) for pattern in timestamp_files: if fnmatch.fnmatch(basename, pattern): - if not isinstance(path, six.string_types): + if not isinstance(path, str): # Target is from bundle; can't # apply timestamp now. continue @@ -936,9 +934,8 @@ def main_func(): # Make all warnings be errors. warnings.simplefilter("error") - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: __ret = main_func() diff --git a/src/pull.py b/src/pull.py index 3b917bc15..342242bcd 100755 --- a/src/pull.py +++ b/src/pull.py @@ -24,7 +24,6 @@ # Copyright (c) 2008, 2022, Oracle and/or its affiliates. # -from __future__ import print_function import pkg.site_paths pkg.site_paths.init() @@ -60,7 +59,7 @@ from pkg.client import global_settings from pkg.misc import emsg, get_pkg_otw_size, msg, PipeError from pkg.client.debugvalues import DebugValues -from six.moves.urllib.parse import quote +from urllib.parse import quote # Globals archive = False @@ -1943,11 +1942,9 @@ def get_basename(pfmri): # Make all warnings be errors. warnings.simplefilter("error") - import six - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: __ret = main_func() except (KeyboardInterrupt, apx.CanceledException): diff --git a/src/setup.py b/src/setup.py index 0696acfe9..7b40b045b 100755 --- a/src/setup.py +++ b/src/setup.py @@ -24,7 +24,6 @@ # Copyright 2023 OmniOS Community Edition (OmniOSce) Association. # -from __future__ import print_function import errno import fnmatch import os diff --git a/src/sysrepo.py b/src/sysrepo.py index efa3a8d22..319c66bc1 100755 --- a/src/sysrepo.py +++ b/src/sysrepo.py @@ -36,7 +36,6 @@ import logging import os import shutil -import six import socket import stat import sys @@ -44,9 +43,7 @@ import warnings from mako.template import Template -from six.moves.urllib.error import URLError -from six.moves.urllib.parse import urlparse -from six.moves.urllib.request import build_opener, HTTPRedirectHandler +from urllib.parse import urlparse from pkg.client import global_settings from pkg.misc import msg, PipeError @@ -323,7 +320,7 @@ def __validate_pub_info(pub_info, no_uri_pubs, api_inst): if not isinstance(pub_info, dict): raise SysrepoException("{0} is not a dict".format(pub_info)) for uri in pub_info: - if not isinstance(uri, six.string_types): + if not isinstance(uri, str): raise SysrepoException("{0} is not a basestring".format(uri)) uri_info = pub_info[uri] if not isinstance(uri_info, list): @@ -334,16 +331,14 @@ def __validate_pub_info(pub_info, no_uri_pubs, api_inst): "{0} does not have 6 " "items".format(props) ) # props [0] and [3] must be strings - if not isinstance(props[0], six.string_types) or not isinstance( - props[3], six.string_types - ): + if not isinstance(props[0], str) or not isinstance(props[3], str): raise SysrepoException( "indices 0 and 3 of {0} " "are not basestrings".format(props) ) # prop[5] must be a string, either "file" or "dir" # and prop[0] must start with file:// - if not isinstance(props[5], six.string_types) or ( + if not isinstance(props[5], str) or ( props[5] not in ["file", "dir"] and props[0].startswith("file://") ): @@ -355,7 +350,7 @@ def __validate_pub_info(pub_info, no_uri_pubs, api_inst): if not isinstance(no_uri_pubs, list): raise SysrepoException("{0} is not a list".format(no_uri_pubs)) for item in no_uri_pubs: - if not isinstance(item, six.string_types): + if not isinstance(item, str): raise SysrepoException("{0} is not a basestring".format(item)) # check that we have entries for each URI for each publisher. @@ -1127,9 +1122,8 @@ def handle_errors(func, *args, **kwargs): # Make all warnings be errors. warnings.simplefilter("error") - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) __retval = handle_errors(main_func) try: diff --git a/src/tests/api/t_action.py b/src/tests/api/t_action.py index fb84f3a59..cd45bc457 100644 --- a/src/tests/api/t_action.py +++ b/src/tests/api/t_action.py @@ -524,7 +524,9 @@ def test_action_errors(self): self.assertInvalid("depend type=require") # Multiple values not allowed for 'fmri' if 'type' is multi-valued. - self.assertInvalid("depend type=require type=require-any fmri=foo fmri=bar") + self.assertInvalid( + "depend type=require type=require-any fmri=foo fmri=bar" + ) # 'path' attribute specified multiple times self.assertInvalid( diff --git a/src/tests/api/t_api.py b/src/tests/api/t_api.py index f38cc9674..3241b83eb 100644 --- a/src/tests/api/t_api.py +++ b/src/tests/api/t_api.py @@ -30,7 +30,7 @@ testutils.setup_environment("../../../proto") import pkg5unittest -from six.moves import cStringIO +import io import os import pkg.client.api as api import pkg.client.api_errors as api_errors @@ -633,7 +633,7 @@ def test_publisher_apis(self): } # Dump the p5i data. - fobj = cStringIO() + fobj = io.StringIO() api_obj.write_p5i(fobj, pkg_names=pnames, pubs=[pub]) # Verify that output matches expected output. diff --git a/src/tests/api/t_api_search.py b/src/tests/api/t_api_search.py index 90253a468..549fa6c11 100644 --- a/src/tests/api/t_api_search.py +++ b/src/tests/api/t_api_search.py @@ -32,12 +32,11 @@ import copy import os import shutil -import six import tempfile import time import unittest -from six.moves.urllib.error import HTTPError -from six.moves.urllib.request import urlopen +from urllib.error import HTTPError +from urllib.request import urlopen import pkg.client.api as api import pkg.client.api_errors as api_errors @@ -3878,7 +3877,7 @@ def test_bug_8318(self): # appear in the log file. This test intermittently # fails as a result. Just check for at least one # UUID in the log. - if six.PY3 and num_expected[d] > 0 and found > 0: + if num_expected[d] > 0 and found > 0: pass elif found != num_expected[d]: raise RuntimeError( diff --git a/src/tests/api/t_async_rpc.py b/src/tests/api/t_async_rpc.py index 03de065c8..8f53bad0c 100644 --- a/src/tests/api/t_async_rpc.py +++ b/src/tests/api/t_async_rpc.py @@ -34,7 +34,6 @@ import os import random import signal -import six import sys import threading import time @@ -85,14 +84,9 @@ def test_async_basics(self): # test async call with invalid arguments ac = AsyncCall() ac.start(self.__add, 1, 2, 3) - if six.PY2: - self.assertRaisesRegex( - AsyncCallException, "takes exactly 2 arguments", ac.result - ) - else: - self.assertRaisesRegex( - AsyncCallException, "takes 2 positional arguments", ac.result - ) + self.assertRaisesRegex( + AsyncCallException, "takes 2 positional arguments", ac.result + ) ac = AsyncCall() ac.start(self.__add, x=1, y=2, z=3) self.assertRaisesRegex( diff --git a/src/tests/api/t_catalog.py b/src/tests/api/t_catalog.py index 08a3488ca..74e9eee9b 100644 --- a/src/tests/api/t_catalog.py +++ b/src/tests/api/t_catalog.py @@ -24,7 +24,6 @@ # Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. # Copyright 2020 OmniOS Community Edition (OmniOSce) Association. -from __future__ import print_function from . import testutils if __name__ == "__main__": diff --git a/src/tests/api/t_client.py b/src/tests/api/t_client.py index 559318e45..ec05808d0 100644 --- a/src/tests/api/t_client.py +++ b/src/tests/api/t_client.py @@ -30,9 +30,9 @@ testutils.setup_environment("../../../proto") import pkg5unittest +import io import logging import os -import six import sys import unittest @@ -54,8 +54,8 @@ class TestSettings(pkg5unittest.Pkg5TestCase): def test_logging(self): global_settings.client_name = "TestSettings" - info_out = six.StringIO() - error_out = six.StringIO() + info_out = io.StringIO() + error_out = io.StringIO() log_fmt = logging.Formatter() diff --git a/src/tests/api/t_config.py b/src/tests/api/t_config.py index c4d7089fa..a7dd59cab 100644 --- a/src/tests/api/t_config.py +++ b/src/tests/api/t_config.py @@ -105,18 +105,13 @@ def __verify_stringify(self, propcls, propname, explist, debug=False): # Verify that the stringified form of the property's # value matches what is expected. p1 = propcls(propname, default=val) - self.assertEqual(six.text_type(p1), expstr) - if six.PY2: - self.assertEqual(str(p1), expstr.encode("utf-8")) - else: - # str() call in Python 3 must return str (unicode). - self.assertEqual(str(p1), expstr) + self.assertEqual(str(p1), expstr) # Verify that a property value's stringified form # provides can be parsed into an exact equivalent # in native form (e.g. list -> string -> list). p2 = propcls(propname) - p2.value = six.text_type(p1) + p2.value = str(p1) self.assertEqual(p1.value, p2.value) self.assertEqualDiff(str(p1), str(p2)) @@ -127,12 +122,9 @@ def __verify_stringify(self, propcls, propname, explist, debug=False): def __verify_ex_stringify(self, ex): encs = str(ex) self.assertNotEqual(len(encs), 0) - unis = six.text_type(ex) + unis = str(ex) self.assertNotEqual(len(unis), 0) - if six.PY2: - self.assertEqualDiff(encs, unis.encode("utf-8")) - else: - self.assertEqualDiff(encs, unis) + self.assertEqualDiff(encs, unis) def test_base(self): """Verify base property functionality works as expected.""" @@ -527,39 +519,19 @@ def test_list(self): # Verify stringified form and that stringified form can be used # to set value. - if six.PY2: - self.__verify_stringify( - propcls, - "list", - [ - ([""], "['']"), - (["box", "cat"], "['box', 'cat']"), - # List literal form uses unicode_escape. - ( - [TH_PACKAGE, "profit"], - "[u'{0}', 'profit']".format( - TH_PACKAGE.encode("unicode_escape") - ), - ), - (["\xfe", "bob cat"], "['\\xfe', 'bob cat']"), - ], - ) - else: - # unicode representation in Python 3 is not using - # escape sequence - self.__verify_stringify( - propcls, - "list", - [ - ([""], "['']"), - (["box", "cat"], "['box', 'cat']"), - ( - [TH_PACKAGE, "profit"], - "['{0}', 'profit']".format(TH_PACKAGE), - ), - (["þ", "bob cat"], "['þ', 'bob cat']"), - ], - ) + self.__verify_stringify( + propcls, + "list", + [ + ([""], "['']"), + (["box", "cat"], "['box', 'cat']"), + ( + [TH_PACKAGE, "profit"], + "['{0}', 'profit']".format(TH_PACKAGE), + ), + (["þ", "bob cat"], "['þ', 'bob cat']"), + ], + ) # Verify allowed value functionality permits expected values. p = propcls( @@ -1026,12 +998,7 @@ class TestPropertySection(pkg5unittest.Pkg5TestCase): def __verify_stringify(self, cls, explist): for val, expstr in explist: - self.assertEqual(six.text_type(cls(val)), expstr) - if six.PY2: - self.assertEqual(str(cls(val)), expstr.encode("utf-8")) - else: - # str() call in Python 3 must return str (unicode). - self.assertEqual(str(cls(val)), expstr) + self.assertEqual(str(cls(val)), expstr) def test_base(self): """Verify base section functionality works as expected.""" @@ -1421,9 +1388,7 @@ class TestConfig(_TestConfigBase): uuid_basic = uuid_default = 16fd2706-8baf-433b-82eb-8c7fada847da """.format( - uni_escape=TH_PACKAGE.encode("unicode_escape") - if six.PY2 - else TH_PACKAGE, + uni_escape=TH_PACKAGE, uni_txt=TH_PACKAGE, ), 1: """\ @@ -1516,31 +1481,17 @@ def test_base(self): ) conf.set_property("first_section", "str_basic", TH_PACKAGE) - if six.PY2: - self.assertEqualDiff( - """\ -[first_section] -bool_basic = False -str_basic = {0} - -""".format( - TH_PACKAGE.encode("utf-8") - ), - str(conf), - ) - else: - # str() must return str (unicode) in Python 3. - self.assertEqualDiff( - """\ + self.assertEqualDiff( + """\ [first_section] bool_basic = False str_basic = {0} """.format( - TH_PACKAGE - ), - str(conf), - ) + TH_PACKAGE + ), + str(conf), + ) # # Test unicode case with and without unicode data. @@ -1553,7 +1504,7 @@ def test_base(self): str_basic = """, - six.text_type(conf), + str(conf), ) conf.set_property("first_section", "str_basic", TH_PACKAGE) @@ -1566,7 +1517,7 @@ def test_base(self): """.format( TH_PACKAGE ), - six.text_type(conf), + str(conf), ) # Verify target is None. @@ -2301,12 +2252,9 @@ def __start_configd(self, sc_repo_filename): def __verify_ex_stringify(self, ex): encs = str(ex) self.assertNotEqual(len(encs), 0) - unis = six.text_type(ex) + unis = str(ex) self.assertNotEqual(len(unis), 0) - if six.PY2: - self.assertEqualDiff(encs, unis.encode("utf-8")) - else: - self.assertEqualDiff(encs, unis) + self.assertEqualDiff(encs, unis) def test_exceptions(self): """Verify that exception classes can be initialized as expected, diff --git a/src/tests/api/t_dependencies.py b/src/tests/api/t_dependencies.py index c5adcee32..3cc5ebacf 100644 --- a/src/tests/api/t_dependencies.py +++ b/src/tests/api/t_dependencies.py @@ -23,7 +23,6 @@ # Copyright (c) 2009, 2022, Oracle and/or its affiliates. # Copyright 2022 OmniOS Community Edition (OmniOSce) Association. -from __future__ import print_function from . import testutils if __name__ == "__main__": diff --git a/src/tests/api/t_fast_quote.py b/src/tests/api/t_fast_quote.py index 976d66ff2..804588671 100644 --- a/src/tests/api/t_fast_quote.py +++ b/src/tests/api/t_fast_quote.py @@ -25,6 +25,7 @@ # from . import testutils + if __name__ == "__main__": testutils.setup_environment("../../../proto") import pkg5unittest @@ -38,7 +39,6 @@ class TestFastQuote(pkg5unittest.Pkg5TestCase): - def test_basic(self): """Verify that fast_quote returns the same values as standard quote.""" for i in range(1024): diff --git a/src/tests/api/t_manifest.py b/src/tests/api/t_manifest.py index 053923fcd..d217b794b 100644 --- a/src/tests/api/t_manifest.py +++ b/src/tests/api/t_manifest.py @@ -32,7 +32,6 @@ import unittest import tempfile import os -import six import sys import types import itertools @@ -144,10 +143,7 @@ def test_set_content1(self): # Verify set_content with a Unicode string works. m = manifest.Manifest() - if six.PY2: - m.set_content(six.text_type(bstr, "utf-8")) - else: - m.set_content(bstr) + m.set_content(bstr) output = list(m.as_lines())[0].rstrip() self.assertEqual(bstr, output) self.assertTrue(isinstance(output, str)) @@ -434,10 +430,7 @@ def test_validate(self): output1 = "".join(m1.as_lines()) m2 = manifest.Manifest() - if six.PY2: - m2.set_content(six.text_type(bstr, "utf-8"), signatures=True) - else: - m2.set_content(bstr, signatures=True) + m2.set_content(bstr, signatures=True) output2 = "".join(m2.as_lines()) self.assertEqualDiff(output1, output2) self.assertEqualDiff(m1.signatures, m2.signatures) @@ -541,6 +534,7 @@ def test_get_directories(self): ] facet_expected = [ + "fm", "vdo", "vo", "opt/dir with spaces in value", diff --git a/src/tests/api/t_p5i.py b/src/tests/api/t_p5i.py index cd4124127..c261be6fc 100644 --- a/src/tests/api/t_p5i.py +++ b/src/tests/api/t_p5i.py @@ -32,6 +32,7 @@ import errno import unittest +import io import os import pkg.client.api_errors as api_errors import pkg.client.publisher as publisher @@ -42,9 +43,8 @@ import sys import tempfile -from six.moves import cStringIO -from six.moves.urllib.parse import urlparse, urlunparse -from six.moves.urllib.request import pathname2url +from urllib.parse import urlparse, urlunparse +from urllib.request import pathname2url class TestP5I(pkg5unittest.Pkg5TestCase): @@ -126,7 +126,7 @@ def test_parse_write(self): } # Dump the p5i data. - fobj = cStringIO() + fobj = io.StringIO() p5i.write(fobj, [pub], pkg_names=pnames) # Verify that the p5i data ends with a terminating newline. @@ -236,7 +236,7 @@ def test_parse_write_partial(self): pub = self.__get_bobcat_pub(omit_repo=True) # Dump the p5i data. - fobj = cStringIO() + fobj = io.StringIO() p5i.write(fobj, [pub]) # Verify that output matches expected output. @@ -285,7 +285,7 @@ def test_parse_write_partial(self): pub.repository.reset_origins() # Dump the p5i data. - fobj = cStringIO() + fobj = io.StringIO() p5i.write(fobj, [pub]) # Verify that output matches expected output. diff --git a/src/tests/api/t_p5p.py b/src/tests/api/t_p5p.py index 312543d0d..0b72d1761 100644 --- a/src/tests/api/t_p5p.py +++ b/src/tests/api/t_p5p.py @@ -44,7 +44,6 @@ import pkg.pkgtarfile as ptf import pkg.portable as portable import shutil -import six import sys import tarfile as tf import tempfile @@ -99,7 +98,7 @@ class TestP5P(pkg5unittest.SingleDepotTestCase): ] def seed_ta_dir(self, certs, dest_dir=None): - if isinstance(certs, six.string_types): + if isinstance(certs, str): certs = [certs] if not dest_dir: dest_dir = self.ta_dir @@ -461,7 +460,7 @@ def __verify_manifest_sig(self, repo, pfmri, content): # p5p archive extraction file return bytes if isinstance(content, bytes): content = pkg.misc.force_str(content) - if isinstance(content, six.string_types): + if isinstance(content, str): dm = pkg.manifest.Manifest() dm.set_content(content=content, signatures=True) else: diff --git a/src/tests/api/t_pkg_api_install.py b/src/tests/api/t_pkg_api_install.py index e41a2507b..d00785078 100644 --- a/src/tests/api/t_pkg_api_install.py +++ b/src/tests/api/t_pkg_api_install.py @@ -46,8 +46,8 @@ import shutil from pkg.client.debugvalues import DebugValues -from six.moves.urllib.parse import urlunparse -from six.moves.urllib.request import pathname2url +from urllib.parse import urlunparse +from urllib.request import pathname2url PKG_CLIENT_NAME = "pkg" diff --git a/src/tests/api/t_printengine.py b/src/tests/api/t_printengine.py index abd51acec..baf15c405 100644 --- a/src/tests/api/t_printengine.py +++ b/src/tests/api/t_printengine.py @@ -22,7 +22,6 @@ # Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. -from __future__ import print_function from . import testutils if __name__ == "__main__": @@ -30,9 +29,9 @@ import pkg5unittest import unittest +import io import os import pty -import six import sys import threading @@ -42,7 +41,7 @@ class TestPrintEngine(pkg5unittest.Pkg5TestCase): def test_posix_printengine_tty(self): """Test POSIX print engine tty mode.""" - sio = six.StringIO() + sio = io.StringIO() def __drain(masterf): """Drain data from masterf and discard until eof.""" @@ -77,7 +76,7 @@ def __drain(masterf): def test_posix_printengine_badtty(self): """Try to make ttymode POSIX print engines on non-ttys.""" - f = six.StringIO() + f = io.StringIO() self.assertRaises( printengine.PrintEngineException, printengine.POSIXPrintEngine, @@ -97,13 +96,13 @@ def test_posix_printengine_badtty(self): def test_posix_printengine_notty(self): """Smoke test POSIX print engine non-tty mode.""" - sio = six.StringIO() + sio = io.StringIO() printengine.test_posix_printengine(sio, False) self.assertTrue(len(sio.getvalue()) > 0) def test_logging_printengine(self): """Smoke test logging print engine.""" - sio = six.StringIO() + sio = io.StringIO() printengine.test_logging_printengine(sio) self.assertTrue(len(sio.getvalue()) > 0) diff --git a/src/tests/api/t_progress.py b/src/tests/api/t_progress.py index d1c33dea8..c67b3b67d 100644 --- a/src/tests/api/t_progress.py +++ b/src/tests/api/t_progress.py @@ -28,10 +28,10 @@ testutils.setup_environment("../../../proto") import pkg5unittest +import io import os import pty import shutil -import six import sys import tempfile import threading @@ -320,10 +320,10 @@ def test_format_pair(self): class TestProgressTrackers(pkg5unittest.Pkg5TestCase): def test_basic_trackers(self): """Basic testing of all trackers; reset, and then retest.""" - sio_c = six.StringIO() - sio_c2 = six.StringIO() - sio_f = six.StringIO() - sio_d = six.StringIO() + sio_c = io.StringIO() + sio_c2 = io.StringIO() + sio_f = io.StringIO() + sio_d = io.StringIO() tc = progress.CommandLineProgressTracker(output_file=sio_c) tc2 = progress.CommandLineProgressTracker( @@ -389,7 +389,7 @@ def test_fancy_unix_tracker(self): def test_fancy_unix_tracker_bad_tty(self): """Try to make a terminal-based tracker on non-terminals.""" - f = six.StringIO() + f = io.StringIO() self.assertRaises( progress.ProgressTrackerException, progress.FancyUNIXProgressTracker, @@ -413,8 +413,8 @@ def test_fancy_unix_tracker_termdelay(self): class TestMultiProgressTracker(pkg5unittest.Pkg5TestCase): def test_multi(self): """Test basic multi functionality.""" - sio1 = six.StringIO() - sio2 = six.StringIO() + sio1 = io.StringIO() + sio2 = io.StringIO() # # The FunctionProgressTracker is used here because its diff --git a/src/tests/api/t_sha512_t.py b/src/tests/api/t_sha512_t.py index 919732d02..1d8154cdf 100644 --- a/src/tests/api/t_sha512_t.py +++ b/src/tests/api/t_sha512_t.py @@ -32,9 +32,7 @@ testutils.setup_environment("../../../proto") import pkg5unittest -import six import unittest -from six.moves import range try: import pkg.sha512_t as sha512_t @@ -153,20 +151,8 @@ def test_basic(self): self.assertRaises(ValueError, sha512_t.SHA512_t, t=160) self.assertRaises(TypeError, sha512_t.SHA512_t.update, 8) - if six.PY2: - # We allow unicode in Python 2 as hashlib does - a = sha512_t.SHA512_t("abc") - expected = "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23" - output = a.hexdigest() - self.assertEqualDiff(expected, output) - # Test special unicode character - a = sha512_t.SHA512_t("α♭¢") - a.hexdigest() - a.update("ρ⑂☂♄øη") - a.hexdigest() - else: - # We don't allow unicode in Python 3 as hashlib does - self.assertRaises(TypeError, sha512_t.SHA512_t, "str") + # Similarly to hashlib, strings are not allowed + self.assertRaises(TypeError, sha512_t.SHA512_t, "str") if __name__ == "__main__": diff --git a/src/tests/api/t_smf.py b/src/tests/api/t_smf.py index ba57c2594..c20a28d59 100644 --- a/src/tests/api/t_smf.py +++ b/src/tests/api/t_smf.py @@ -22,7 +22,6 @@ # Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. -from __future__ import print_function from . import testutils if __name__ == "__main__": diff --git a/src/tests/bandit-baseline.json b/src/tests/bandit-baseline.json index b55ad48a7..cfae6e976 100644 --- a/src/tests/bandit-baseline.json +++ b/src/tests/bandit-baseline.json @@ -5046,7 +5046,7 @@ "test_name": "blacklist" }, { - "code": "1878 response.status = http_client.UNAUTHORIZED\n1879 response.headers[\"X-Ipkg-Error\"] = random.choice(\n1880 [\"ENT\", \"LIC\", \"SVR\", \"MNT\", \"YYZ\", \"\"]\n1881 )\n1882 return \"\"\n", + "code": "1878 response.status = http.client.UNAUTHORIZED\n1879 response.headers[\"X-Ipkg-Error\"] = random.choice(\n1880 [\"ENT\", \"LIC\", \"SVR\", \"MNT\", \"YYZ\", \"\"]\n1881 )\n1882 return \"\"\n", "col_offset": 47, "end_col_offset": 13, "filename": "./modules/server/depot.py", @@ -5802,7 +5802,6 @@ "test_name": "try_except_pass" }, { - "code": "28 from __future__ import print_function\n29 import cPickle as pickle\n30 import GeoIP\n", "col_offset": 0, "end_col_offset": 24, "filename": "./util/log-scripts/an_report.py", @@ -5965,4 +5964,4 @@ "test_name": "blacklist" } ] -} \ No newline at end of file +} diff --git a/src/tests/baseline.py b/src/tests/baseline.py index 942f2972d..c0cb59c38 100644 --- a/src/tests/baseline.py +++ b/src/tests/baseline.py @@ -24,7 +24,6 @@ # Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import os import sys import unittest diff --git a/src/tests/cli/t_actuators.py b/src/tests/cli/t_actuators.py index 60a401409..f67dc14e4 100644 --- a/src/tests/cli/t_actuators.py +++ b/src/tests/cli/t_actuators.py @@ -28,7 +28,6 @@ testutils.setup_environment("../../../proto") import os -import six import pkg5unittest import unittest import stat @@ -457,22 +456,15 @@ def test_actuators(self): # Test with multi-valued actuators self.pkg("install basics@1.8") self.pkg("verify") - if six.PY2: - self.file_contains( - svcadm_output, - "svcadm restart svc:/system/test_multi_svc1:default " + # output order is not stable + self.file_contains( + svcadm_output, + [ + "svcadm restart", + "svc:/system/test_multi_svc1:default", "svc:/system/test_multi_svc2:default", - ) - else: - # output order is not stable in Python 3 - self.file_contains( - svcadm_output, - [ - "svcadm restart", - "svc:/system/test_multi_svc1:default", - "svc:/system/test_multi_svc2:default", - ], - ) + ], + ) # Test synchronous options # synchronous restart @@ -533,22 +525,15 @@ def test_actuators(self): self.pkg("install basics@1.9") self.pkg("verify") self.pkg("uninstall basics") - if six.PY2: - self.file_contains( - svcadm_output, - "svcadm disable -s svc:/system/test_multi_svc1:default " + # output order is not stable + self.file_contains( + svcadm_output, + [ + "svcadm disable -s", + "svc:/system/test_multi_svc1:default", "svc:/system/test_multi_svc2:default", - ) - else: - # output order is not stable in Python 3 - self.file_contains( - svcadm_output, - [ - "svcadm disable -s", - "svc:/system/test_multi_svc1:default", - "svc:/system/test_multi_svc2:default", - ], - ) + ], + ) os.unlink(svcadm_output) def test_actuator_plan_display(self): diff --git a/src/tests/cli/t_depot_config.py b/src/tests/cli/t_depot_config.py index 4be0e9b18..b5c9d7e34 100644 --- a/src/tests/cli/t_depot_config.py +++ b/src/tests/cli/t_depot_config.py @@ -33,15 +33,14 @@ import copy import os -import six import time import unittest import certgenerator import shutil -from six.moves import http_client -from six.moves.urllib.error import HTTPError -from six.moves.urllib.parse import quote -from six.moves.urllib.request import urlopen +import http.client +from urllib.error import HTTPError +from urllib.parse import quote +from urllib.request import urlopen from pkg.client.debugvalues import DebugValues import pkg.fmri @@ -906,13 +905,7 @@ def header_contains(url, header, value): ret = False try: u = urlopen(url) - if six.PY2: - h = u.headers.get(header, "") - else: - # HTTPMessage inherits from - # email.Message in Python 3 so that it - # has a different method - h = u.headers.get_all(header, "") + h = u.headers.get_all(header, "") if value in h: return True except Exception as e: @@ -988,7 +981,7 @@ def test_16_htfragment(self): # httpd.conf u = urlopen("{0}/pkg5test-server-status".format(self.ac.url)) self.assertTrue( - u.code == http_client.OK, "Error getting pkg5-server-status" + u.code == http.client.OK, "Error getting pkg5-server-status" ) self.image_create() diff --git a/src/tests/cli/t_https.py b/src/tests/cli/t_https.py index beeb78807..e4fa0ce05 100644 --- a/src/tests/cli/t_https.py +++ b/src/tests/cli/t_https.py @@ -33,7 +33,6 @@ import hashlib import os import shutil -import six import stat import tempfile import certgenerator @@ -343,7 +342,7 @@ def pkg(self, command, *args, **kwargs): ) def seed_ta_dir(self, certs, dest_dir=None): - if isinstance(certs, six.string_types): + if isinstance(certs, str): certs = [certs] if not dest_dir: dest_dir = self.ta_dir diff --git a/src/tests/cli/t_origin_fw.py b/src/tests/cli/t_origin_fw.py index ca233d400..5b2dbeee0 100644 --- a/src/tests/cli/t_origin_fw.py +++ b/src/tests/cli/t_origin_fw.py @@ -21,7 +21,6 @@ # # Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. -from __future__ import print_function from . import testutils if __name__ == "__main__": diff --git a/src/tests/cli/t_pkg_composite.py b/src/tests/cli/t_pkg_composite.py index b717d6433..552fbb668 100644 --- a/src/tests/cli/t_pkg_composite.py +++ b/src/tests/cli/t_pkg_composite.py @@ -38,7 +38,6 @@ import pkg.misc as misc import pkg.p5p import shutil -import six import stat import tempfile import unittest @@ -114,7 +113,7 @@ class TestPkgCompositePublishers(pkg5unittest.ManyDepotTestCase): ] def __seed_ta_dir(self, certs, dest_dir=None): - if isinstance(certs, six.string_types): + if isinstance(certs, str): certs = [certs] if not dest_dir: dest_dir = self.ta_dir @@ -425,8 +424,7 @@ def test_01_info(self): self.assertEqualDiff(expected, self.output) # Change locale back to 'UTF-8' to not affect other test cases. - if six.PY3: - os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["LC_ALL"] = "en_US.UTF-8" def test_02_contents(self): """Verify that the contents operation works as expected when diff --git a/src/tests/cli/t_pkg_depotd.py b/src/tests/cli/t_pkg_depotd.py index 3c1d2152a..e3519c60c 100644 --- a/src/tests/cli/t_pkg_depotd.py +++ b/src/tests/cli/t_pkg_depotd.py @@ -31,6 +31,7 @@ import pkg5unittest import datetime +import http.client import os import shutil import six @@ -39,10 +40,9 @@ import time import unittest -from six.moves import http_client -from six.moves.urllib.error import HTTPError, URLError -from six.moves.urllib.parse import quote, urljoin -from six.moves.urllib.request import urlopen +from urllib.error import HTTPError, URLError +from urllib.parse import quote, urljoin +from urllib.request import urlopen import pkg.client.publisher as publisher import pkg.depotcontroller as dc @@ -227,7 +227,7 @@ def test_bug_3739(self): try: urlopen("{0}/{1}/0/{2}".format(durl, operation, entry)) except HTTPError as e: - if e.code != http_client.BAD_REQUEST: + if e.code != http.client.BAD_REQUEST: raise def test_bug_5366(self): @@ -323,8 +323,7 @@ def test_info(self): self.assertEqual(info_dic["Size"], misc.bytes_to_str(size)) self.assertEqual(info_dic["Compressed Size"], misc.bytes_to_str(csize)) self.assertEqual(info_dic["FMRI"], fmri_content) - if six.PY3: - os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["LC_ALL"] = "en_US.UTF-8" def test_bug_5707(self): """Testing depotcontroller.refresh().""" @@ -359,7 +358,7 @@ def test_face_root(self): try: urlopen("{0}/../../../../bin/pkg".format(depot_url)) except HTTPError as e: - if e.code != http_client.NOT_FOUND: + if e.code != http.client.NOT_FOUND: raise f = urlopen("{0}/robots.txt".format(depot_url)) @@ -714,7 +713,7 @@ def test_disable_ops(self): try: urlopen("{0}/catalog/1/".format(durl)) except HTTPError as e: - self.assertEqual(e.code, http_client.NOT_FOUND) + self.assertEqual(e.code, http.client.NOT_FOUND) self.__dc.stop() # For this disabled case, all /catalog/ operations should return @@ -727,7 +726,7 @@ def test_disable_ops(self): try: urlopen("{0}/catalog/{1:d}/".format(durl, ver)) except HTTPError as e: - self.assertEqual(e.code, http_client.NOT_FOUND) + self.assertEqual(e.code, http.client.NOT_FOUND) self.__dc.stop() # In the normal case, /catalog/1/ should return @@ -738,7 +737,7 @@ def test_disable_ops(self): try: urlopen("{0}/catalog/1/".format(durl)) except HTTPError as e: - self.assertEqual(e.code, http_client.FORBIDDEN) + self.assertEqual(e.code, http.client.FORBIDDEN) self.__dc.stop() # A bogus operation should prevent the depot from starting. @@ -1137,7 +1136,7 @@ def test_2_depot_p5i(self): try: urlopen(urljoin(durl, "p5i/0/nosuchpackage")) except HTTPError as e: - if e.code != http_client.NOT_FOUND: + if e.code != http.client.NOT_FOUND: raise def test_3_headers(self): @@ -1181,20 +1180,12 @@ def get_headers(req_path): "file/0/3aad0bca6f3a6f502c175700ebe90ef36e312d7e", ): hdrs = dict(get_headers(req_path)) - if six.PY2: - # Fields must be referenced in lowercase. - cc = hdrs.get("cache-control", "") - self.assertTrue( - cc.startswith("must-revalidate, " "no-transform, max-age=") - ) - exp = hdrs.get("expires", None) - else: - # Fields begin with uppercase. - cc = hdrs.get("Cache-Control", "") - self.assertTrue( - cc.startswith("must-revalidate, " "no-transform, max-age=") - ) - exp = hdrs.get("Expires", None) + # Fields begin with uppercase. + cc = hdrs.get("Cache-Control", "") + self.assertTrue( + cc.startswith("must-revalidate, " "no-transform, max-age=") + ) + exp = hdrs.get("Expires", None) self.assertNotEqual(exp, None) self.assertTrue(exp.endswith(" GMT")) @@ -1203,12 +1194,8 @@ def get_headers(req_path): "file/0/3aad0bca6f3a6f502c175700ebe90ef36e312d7f", ): hdrs = dict(get_headers(req_path)) - if six.PY2: - cc = hdrs.get("cache-control", None) - prg = hdrs.get("pragma", None) - else: - cc = hdrs.get("Cache-Control", None) - prg = hdrs.get("Pragma", None) + cc = hdrs.get("Cache-Control", None) + prg = hdrs.get("Pragma", None) self.assertEqual(cc, None) self.assertEqual(prg, None) diff --git a/src/tests/cli/t_pkg_help.py b/src/tests/cli/t_pkg_help.py index d407251e7..61f3b71a4 100644 --- a/src/tests/cli/t_pkg_help.py +++ b/src/tests/cli/t_pkg_help.py @@ -31,7 +31,6 @@ import codecs import os import re -import six import unittest from pkg.misc import force_text diff --git a/src/tests/cli/t_pkg_history.py b/src/tests/cli/t_pkg_history.py index 750fcaced..158be06fa 100644 --- a/src/tests/cli/t_pkg_history.py +++ b/src/tests/cli/t_pkg_history.py @@ -35,7 +35,6 @@ import random import re import shutil -import six import subprocess import time import unittest diff --git a/src/tests/cli/t_pkg_info.py b/src/tests/cli/t_pkg_info.py index ce38ac479..49bef88ae 100644 --- a/src/tests/cli/t_pkg_info.py +++ b/src/tests/cli/t_pkg_info.py @@ -31,7 +31,6 @@ import json import os import shutil -import six import unittest import pkg.catalog as catalog @@ -623,8 +622,7 @@ def test_ranked(self): """ self.assertEqualDiff(expected, self.reduceSpaces(self.output)) - if six.PY3: - os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["LC_ALL"] = "en_US.UTF-8" def test_renamed_packages(self): """Verify that info returns the expected output for renamed @@ -776,8 +774,7 @@ def test_renamed_packages(self): ) self.assertEqualDiff(expected, actual) - if six.PY3: - os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["LC_ALL"] = "en_US.UTF-8" def test_legacy_packages(self): """Verify that info returns the expected output for legacy @@ -887,8 +884,7 @@ def test_legacy_packages(self): ) self.assertEqualDiff(expected, actual) - if six.PY3: - os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["LC_ALL"] = "en_US.UTF-8" def test_appropriate_license_files(self): """Verify that the correct license file is displayed.""" @@ -989,8 +985,7 @@ def test_info_update_install(self): ) ) - if six.PY3: - os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["LC_ALL"] = "en_US.UTF-8" class TestPkgInfoPerTestRepo(pkg5unittest.SingleDepotTestCase): diff --git a/src/tests/cli/t_pkg_install.py b/src/tests/cli/t_pkg_install.py index eec95c56d..3f200a8be 100644 --- a/src/tests/cli/t_pkg_install.py +++ b/src/tests/cli/t_pkg_install.py @@ -47,14 +47,8 @@ import time import unittest import locale -from six.moves import range -from six.moves.urllib.parse import quote -from six.moves.urllib.request import ( - urlopen, - build_opener, - ProxyHandler, - Request, -) +from urllib.parse import quote +from urllib.request import urlopen, build_opener, ProxyHandler, Request import pkg.actions import pkg.digest as digest diff --git a/src/tests/cli/t_pkg_linked.py b/src/tests/cli/t_pkg_linked.py index 4ae574776..1fc49d1e4 100644 --- a/src/tests/cli/t_pkg_linked.py +++ b/src/tests/cli/t_pkg_linked.py @@ -26,7 +26,6 @@ # from __future__ import division -from __future__ import print_function from . import testutils @@ -4786,9 +4785,7 @@ def test_linked_install_hold_relax_constrained_4(self): class TestPkgLinkedScale(pkg5unittest.ManyDepotTestCase): """Test the scalability of the linked image subsystem.""" - max_image_count = 256 - if six.PY3: - max_image_count = 32 + max_image_count = 32 p_sync1 = [] p_vers = [ diff --git a/src/tests/cli/t_pkg_mediated.py b/src/tests/cli/t_pkg_mediated.py index ac2f09823..c831f4b12 100644 --- a/src/tests/cli/t_pkg_mediated.py +++ b/src/tests/cli/t_pkg_mediated.py @@ -35,7 +35,6 @@ import pkg.misc as misc import pkg.p5p import shutil -import six import stat import tempfile import unittest @@ -340,8 +339,7 @@ def setUp(self): [ getattr(self, p) for p in dir(self) - if p.startswith("pkg_") - and isinstance(getattr(self, p), six.string_types) + if p.startswith("pkg_") and isinstance(getattr(self, p), str) ], ) diff --git a/src/tests/cli/t_pkg_nasty.py b/src/tests/cli/t_pkg_nasty.py index 2762c732f..210c892d1 100644 --- a/src/tests/cli/t_pkg_nasty.py +++ b/src/tests/cli/t_pkg_nasty.py @@ -24,7 +24,6 @@ # Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function from . import testutils if __name__ == "__main__": diff --git a/src/tests/cli/t_pkg_search.py b/src/tests/cli/t_pkg_search.py index ff50117b6..8a92ef9ba 100644 --- a/src/tests/cli/t_pkg_search.py +++ b/src/tests/cli/t_pkg_search.py @@ -24,7 +24,6 @@ # Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function from . import testutils if __name__ == "__main__": @@ -35,11 +34,10 @@ import hashlib import os import shutil -import six import sys import unittest -from six.moves.urllib.error import HTTPError -from six.moves.urllib.request import urlopen +from urllib.error import HTTPError +from urllib.request import urlopen import pkg.catalog as catalog import pkg.client.pkgdefs as pkgdefs diff --git a/src/tests/cli/t_pkg_sysrepo.py b/src/tests/cli/t_pkg_sysrepo.py index 7b9c14b2d..28a385338 100644 --- a/src/tests/cli/t_pkg_sysrepo.py +++ b/src/tests/cli/t_pkg_sysrepo.py @@ -24,7 +24,6 @@ # Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function from . import testutils if __name__ == "__main__": @@ -35,7 +34,6 @@ import glob import os import shutil -import six import pkg.client.api_errors as apx import pkg.client.transport.exception as tx @@ -527,7 +525,7 @@ def __prep_configuration(self, names, port=None, use_config_cache=False): if not port: port = self.sysrepo_port self.__configured_names = [] - if isinstance(names, six.string_types): + if isinstance(names, str): names = [names] for name in names: props, pcs = self.configs[name] diff --git a/src/tests/cli/t_pkg_temp_sources.py b/src/tests/cli/t_pkg_temp_sources.py index 8e590b1c2..84763b78c 100644 --- a/src/tests/cli/t_pkg_temp_sources.py +++ b/src/tests/cli/t_pkg_temp_sources.py @@ -39,7 +39,6 @@ import pkg.misc as misc import pkg.p5p import shutil -import six import stat import tempfile import unittest @@ -127,7 +126,7 @@ class TestPkgTempSources(pkg5unittest.ManyDepotTestCase): ] def __seed_ta_dir(self, certs, dest_dir=None): - if isinstance(certs, six.string_types): + if isinstance(certs, str): certs = [certs] if not dest_dir: dest_dir = self.ta_dir @@ -665,8 +664,7 @@ def pd(pfmri): # Cleanup. self.image_destroy() # Change locale back to 'UTF-8' to not affect other test cases. - if six.PY3: - os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["LC_ALL"] = "en_US.UTF-8" def test_02_contents(self): """Verify that the contents operation works as expected for diff --git a/src/tests/cli/t_pkg_varcet.py b/src/tests/cli/t_pkg_varcet.py index 77c2a5498..633203706 100644 --- a/src/tests/cli/t_pkg_varcet.py +++ b/src/tests/cli/t_pkg_varcet.py @@ -34,7 +34,6 @@ import pkg.misc as misc import pkg.p5p import shutil -import six import stat import tempfile import unittest @@ -138,8 +137,7 @@ def setUp(self): [ getattr(self, p) for p in dir(self) - if p.startswith("pkg_") - and isinstance(getattr(self, p), six.string_types) + if p.startswith("pkg_") and isinstance(getattr(self, p), str) ], ) @@ -888,7 +886,6 @@ def test_03_variant_globbing(self): ) - class TestPkgVarcetErrors(pkg5unittest.Pkg5TestCase): """This test class verifies that errors raised while within the _varcet extension are handled gracefully and won't cause segmentation faults.""" @@ -924,7 +921,7 @@ def __init__(self, problem, inproblem): self.assertRaises(TypeError, facets.allow_action, Action(1, 0), None) # value encoding failure handling - self.assertEquals(facets.allow_action(Action(0, 1), None), False) + self.assertEqual(facets.allow_action(Action(0, 1), None), False) self.assertRaises( KeyboardInterrupt, facets.allow_action, Action(0, 2), None ) @@ -949,7 +946,7 @@ def __init__(self, problem): # attr and value encoding failure handling self.assertRaises(TypeError, variants.allow_action, Action(1), None) - self.assertEquals(variants.allow_action(Action(2), None), False) + self.assertEqual(variants.allow_action(Action(2), None), False) # variant value encoding failure handling variants = variant.Variants({"variant.icecream": b"strawberry"}) diff --git a/src/tests/cli/t_pkgdep.py b/src/tests/cli/t_pkgdep.py index 564f3fe3e..39b070246 100644 --- a/src/tests/cli/t_pkgdep.py +++ b/src/tests/cli/t_pkgdep.py @@ -1291,7 +1291,7 @@ def pkgsend_with_fmri(self, pth): def check_res(self, expected, seen): def pick_file(act): fs = act.attrs[DDP + ".file"] - if isinstance(fs, six.string_types): + if isinstance(fs, str): fs = [fs] for f in fs: if f.endswith(".py") and "__init__" not in f: diff --git a/src/tests/cli/t_pkgrecv.py b/src/tests/cli/t_pkgrecv.py index 607b1c5bc..d06a4ba12 100644 --- a/src/tests/cli/t_pkgrecv.py +++ b/src/tests/cli/t_pkgrecv.py @@ -53,8 +53,8 @@ from pkg.actions import fromstr from pkg.digest import DEFAULT_HASH_FUNC import pkg.json as json -from six.moves.urllib.parse import urlparse -from six.moves.urllib.request import url2pathname +from urllib.parse import urlparse +from urllib.request import url2pathname try: import pkg.sha512_t diff --git a/src/tests/cli/t_pkgrepo.py b/src/tests/cli/t_pkgrepo.py index af0510e2a..2cc3b0f1d 100644 --- a/src/tests/cli/t_pkgrepo.py +++ b/src/tests/cli/t_pkgrepo.py @@ -45,7 +45,6 @@ import pkg.client.api_errors as apx import pkg.p5p import shutil -import six import subprocess import tempfile import time diff --git a/src/tests/cli/t_pkgsend.py b/src/tests/cli/t_pkgsend.py index bc14fa645..7b1654ae6 100644 --- a/src/tests/cli/t_pkgsend.py +++ b/src/tests/cli/t_pkgsend.py @@ -39,9 +39,8 @@ import tempfile import unittest import six -from six.moves import range -from six.moves.urllib.error import HTTPError -from six.moves.urllib.request import urlopen, Request, pathname2url +from urllib.error import HTTPError +from urllib.request import urlopen, Request, pathname2url from pkg import misc from pkg.actions import fromstr diff --git a/src/tests/cli/t_pkgsign.py b/src/tests/cli/t_pkgsign.py index 9b0d8ebd7..a177a1559 100644 --- a/src/tests/cli/t_pkgsign.py +++ b/src/tests/cli/t_pkgsign.py @@ -24,7 +24,6 @@ # Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function from . import testutils if __name__ == "__main__": diff --git a/src/tests/cli/t_publish_api.py b/src/tests/cli/t_publish_api.py index 731c00890..6ebabc5ae 100644 --- a/src/tests/cli/t_publish_api.py +++ b/src/tests/cli/t_publish_api.py @@ -31,8 +31,8 @@ import pkg5unittest import os -from six.moves.urllib.parse import urlunparse -from six.moves.urllib.request import pathname2url +from urllib.parse import urlunparse +from urllib.request import pathname2url import pkg.client.publisher as publisher import pkg.client.transport.transport as transport diff --git a/src/tests/cli/t_sysrepo.py b/src/tests/cli/t_sysrepo.py index 41842a394..cad3162f8 100644 --- a/src/tests/cli/t_sysrepo.py +++ b/src/tests/cli/t_sysrepo.py @@ -35,19 +35,17 @@ import errno import hashlib import importlib.util +import io import os import os.path import pkg.p5p import shutil import unittest import shutil -import six import stat import sys import time -from six.moves.urllib.error import HTTPError -from six.moves.urllib.parse import urlparse, unquote -from six.moves.urllib.request import urlopen +from urllib.parse import urlparse, unquote import pkg.misc as misc import pkg.json as json @@ -768,7 +766,7 @@ def test_15_unicode(self): # will fail with some unicode characters in Python 3 because # os.mkdir uses the file system encoding. We don't have a way # to set the file system encoding in Python, so we just skip. - if six.PY3 and sys.getfilesystemencoding() == "ascii": + if sys.getfilesystemencoding() == "ascii": return unicode_str = "ΰŇﺇ⊂⏣⊅ℇ" unicode_dir = os.path.join(self.test_root, unicode_str) @@ -1176,7 +1174,7 @@ def test_query_responses(queries, code, expect_content=False): # so to reduce console noise, we # redirect that temporarily. saved_stdout = sys.stdout - sys.stdout = six.StringIO() + sys.stdout = io.StringIO() for item in self.sysrepo_p5p.application( environ, start_response ): diff --git a/src/tests/cli/t_util_merge.py b/src/tests/cli/t_util_merge.py index 262c42a33..6d65f8987 100644 --- a/src/tests/cli/t_util_merge.py +++ b/src/tests/cli/t_util_merge.py @@ -40,8 +40,7 @@ import unittest import zlib -from six.moves.urllib.parse import urlparse -from six.moves.urllib.request import url2pathname +from urllib.parse import urlparse class TestUtilMerge(pkg5unittest.ManyDepotTestCase): diff --git a/src/tests/interactive/runprintengine.py b/src/tests/interactive/runprintengine.py index cec583939..69f2f9350 100755 --- a/src/tests/interactive/runprintengine.py +++ b/src/tests/interactive/runprintengine.py @@ -24,7 +24,6 @@ # Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import getopt import locale import gettext diff --git a/src/tests/interactive/runprogress.py b/src/tests/interactive/runprogress.py index 4d1d32a03..83bd24a82 100755 --- a/src/tests/interactive/runprogress.py +++ b/src/tests/interactive/runprogress.py @@ -24,7 +24,6 @@ # Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import sys import getopt import gettext diff --git a/src/tests/perf/actionbench.py b/src/tests/perf/actionbench.py index f4528d47c..1e76d5c48 100644 --- a/src/tests/perf/actionbench.py +++ b/src/tests/perf/actionbench.py @@ -29,7 +29,6 @@ # from __future__ import division -from __future__ import print_function import pkg.actions as actions diff --git a/src/tests/perf/fmribench.py b/src/tests/perf/fmribench.py index bb9ab2d06..2324b94d6 100644 --- a/src/tests/perf/fmribench.py +++ b/src/tests/perf/fmribench.py @@ -30,7 +30,6 @@ # from __future__ import division -from __future__ import print_function import pkg.fmri as fmri import pkg.version as version diff --git a/src/tests/perf/manbench.py b/src/tests/perf/manbench.py index 99f62e4fb..ca2e4f64d 100644 --- a/src/tests/perf/manbench.py +++ b/src/tests/perf/manbench.py @@ -29,7 +29,6 @@ # from __future__ import division -from __future__ import print_function import sys diff --git a/src/tests/perf/membench.py b/src/tests/perf/membench.py index 25cdd22e0..0b83d5982 100644 --- a/src/tests/perf/membench.py +++ b/src/tests/perf/membench.py @@ -29,7 +29,6 @@ # from __future__ import division -from __future__ import print_function import pkg.fmri as fmri import pkg.version as version diff --git a/src/tests/pkg5testenv.py b/src/tests/pkg5testenv.py index 6de906fa8..733f31a02 100644 --- a/src/tests/pkg5testenv.py +++ b/src/tests/pkg5testenv.py @@ -22,7 +22,6 @@ # Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. -from __future__ import print_function import os import sys import platform diff --git a/src/tests/pkg5unittest.py b/src/tests/pkg5unittest.py index f02041faf..de096359e 100644 --- a/src/tests/pkg5unittest.py +++ b/src/tests/pkg5unittest.py @@ -35,14 +35,16 @@ # from __future__ import division -from __future__ import print_function import baseline +import configparser import copy import difflib import errno import gettext import grp import hashlib +import http.client +import io import locale import logging import multiprocessing @@ -71,10 +73,9 @@ from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from importlib import reload -from six.moves import configparser, http_client -from six.moves.urllib.error import HTTPError, URLError -from six.moves.urllib.parse import urljoin -from six.moves.urllib.request import urlopen +from urllib.error import HTTPError, URLError +from urllib.parse import urljoin +from urllib.request import urlopen from socket import error as socketerror import pkg.client.api_errors as apx @@ -327,9 +328,7 @@ def assertRegexp(self, text, regexp): '"{0}" does not match "{1}"'.format(regexp, text) ) - def assertRaisesRegex( - self, excClass, regexp, callableObj, *args, **kwargs - ): + def assertRaisesRegex(self, excClass, regexp, callableObj, *args, **kwargs): """Perform the same logic as assertRaises, but then verify that the stringified version of the exception contains the regexp pattern. @@ -402,7 +401,7 @@ def __drain(masterf, outlist): outlist.append(termdata) # This is the arg handling protocol from Popen - if isinstance(args, six.string_types): + if isinstance(args, str): args = [args] else: args = list(args) @@ -946,7 +945,7 @@ def make_misc_files(self, files, prefix=None, mode=0o644, copy=False): # a list, simply turn it into a dict where each file's # contents is its own name, so that we get some uniqueness. # - if isinstance(files, six.string_types): + if isinstance(files, str): files = [files] if isinstance(files, list): @@ -1019,9 +1018,9 @@ def assertEqualDiff( ): """Compare two strings.""" - if not isinstance(expected, six.string_types): + if not isinstance(expected, str): expected = pprint.pformat(expected) - if not isinstance(actual, six.string_types): + if not isinstance(actual, str): actual = pprint.pformat(actual) expected_lines = expected.splitlines() @@ -1095,7 +1094,7 @@ def assertEqualParsable( """Check that the parsable output in 'output' is what is expected.""" - if isinstance(output, six.string_types): + if isinstance(output, str): try: outd = json.loads(output) except Exception as e: @@ -1706,7 +1705,7 @@ def q_run( # suite and we're about to start running it. outq.put(("START", find_names(test_suite.tests[0]), i), block=True) - buf = six.StringIO() + buf = io.StringIO() b = baseline.ReadOnlyBaseLine(filename=baseline_filepath) b.load() # Build a _Pkg5TestResult object to use for this test. @@ -4036,7 +4035,7 @@ def file_contains(self, path, strings, appearances=1): image. The counting of appearances is line based. Repeated string on the same line will be count once.""" - if isinstance(strings, six.string_types): + if isinstance(strings, str): strings = [strings] # Initialize a dict for counting appearances. @@ -4072,7 +4071,7 @@ def file_contains(self, path, strings, appearances=1): def file_doesnt_contain(self, path, strings): """Assert the non-existence of strings in a file in the image.""" - if isinstance(strings, six.string_types): + if isinstance(strings, str): strings = [strings] file_path = os.path.join(self.get_img_path(), path) @@ -4108,7 +4107,7 @@ def file_append(self, path, string): f.write("\n{0}\n".format(string)) def seed_ta_dir(self, certs, dest_dir=None): - if isinstance(certs, six.string_types): + if isinstance(certs, str): certs = [certs] if not dest_dir: dest_dir = self.ta_dir @@ -4378,7 +4377,7 @@ def pkgrepo(self, command, *args, **kwargs): return ApacheDepotTestCase.pkgrepo(self, command, *args, **kwargs) def seed_ta_dir(self, certs, dest_dir=None): - if isinstance(certs, six.string_types): + if isinstance(certs, str): certs = [certs] if not dest_dir: dest_dir = self.ta_dir @@ -5097,7 +5096,7 @@ def _network_ping(self): try: urlopen(self.__url) except HTTPError as e: - if e.code == http_client.FORBIDDEN: + if e.code == http.client.FORBIDDEN: return True return False except URLError as e: @@ -5294,7 +5293,7 @@ def _network_ping(self): try: urlopen(urljoin(self.url, "syspub/0")) except HTTPError as e: - if e.code == http_client.FORBIDDEN: + if e.code == http.client.FORBIDDEN: return True return False except URLError: @@ -5318,7 +5317,7 @@ def _network_ping(self): # if the depot is running. urlopen(repourl, context=ssl._create_unverified_context()) except HTTPError as e: - if e.code == http_client.FORBIDDEN: + if e.code == http.client.FORBIDDEN: return True return False except URLError: diff --git a/src/tests/ro_data/signing_certs/generate_certs.py b/src/tests/ro_data/signing_certs/generate_certs.py index 58b000310..cb1d89395 100755 --- a/src/tests/ro_data/signing_certs/generate_certs.py +++ b/src/tests/ro_data/signing_certs/generate_certs.py @@ -24,7 +24,6 @@ # Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import os import pkg.pkgsubprocess as subprocess import shutil diff --git a/src/tests/run.py b/src/tests/run.py index 73954f257..974ec1260 100755 --- a/src/tests/run.py +++ b/src/tests/run.py @@ -25,7 +25,6 @@ # Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # -from __future__ import print_function import multiprocessing import json as stdlibjson import os diff --git a/src/util/apache2/depot/depot_index.py b/src/util/apache2/depot/depot_index.py index 9bca46001..6001eb65c 100755 --- a/src/util/apache2/depot/depot_index.py +++ b/src/util/apache2/depot/depot_index.py @@ -21,11 +21,11 @@ # # Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. -from __future__ import print_function import atexit import cherrypy import logging import mako +import http.client import os import re import shutil @@ -35,9 +35,7 @@ import time import traceback -from six.moves import http_client, queue -from six.moves.urllib.parse import quote -from six.moves.urllib.request import urlopen +from urllib.parse import quote import pkg.misc as misc import pkg.p5i @@ -82,7 +80,7 @@ class DepotException(Exception): def __init__(self, request, message): self.request = request self.message = message - self.http_status = http_client.INTERNAL_SERVER_ERROR + self.http_status = http.client.INTERNAL_SERVER_ERROR def __str__(self): return "{0}: {1}".format(self.message, self.request) @@ -94,7 +92,7 @@ class AdminOpsDisabledException(DepotException): def __init__(self, request): self.request = request - self.http_status = http_client.FORBIDDEN + self.http_status = http.client.FORBIDDEN def __str__(self): return ( @@ -111,7 +109,7 @@ class AdminOpNotSupportedException(DepotException): def __init__(self, request, cmd): self.request = request self.cmd = cmd - self.http_status = http_client.NOT_IMPLEMENTED + self.http_status = http.client.NOT_IMPLEMENTED def __str__(self): return ( @@ -127,7 +125,7 @@ class IndexOpDisabledException(DepotException): def __init__(self, request): self.request = request - self.http_status = http_client.FORBIDDEN + self.http_status = http.client.FORBIDDEN def __str__(self): return ( @@ -694,7 +692,7 @@ def admin(self, *tokens, **params): pass if not success: raise cherrypy.HTTPError( - status=http_client.SERVICE_UNAVAILABLE, + status=http.client.SERVICE_UNAVAILABLE, message="Unable to refresh the " "index for {0} after repeated " "retries. Try again later.".format(request.path_info), @@ -734,7 +732,7 @@ def __init__(self, wsgi_depot): @staticmethod def default_error_page( - status=http_client.NOT_FOUND, + status=http.client.NOT_FOUND, message="oops", traceback=None, version=None, @@ -751,15 +749,15 @@ def default_error_page( # Server errors are interesting, so let's log them. In the case # of an internal server error, we send a 404 to the client. but # log the full details in the server log. - if status == http_client.INTERNAL_SERVER_ERROR or status.startswith( + if status == http.client.INTERNAL_SERVER_ERROR or status.startswith( "500 " ): # Convert the error to a 404 to obscure implementation # from the client, but log the original error to the # server logs. error = cherrypy._cperror._HTTPErrorTemplate % { - "status": http_client.NOT_FOUND, - "message": http_client.responses[http_client.NOT_FOUND], + "status": http.client.NOT_FOUND, + "message": http.client.responses[http.client.NOT_FOUND], "traceback": "", "version": cherrypy.__version__, } @@ -772,7 +770,7 @@ def default_error_page( return error else: error = cherrypy._cperror._HTTPErrorTemplate % { - "status": http_client.NOT_FOUND, + "status": http.client.NOT_FOUND, "message": message, "traceback": "", "version": cherrypy.__version__, @@ -851,7 +849,7 @@ def dispatch(self, path_info): # converted and logged by our error handler # before the client sees it. raise cherrypy.HTTPError( - status=http_client.INTERNAL_SERVER_ERROR, + status=http.client.INTERNAL_SERVER_ERROR, message="".join(traceback.format_exc(e)), ) diff --git a/src/util/apache2/sysrepo/sysrepo_p5p.py b/src/util/apache2/sysrepo/sysrepo_p5p.py index f40f89c05..629a20401 100755 --- a/src/util/apache2/sysrepo/sysrepo_p5p.py +++ b/src/util/apache2/sysrepo/sysrepo_p5p.py @@ -22,16 +22,14 @@ # Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. # Copyright 2020 OmniOS Community Edition (OmniOSce) Association. -from __future__ import print_function import pkg.p5p +import http.client import os import shutil -import six import sys import threading import traceback -from six.moves import http_client import pkg.json as json from pkg.misc import force_str @@ -39,17 +37,17 @@ sys.stdout = sys.stderr SERVER_OK_STATUS = "{0} {1}".format( - http_client.OK, http_client.responses[http_client.OK] + http.client.OK, http.client.responses[http.client.OK] ) SERVER_ERROR_STATUS = "{0} {1}".format( - http_client.INTERNAL_SERVER_ERROR, - http_client.responses[http_client.INTERNAL_SERVER_ERROR], + http.client.INTERNAL_SERVER_ERROR, + http.client.responses[http.client.INTERNAL_SERVER_ERROR], ) SERVER_NOTFOUND_STATUS = "{0} {1}".format( - http_client.NOT_FOUND, http_client.responses[http_client.NOT_FOUND] + http.client.NOT_FOUND, http.client.responses[http.client.NOT_FOUND] ) SERVER_BADREQUEST_STATUS = "{0} {1}".format( - http_client.BAD_REQUEST, http_client.responses[http_client.BAD_REQUEST] + http.client.BAD_REQUEST, http.client.responses[http.client.BAD_REQUEST] ) response_headers = [("content-type", "application/binary")] @@ -323,18 +321,14 @@ def execute(self): try: pub, hsh, path = self._parse_query() self.p5p_path = self.environ[hsh] - if six.PY3: - # The pathname return from environ contains - # hex escaped sequences, but we need its unicode - # character to be able to find the file. - self.p5p_path = self.p5p_path.encode("iso-8859-1").decode( - "utf-8" - ) - # In order to keep only one copy of the p5p index in - # memory, we cache it locally, and reuse it any time - # we're opening the same p5p file. Before doing - # so, we need to ensure the p5p file hasn't been - # modified since we last looked at it. + # The pathname returned from environ contains hex escaped + # sequences, but we need its unicode character to be able to find + # the file. + self.p5p_path = self.p5p_path.encode("iso-8859-1").decode("utf-8") + # In order to keep only one copy of the p5p index in memory, we + # cache it locally, and reuse it any time we're opening the same + # p5p file. Before doing so, we need to ensure the p5p file hasn't + # been modified since we last looked at it. if self.need_update(pub, hsh) or self.p5p_path not in p5p_indices: p5p_update_lock.acquire() try: @@ -429,7 +423,7 @@ def __call__(self, environ, start_response): if __name__ == "__main__": """A simple main function to allows us to test any given query/env""" - from six.moves.urllib.parse import unquote + from urllib.parse import unquote def start_response(status, response_headers, exc_info=None): """A dummy response function.""" @@ -458,7 +452,7 @@ def start_response(status, response_headers, exc_info=None): environ[hsh] = path for response in application(environ, start_response): - if isinstance(response, six.string_types): + if isinstance(response, str): print(response.rstrip()) elif response: for line in response.readlines(): diff --git a/src/util/log-scripts/an2_ip_active.py b/src/util/log-scripts/an2_ip_active.py index fe59eb1e8..e458bb9c4 100644 --- a/src/util/log-scripts/an2_ip_active.py +++ b/src/util/log-scripts/an2_ip_active.py @@ -25,7 +25,6 @@ # from __future__ import division -from __future__ import print_function import six.moves.cPickle as pickle import datetime import time diff --git a/src/util/log-scripts/an_catalog.py b/src/util/log-scripts/an_catalog.py index 465e4fb6e..ed4b5953c 100644 --- a/src/util/log-scripts/an_catalog.py +++ b/src/util/log-scripts/an_catalog.py @@ -45,7 +45,6 @@ printed to catalog.html in the current directory. """ -from __future__ import print_function import datetime import fileinput import getopt diff --git a/src/util/log-scripts/an_filelist.py b/src/util/log-scripts/an_filelist.py index 244388b95..325c7daab 100644 --- a/src/util/log-scripts/an_filelist.py +++ b/src/util/log-scripts/an_filelist.py @@ -25,7 +25,6 @@ # from __future__ import division -from __future__ import print_function import datetime import fileinput import getopt diff --git a/src/util/log-scripts/an_first_timestamp.py b/src/util/log-scripts/an_first_timestamp.py index 138fc2a9b..3b5f931a1 100644 --- a/src/util/log-scripts/an_first_timestamp.py +++ b/src/util/log-scripts/an_first_timestamp.py @@ -28,7 +28,6 @@ """an_first_timestamp.py - read first line of an Apache HTTPD log, and print Unix timestamp""" -from __future__ import print_function import datetime import fileinput import re diff --git a/src/util/log-scripts/an_manifest.py b/src/util/log-scripts/an_manifest.py index 60196d32f..d051de7b3 100644 --- a/src/util/log-scripts/an_manifest.py +++ b/src/util/log-scripts/an_manifest.py @@ -24,7 +24,6 @@ # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import datetime import fileinput import getopt @@ -35,7 +34,7 @@ import time from an_report import * -from six.moves.urllib.parse import unquote +from urllib.parse import unquote after = None before = None diff --git a/src/util/log-scripts/an_report.py b/src/util/log-scripts/an_report.py index 341f61345..786821bee 100644 --- a/src/util/log-scripts/an_report.py +++ b/src/util/log-scripts/an_report.py @@ -25,7 +25,6 @@ # from __future__ import division -from __future__ import print_function import cPickle as pickle import GeoIP import datetime @@ -36,7 +35,6 @@ import sys import config -from six.moves.urllib.request import urlopen # Apache combined log pattern comb_log_pat = re.compile( diff --git a/src/util/log-scripts/an_search.py b/src/util/log-scripts/an_search.py index 4cce1da8b..752114044 100644 --- a/src/util/log-scripts/an_search.py +++ b/src/util/log-scripts/an_search.py @@ -24,7 +24,6 @@ # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import datetime import fileinput import getopt @@ -35,7 +34,7 @@ import time from an_report import * -from six.moves.urllib.parse import unquote +from urllib.parse import unquote after = None before = None diff --git a/src/util/log-scripts/config.py b/src/util/log-scripts/config.py index 37275ec6a..0dc47a071 100644 --- a/src/util/log-scripts/config.py +++ b/src/util/log-scripts/config.py @@ -25,7 +25,6 @@ # import os -from six.moves import configparser CFGFILE = "site-config" diff --git a/src/util/log-scripts/in_footer.py b/src/util/log-scripts/in_footer.py index ae0281eef..9eae79aea 100644 --- a/src/util/log-scripts/in_footer.py +++ b/src/util/log-scripts/in_footer.py @@ -24,7 +24,6 @@ # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function footer = """ diff --git a/src/util/log-scripts/in_header.py b/src/util/log-scripts/in_header.py index 6ab4e2956..9c8bbc2d1 100644 --- a/src/util/log-scripts/in_header.py +++ b/src/util/log-scripts/in_header.py @@ -24,7 +24,6 @@ # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import config hostname = config.get("hostname", default="pkg") diff --git a/src/util/log-scripts/log.py b/src/util/log-scripts/log.py index 7eebff63c..90164f3af 100644 --- a/src/util/log-scripts/log.py +++ b/src/util/log-scripts/log.py @@ -25,7 +25,6 @@ # from __future__ import division -from __future__ import print_function import pkg.site_paths pkg.site_paths.init() diff --git a/src/util/log-scripts/translate.py b/src/util/log-scripts/translate.py index e7542fbc2..fa51f05f3 100644 --- a/src/util/log-scripts/translate.py +++ b/src/util/log-scripts/translate.py @@ -24,7 +24,6 @@ # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import GeoIP import md5 import sys diff --git a/src/util/publish/pkgdiff.py b/src/util/publish/pkgdiff.py index 8d0130914..0b64102c6 100644 --- a/src/util/publish/pkgdiff.py +++ b/src/util/publish/pkgdiff.py @@ -24,14 +24,12 @@ # Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import pkg.site_paths pkg.site_paths.init() import getopt import gettext import locale -import six import sys import traceback import warnings @@ -418,9 +416,8 @@ def conditional_print(s, a): gettext.install("pkg", "/usr/share/locale") misc.set_fd_limits(printer=error) - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: exit_code = main_func() except (PipeError, KeyboardInterrupt): diff --git a/src/util/publish/pkgfmt.py b/src/util/publish/pkgfmt.py index bf8bdac2e..89696d434 100755 --- a/src/util/publish/pkgfmt.py +++ b/src/util/publish/pkgfmt.py @@ -24,7 +24,6 @@ # Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # -from __future__ import print_function import pkg.site_paths pkg.site_paths.init() @@ -62,6 +61,7 @@ import errno import getopt import gettext + import io import locale import operator import os @@ -73,7 +73,6 @@ import warnings from difflib import unified_diff from functools import cmp_to_key - from six.moves import cStringIO import pkg import pkg.actions @@ -614,8 +613,8 @@ def main_func(): def difference(in_file): whole_f1 = in_file.readlines() - f2 = cStringIO() - fmt_file(cStringIO("".join(whole_f1)), f2) + f2 = io.StringIO() + fmt_file(io.StringIO("".join(whole_f1)), f2) f2.seek(0) whole_f2 = f2.readlines() @@ -630,7 +629,7 @@ def difference(in_file): flist = pargs if not flist: try: - in_file = cStringIO() + in_file = io.StringIO() in_file.write(sys.stdin.read()) in_file.seek(0) @@ -790,9 +789,8 @@ def fmt_file(in_file, out_file): gettext.install("pkg", "/usr/share/locale") misc.set_fd_limits(printer=error) - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: __ret = main_func() except (PipeError, KeyboardInterrupt): diff --git a/src/util/publish/pkglint.py b/src/util/publish/pkglint.py index fd6e909cd..973fe98dd 100755 --- a/src/util/publish/pkglint.py +++ b/src/util/publish/pkglint.py @@ -29,7 +29,6 @@ pkg.site_paths.init() import codecs import logging -import six import sys import os import gettext @@ -396,9 +395,8 @@ def _make_list(opt): gettext.install("pkg", "/usr/share/locale") misc.set_fd_limits(printer=error) - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: __ret = main_func() except (PipeError, KeyboardInterrupt): diff --git a/src/util/publish/pkgmerge.py b/src/util/publish/pkgmerge.py index 086ba1097..64be45592 100755 --- a/src/util/publish/pkgmerge.py +++ b/src/util/publish/pkgmerge.py @@ -23,7 +23,6 @@ # Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import pkg.site_paths pkg.site_paths.init() @@ -54,7 +53,7 @@ from functools import reduce from pkg.misc import PipeError, emsg, msg - from six.moves.urllib.parse import quote + from urllib.parse import quote from pkg.client.pkgdefs import EXIT_OK, EXIT_OOPS, EXIT_BADOPT, EXIT_PARTIAL except KeyboardInterrupt: import sys @@ -1024,9 +1023,8 @@ def match_user_fmris(patterns, cat): import warnings warnings.simplefilter("error") - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: __ret = main_func() except ( diff --git a/src/util/publish/pkgmogrify.py b/src/util/publish/pkgmogrify.py index fa038723f..9a4387a5c 100755 --- a/src/util/publish/pkgmogrify.py +++ b/src/util/publish/pkgmogrify.py @@ -23,14 +23,12 @@ # Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import pkg.site_paths pkg.site_paths.init() import getopt import gettext import locale -import six import sys import traceback import warnings @@ -170,9 +168,8 @@ def main_func(): # Make all warnings be errors. warnings.simplefilter("error") - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: exit_code = main_func() except (PipeError, KeyboardInterrupt): diff --git a/src/util/publish/pkgsurf.py b/src/util/publish/pkgsurf.py index 1d78ea110..ced81db85 100644 --- a/src/util/publish/pkgsurf.py +++ b/src/util/publish/pkgsurf.py @@ -74,7 +74,6 @@ import locale import os import shutil -import six import sys import tempfile import traceback @@ -423,7 +422,7 @@ def use_ref(a, deps, ignores): if a.name == "depend": # TODO: support dependency lists # For now, treat as content change. - if not isinstance(a.attrs["fmri"], six.string_types): + if not isinstance(a.attrs["fmri"], str): return False dpfmri = fmri.PkgFmri(a.attrs["fmri"]) deps.add(dpfmri.get_pkg_stem()) @@ -994,9 +993,8 @@ def main_func(): gettext.install("pkg", "/usr/share/locale") misc.set_fd_limits(printer=error) - if six.PY3: - # disable ResourceWarning: unclosed file - warnings.filterwarnings("ignore", category=ResourceWarning) + # disable ResourceWarning: unclosed file + warnings.filterwarnings("ignore", category=ResourceWarning) try: __ret = main_func() except PipeError: diff --git a/src/util/qual-simulator/scenario.py b/src/util/qual-simulator/scenario.py index 279b8a07f..9521de743 100644 --- a/src/util/qual-simulator/scenario.py +++ b/src/util/qual-simulator/scenario.py @@ -24,7 +24,6 @@ # Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. # -from __future__ import print_function import gettext import locale import sys diff --git a/src/web/config.shtml b/src/web/config.shtml index 6ca06f238..4ce9350a1 100644 --- a/src/web/config.shtml +++ b/src/web/config.shtml @@ -25,7 +25,7 @@ ## <%! import re - from six.moves.urllib.parse import urlparse + from urllib.parse import urlparse %>\ <%page args="g_vars"/>\ <% diff --git a/src/web/en/advanced_search.shtml b/src/web/en/advanced_search.shtml index 30ac897c9..a3ca979cc 100644 --- a/src/web/en/advanced_search.shtml +++ b/src/web/en/advanced_search.shtml @@ -23,7 +23,7 @@ ## <%! import pkg.query_parser as qp - from six.moves.urllib.parse import unquote, quote + from urllib.parse import unquote, quote %>\ <%inherit file="search.shtml"/>\ <%page args="g_vars"/>\ diff --git a/src/web/en/catalog.shtml b/src/web/en/catalog.shtml index f786f51fe..09c9e5301 100644 --- a/src/web/en/catalog.shtml +++ b/src/web/en/catalog.shtml @@ -23,7 +23,7 @@ ## <%! import pkg.fmri - from six.moves.urllib.parse import quote + from urllib.parse import quote %>\ <%inherit file="layout.shtml"/>\ <%page args="g_vars"/>\ diff --git a/src/web/en/search.shtml b/src/web/en/search.shtml index dde34d174..ef4d97ff9 100644 --- a/src/web/en/search.shtml +++ b/src/web/en/search.shtml @@ -23,18 +23,14 @@ ## <%! import six - if six.PY2: - import cgi - else: - # cgi.escape is deprecated since python 3.2 - import html as cgi + import html as cgi import itertools import pkg.actions as actions import pkg.query_parser as qp import pkg.server.api_errors as api_errors import pkg.version as version import re - from six.moves.urllib.parse import urlencode, quote, urlparse, urlunparse + from urllib.parse import urlencode, quote, urlparse, urlunparse %>\ <%inherit file="layout.shtml"/>\ <%page args="g_vars"/>\ @@ -131,10 +127,7 @@ # have to be checked for the real return type. if results: try: - if six.PY3: - result = results.__next__() - else: - result = results.next() + result = results.__next__() except StopIteration: result = None results = None From 12e2a152fad49b14bff024a97e8adddadf89e18b Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Tue, 5 Dec 2023 14:17:38 +0000 Subject: [PATCH 12/15] Update README.sync --- README.sync | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.sync b/README.sync index 9b629d6ce..b5a63effe 100644 --- a/README.sync +++ b/README.sync @@ -4,11 +4,12 @@ The pkg5 components have been updated to the latest upstream solaris-ips as of: -commit c5674fc26b31cd234007b090c451aa4ea0e0a668 +commit fc93022c19a68dae3db7613ff1860e6371fe85bc Author: Jakub Kulik -Date: Fri Oct 20 06:43:37 2023 -0700 +Date: Tue Dec 5 00:40:48 2023 -0800 - 34044891 pkg verify is outputting ELF error that makes no sense + 36066495 remove all trivial use of six library from pkg(7) and related + tools ----------------------------------------------------------------------------- From f33a7e650a99b1c1f4ce084d5542d94cc0846cea Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Tue, 5 Dec 2023 14:14:32 +0000 Subject: [PATCH 13/15] Bump bundled modules --- src/brand/bhyve/requirements.txt | 4 ++-- src/requirements.txt | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/brand/bhyve/requirements.txt b/src/brand/bhyve/requirements.txt index 9f3f5fd85..8729d893e 100644 --- a/src/brand/bhyve/requirements.txt +++ b/src/brand/bhyve/requirements.txt @@ -1,7 +1,7 @@ # # This file was automatically produced by tools/updatereqs -# Generated on Fri Nov 10 13:47:42 UTC 2023 +# Generated on Tue Dec 5 14:13:54 UTC 2023 # Do not edit directly # -construct==2.10.69 +construct==2.10.70 PyYAML==6.0.1 diff --git a/src/requirements.txt b/src/requirements.txt index 6dd436a96..9d15debdc 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,6 +1,6 @@ # # This file was automatically produced by tools/updatereqs -# Generated on Fri Nov 10 13:47:29 UTC 2023 +# Generated on Tue Dec 5 14:13:41 UTC 2023 # Do not edit directly # annotated-types==0.6.0 @@ -11,7 +11,7 @@ inflect==7.0.0 jaraco.collections==4.3.0 jaraco.context==4.3.0 jaraco.functools==4.0.0 -jaraco.text==3.11.1 +jaraco.text==3.12.0 Mako==1.3.0 MarkupSafe==2.1.3 more-itertools==10.1.0 @@ -20,10 +20,10 @@ portend==3.2.0 prettytable==3.9.0 pybonjour @ https://mirrors.omnios.org/pymodules/pybonjour/pybonjour-1.1.1-python3.tar.gz#sha256 pycurl==7.44.1 # stuck on 7.44.1 - https://github.com/pycurl/pycurl/issues/748 -pydantic==2.4.2 -pydantic_core==2.10.1 +pydantic==2.5.2 +pydantic_core==2.14.5 pytz==2023.3.post1 tempora==5.5.0 typing_extensions==4.8.0 -wcwidth==0.2.9 +wcwidth==0.2.12 zc.lockfile==3.0.post1 From 5ace398b34860f3df1b37b15a1fd37d7d9b89ce3 Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Tue, 5 Dec 2023 14:52:38 +0000 Subject: [PATCH 14/15] More six removals --- src/client.py | 15 +++---- src/modules/actions/depend.py | 3 +- src/modules/actions/driver.py | 5 +-- src/modules/actions/file.py | 3 +- src/modules/actions/generic.py | 5 +-- src/modules/actions/group.py | 2 +- src/modules/actions/link.py | 3 +- src/modules/actions/user.py | 2 +- src/modules/api_common.py | 3 +- src/modules/catalog.py | 51 ++++++++++++------------ src/modules/cfgfiles.py | 5 +-- src/modules/client/actuator.py | 7 ++-- src/modules/client/api.py | 18 ++++----- src/modules/client/api_errors.py | 12 ++---- src/modules/client/client_api.py | 8 +--- src/modules/client/debugvalues.py | 4 +- src/modules/client/firmware.py | 3 +- src/modules/client/history.py | 5 +-- src/modules/client/image.py | 10 ++--- src/modules/client/imageconfig.py | 29 +++++++------- src/modules/client/imageplan.py | 41 ++++++++----------- src/modules/client/linkedimage/common.py | 32 +++++++-------- src/modules/client/linkedimage/zone.py | 7 ++-- src/modules/client/pkg_solver.py | 25 +++++------- src/modules/client/pkgplan.py | 3 +- src/modules/client/plandesc.py | 5 +-- src/modules/client/printengine.py | 4 +- src/modules/client/progress.py | 12 +++--- src/modules/client/publisher.py | 11 +++-- src/modules/client/transport/engine.py | 5 +-- src/modules/client/transport/repo.py | 14 ++----- src/modules/config.py | 19 +++++---- src/modules/depotcontroller.py | 3 +- src/modules/facet.py | 13 ++---- src/modules/lint/pkglint_action.py | 3 +- src/modules/manifest.py | 23 +++++------ src/modules/misc.py | 20 +++++----- src/modules/mogrify.py | 3 +- src/modules/pkgsubprocess.py | 3 +- src/modules/publish/dependencies.py | 15 +++---- src/modules/publish/transaction.py | 5 +-- src/modules/server/api.py | 7 ++-- src/modules/server/depot.py | 9 ++--- src/modules/server/feed.py | 3 +- src/modules/server/repository.py | 3 +- src/modules/sha512_t.py | 3 +- src/pkgdep.py | 3 +- src/pkgrepo.py | 11 +++-- src/tests/api/t_action.py | 7 ++-- src/tests/api/t_catalog.py | 5 +-- src/tests/api/t_config.py | 9 ++--- src/tests/cli/t_pkg_depotd.py | 5 +-- src/tests/cli/t_pkg_image_create.py | 3 +- src/tests/cli/t_pkg_linked.py | 3 +- src/tests/cli/t_pkg_publisher.py | 5 +-- src/tests/cli/t_pkgmogrify.py | 7 ++-- src/tests/cli/t_pkgrecv.py | 5 +-- src/tests/cli/t_pkgsend.py | 5 +-- src/tests/pkg5unittest.py | 5 +-- src/util/log-scripts/an2_ip_active.py | 2 +- src/util/log-scripts/an_ip_active.py | 2 +- src/util/publish/pkgfmt.py | 5 +-- src/util/publish/pkgmerge.py | 5 +-- src/web/en/search.shtml | 7 ++-- src/web/shared.shtml | 3 +- 65 files changed, 244 insertions(+), 337 deletions(-) diff --git a/src/client.py b/src/client.py index 8c6c888fc..2a54890ee 100755 --- a/src/client.py +++ b/src/client.py @@ -74,7 +74,6 @@ import logging import os import re - import six import socket import sys import tempfile @@ -151,7 +150,7 @@ all_formats = ("default", "json", "tsv") default_attrs = {} -for atype, aclass in six.iteritems(actions.types): +for atype, aclass in actions.types.items(): default_attrs[atype] = [aclass.key_attr] if atype == "depend": default_attrs[atype].insert(0, "type") @@ -3695,7 +3694,7 @@ def list_mediators( # Configured mediator information gen_mediators = ( (mediator, mediation) - for mediator, mediation in six.iteritems(api_inst.mediators) + for mediator, mediation in api_inst.mediators.items() ) # Set minimum widths for mediator and version columns by using the @@ -4049,9 +4048,11 @@ def __display_avoids(api_inst): that pkg""" for avoid, tracking in sorted(api_inst.get_avoid_list()): if tracking: - logger.info(_( - " {avoid_pkg} (group dependency of '{tracking_pkg}')") - .format(avoid_pkg=avoid, tracking_pkg=" ".join(tracking))) + logger.info( + _( + " {avoid_pkg} (group dependency of '{tracking_pkg}')" + ).format(avoid_pkg=avoid, tracking_pkg=" ".join(tracking)) + ) else: logger.info(" {0}".format(avoid)) @@ -5672,7 +5673,7 @@ def display_ssl_info(uri_data): if "Properties" not in pub: continue - pub_items = sorted(six.iteritems(pub["Properties"])) + pub_items = sorted(pub["Properties"].items()) property_padding = " " properties_displayed = False for k, v in pub_items: diff --git a/src/modules/actions/depend.py b/src/modules/actions/depend.py index f82001cf8..3e93d2735 100644 --- a/src/modules/actions/depend.py +++ b/src/modules/actions/depend.py @@ -33,7 +33,6 @@ from . import generic import re -import six import pkg.actions import pkg.client.pkgdefs as pkgdefs @@ -473,7 +472,7 @@ def astr(aout): # Now build the action output string an attribute at a # time. - for k, v in sorted(six.iteritems(act.attrs), key=key_func): + for k, v in sorted(act.attrs.items(), key=key_func): # Newline breaks are only forced when there is # more than one value for an attribute. if not (isinstance(v, list) or isinstance(v, set)): diff --git a/src/modules/actions/driver.py b/src/modules/actions/driver.py index 4223fe1b6..6f99d1b0e 100644 --- a/src/modules/actions/driver.py +++ b/src/modules/actions/driver.py @@ -32,7 +32,6 @@ import os from . import generic -import six from tempfile import mkstemp @@ -226,14 +225,14 @@ def install(self, pkgplan, orig): a2d = {} for alias, name in ( (a, n) - for n, act_list in six.iteritems(driver_actions) + for n, act_list in driver_actions.items() for act in act_list for a in act.attrlist("alias") ): a2d.setdefault(alias, set()).add(name) # Enhance that mapping with data from driver_aliases. - for name, aliases in six.iteritems(file_db): + for name, aliases in file_db.items(): for alias in aliases: a2d.setdefault(alias, set()).add(name) diff --git a/src/modules/actions/file.py b/src/modules/actions/file.py index dba1505ae..7557ee8f4 100644 --- a/src/modules/actions/file.py +++ b/src/modules/actions/file.py @@ -32,7 +32,6 @@ import errno from . import generic import os -import six import stat import tempfile import types @@ -875,7 +874,7 @@ def remove(self, pkgplan): self.remove_fsobj(pkgplan, path) except Exception as e: # Raise new exception chained to old. - six.raise_from(e, rm_exc) + raise e from rm_exc finally: # If parent directory wasn't image root, then assume # mode needs reset. diff --git a/src/modules/actions/generic.py b/src/modules/actions/generic.py index 64cf49c18..aa4aa6187 100644 --- a/src/modules/actions/generic.py +++ b/src/modules/actions/generic.py @@ -37,7 +37,6 @@ os.SEEK_SET except AttributeError: os.SEEK_SET, os.SEEK_CUR, os.SEEK_END = range(3) -import six import stat import types from io import BytesIO @@ -144,9 +143,7 @@ def fromstate(state, jd_state=None): return pkg.actions.fromstr(state) -# metaclass-assignment; pylint: disable=W1623 -@six.add_metaclass(NSG) -class Action(object): +class Action(object, metaclass=NSG): """Class representing a generic packaging object. An Action is a very simple wrapper around two dictionaries: a named set diff --git a/src/modules/actions/group.py b/src/modules/actions/group.py index a0773dbe6..6881f8cce 100644 --- a/src/modules/actions/group.py +++ b/src/modules/actions/group.py @@ -187,7 +187,7 @@ def verify(self, img, **args): # Get the default values if they're non-empty grdefval = dict( - ((k, v) for k, v in six.iteritems(gr.getdefaultvalues()) if v != "") + ((k, v) for k, v in gr.getdefaultvalues().items() if v != "") ) # If "gid" is set dynamically, ignore what's on disk. diff --git a/src/modules/actions/link.py b/src/modules/actions/link.py index bcb7760a5..f4245df4b 100644 --- a/src/modules/actions/link.py +++ b/src/modules/actions/link.py @@ -31,7 +31,6 @@ import errno import os -import six import stat from . import generic @@ -146,7 +145,7 @@ def generate_indices(self): if "mediator" in self.attrs: rval.extend( (self.name, k, v, None) - for k, v in six.iteritems(self.attrs) + for k, v in self.attrs.items() if k.startswith("mediator") ) return rval diff --git a/src/modules/actions/user.py b/src/modules/actions/user.py index ddda00e77..938a78730 100644 --- a/src/modules/actions/user.py +++ b/src/modules/actions/user.py @@ -269,7 +269,7 @@ def verify(self, img, **args): # Get the default values if they're non-empty pwdefval = dict( - ((k, v) for k, v in six.iteritems(pw.getdefaultvalues()) if v != "") + ((k, v) for k, v in pw.getdefaultvalues().items() if v != "") ) # Certain defaults are dynamic, so we need to ignore what's on diff --git a/src/modules/api_common.py b/src/modules/api_common.py index c6fbea439..2701b602f 100644 --- a/src/modules/api_common.py +++ b/src/modules/api_common.py @@ -30,7 +30,6 @@ """Contains API functions and classes common to both pkg.client.api and pkg.server.api.""" -import six import pkg.client.pkgdefs as pkgdefs import pkg.fmri as fmri @@ -239,7 +238,7 @@ def get_attr_values(self, name, modifiers=()): and tuple([sorted(modifiers[k])]) or tuple(sorted(modifiers[k])), ) - for k in sorted(six.iterkeys(modifiers)) + for k in sorted(modifiers.keys()) ) return self.attrs.get(name, {modifiers: []}).get(modifiers, []) diff --git a/src/modules/catalog.py b/src/modules/catalog.py index f3526de6d..5580746d7 100644 --- a/src/modules/catalog.py +++ b/src/modules/catalog.py @@ -33,7 +33,6 @@ import fnmatch import hashlib import os -import six import stat import threading import types @@ -558,7 +557,7 @@ def entries_by_version(self, name, pubs=EmptyI): entries.setdefault(sver, []) entries[sver].append((pfmri, entry)) - for key, ver in sorted(six.iteritems(versions), key=itemgetter(1)): + for key, ver in sorted(versions.items(), key=itemgetter(1)): yield ver, entries[key] def fmris(self, last=False, objects=True, ordered=False, pubs=EmptyI): @@ -626,7 +625,7 @@ def fmris_by_version(self, name, pubs=EmptyI): entries.setdefault(sver, []) entries[sver].append(pfmri) - for key, ver in sorted(six.iteritems(versions), key=itemgetter(1)): + for key, ver in sorted(versions.items(), key=itemgetter(1)): yield ver, entries[key] def get_entry(self, pfmri=None, pub=None, stem=None, ver=None): @@ -1197,7 +1196,7 @@ def __transform(self): # Use a copy to prevent the in-memory version from being # affected by the transformations. struct = copy.deepcopy(self.__data) - for key, val in six.iteritems(struct): + for key, val in struct.items(): if isinstance(val, datetime.datetime): # Convert datetime objects to an ISO-8601 # basic format string. @@ -1234,7 +1233,7 @@ def cat_ts_to_datetime(val): except ValueError: raise api_errors.InvalidCatalogFile(location) - for key, val in six.iteritems(struct): + for key, val in struct.items(): if key in ("created", "last-modified"): # Convert ISO-8601 basic format strings to # datetime objects. These dates can be @@ -1576,7 +1575,7 @@ def __entries( parts.append(part) def merge_entry(src, dest): - for k, v in six.iteritems(src): + for k, v in src.items(): if k == "actions": dest.setdefault(k, []) dest[k] += v @@ -1596,7 +1595,7 @@ def merge_entry(src, dest): # Part doesn't have this FMRI, # so skip it. continue - for k, v in six.iteritems(entry): + for k, v in entry.items(): if k == "actions": mdata.setdefault(k, []) mdata[k] += v @@ -1616,7 +1615,7 @@ def merge_entry(src, dest): # Part doesn't have this FMRI, # so skip it. continue - for k, v in six.iteritems(entry): + for k, v in entry.items(): if k == "actions": mdata.setdefault(k, []) mdata[k] += v @@ -1820,13 +1819,13 @@ def __log_update(self, pfmri, operation, op_time, entries=None): parts[pname] = entries[pname] logdate = datetime_to_update_ts(op_time) - for locale, metadata in six.iteritems(updates): + for locale, metadata in updates.items(): name = "update.{0}.{1}".format(logdate, locale) ulog = self.__get_update(name) ulog.add(pfmri, operation, metadata=metadata, op_time=op_time) attrs.updates[name] = {"last-modified": op_time} - for name, part in six.iteritems(self.__parts): + for name, part in self.__parts.items(): # Signature data for each part needs to be cleared, # and will only be available again after save(). attrs.parts[name] = {"last-modified": part.last_modified} @@ -1901,7 +1900,7 @@ def __save(self, fmt="utf8"): attrs = self._attrs if self.log_updates: - for name, ulog in six.iteritems(self.__updates): + for name, ulog in self.__updates.items(): ulog.load() ulog.set_feature(FEATURE_UTF8, fmt == "utf8") ulog.save() @@ -1911,13 +1910,13 @@ def __save(self, fmt="utf8"): entry = attrs.updates[name] = { "last-modified": ulog.last_modified } - for n, v in six.iteritems(ulog.signatures): + for n, v in ulog.signatures.items(): entry["signature-{0}".format(n)] = v # Save any CatalogParts that are currently in-memory, # updating their related information in catalog.attrs # as they are saved. - for name, part in six.iteritems(self.__parts): + for name, part in self.__parts.items(): # Must save first so that signature data is # current. @@ -1932,7 +1931,7 @@ def __save(self, fmt="utf8"): # Now replace the existing signature data with # the new signature data. entry = attrs.parts[name] = {"last-modified": part.last_modified} - for n, v in six.iteritems(part.signatures): + for n, v in part.signatures.items(): entry["signature-{0}".format(n)] = v # Finally, save the catalog attributes. @@ -2196,7 +2195,7 @@ def group_actions(actions): if metadata: entry["metadata"] = metadata if manifest: - for k, v in six.iteritems(manifest.signatures): + for k, v in manifest.signatures.items(): entry["signature-{0}".format(k)] = v part = self.get_part(self.__BASE_PART) entries[part.name] = part.add( @@ -2300,7 +2299,7 @@ def apply_incremental(name): # (Which is why __get_update is not used.) ulog = CatalogUpdate(name, meta_root=path) for pfmri, op_type, op_time, metadata in ulog.updates(): - for pname, pdata in six.iteritems(metadata): + for pname, pdata in metadata.items(): part = self.get_part(pname, must_exist=True) if part is None: # Part doesn't exist; skip. @@ -2348,7 +2347,7 @@ def apply_full(name): # signature that matches the new catalog.attrs file. new_attrs = CatalogAttrs(meta_root=path) new_sigs = {} - for name, mdata in six.iteritems(new_attrs.parts): + for name, mdata in new_attrs.parts.items(): new_sigs[name] = {} for key in mdata: if not key.startswith("signature-"): @@ -2361,7 +2360,7 @@ def apply_full(name): self.batch_mode = old_batch_mode self.finalize() - for name, part in six.iteritems(self.__parts): + for name, part in self.__parts.items(): part.validate(signatures=new_sigs[name]) # Finally, save the catalog, and then copy the new @@ -2581,7 +2580,7 @@ def entries_by_version( parts.append(part) def merge_entry(src, dest): - for k, v in six.iteritems(src): + for k, v in src.items(): if k == "actions": dest.setdefault(k, []) dest[k] += v @@ -2817,7 +2816,7 @@ def get_entry(self, pfmri, info_needed=EmptyI, locales=None): """ def merge_entry(src, dest): - for k, v in six.iteritems(src): + for k, v in src.items(): if k == "actions": dest.setdefault(k, []) dest[k] += v @@ -2960,7 +2959,7 @@ def get_entry_signatures(self, pfmri): raise api_errors.UnknownCatalogEntry(pfmri.get_fmri()) return ( (k.split("signature-")[1], v) - for k, v in six.iteritems(entry) + for k, v in entry.items() if k.startswith("signature-") ) @@ -3189,7 +3188,7 @@ def gen_packages( # } mods = frozenset( (k, frozenset(a.attrlist(k))) - for k in six.iterkeys(a.attrs) + for k in a.attrs.keys() if k not in ("name", "value") ) if mods not in attrs[atname]: @@ -3418,7 +3417,7 @@ def get_matching_fmris(self, patterns): # fmri matches. proposed_dict = {} for d in ret.values(): - for k, l in six.iteritems(d): + for k, l in d.items(): proposed_dict.setdefault(k, []).extend(l) # construct references so that we can know which pattern @@ -3617,7 +3616,7 @@ def get_updates_needed(self, path): if not last_lm or lm > last_lm: last_lm = lm - for name, uattrs in six.iteritems(new_attrs.updates): + for name, uattrs in new_attrs.updates.items(): up_lm = uattrs["last-modified"] # The last component of the update name is the @@ -3940,7 +3939,7 @@ def get_sigs(mdata): return None return sigs - for name, mdata in six.iteritems(self._attrs.parts): + for name, mdata in self._attrs.parts.items(): part = self.get_part(name, must_exist=True) if part is None: # Part does not exist; no validation needed. @@ -3950,7 +3949,7 @@ def get_sigs(mdata): require_signatures=require_signatures, ) - for name, mdata in six.iteritems(self._attrs.updates): + for name, mdata in self._attrs.updates.items(): ulog = self.__get_update(name, cache=False, must_exist=True) if ulog is None: # Update does not exist; no validation needed. diff --git a/src/modules/cfgfiles.py b/src/modules/cfgfiles.py index 91fd2fe95..f7c752136 100644 --- a/src/modules/cfgfiles.py +++ b/src/modules/cfgfiles.py @@ -31,7 +31,6 @@ import errno import os import re -import six import stat import sys import tempfile @@ -300,7 +299,7 @@ def removevalue(self, template): def getnextuid(self): """returns next free system (<=99) uid""" uids = [] - for t in six.itervalues(self.password_file.index): + for t in self.password_file.index.values(): if t[1]: uids.append(t[1]["uid"]) for i in range(100): @@ -361,7 +360,7 @@ def __init__(self, image): def getnextgid(self): """returns next free system (<=99) gid""" gids = [] - for t in six.itervalues(self.index): + for t in self.index.values(): if t[1]: gids.append(t[1]["gid"]) for i in range(100): diff --git a/src/modules/client/actuator.py b/src/modules/client/actuator.py index e0a5b4e2a..305c453e2 100644 --- a/src/modules/client/actuator.py +++ b/src/modules/client/actuator.py @@ -32,7 +32,6 @@ from pkg.client.debugvalues import DebugValues from pkg.client.imagetypes import IMG_USER, IMG_ENTIRE -import six class Actuator(object): @@ -393,15 +392,15 @@ def exec_post_actuators(self, image): # handle callables first - for act in six.itervalues(self.removal): + for act in self.removal.values(): if hasattr(act, "__call__"): act() - for act in six.itervalues(self.install): + for act in self.install.values(): if hasattr(act, "__call__"): act() - for act in six.itervalues(self.update): + for act in self.update.values(): if hasattr(act, "__call__"): act() diff --git a/src/modules/client/api.py b/src/modules/client/api.py index 2f3ac13b7..f88fbd2df 100644 --- a/src/modules/client/api.py +++ b/src/modules/client/api.py @@ -582,7 +582,7 @@ def mediators(self): """ ret = {} - for m, mvalues in six.iteritems(self._img.cfg.mediators): + for m, mvalues in self._img.cfg.mediators.items(): ret[m] = copy.copy(mvalues) if "version" in ret[m]: # Don't expose internal Version object to @@ -980,7 +980,7 @@ def gen_available_mediators(self): def get_avoid_list(self): """Return list of tuples of (pkg stem, pkgs w/ group dependencies on this)""" - return [a for a in six.iteritems(self._img.get_avoid_dict())] + return [a for a in self._img.get_avoid_dict().items()] def gen_facets(self, facet_list, implicit=False, patterns=misc.EmptyI): """A generator function that produces tuples of the form: @@ -4098,7 +4098,7 @@ def __get_alt_pkg_data(self, repos): # copy() is too slow here and catalog # entries are shallow so this should be # sufficient. - entry = dict(six.iteritems(sentry)) + entry = dict(sentry.items()) if not base: # Nothing else to do except add # the entry for non-base catalog @@ -4827,7 +4827,7 @@ def pub_key(a): # structure sanely somewhere. mods = tuple( (k, tuple(sorted(a.attrlist(k)))) - for k in sorted(six.iterkeys(a.attrs)) + for k in sorted(a.attrs.keys()) if k not in ("name", "value") ) attrs[atname][mods].extend(atvlist) @@ -4871,7 +4871,7 @@ def pub_key(a): # image, elide packages that are not for # a matching variant value. is_list = type(atvalue) == list - for vn, vv in six.iteritems(img_variants): + for vn, vv in img_variants.items(): if vn == atname and ( (is_list and vv not in atvalue) or (not is_list and vv != atvalue) @@ -6038,7 +6038,7 @@ def need_refresh(oldo, newo): # First, attempt to match the updated publisher object to an # existing one using the object id that was stored during # copy(). - for key, old in six.iteritems(publishers): + for key, old in publishers.items(): if pub._source_object_id == id(old): # Store the new publisher's id and the old # publisher object so it can be restored if the @@ -6054,7 +6054,7 @@ def need_refresh(oldo, newo): # Next, be certain that the publisher's prefix and alias # are not already in use by another publisher. - for key, old in six.iteritems(publishers): + for key, old in publishers.items(): if pub._source_object_id == id(old): # Don't check the object we're replacing. continue @@ -6069,7 +6069,7 @@ def need_refresh(oldo, newo): # Next, determine what needs updating and add the updated # publisher. - for key, old in six.iteritems(publishers): + for key, old in publishers.items(): if pub._source_object_id == id(old): old = orig_pub[-1] if need_refresh(old, pub): @@ -6094,7 +6094,7 @@ def cleanup(): # Attempting to unpack a non-sequence%s; # pylint: disable=W0633 new_id, old_pub = orig_pub - for new_pfx, new_pub in six.iteritems(publishers): + for new_pfx, new_pub in publishers.items(): if id(new_pub) == new_id: publishers[old_pub.prefix] = old_pub break diff --git a/src/modules/client/api_errors.py b/src/modules/client/api_errors.py index 9fe80aa1a..7c00916f7 100644 --- a/src/modules/client/api_errors.py +++ b/src/modules/client/api_errors.py @@ -28,7 +28,6 @@ import errno import operator import os -import six import xml.parsers.expat as expat from functools import total_ordering from urllib.parse import urlsplit @@ -736,7 +735,7 @@ def __str__(self): if self.invalid_mediations: s = _("The following mediations are not syntactically " "valid:") - for m, entries in six.iteritems(self.invalid_mediations): + for m, entries in self.invalid_mediations.items(): for value, error in entries.values(): res.append(error) @@ -963,7 +962,7 @@ def __str__(self): "The following packages deliver conflicting " "action types to {0}:\n" ).format(kv) - for name, pl in six.iteritems(ad): + for name, pl in ad.items(): s += "\n {0}:".format(name) s += "".join("\n {0}".format(p) for p in pl) s += _( @@ -1001,7 +1000,7 @@ def __str__(self): def ou(action): ua = dict( (k, v) - for k, v in six.iteritems(action.attrs) + for k, v in action.attrs.items() if ( ( k in action.unique_attrs @@ -1021,10 +1020,7 @@ def ou(action): if a[0].attrs.get("implicit", "false") == "false": d.setdefault(str(ou(a[0])), set()).add(a[1]) l = sorted( - [ - (len(pkglist), action, pkglist) - for action, pkglist in six.iteritems(d) - ] + [(len(pkglist), action, pkglist) for action, pkglist in d.items()] ) s = _( diff --git a/src/modules/client/client_api.py b/src/modules/client/client_api.py index b16ba7086..8e7f5222f 100644 --- a/src/modules/client/client_api.py +++ b/src/modules/client/client_api.py @@ -34,7 +34,6 @@ import itertools import os import re -import six import socket import sys import tempfile @@ -94,10 +93,7 @@ def _strify(input): if isinstance(input, dict): return dict( - [ - (_strify(key), _strify(value)) - for key, value in six.iteritems(input) - ] + [(_strify(key), _strify(value)) for key, value in input.items()] ) elif isinstance(input, list): return [_strify(element) for element in input] @@ -2836,7 +2832,7 @@ def collect_signing_certs(p, pub_data): pub_data["sys_pub"] = "No" if pub.properties: pub_data["Properties"] = {} - for k, v in six.iteritems(pub.properties): + for k, v in pub.properties.items(): pub_data["Properties"][k] = v data.setdefault("publisher_details", []).append(pub_data) return __prepare_json(retcode, data=data, errors=errors_json, op=op) diff --git a/src/modules/client/debugvalues.py b/src/modules/client/debugvalues.py index a4291bf5a..00ea99b9e 100644 --- a/src/modules/client/debugvalues.py +++ b/src/modules/client/debugvalues.py @@ -24,8 +24,6 @@ # Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. # -import six - class Singleton(type): """Set __metaclass__ to Singleton to create a singleton. @@ -42,7 +40,7 @@ def __call__(self, *args, **kw): return self.instance -class DebugValues(six.with_metaclass(Singleton, dict)): +class DebugValues(dict, metaclass=Singleton): """Singleton dict that returns None if unknown value is referenced""" diff --git a/src/modules/client/firmware.py b/src/modules/client/firmware.py index 6c0333772..3830432f0 100644 --- a/src/modules/client/firmware.py +++ b/src/modules/client/firmware.py @@ -24,7 +24,6 @@ # Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. # import os.path -import six import sys import pkg.misc as misc @@ -60,7 +59,7 @@ def check_firmware(self, dep_action, firmware_name): args.extend( [ "{0}={1}".format(k, quote_attr_value(v)) - for k, v in sorted(six.iteritems(dep_action.attrs)) + for k, v in sorted(dep_action.attrs.items()) if k not in ["type", "root-image", "fmri"] ] ) diff --git a/src/modules/client/history.py b/src/modules/client/history.py index 610e70ed4..89f877191 100644 --- a/src/modules/client/history.py +++ b/src/modules/client/history.py @@ -28,7 +28,6 @@ import errno import os import shutil -import six import sys import traceback import xml.dom.minidom as xmini @@ -846,7 +845,7 @@ def log_operation_end(self, error=None, result=None, release_notes=None): except (AttributeError, KeyError): # Failing an exact match, determine if this # error is a subclass of an existing one. - for entry, val in six.iteritems(error_results): + for entry, val in error_results.items(): if isinstance(error, entry): result = val break @@ -935,7 +934,7 @@ def restore_snapshot(self): if not self.__snapshot: return - for name, val in six.iteritems(self.__snapshot): + for name, val in self.__snapshot.items(): if not name.startswith("__"): object.__setattr__(self, name, val) self.__operations = self.__snapshot["__operations"] diff --git a/src/modules/client/image.py b/src/modules/client/image.py index 8029aa3e9..20c3397a1 100644 --- a/src/modules/client/image.py +++ b/src/modules/client/image.py @@ -3327,7 +3327,7 @@ def __rebuild_image_catalogs(self, progtrack=None): # copy() is too slow here and catalog entries # are shallow so this should be sufficient. - entry = dict(six.iteritems(sentry)) + entry = dict(sentry.items()) if not base: # Nothing else to do except add the # entry for non-base catalog parts. @@ -4590,7 +4590,7 @@ def __calc_frozen(): return dict( [ (s, __make_publisherless_fmri(p)) - for s, p in six.iteritems(stems_and_pats) + for s, p in stems_and_pats.items() ] ) @@ -4606,7 +4606,7 @@ def __calc_frozen(): d.update( [ (s, (str(p), comment, timestamp)) - for s, p in six.iteritems(stems_and_pats) + for s, p in stems_and_pats.items() ] ) self._freeze_dict_save(d) @@ -4813,8 +4813,8 @@ def make_change_varcets_plan( progtrack.plan_all_start() # compute dict of changing variants if variants: - new = set(six.iteritems(variants)) - cur = set(six.iteritems(self.cfg.variants)) + new = set(variants.items()) + cur = set(self.cfg.variants.items()) variants = dict(new - cur) elif facets: new_facets = self.get_facets() diff --git a/src/modules/client/imageconfig.py b/src/modules/client/imageconfig.py index 59de07875..cd160989f 100644 --- a/src/modules/client/imageconfig.py +++ b/src/modules/client/imageconfig.py @@ -30,7 +30,6 @@ import os.path import platform import re -import six from urllib.parse import quote, unquote @@ -479,7 +478,7 @@ def __publisher_iter(self): def __publisher_iteritems(self): """Support iteritems on publishers""" - return six.iteritems(self.__publishers) + return self.__publishers.items() def __publisher_keys(self): """Support keys() on publishers""" @@ -553,13 +552,13 @@ def reset(self, overrides=misc.EmptyDict): self.variants.update(idx.get("variant", {})) # Variants and facets are encoded so they can contain # '/' characters. - for k, v in six.iteritems(idx.get("variant", {})): + for k, v in idx.get("variant", {}).items(): # convert variant name from unicode to a string self.variants[str(unquote(k))] = v - for k, v in six.iteritems(idx.get("facet", {})): + for k, v in idx.get("facet", {}).items(): # convert facet name from unicode to a string self.facets[str(unquote(k))] = v - for k, v in six.iteritems(idx.get("inherited_facet", {})): + for k, v in idx.get("inherited_facet", {}).items(): # convert facet name from unicode to a string self.facets._set_inherited(str(unquote(k)), v) @@ -573,7 +572,7 @@ def reset(self, overrides=misc.EmptyDict): self.variants["variant.opensolaris.imagetype"] = "full" # load linked image child properties - for s, v in six.iteritems(idx): + for s, v in idx.items(): if not re.match("linked_.*", s): continue linked_props = self.read_linked(s, v) @@ -599,7 +598,7 @@ def reset(self, overrides=misc.EmptyDict): # Sort the index so that the prefixes are added to the list # "publisher-search-order" in alphabetic order. - for s, v in collections.OrderedDict(sorted(six.iteritems(idx))).items(): + for s, v in collections.OrderedDict(sorted(idx.items())).items(): if re.match("authority_.*", s): k, a = self.read_publisher(s, v) # this will call __set_publisher and add the @@ -608,7 +607,7 @@ def reset(self, overrides=misc.EmptyDict): # Move any properties found in policy section (from older # images) to the property section. - for k, v in six.iteritems(idx.get("policy", {})): + for k, v in idx.get("policy", {}).items(): self.set_property("property", k, v) self.remove_property("policy", k) @@ -631,7 +630,7 @@ def reset(self, overrides=misc.EmptyDict): self.set_property("property", "publisher-search-order", pso) # Load mediator data. - for entry, value in six.iteritems(idx.get("mediators", {})): + for entry, value in idx.get("mediators", {}).items(): mname, mtype = entry.rsplit(".", 1) # convert mediator name+type from unicode to a string mname = str(mname) @@ -723,8 +722,8 @@ def write(self, ignore_unprivileged=False): self.remove_section("mediators") except cfg.UnknownSectionError: pass - for mname, mvalues in six.iteritems(self.mediators): - for mtype, mvalue in six.iteritems(mvalues): + for mname, mvalues in self.mediators.items(): + for mtype, mvalue in mvalues.items(): # name.implementation[-(source|version)] # name.version[-source] pname = mname + "." + mtype @@ -732,7 +731,7 @@ def write(self, ignore_unprivileged=False): # remove all linked image child configuration idx = self.get_index() - for s, v in six.iteritems(idx): + for s, v in idx.items(): if not re.match("linked_.*", s): continue self.remove_section(s) @@ -1037,7 +1036,7 @@ def read_publisher(self, sname, sec_idx): ) props = {} - for k, v in six.iteritems(sec_idx): + for k, v in sec_idx.items(): if not k.startswith("property."): continue prop_name = k[len("property.") :] @@ -1051,7 +1050,7 @@ def read_publisher(self, sname, sec_idx): # Load repository data. repo_data = {} - for key, val in six.iteritems(sec_idx): + for key, val in sec_idx.items(): if key.startswith("repo."): pname = key[len("repo.") :] repo_data[pname] = val @@ -1781,7 +1780,7 @@ def __publisher_iter(self): def __publisher_iteritems(self): """Support iteritems on publishers""" - return six.iteritems(self.__publishers) + return self.__publishers.items() def __publisher_keys(self): """Support keys() on publishers""" diff --git a/src/modules/client/imageplan.py b/src/modules/client/imageplan.py index 3116d9e93..26cc9ba3b 100644 --- a/src/modules/client/imageplan.py +++ b/src/modules/client/imageplan.py @@ -35,7 +35,6 @@ import operator import os import shutil -import six import stat import sys import tempfile @@ -3433,7 +3432,7 @@ def __check_conflicts(self, new, old, action_classes, ns, errs): """Check all the newly installed actions for conflicts with existing actions.""" - for key, actions in six.iteritems(new): + for key, actions in new.items(): oactions = old.get(key, []) self.__progtrack.plan_add_progress( @@ -3493,7 +3492,7 @@ def __check_conflicts(self, new, old, action_classes, ns, errs): # Ensure that overlay and preserve file semantics are handled # as expected when conflicts only exist in packages that are # being removed. - for key, oactions in six.iteritems(old): + for key, oactions in old.items(): self.__progtrack.plan_add_progress( self.__progtrack.PLAN_ACTION_CONFLICT ) @@ -3529,12 +3528,12 @@ def noop(*args): return None bad_keys = set() - for ns, key_dict in six.iteritems(nsd): + for ns, key_dict in nsd.items(): if type(ns) != int: type_func = ImagePlan.__check_inconsistent_types else: type_func = noop - for key, actions in six.iteritems(key_dict): + for key, actions in key_dict.items(): if len(actions) == 1: continue if type_func(actions, []) is not None: @@ -3636,7 +3635,7 @@ def key(a): return 20 return kf - types = sorted(six.itervalues(pkg.actions.types), key=key) + types = sorted(pkg.actions.types.values(), key=key) namespace_dict = dict( (ns, list(action_classes)) @@ -3653,7 +3652,7 @@ def key(a): fmri_dict = weakref.WeakValueDictionary() # Iterate over action types in namespace groups first; our first # check should be for action type consistency. - for ns, action_classes in six.iteritems(namespace_dict): + for ns, action_classes in namespace_dict.items(): pt.plan_add_progress(pt.PLAN_ACTION_CONFLICT) # There's no sense in checking actions which have no # limits @@ -3692,9 +3691,7 @@ def key(a): # cache which could conflict with the new # actions being installed, or with actions # already installed, but not getting removed. - keys = set( - itertools.chain(six.iterkeys(new), six.iterkeys(old)) - ) + keys = set(itertools.chain(new.keys(), old.keys())) self.__update_act( keys, old, @@ -3710,7 +3707,7 @@ def key(a): # action cache which are staying on the system, # and could conflict with the actions being # installed. - keys = set(six.iterkeys(old)) + keys = set(old.keys()) self.__update_act( keys, new, @@ -4793,7 +4790,7 @@ def __finalize_mediation(self, prop_mediators, mediated_del_path_target): # mediations provided by the image administrator. prop_mediators[m] = new_mediation - for m, new_mediation in six.iteritems(prop_mediators): + for m, new_mediation in prop_mediators.items(): # If after processing all mediation data, a source wasn't # marked for a particular component, mark it as being # sourced from 'system'. @@ -5830,7 +5827,7 @@ def execute(self): root = os.path.normpath(self.image.root) rzones = zone.list_running_zones() - for z, path in six.iteritems(rzones): + for z, path in rzones.items(): if os.path.normpath(path) == root: self.pd._actuators.set_zone(z) # there should be only on zone per path @@ -5865,7 +5862,7 @@ def execute(self): # aliases drivers have lost in the new image. # This prevents two drivers from ever attempting # to have the same alias at the same time. - for name, aliases in six.iteritems(self.pd._rm_aliases): + for name, aliases in self.pd._rm_aliases.items(): driver.DriverAction.remove_aliases( name, aliases, self.image ) @@ -5987,10 +5984,6 @@ def execute(self): except: # Ensure the real cause of failure is raised. pass - # six.reraise requires the first argument - # callable if the second argument is None. - # Also the traceback is automatically attached, - # in Python 3, so we can simply raise it. raise api_errors.InvalidPackageErrors([exc_value]) except: exc_type, exc_value, exc_tb = sys.exc_info() @@ -6536,7 +6529,7 @@ def __match_user_fmris( # value. atvalue = a.attrs["value"] is_list = type(atvalue) == list - for vn, vv in six.iteritems(variants): + for vn, vv in variants.items(): if vn == atname and ( (is_list and vv not in atvalue) or (not is_list and vv != atvalue) @@ -6643,12 +6636,12 @@ def __match_user_fmris( ) else: # single match or wildcard - for k, pfmris in six.iteritems(ret[p]): + for k, pfmris in ret[p].items(): # for each matching package name matchdict.setdefault(k, []).append((p, pfmris)) proposed_dict = {} - for name, lst in six.iteritems(matchdict): + for name, lst in matchdict.items(): nwc_ps = [ (p, set(pfmris)) for p, pfmris in lst @@ -6800,7 +6793,7 @@ def __match_user_fmris( # Rebuild proposed_dict based on latest version of every # package. sort_key = operator.attrgetter("version") - for pname, flist in six.iteritems(proposed_dict): + for pname, flist in proposed_dict.items(): # Must sort on version; sorting by FMRI would # sort by publisher, then by version which is # not desirable. @@ -6883,7 +6876,7 @@ def freeze_pkgs_match(image, pats): # For each fmri, pattern where the pattern matched the fmri # including the version ... - for full_fmri, pat in six.iteritems(references): + for full_fmri, pat in references.items(): parts = pat.split("@", 1) # If the pattern doesn't include a version, then add the # version the package is installed at to the list of @@ -6926,7 +6919,7 @@ def freeze_pkgs_match(image, pats): ).add(p) # Check whether one stem has been frozen at non-identical # versions. - for k, v in six.iteritems(stems): + for k, v in stems.items(): if len(v) > 1: multiversions.append((k, v)) else: diff --git a/src/modules/client/linkedimage/common.py b/src/modules/client/linkedimage/common.py index ef2a23907..21769a2ba 100644 --- a/src/modules/client/linkedimage/common.py +++ b/src/modules/client/linkedimage/common.py @@ -49,10 +49,8 @@ import os import select -# Imports from package six are not grouped: pylint: disable=C0412 from functools import reduce -import six # pkg classes import pkg.actions @@ -175,7 +173,7 @@ def _li_rvdict_check(rvdict): entries.""" assert type(rvdict) == dict - for k, v in six.iteritems(rvdict): + for k, v in rvdict.items(): assert type(k) == LinkedImageName, ("Unexpected rvdict key: ", k) _li_rvtuple_check(v) @@ -547,12 +545,12 @@ def _init_root(self): # Tell linked image plugins about the updated paths # Unused variable 'plugin'; pylint: disable=W0612 - for plugin, lip in six.iteritems(self.__plugins): + for plugin, lip in self.__plugins.items(): # pylint: enable=W0612 lip.init_root(root) # Tell linked image children about the updated paths - for lic in six.itervalues(self.__lic_dict): + for lic in self.__lic_dict.values(): lic.child_init_root() def __update_props(self, props=None): @@ -692,7 +690,7 @@ def __guess_path_transform(self, ignore_errors=False): # ask each plugin if we're operating in an alternate root p_transforms = [] - for plugin, lip in six.iteritems(self.__plugins): + for plugin, lip in self.__plugins.items(): p_transform = lip.guess_path_transform(ignore_errors=ignore_errors) if p_transform is not PATH_TRANSFORM_NONE: p_transforms.append((plugin, p_transform)) @@ -794,7 +792,7 @@ def __load_ondisk_pfacets(self, tmp=True): return None rv = pkg.facet.Facets() - for k, v in six.iteritems(pfacets): + for k, v in pfacets.items(): # W0212 Access to a protected member # pylint: disable=W0212 rv._set_inherited(k, v) @@ -929,7 +927,7 @@ def __validate_attach_props(self, model, props): errs = [] # check each property the user specified. - for k, v in six.iteritems(props): + for k, v in props.items(): # did the user specify an allowable property? if k not in validate_props: errs.append(apx.LinkedImageException(attach_bad_prop=k)) @@ -1454,7 +1452,7 @@ def attach_parent(self, lin, path, props, allow_relink=False, force=False): props[PROP_PARENT_PATH] = path.rstrip(os.sep) + os.sep self.set_path_transform(props, path_transform, current_path=self.__root) - for k, v in six.iteritems(lip.attach_props_def): + for k, v in lip.attach_props_def.items(): if k not in self.__pull_child_props: # this prop doesn't apply to pull images continue @@ -1598,12 +1596,12 @@ def __rvdict2rv(rvdict, rv_map=None): p_dicts = [ rvtuple.rvt_p_dict - for rvtuple in six.itervalues(rvdict) + for rvtuple in rvdict.values() if rvtuple.rvt_p_dict is not None ] rv_mapped = set() - rv_seen = set([rvtuple.rvt_rv for rvtuple in six.itervalues(rvdict)]) + rv_seen = set([rvtuple.rvt_rv for rvtuple in rvdict.values()]) for rv_map_set, rv_map_rv in rv_map: if rv_seen == rv_map_set: return LI_RVTuple(rv_map_rv, None, p_dicts) @@ -1616,7 +1614,7 @@ def __rvdict2rv(rvdict, rv_map=None): # if we had errors for unmapped return values, bundle them up errs = [ rvtuple.rvt_e - for rvtuple in six.itervalues(rvdict) + for rvtuple in rvdict.values() if rvtuple.rvt_e and rvtuple.rvt_rv not in rv_mapped ] if len(errs) == 1: @@ -1885,7 +1883,7 @@ def attach_child( ) # fill in any missing defaults options - for k, v in six.iteritems(lip.attach_props_def): + for k, v in lip.attach_props_def.items(): if k not in child_props: child_props[k] = v @@ -2067,7 +2065,7 @@ def detach_children( # if any of the children successfully detached, then we want # to discard our metadata for that child. - for lin, rvtuple in six.iteritems(rvdict): + for lin, rvtuple in rvdict.items(): # if the detach failed leave metadata in parent if rvtuple.rvt_e and not force: continue @@ -2794,7 +2792,7 @@ def recurse_nothingtodo(self): """Return True if there is no planned work to do on child image.""" - for lic in six.itervalues(self.__lic_dict): + for lic in self.__lic_dict.values(): if lic.child_name not in self.__img.imageplan.pd.children_nop: return False return True @@ -3843,7 +3841,7 @@ def PkgDecoder(dct): """Utility class used when json decoding linked image metadata.""" # Replace unicode keys/values with strings rvdct = {} - for k, v in six.iteritems(dct): + for k, v in dct.items(): k = misc.force_str(k) v = misc.force_str(v) @@ -3860,7 +3858,7 @@ def PkgDecoder(dct): def rm_dict_ent(d, keys): """Remove a set of keys from a dictionary.""" - return dict([(k, v) for k, v in six.iteritems(d) if k not in keys]) + return dict([(k, v) for k, v in d.items() if k not in keys]) def _rterr( diff --git a/src/modules/client/linkedimage/zone.py b/src/modules/client/linkedimage/zone.py index b73a7cddd..499e45826 100644 --- a/src/modules/client/linkedimage/zone.py +++ b/src/modules/client/linkedimage/zone.py @@ -36,7 +36,6 @@ import os import tempfile -import six # pkg classes import pkg.client.api_errors as apx @@ -264,7 +263,7 @@ def __list_zones_cached(self, nocache=False, ignore_errors=False): zlist = [] # state is unused # pylint: disable=W0612 - for zone, (path, state) in six.iteritems(zdict): + for zone, (path, state) in zdict.items(): lin = li.LinkedImageName("{0}:{1}".format(self.__pname, zone)) zlist.append([lin, path]) @@ -334,7 +333,7 @@ def get_child_props(self, lin): assert li.PROP_PATH in props props[li.PROP_MODEL] = li.PV_MODEL_PUSH - for k, v in six.iteritems(self.attach_props_def): + for k, v in self.attach_props_def.items(): if k not in props: props[k] = v @@ -542,7 +541,7 @@ def list_running_zones(): zdict = _list_zones("/", li.PATH_TRANSFORM_NONE) rzdict = {} - for z_name, (z_path, z_state) in six.iteritems(zdict): + for z_name, (z_path, z_state) in zdict.items(): if z_state == ZONE_STATE_STR_RUNNING: rzdict[z_name] = z_path diff --git a/src/modules/client/pkg_solver.py b/src/modules/client/pkg_solver.py index c3150fc38..09fefcf0b 100644 --- a/src/modules/client/pkg_solver.py +++ b/src/modules/client/pkg_solver.py @@ -32,12 +32,7 @@ import time from collections import defaultdict - from functools import reduce - -import six - -# Imports from package six are not grouped: pylint: disable=C0412 from itertools import chain import pkg.actions @@ -583,7 +578,7 @@ def __update_possible_closure( break # Remove trimmed items from possible_set. - possible.difference_update(six.iterkeys(self.__trim_dict)) + possible.difference_update(self.__trim_dict.keys()) def __enforce_unique_packages(self, excludes): """Constrain the solver solution so that only one version of @@ -1255,7 +1250,7 @@ def solve_install( self.__start_subphase(10) # remove all trimmed fmris from consideration - possible_set.difference_update(six.iterkeys(self.__trim_dict)) + possible_set.difference_update(self.__trim_dict.keys()) # remove any versions from proposed_dict that are in trim_dict # as trim dict has been updated w/ missing dependencies try: @@ -1442,7 +1437,7 @@ def solve_update_all( self.__start_subphase(4) # remove all trimmed fmris from consideration - possible_set.difference_update(six.iterkeys(self.__trim_dict)) + possible_set.difference_update(self.__trim_dict.keys()) # # Generate ids, possible_dict for clause generation. Prepare @@ -1765,7 +1760,7 @@ def __assign_fmri_ids(self, possible_set): # assign clause numbers (ids) to possible pkgs pkgid = 1 - for name in sorted(six.iterkeys(self.__possible_dict)): + for name in sorted(self.__possible_dict.keys()): for fmri in reversed(self.__possible_dict[name]): self.__id2fmri[pkgid] = fmri self.__fmri2id[fmri] = pkgid @@ -2761,7 +2756,7 @@ def get_trim_errors(self): assert DebugValues["plan"] return self.__fmri_list_errors( - six.iterkeys(self.__trim_dict), already_seen=set(), verbose=True + self.__trim_dict.keys(), already_seen=set(), verbose=True ) def __check_installed(self): @@ -3270,7 +3265,7 @@ def __get_installed_unbound_inc_list(self, proposed_pkgs, excludes=EmptyI): relaxed_holds |= set( [ hold - for hold in six.itervalues(install_holds) + for hold in install_holds.values() if [r for r in relaxed_holds if hold.startswith(r + ".")] ] ) @@ -3300,7 +3295,7 @@ def __get_installed_unbound_inc_list(self, proposed_pkgs, excludes=EmptyI): versioned_dependents -= set( [ pkg_name - for pkg_name, hold_value in six.iteritems(install_holds) + for pkg_name, hold_value in install_holds.items() if hold_value not in relaxed_holds ] ) @@ -3710,9 +3705,9 @@ def __get_older_incorp_pkgs( # - upgrades of packages that are no longer incorporated # in a newer version of an incorporating package and a newer # version is otherwise allowed - for matchdg, nonmatchdg in six.itervalues( - self.__get_incorp_nonmatch_dict(fmri, excludes) - ): + for matchdg, nonmatchdg in self.__get_incorp_nonmatch_dict( + fmri, excludes + ).values(): match = next(iter(matchdg), None) if not match or match.pkg_name not in self.__installed_dict: continue diff --git a/src/modules/client/pkgplan.py b/src/modules/client/pkgplan.py index 88ada8413..73b749ad4 100644 --- a/src/modules/client/pkgplan.py +++ b/src/modules/client/pkgplan.py @@ -29,7 +29,6 @@ import itertools import os import pwd -import six import stat import pkg.actions @@ -474,7 +473,7 @@ def get_licenses(self): entry). Where 'entry' is a dict containing the license status information.""" - for lic, entry in six.iteritems(self._license_status): + for lic, entry in self._license_status.items(): yield lic, entry def set_license_status(self, plicense, accepted=None, displayed=None): diff --git a/src/modules/client/plandesc.py b/src/modules/client/plandesc.py index f5ebf8f78..6b0659975 100644 --- a/src/modules/client/plandesc.py +++ b/src/modules/client/plandesc.py @@ -41,7 +41,6 @@ import collections import itertools import operator -import six from typing import Iterator import pkg.actions @@ -987,7 +986,7 @@ def __gen_ordered_msg(self, stages): [item_id, None] + PlanDescription.__msg_dict2list(msg) ) msg["msg_stage"] = OP_STAGE_PRINTED - for si, si_list in six.iteritems(self._item_msgs[item_id]): + for si, si_list in self._item_msgs[item_id].items(): if si == "messages": continue for msg in si_list: @@ -1003,7 +1002,7 @@ def __gen_ordered_msg(self, stages): def __gen_unordered_msg(self, stages): """Generate unordered messages.""" for item_id in self._item_msgs: - for si, si_list in six.iteritems(self._item_msgs[item_id]): + for si, si_list in self._item_msgs[item_id].items(): if si == "messages": iid = item_id pid = None diff --git a/src/modules/client/printengine.py b/src/modules/client/printengine.py index d3a7b1c6f..7ca7ed0c1 100644 --- a/src/modules/client/printengine.py +++ b/src/modules/client/printengine.py @@ -38,8 +38,6 @@ import time from abc import ABCMeta, abstractmethod -import six - from pkg.misc import PipeError, force_str @@ -50,7 +48,7 @@ def __str__(self): return "PrintEngineException: {0}".format(" ".join(self.args)) -class PrintEngine(six.with_metaclass(ABCMeta, object)): +class PrintEngine(object, metaclass=ABCMeta): """Abstract class defining what a PrintEngine must know how to do.""" def __init__(self): diff --git a/src/modules/client/progress.py b/src/modules/client/progress.py index 69ee8d811..ed60524a0 100644 --- a/src/modules/client/progress.py +++ b/src/modules/client/progress.py @@ -40,8 +40,6 @@ from functools import wraps -import six - import pkg.client.pkgdefs as pkgdefs import pkg.client.publisher as publisher import pkg.fmri @@ -1804,7 +1802,7 @@ def multido(*args, **kwargs): # Look in the ProgressTrackerFrontend for a list of frontend # methods to multiplex. # - for methname, m in six.iteritems(ProgressTrackerFrontend.__dict__): + for methname, m in ProgressTrackerFrontend.__dict__.items(): if methname == "__init__": continue if not inspect.isfunction(m): @@ -3526,7 +3524,7 @@ def test_progress_tracker(t, gofast=False): hunkmax = 8192 approx_time = 5.0 * fast # how long we want the dl to take # invent a list of random download chunks. - for pkgname, filelist in six.iteritems(dlscript): + for pkgname, filelist in dlscript.items(): for f in range(0, perpkgfiles): filesize = random.randint(0, filesizemax) hunks = [] @@ -3544,7 +3542,7 @@ def test_progress_tracker(t, gofast=False): try: t.download_set_goal(len(dlscript), pkggoalfiles, pkggoalbytes) n = 0 - for pkgname, pkgfiles in six.iteritems(dlscript): + for pkgname, pkgfiles in dlscript.items(): fmri = pkg.fmri.PkgFmri(pkgname) t.download_start_pkg(fmri) for pkgfile in pkgfiles: @@ -3561,7 +3559,7 @@ def test_progress_tracker(t, gofast=False): t.reset_download() t.republish_set_goal(len(dlscript), pkggoalbytes, pkggoalbytes) n = 0 - for pkgname, pkgfiles in six.iteritems(dlscript): + for pkgname, pkgfiles in dlscript.items(): fmri = pkg.fmri.PkgFmri(pkgname) t.republish_start_pkg(fmri) for pkgfile in pkgfiles: @@ -3579,7 +3577,7 @@ def test_progress_tracker(t, gofast=False): t.reset_download() t.archive_set_goal("testarchive", pkggoalfiles, pkggoalbytes) n = 0 - for pkgname, pkgfiles in six.iteritems(dlscript): + for pkgname, pkgfiles in dlscript.items(): for pkgfile in pkgfiles: for hunk in pkgfile: t.archive_add_progress(0, hunk) diff --git a/src/modules/client/publisher.py b/src/modules/client/publisher.py index 51e656d8c..59700293a 100644 --- a/src/modules/client/publisher.py +++ b/src/modules/client/publisher.py @@ -44,7 +44,6 @@ import os import pycurl import shutil -import six import tempfile import time import uuid @@ -2135,7 +2134,7 @@ def __rebuild_catalog(self): for t, sentry in spart.tuple_entries(pubs=[self.prefix]): pub, stem, ver = t - entry = dict(six.iteritems(sentry)) + entry = dict(sentry.items()) try: npart.add( metadata=entry, @@ -3359,7 +3358,7 @@ def verify_chain( certs_with_problems = [] ca_dict = copy.copy(ca_dict) - for k, v in six.iteritems(self.get_ca_certs()): + for k, v in self.get_ca_certs().items(): if k in ca_dict: ca_dict[k].extend(v) else: @@ -3647,7 +3646,7 @@ def __prop_iter(self): def __prop_iteritems(self): """Support iteritems on properties""" - return six.iteritems(self.__properties) + return self.__properties.items() def __prop_keys(self): """Support keys() on properties""" @@ -3676,8 +3675,8 @@ def __prop_update(self, d): # The logic in __set_prop requires that the item with key # 'SIGNATURE_POLICY' comes before the item with key # 'signature-required-names'. - od = collections.OrderedDict(sorted(six.iteritems(d))) - for k, v in six.iteritems(od): + od = collections.OrderedDict(sorted(d.items())) + for k, v in od.items(): # Must iterate through each value and # set it this way so that the logic # in __set_prop is used. diff --git a/src/modules/client/transport/engine.py b/src/modules/client/transport/engine.py index b21a13a0f..5e4af10e0 100644 --- a/src/modules/client/transport/engine.py +++ b/src/modules/client/transport/engine.py @@ -31,7 +31,6 @@ import http.client import os import pycurl -import six import time from urllib.parse import urlsplit @@ -950,13 +949,13 @@ def __setup_handle(self, hdl, treq): headerlist = [] # Headers common to all requests - for k, v in six.iteritems(self.__common_header): + for k, v in self.__common_header.items(): headerstr = "{0}: {1}".format(k, v) headerlist.append(headerstr) # Headers specific to this request if treq.header: - for k, v in six.iteritems(treq.header): + for k, v in treq.header.items(): headerstr = "{0}: {1}".format(k, v) headerlist.append(headerstr) diff --git a/src/modules/client/transport/repo.py b/src/modules/client/transport/repo.py index 996757181..071dbbe47 100644 --- a/src/modules/client/transport/repo.py +++ b/src/modules/client/transport/repo.py @@ -31,7 +31,6 @@ import itertools import os import shutil -import six import sys import tempfile @@ -518,13 +517,8 @@ def __check_response_body(self, fobj): exc_type, exc_value, exc_tb = sys.exc_info() try: e.details = self._parse_html_error(fobj.read()) - # six.reraise requires the first argument - # callable if the second argument is None. - # Also the traceback is automatically attached, - # in Python 3, so we can simply raise it. except: - # If parse fails, raise original - # exception. + # If parse fails, raise original exception. raise exc_value raise finally: @@ -1249,7 +1243,7 @@ def get_compressed_attrs( csize = resp.getheader("Content-Length", None) chashes = dict( val.split("=", 1) - for hdr, val in six.iteritems(resp.headers) + for hdr, val in resp.headers.items() if hdr.lower().startswith("x-ipkg-attr") ) return (csize, chashes) @@ -1966,7 +1960,7 @@ def get_versions(self, header=None, ccancel=None): buf.write( "\n".join( "{0} {1}".format(op, " ".join(vers)) - for op, vers in six.iteritems(vops) + for op, vers in vops.items() ) + "\n" ) @@ -2594,7 +2588,7 @@ def get_versions(self, header=None, ccancel=None): buf.write( "\n".join( "{0} {1}".format(op, " ".join(vers)) - for op, vers in six.iteritems(vops) + for op, vers in vops.items() ) + "\n" ) diff --git a/src/modules/config.py b/src/modules/config.py index 077f71073..671a9f572 100644 --- a/src/modules/config.py +++ b/src/modules/config.py @@ -54,7 +54,6 @@ import os import re import shlex -import six import stat import subprocess import tempfile @@ -934,7 +933,7 @@ def get_index(self): name.""" return dict( (pname, p.value) - for pname, p in six.iteritems(self.__properties) + for pname, p in self.__properties.items() if hasattr(p, "value") ) @@ -948,7 +947,7 @@ def get_property(self, name): def get_properties(self): """Returns a generator that yields the list of property objects.""" - return six.itervalues(self.__properties) + return self.__properties.values() def remove_property(self, name): """Removes any matching property object from the section.""" @@ -1186,8 +1185,8 @@ def __reset(self, overrides=misc.EmptyDict): list(map(secobj.remove_property, elide)) self.add_section(secobj) - for sname, props in six.iteritems(overrides): - for pname, val in six.iteritems(props): + for sname, props in overrides.items(): + for pname, val in props.items(): self.set_property(sname, pname, val) def add_property_value(self, section, name, value): @@ -1276,7 +1275,7 @@ def get_section(self, name): def get_sections(self): """Returns a generator that yields the list of property section objects.""" - return six.itervalues(self.__sections) + return self.__sections.values() def remove_property(self, section, name): """Remove the property object matching the given section and @@ -1397,9 +1396,9 @@ def set_properties(self, properties): # Dict is in arbitrary order, sort it first to ensure the # order is same in Python 2 and 3. properties = OrderedDict(sorted(properties.items())) - for section, props in six.iteritems(properties): + for section, props in properties.items(): props = OrderedDict(sorted(props.items())) - for pname, pval in six.iteritems(props): + for pname, pval in props.items(): self.set_property(section, pname, pval) @property @@ -1848,11 +1847,11 @@ def __read(self, overrides=misc.EmptyDict): # shlex.split() automatically does escaping for a list of values # so no need to do it here. - for section, props in six.iteritems(cfgdata): + for section, props in cfgdata.items(): if section == "CONFIGURATION": # Reserved for configuration file management. continue - for prop, value in six.iteritems(props): + for prop, value in props.items(): if section in overrides and prop in overrides[section]: continue diff --git a/src/modules/depotcontroller.py b/src/modules/depotcontroller.py index c8dd30ec0..285e5d3c8 100755 --- a/src/modules/depotcontroller.py +++ b/src/modules/depotcontroller.py @@ -27,7 +27,6 @@ import platform import shlex import signal -import six import ssl import sys import time @@ -380,7 +379,7 @@ def get_args(self): if self.__nasty_sleep: args.append("--nasty-sleep {0:d}".format(self.__nasty_sleep)) for section in self.__props: - for prop, val in six.iteritems(self.__props[section]): + for prop, val in self.__props[section].items(): args.append( "--set-property={0}.{1}='{2}'".format(section, prop, val) ) diff --git a/src/modules/facet.py b/src/modules/facet.py index 1f9cd6085..8d4dc70da 100644 --- a/src/modules/facet.py +++ b/src/modules/facet.py @@ -29,7 +29,6 @@ import pkg.misc as misc import fnmatch import re -import six import types from functools import cmp_to_key @@ -113,12 +112,8 @@ def getstate(obj, je_state=None): that that can be easily stored using JSON, pickle, etc.""" return [ - [misc.force_text(k), v, True] - for k, v in six.iteritems(obj.__inherited) - ] + [ - [misc.force_text(k), v, False] - for k, v in six.iteritems(obj.__local) - ] + [misc.force_text(k), v, True] for k, v in obj.__inherited.items() + ] + [[misc.force_text(k), v, False] for k, v in obj.__local.items()] @staticmethod def fromstate(state, jd_state=None): @@ -441,9 +436,9 @@ def setdefault(self, item, default=None): def update(self, d): if type(d) == Facets: # preserve inherited facets. - for k, v in six.iteritems(d.__inherited): + for k, v in d.__inherited.items(): self._set_inherited(k, v) - for k, v in six.iteritems(d.__local): + for k, v in d.__local.items(): self[k] = v return diff --git a/src/modules/lint/pkglint_action.py b/src/modules/lint/pkglint_action.py index 5e7618da3..78516f3f2 100644 --- a/src/modules/lint/pkglint_action.py +++ b/src/modules/lint/pkglint_action.py @@ -35,7 +35,6 @@ from pkg.actions import ActionError from pkg.actions.file import FileAction import re -import six import stat ObsoleteFmri = collections.namedtuple("ObsoleteFmri", "is_obsolete, fmri") @@ -134,7 +133,7 @@ def mf_gen(atype): variants = action.get_variant_template() variants.merge_unknown(pkg_vars) # Action attributes must be lists or strings. - for k, v in six.iteritems(variants): + for k, v in variants.items(): if isinstance(v, set): action.attrs[k] = list(v) else: diff --git a/src/modules/manifest.py b/src/modules/manifest.py index 7b11f8cd0..d1ddc2c49 100644 --- a/src/modules/manifest.py +++ b/src/modules/manifest.py @@ -33,7 +33,6 @@ import hashlib import os import re -import six import tempfile from itertools import groupby, chain, product, repeat from operator import itemgetter @@ -64,7 +63,7 @@ def _compile_fnpats(fn_pats): for pat in pats ], ) - for (key, pats) in six.iteritems(fn_pats) + for (key, pats) in fn_pats.items() ) @@ -77,7 +76,7 @@ def _attr_matches(action, attr_match): if not attr_match: return True - for attr, matches in six.iteritems(attr_match): + for attr, matches in attr_match.items(): if attr in action.attrs: for match in matches: for attrval in action.attrlist(attr): @@ -269,8 +268,8 @@ def dictify(mf, excludes): sdict = dict(dictify(self, self_exclude)) odict = dict(dictify(origin, origin_exclude)) - sset = set(six.iterkeys(sdict)) - oset = set(six.iterkeys(odict)) + sset = set(sdict.keys()) + oset = set(odict.keys()) added = [(None, sdict[i]) for i in sset - oset] removed = [(odict[i], None) for i in oset - sset] @@ -452,7 +451,7 @@ def gen_references(a): ) mediators = self._actions_to_dict(gen_references) - for mediation, mvariants in six.iteritems(mediators): + for mediation, mvariants in mediators.items(): values = { "mediator-priority": mediation[1], "mediator-version": mediation[2], @@ -461,10 +460,8 @@ def gen_references(a): for mvariant in mvariants: a = "set name=pkg.mediator " "value={0} {1} {2}\n".format( mediation[0], - " ".join( - ("=".join(t) for t in six.iteritems(values) if t[1]) - ), - " ".join(("=".join(t) for t in six.iteritems(mvariant))), + " ".join(("=".join(t) for t in values.items() if t[1])), + " ".join(("=".join(t) for t in mvariant.items())), ) yield a @@ -659,7 +656,7 @@ def _gen_attrs_to_str(self): # Now emit a pkg.facet action for each variant # combination containing the list of facets unique to # that combination. - for varkey, fnames in six.iteritems(facets): + for varkey, fnames in facets.items(): # A unique key for each combination is needed, # and using a hash obfuscates that interface # while giving us a reliable way to generate @@ -1363,7 +1360,7 @@ def hash_create(mfstcontent): # This must be an SHA-1 hash in order to interoperate with # older clients. sha_1 = hashlib.sha1() - if isinstance(mfstcontent, six.text_type): + if isinstance(mfstcontent, str): # Byte stream expected, so pass encoded. sha_1.update(mfstcontent.encode("utf-8")) else: @@ -1704,7 +1701,7 @@ def __storebytype(self): # so that empty cache files are created if no action of that # type exists for the package (avoids full manifest loads # later). - for n, acts in six.iteritems(self.actions_bytype): + for n, acts in self.actions_bytype.items(): t_prefix = "manifest.{0}.".format(n) try: diff --git a/src/modules/misc.py b/src/modules/misc.py index fa43ac3f1..abd2de84e 100644 --- a/src/modules/misc.py +++ b/src/modules/misc.py @@ -1008,7 +1008,7 @@ class ProcFS(object): } # fill in and in _struct_descriptions - for struct_name, v in six.iteritems(_struct_descriptions): + for struct_name, v in _struct_descriptions.items(): desc = v[0] # update _struct_descriptions with a format string @@ -1774,7 +1774,7 @@ def api_pkgcmd(): pkg_cmd = [sys.executable] + [pkg_bin] # propagate debug options - for k, v in six.iteritems(DebugValues): + for k, v in DebugValues.items(): pkg_cmd.append("-D") pkg_cmd.append("{0}={1}".format(k, v)) @@ -1969,7 +1969,7 @@ def fmt_val(v): if isinstance(v, (list, tuple, set, frozenset)): return [fmt_val(e) for e in v] if isinstance(v, dict): - for k, e in six.iteritems(v): + for k, e in v.items(): v[k] = fmt_val(e) return v return str(v) @@ -2014,7 +2014,7 @@ def fmt_val(v): set_value, ( (field_data[f], v) - for f, v in six.iteritems(entry) + for f, v in entry.items() if f in field_data ), ) @@ -2172,7 +2172,7 @@ def je_return(name, data, finish, je_state): # strings (that way we're encoder/decoder independent). obj_cache = je_state[1] obj_cache2 = {} - for obj_id, obj_state in six.itervalues(obj_cache): + for obj_id, obj_state in obj_cache.values(): obj_cache2[str(obj_id)] = obj_state data = {"json_state": data, "json_objects": obj_cache2} @@ -2235,7 +2235,7 @@ def je_return(name, data, finish, je_state): assert len(desc) == 1 # encode all key / value pairs - for k, v in six.iteritems(data): + for k, v in data.items(): # encode the key name2 = "{0}[{1}].key()".format(name, desc_k) k2 = json_encode(name2, k, desc_k, je_state=je_state) @@ -2251,7 +2251,7 @@ def je_return(name, data, finish, je_state): # we have element specific value type descriptions. # encode the specific values. rv.update(data) - for desc_k, desc_v in six.iteritems(desc): + for desc_k, desc_v in desc.items(): # check for the specific key if desc_k not in rv: continue @@ -2459,7 +2459,7 @@ def jd_return(name, data, desc, finish, jd_state): assert len(desc) == 1 # decode all key / value pairs - for k, v in six.iteritems(data): + for k, v in data.items(): # decode the key name2 = "{0}[{1}].key()".format(name, desc_k) k2 = json_decode(name2, k, desc_k, jd_state=jd_state) @@ -2475,7 +2475,7 @@ def jd_return(name, data, desc, finish, jd_state): # we have element specific value type descriptions. # copy all data and then decode the specific values rv.update(data) - for desc_k, desc_v in six.iteritems(desc): + for desc_k, desc_v in desc.items(): # check for the specific key if desc_k not in rv: continue @@ -2644,7 +2644,7 @@ def json_hook(dct): objects are converted to str objects in Python 3.""" rvdct = {} - for k, v in six.iteritems(dct): + for k, v in dct.items(): if isinstance(k, str): k = force_str(k) if isinstance(v, str): diff --git a/src/modules/mogrify.py b/src/modules/mogrify.py index 56fb6880f..b6957dcfb 100755 --- a/src/modules/mogrify.py +++ b/src/modules/mogrify.py @@ -27,7 +27,6 @@ import os import re import shlex -import six import sys import pkg.actions @@ -567,7 +566,7 @@ def apply_transforms( s = transform[11 : transform.index("->")] # Map each pattern to its position in the original match string. matchorder = {} - for attr, match in six.iteritems(attrdict): + for attr, match in attrdict.items(): # Attributes might be quoted even if they don't need it, # and lead to a mis-match. These three patterns are all # safe to try. If we fail to find the match expression, diff --git a/src/modules/pkgsubprocess.py b/src/modules/pkgsubprocess.py index 5a4899ad2..ba4c2a13e 100644 --- a/src/modules/pkgsubprocess.py +++ b/src/modules/pkgsubprocess.py @@ -28,7 +28,6 @@ import os import sys import types -import six import subprocess import pkg.portable @@ -291,7 +290,7 @@ def _pkg_execute_child( # The bundled subprocess module takes a dict in # the "env" argument. Allow that here by doing # the explicit conversion to a list. - env = ["{0}={1}".format(k, v) for k, v in six.iteritems(env)] + env = ["{0}={1}".format(k, v) for k, v in env.items()] self.pid = posix_spawnp(executable, args, sfa, env) self._child_created = True diff --git a/src/modules/publish/dependencies.py b/src/modules/publish/dependencies.py index 90128d35f..775e2074d 100644 --- a/src/modules/publish/dependencies.py +++ b/src/modules/publish/dependencies.py @@ -29,7 +29,6 @@ import operator import os import re -import six from collections import namedtuple from urllib.parse import unquote @@ -183,7 +182,7 @@ def __init__(self, pkg, reason_variants, manual_dep): def __str__(self): s = "" - for r, diff in sorted(six.iteritems(self.rvs)): + for r, diff in sorted(self.rvs.items()): for kind in diff.type_diffs: s += _( "\t{r:15} Variant '{kind}' is not " "declared.\n" @@ -464,7 +463,7 @@ def list_implicit_deps_for_manifest( # for each of them. for a in mfst.gen_actions(): pvars = a.get_variant_template() - for k, v in six.iteritems(pvars): + for k, v in pvars.items(): if k not in pkg_vars or not v.issubset(pkg_vars[k]): warnings.append( UndeclaredVariantWarning( @@ -1443,9 +1442,7 @@ def __remove_unneeded_require_and_require_any(deps, pkg_fmri): if files_prefix in cur_dep.attrs or fullpaths_prefix in cur_dep.attrs: # convert to a set for set operation cur_fmris_set = set(cur_fmris) - for (comp_dep, comp_vars), comp_fmris_set in six.iteritems( - fmri_dict - ): + for (comp_dep, comp_vars), comp_fmris_set in fmri_dict.items(): if ( comp_fmris_set != cur_fmris_set and comp_fmris_set.issubset(cur_fmris_set) @@ -1708,7 +1705,7 @@ def prune_debug_attrs(action): attrs = dict( (k, v) - for k, v in six.iteritems(action.attrs) + for k, v in action.attrs.items() if not k.startswith(base.Dependency.DEPEND_DEBUG_PREFIX) ) return actions.depend.DependencyAction(**attrs) @@ -1955,7 +1952,7 @@ def __merge_actvct_with_pkgvct(act_vct, pkg_vct): for pkg_vct in package_vars.values(): pkg_vct.merge_unknown(distro_vars) # Populate the installed files dictionary. - for pth, l in six.iteritems(tmp_files): + for pth, l in tmp_files.items(): new_val = [ (p, __merge_actvct_with_pkgvct(tmpl, package_vars[p.pkg_name])) for (p, tmpl) in l @@ -1965,7 +1962,7 @@ def __merge_actvct_with_pkgvct(act_vct, pkg_vct): # Populate the link dictionary using the installed packages' # information. - for pth, l in six.iteritems(tmp_links): + for pth, l in tmp_links.items(): new_val = [ ( p, diff --git a/src/modules/publish/transaction.py b/src/modules/publish/transaction.py index 6b00ef9e0..f80bebc59 100644 --- a/src/modules/publish/transaction.py +++ b/src/modules/publish/transaction.py @@ -30,7 +30,6 @@ import os import shutil -import six from urllib.parse import quote, unquote, urlparse, urlunparse import tempfile @@ -552,12 +551,12 @@ def _process_action(self, action, exact=False, path=None): self.__uploads[fname] = (elf_attrs, csize, chashes) - for k, v in six.iteritems(elf_attrs): + for k, v in elf_attrs.items(): if isinstance(v, list): action.attrs[k] = v + action.attrlist(k) else: action.attrs[k] = v - for k, v in six.iteritems(chashes): + for k, v in chashes.items(): if k == "pkg.content-hash": action.attrs[k] = action.attrlist(k) + [v] else: diff --git a/src/modules/server/api.py b/src/modules/server/api.py index 43be05d30..98dfd5c61 100644 --- a/src/modules/server/api.py +++ b/src/modules/server/api.py @@ -26,7 +26,6 @@ import cherrypy import itertools import os -import six from functools import cmp_to_key from io import BytesIO @@ -158,7 +157,7 @@ def gen_allowed_packages(self, pfmris, build_release=None): # Add packages not incorporated by the recursively discovered # incorporations above. cat_info = frozenset([cat.DEPENDENCY]) - remaining = frozenset(cat.names(pubs=pubs)) - set(six.iterkeys(allowed)) + remaining = frozenset(cat.names(pubs=pubs)) - set(allowed.keys()) for pkg_name in remaining: allowed.setdefault(pkg_name, []) @@ -777,7 +776,7 @@ def get_depot_properties(self): See pkg.depotd(8) for the list of properties. """ rval = {} - for sname, props in six.iteritems(self._depot.cfg.get_index()): + for sname, props in self._depot.cfg.get_index().items(): rval[sname] = [p for p in props] return rval @@ -806,7 +805,7 @@ def get_repo_properties(self): format. """ rval = {} - for sname, props in six.iteritems(self._depot.repo.cfg.get_index()): + for sname, props in self._depot.repo.cfg.get_index().items(): rval[sname] = [p for p in props] return rval diff --git a/src/modules/server/depot.py b/src/modules/server/depot.py index 63f93c3dc..4b239a1d3 100644 --- a/src/modules/server/depot.py +++ b/src/modules/server/depot.py @@ -54,7 +54,6 @@ import random import re import shutil -import six import socket import tarfile import tempfile @@ -506,7 +505,7 @@ def versions_0(self, *tokens): versions += ( "\n".join( "{0} {1}".format(op, " ".join(str(v) for v in vers)) - for op, vers in six.iteritems(self.vops) + for op, vers in self.vops.items() ) + "\n" ) @@ -1779,7 +1778,7 @@ def __init__(self, repo, dconf): } self.errlist = [] - for x, n in six.iteritems(errors): + for x, n in errors.items(): for i in range(0, n): self.errlist.append(x) cherrypy.log("NASTY Depot Error List: {0}".format(str(self.errlist))) @@ -1896,7 +1895,7 @@ def versions_0(self, *tokens): if self.need_nasty_2(): cherrypy.log("NASTY versions_0: modified version #s") versions = "pkg-server {0}-nasty\n".format(pkg.VERSION) - for op, vers in six.iteritems(self.vops): + for op, vers in self.vops.items(): versions += op + " " verlen = len(vers) for v in vers: @@ -1927,7 +1926,7 @@ def versions_0(self, *tokens): versions += ( "\n".join( "{0} {1}".format(op, " ".join(str(v) for v in vers)) - for op, vers in six.iteritems(self.vops) + for op, vers in self.vops.items() ) + "\n" ) diff --git a/src/modules/server/feed.py b/src/modules/server/feed.py index 14c8b2707..2d1fa4596 100644 --- a/src/modules/server/feed.py +++ b/src/modules/server/feed.py @@ -36,7 +36,6 @@ import http.client import os import shutil -import six import time import xml.dom.minidom as xmini @@ -228,7 +227,7 @@ def get_updates_needed(repo, ts, pub): return [] updates = set() - for name, mdata in six.iteritems(c.updates): + for name, mdata in c.updates.items(): # The last component of the update name is the locale. locale = name.split(".", 2)[2] diff --git a/src/modules/server/repository.py b/src/modules/server/repository.py index 5d2ce12ad..e4fafaa80 100644 --- a/src/modules/server/repository.py +++ b/src/modules/server/repository.py @@ -30,7 +30,6 @@ import os import os.path import shutil -import six import stat import sys import tempfile @@ -3669,7 +3668,7 @@ def get_matching_fmris(self, patterns, pubs=misc.EmptyI): """ def merge(src, dest): - for k, v in six.iteritems(src): + for k, v in src.items(): if k in dest: dest[k].extend(v) else: diff --git a/src/modules/sha512_t.py b/src/modules/sha512_t.py index 610478974..6a332b56e 100644 --- a/src/modules/sha512_t.py +++ b/src/modules/sha512_t.py @@ -26,7 +26,6 @@ # from __future__ import division, unicode_literals -import six from pkg._sha512_t import lib, ffi """A hash module computes SHA512/t. Now it only supports SHA512/256 and @@ -92,7 +91,7 @@ def digest(self): lib.memcpy(shc, self.ctx, ffi.sizeof("SHA2_CTX")) lib.SHA2Final(digest, shc) - return b"".join(six.int2byte(i) for i in digest) + return b"".join(bytes((i,)) for i in digest) def hexdigest(self): """Return hexadecimal digest of the strings passed to the update() diff --git a/src/pkgdep.py b/src/pkgdep.py index a5d76cd1f..8adbc31ff 100644 --- a/src/pkgdep.py +++ b/src/pkgdep.py @@ -29,7 +29,6 @@ import gettext import locale import os -import six import sys import traceback import warnings @@ -231,7 +230,7 @@ def generate(args): for d in sorted(ds, key=str): msg(d) - for key, value in six.iteritems(pkg_attrs): + for key, value in pkg_attrs.items(): msg(actions.attribute.AttributeAction(**{key: value})) if show_missing: diff --git a/src/pkgrepo.py b/src/pkgrepo.py index a86e89834..0d428e5fc 100755 --- a/src/pkgrepo.py +++ b/src/pkgrepo.py @@ -62,7 +62,6 @@ import re import shlex import shutil -import six import sys import tempfile import textwrap @@ -1647,7 +1646,7 @@ def subcmd_set(conf, args): def _set_pub(conf, subcommand, props, pubs, repo): """Set publisher properties.""" - for sname, sprops in six.iteritems(props): + for sname, sprops in props.items(): if sname not in ("publisher", "repository"): usage( _("unknown property section " "'{0}'").format(sname), @@ -1697,7 +1696,7 @@ def _set_pub(conf, subcommand, props, pubs, repo): try: # Set/update the publisher's properties. - for sname, sprops in six.iteritems(props): + for sname, sprops in props.items(): if sname == "publisher": target = pub elif sname == "repository": @@ -1706,7 +1705,7 @@ def _set_pub(conf, subcommand, props, pubs, repo): target = publisher.Repository() pub.repository = target - for pname, val in six.iteritems(sprops): + for pname, val in sprops.items(): attrname = pname.replace("-", "_") pval = getattr(target, attrname) if isinstance(pval, list) and not isinstance(val, list): @@ -1746,8 +1745,8 @@ def _set_repo(conf, subcommand, props, repo): """Set repository properties.""" # Set properties. - for sname, props in six.iteritems(props): - for pname, val in six.iteritems(props): + for sname, props in props.items(): + for pname, val in props.items(): repo.cfg.set_property(sname, pname, val) repo.write_config() diff --git a/src/tests/api/t_action.py b/src/tests/api/t_action.py index cd45bc457..abd819a64 100644 --- a/src/tests/api/t_action.py +++ b/src/tests/api/t_action.py @@ -30,7 +30,6 @@ testutils.setup_environment("../../../proto") import pkg5unittest -import six import sys import unittest import pkg.actions as action @@ -346,7 +345,7 @@ def test_action_tostr(self): } astr = "file {0} path=usr/bin/foo mode=0755 owner=root group=bin" - for k, v in six.iteritems(d): + for k, v in d.items(): a = action.fromstr(astr.format(k)) self.assertTrue(action.fromstr(str(a)) == a) self.assertTrue(a.hash == v) @@ -720,7 +719,7 @@ def assertActionError(astr, error=action.InvalidActionAttributesError): "mediator-implementation": "svr4", "mediator-priority": "site", } - for prop, val in six.iteritems(props): + for prop, val in props.items(): nact = ( "{0} path=usr/bin/vi " "target=../sunos/bin/edit {1}={2}".format(aname, prop, val) @@ -729,7 +728,7 @@ def assertActionError(astr, error=action.InvalidActionAttributesError): # Action with multiple values for any property is # invalid. - for prop, val in six.iteritems(props): + for prop, val in props.items(): nact = ( "{0} path=usr/bin/vi " "target=../sunos/bin/edit mediator=vi " diff --git a/src/tests/api/t_catalog.py b/src/tests/api/t_catalog.py index 74e9eee9b..7b33d17fc 100644 --- a/src/tests/api/t_catalog.py +++ b/src/tests/api/t_catalog.py @@ -33,7 +33,6 @@ import errno import os import shutil -import six import stat import unittest from functools import cmp_to_key @@ -515,7 +514,7 @@ def test_04_store_and_validate(self): c = catalog.Catalog(meta_root=cpath, log_updates=True) # Verify that a newly created catalog has no signature data. - for sigs in six.itervalues(c.signatures): + for sigs in c.signatures.values(): self.assertEqual(len(sigs), 0) # Verify that a newly created catalog will validate since no @@ -541,7 +540,7 @@ def test_04_store_and_validate(self): self.assertTrue("catalog.base.C" in old_sigs) updates = 0 - for fname, sigs in six.iteritems(old_sigs): + for fname, sigs in old_sigs.items(): self.assertTrue(len(sigs) >= 1) if fname.startswith("update."): diff --git a/src/tests/api/t_config.py b/src/tests/api/t_config.py index a7dd59cab..a61d033a2 100644 --- a/src/tests/api/t_config.py +++ b/src/tests/api/t_config.py @@ -37,7 +37,6 @@ import re import shutil import signal -import six import stat import tempfile import time @@ -1457,8 +1456,8 @@ def test_base(self): definitions=self._defs, overrides=overrides, version=0 ) exp_state = copy.deepcopy(self._initial_state[0]) - for sname, props in six.iteritems(overrides): - for pname, value in six.iteritems(props): + for sname, props in overrides.items(): + for pname, value in props.items(): exp_state[sname][pname] = value self._verify_initial_state(conf, 0, exp_state=exp_state) @@ -1659,7 +1658,7 @@ def test_file_read_write(self): portable.remove(scpath) # Verify read and write of sample files. - for ver, content in six.iteritems(self._initial_files): + for ver, content in self._initial_files.items(): scpath = self.make_misc_files({"cfg_cache": content})[0] # Verify verison of content is auto detected and that @@ -2393,7 +2392,7 @@ def test_mfst(svc_fmri, ver, mfst_content, defs, exp_state=None): # attempted (not currently supported). self.assertRaises(cfg.SMFWriteError, conf.write) - for ver, mfst_content in six.iteritems(self._initial_files): + for ver, mfst_content in self._initial_files.items(): test_mfst(svc_fmri, ver, mfst_content, self._defs) # Verify configuration data with unknown sections or properties diff --git a/src/tests/cli/t_pkg_depotd.py b/src/tests/cli/t_pkg_depotd.py index e3519c60c..7095bb3ec 100644 --- a/src/tests/cli/t_pkg_depotd.py +++ b/src/tests/cli/t_pkg_depotd.py @@ -34,7 +34,6 @@ import http.client import os import shutil -import six import sys import tempfile import time @@ -1037,7 +1036,7 @@ def __update_repo_config(self): pub_repo = publisher.Repository() pub.repository = pub_repo - for attr, val in six.iteritems(self.pub_repo_cfg): + for attr, val in self.pub_repo_cfg.items(): setattr(pub_repo, attr, val) repo.update_publisher(pub) @@ -1071,7 +1070,7 @@ def test_1_depot_publisher(self): self.assertEqual(getattr(pub, prop), cfgdata["publisher"][prop]) repo = pub.repository - for prop, expected in six.iteritems(self.pub_repo_cfg): + for prop, expected in self.pub_repo_cfg.items(): returned = getattr(repo, prop) if prop.endswith("uris") or prop == "origins": uris = [] diff --git a/src/tests/cli/t_pkg_image_create.py b/src/tests/cli/t_pkg_image_create.py index 5a405f921..3e8677637 100644 --- a/src/tests/cli/t_pkg_image_create.py +++ b/src/tests/cli/t_pkg_image_create.py @@ -37,7 +37,6 @@ import pkg.config as cfg import pkg.misc as misc import shutil -import six import unittest @@ -243,7 +242,7 @@ def __verify_pub_cfg(self, img_path, prefix, pub_cfg): ) pub = img.get_publisher(prefix=prefix) for section in pub_cfg: - for prop, val in six.iteritems(pub_cfg[section]): + for prop, val in pub_cfg[section].items(): if section == "publisher": pub_val = getattr(pub, prop) else: diff --git a/src/tests/cli/t_pkg_linked.py b/src/tests/cli/t_pkg_linked.py index 1fc49d1e4..d1526fc39 100644 --- a/src/tests/cli/t_pkg_linked.py +++ b/src/tests/cli/t_pkg_linked.py @@ -38,7 +38,6 @@ import itertools import re import shutil -import six import tempfile import unittest import sys @@ -5232,7 +5231,7 @@ def __check_linked_props( ) self.__ccmd("cat {0}".format(outfile1)) - for p, v in six.iteritems(props): + for p, v in props.items(): if v is None: # verify property is not present self.__ccmd('grep "^{0}[ ]" {1}'.format(p, outfile1), rv=1) diff --git a/src/tests/cli/t_pkg_publisher.py b/src/tests/cli/t_pkg_publisher.py index 07eb8418c..cc5ae6209 100644 --- a/src/tests/cli/t_pkg_publisher.py +++ b/src/tests/cli/t_pkg_publisher.py @@ -35,7 +35,6 @@ import pkg.client.image as image import pkg.misc import shutil -import six import tempfile import unittest @@ -1139,7 +1138,7 @@ def __verify_pub_cfg(self, prefix, pub_cfg): ) pub = img.get_publisher(prefix=prefix) for section in pub_cfg: - for prop, val in six.iteritems(pub_cfg[section]): + for prop, val in pub_cfg[section].items(): if section == "publisher": pub_val = getattr(pub, prop) else: @@ -1171,7 +1170,7 @@ def __update_repo_pub_cfg(self, dc, pubcfg): rpath = dc.get_repodir() props = "" for sname in pubcfg: - for pname, pval in six.iteritems(pubcfg[sname]): + for pname, pval in pubcfg[sname].items(): if sname == "publisher" and pname == "prefix": continue pname = pname.replace("_", "-") diff --git a/src/tests/cli/t_pkgmogrify.py b/src/tests/cli/t_pkgmogrify.py index ae7a9ae3a..a2d066b52 100644 --- a/src/tests/cli/t_pkgmogrify.py +++ b/src/tests/cli/t_pkgmogrify.py @@ -33,7 +33,6 @@ import os import re import shutil -import six import stat import sys import tempfile @@ -169,14 +168,14 @@ def setUp(self): xformpaths = dict( ( (name, os.path.join(self.test_root, "transform_{0}".format(i))) - for i, name in enumerate(six.iterkeys(self.transforms)) + for i, name in enumerate(self.transforms.keys()) ) ) # Now that we have path names, we can use the expandos in the # transform contents to embed those pathnames, and write the # transform files out. - for name, path in six.iteritems(xformpaths): + for name, path in xformpaths.items(): with open(path, "w") as f: self.transforms[name] = self.transforms[name].format( **xformpaths @@ -199,7 +198,7 @@ def pkgmogrify( defines = self.basic_defines defines = " ".join( - ["-D {0}={1}".format(k, v) for k, v in six.iteritems(defines)] + ["-D {0}={1}".format(k, v) for k, v in defines.items()] ) sources = " ".join(sources) diff --git a/src/tests/cli/t_pkgrecv.py b/src/tests/cli/t_pkgrecv.py index d06a4ba12..676b92116 100644 --- a/src/tests/cli/t_pkgrecv.py +++ b/src/tests/cli/t_pkgrecv.py @@ -32,7 +32,6 @@ import pkg5unittest import os -import six import pkg.catalog as catalog import pkg.config as cfg import pkg.client.pkgdefs as pkgdefs @@ -277,14 +276,14 @@ def setUp(self): xformpaths = dict( ( (name, os.path.join(self.test_root, "transform_{0}".format(i))) - for i, name in enumerate(six.iterkeys(self.transforms)) + for i, name in enumerate(self.transforms.keys()) ) ) # Now that we have path names, we can use the expandos in the # transform contents to embed those pathnames, and write the # transform files out. - for name, path in six.iteritems(xformpaths): + for name, path in xformpaths.items(): f = open(path, "w") self.transforms[name] = self.transforms[name].format(**xformpaths) f.write(self.transforms[name]) diff --git a/src/tests/cli/t_pkgsend.py b/src/tests/cli/t_pkgsend.py index 7b1654ae6..13229e8b6 100644 --- a/src/tests/cli/t_pkgsend.py +++ b/src/tests/cli/t_pkgsend.py @@ -38,7 +38,6 @@ import stat import tempfile import unittest -import six from urllib.error import HTTPError from urllib.request import urlopen, Request, pathname2url @@ -1678,9 +1677,7 @@ def test_28_content_attrs(self): "pkg.csize": "1358", "pkg.size": "3948", } - actual = dict( - (k, v) for (k, v) in six.iteritems(a.attrs) if k in expected - ) + actual = dict((k, v) for (k, v) in a.attrs.items() if k in expected) self.assertEqualDiff(expected, actual) # 'elfhash' and 'pkg.content-hash' can vary depending upon diff --git a/src/tests/pkg5unittest.py b/src/tests/pkg5unittest.py index de096359e..7c4b496b9 100644 --- a/src/tests/pkg5unittest.py +++ b/src/tests/pkg5unittest.py @@ -52,7 +52,6 @@ import pprint import shutil import signal -import six import stat import subprocess import sys @@ -577,7 +576,7 @@ def debugfilecreate(self, content, path): ins = " [+{0:d} lines...]".format(len(lines) - 1) else: ins = "" - if isinstance(lines[0], six.text_type): + if isinstance(lines[0], str): lines[0] = lines[0].encode("utf-8") self.debugcmd("echo '{0}{1}' > {2}".format(lines[0], ins, path)) @@ -3705,7 +3704,7 @@ def prep_depot( dc.set_port(port) for section in properties: - for prop, val in six.iteritems(properties[section]): + for prop, val in properties[section].items(): dc.set_property(section, prop, val) if refresh_index: dc.set_refresh_index() diff --git a/src/util/log-scripts/an2_ip_active.py b/src/util/log-scripts/an2_ip_active.py index e458bb9c4..726cf14e5 100644 --- a/src/util/log-scripts/an2_ip_active.py +++ b/src/util/log-scripts/an2_ip_active.py @@ -25,7 +25,7 @@ # from __future__ import division -import six.moves.cPickle as pickle +import pickle import datetime import time diff --git a/src/util/log-scripts/an_ip_active.py b/src/util/log-scripts/an_ip_active.py index c318bfd47..90f19d574 100644 --- a/src/util/log-scripts/an_ip_active.py +++ b/src/util/log-scripts/an_ip_active.py @@ -24,7 +24,7 @@ # Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. # -import six.moves.cPickle as pickle +import pickle import datetime import fileinput import GeoIP diff --git a/src/util/publish/pkgfmt.py b/src/util/publish/pkgfmt.py index 89696d434..3f08b10a9 100755 --- a/src/util/publish/pkgfmt.py +++ b/src/util/publish/pkgfmt.py @@ -66,7 +66,6 @@ import operator import os import re - import six import sys import tempfile import traceback @@ -353,7 +352,7 @@ def write_line(line, fileobj): if opt_strip: sattrs = dict( (k, v) - for k, v in six.iteritems(sattrs) + for k, v in sattrs.items() if not k.startswith("pkg.depend.") and not k.startswith("pkg.debug") ) @@ -497,7 +496,7 @@ def astr(aout): rem_count = total_count # Now build the action output string an attribute at a time. - for k, v in sorted(six.iteritems(sattrs), key=key_func): + for k, v in sorted(sattrs.items(), key=key_func): # Newline breaks are only forced when there is more than # one value for an attribute. if not (isinstance(v, list) or isinstance(v, set)): diff --git a/src/util/publish/pkgmerge.py b/src/util/publish/pkgmerge.py index 64be45592..2ec805ae8 100755 --- a/src/util/publish/pkgmerge.py +++ b/src/util/publish/pkgmerge.py @@ -36,7 +36,6 @@ import locale import os import shutil - import six import sys import tempfile import traceback @@ -271,7 +270,7 @@ def main_func(): variants = set() vcombos = collections.defaultdict(set) for src_vars in variant_list: - for v, vval in six.iteritems(src_vars): + for v, vval in src_vars.items(): variants.add(v) vcombos[v].add((v, vval)) @@ -886,7 +885,7 @@ def build_merge_list(include, exclude, cat): return ( dict( (k, sorted(list(v), reverse=True)[0]) - for k, v in six.iteritems(include_dict) + for k, v in include_dict.items() if v ), include_misses, diff --git a/src/web/en/search.shtml b/src/web/en/search.shtml index ef4d97ff9..87dc7905c 100644 --- a/src/web/en/search.shtml +++ b/src/web/en/search.shtml @@ -22,7 +22,6 @@ ## Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. ## <%! - import six import html as cgi import itertools import pkg.actions as actions @@ -180,7 +179,7 @@ scheme, netloc, path, params, query, fragment = urlparse(uri) nparams = [] - for name, val in six.iteritems(request.params): + for name, val in request.params.items(): if name == "start": continue nparams.append((name, val)) @@ -204,7 +203,7 @@ scheme, netloc, path, params, query, fragment = urlparse(uri) nparams = [] - for name, val in six.iteritems(request.params): + for name, val in request.params.items(): if name == "start": continue nparams.append((name, val)) @@ -310,7 +309,7 @@ Next fragment = urlparse(uri) nparams = [] - for name, val in six.iteritems(request.params): + for name, val in request.params.items(): if name in ("failed", "query_error"): continue nparams.append((name, val)) diff --git a/src/web/shared.shtml b/src/web/shared.shtml index 86e5be9ce..e28be5bbc 100644 --- a/src/web/shared.shtml +++ b/src/web/shared.shtml @@ -22,7 +22,6 @@ ## Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. ## <%! - import six import operator %> ## Returns the value of the named respository configuration property in the @@ -67,7 +66,7 @@ return [ ver[1] for ver in - sorted(six.iteritems(versions), key=operator.itemgetter(1), + sorted(versions.items(), key=operator.itemgetter(1), reverse=True) ] %>\ From 308f2a63537975bc5abb24c8e232245bb1d3959d Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Tue, 5 Dec 2023 15:25:43 +0000 Subject: [PATCH 15/15] Add "fmt" make target --- src/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Makefile b/src/Makefile index 6cd8e3c6d..0d1a72866 100644 --- a/src/Makefile +++ b/src/Makefile @@ -64,6 +64,10 @@ packages: install test: install .WAIT $(PYTESTS) $(TESTRESULTS) +fmt: FRC + python$(PYVER) -mpip install --quiet --user --upgrade black + $(HOME)/.local/bin/black --config $(CODE_WS)/.black $(CODE_WS)/src + $(SUBDIRS) cffi_src: FRC @cd $@; pwd; $(MAKE) $(TARGET) CC=$(CC)