Index: src/sas/qtgui/Calculators/DataOperationUtilityPanel.py
===================================================================
--- src/sas/qtgui/Calculators/DataOperationUtilityPanel.py	(revision 7d9c83c92cef3381669815551c3850802b12abf0)
+++ src/sas/qtgui/Calculators/DataOperationUtilityPanel.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -13,5 +13,5 @@
 import sas.qtgui.Utilities.GuiUtils as GuiUtils
 
-from UI.DataOperationUtilityUI import Ui_DataOperationUtility
+from .UI.DataOperationUtilityUI import Ui_DataOperationUtility
 
 BG_WHITE = "background-color: rgb(255, 255, 255);"
@@ -76,5 +76,5 @@
         self.filenames = filenames
 
-        if filenames.keys():
+        if list(filenames.keys()):
             # clear contents of comboboxes
             self.cbData1.clear()
@@ -85,5 +85,5 @@
             list_datafiles = []
 
-            for key_id in filenames.keys():
+            for key_id in list(filenames.keys()):
                 if filenames[key_id].get_data().title:
                     # filenames with titles
@@ -139,5 +139,5 @@
             data1 = self.data1
             data2 = self.data2
-            exec "output = data1 %s data2" % operator
+            exec("output = data1 %s data2" % operator)
         except:
             raise
@@ -300,5 +300,5 @@
                 self.cbData1.setStyleSheet(QtCore.QString(BG_RED))
                 self.cbData2.setStyleSheet(QtCore.QString(BG_RED))
-                print self.data1.__class__.__name__ != self.data2.__class__.__name__
+                print(self.data1.__class__.__name__ != self.data2.__class__.__name__)
                 logging.warning('Cannot compute data of different dimensions')
                 return False
@@ -354,7 +354,7 @@
     def _findId(self, name):
         """ find id of name in list of filenames """
-        isinstance(name, basestring)
-
-        for key_id in self.filenames.keys():
+        isinstance(name, str)
+
+        for key_id in list(self.filenames.keys()):
             # data with title
             if self.filenames[key_id].get_data().title:
Index: src/sas/qtgui/Calculators/DensityPanel.py
===================================================================
--- src/sas/qtgui/Calculators/DensityPanel.py	(revision b0c5e8c49a3e4e82f4f885ba7ad4d73fb8d6c59f)
+++ src/sas/qtgui/Calculators/DensityPanel.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -14,5 +14,5 @@
 
 def enum(*sequential, **named):
-    enums = dict(zip(sequential, range(len(sequential))), **named)
+    enums = dict(list(zip(sequential, list(range(len(sequential))))), **named)
     return type('Enum', (), enums)
 
@@ -95,5 +95,5 @@
 
     def dataChanged(self, top, bottom):
-        for index in xrange(top.row(), bottom.row() + 1):
+        for index in range(top.row(), bottom.row() + 1):
             if index == MODEL.MOLECULAR_FORMULA:
                 molarMass = toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text())
Index: src/sas/qtgui/Calculators/GenericScatteringCalculator.py
===================================================================
--- src/sas/qtgui/Calculators/GenericScatteringCalculator.py	(revision fef38e8f19a097daafbdbdd6edb786c11fb2b995)
+++ src/sas/qtgui/Calculators/GenericScatteringCalculator.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -22,5 +22,5 @@
 
 # Local UI
-from UI.GenericScatteringCalculator import Ui_GenericScatteringCalculator
+from .UI.GenericScatteringCalculator import Ui_GenericScatteringCalculator
 
 _Q1D_MIN = 0.001
@@ -119,5 +119,5 @@
         TODO Temporary solution to display information about option 'Ellipsoid'
         """
-        print "The option Ellipsoid has not been implemented yet."
+        print("The option Ellipsoid has not been implemented yet.")
         self.communicator.statusBarUpdateSignal.emit(
             "The option Ellipsoid has not been implemented yet.")
@@ -165,5 +165,5 @@
                 self.reader.queue()
         except (RuntimeError, IOError):
-            log_msg = "Generic SAS Calculator: %s" % sys.exc_value
+            log_msg = "Generic SAS Calculator: %s" % sys.exc_info()[1]
             logging.info(log_msg)
             raise
@@ -556,5 +556,5 @@
             d.addCallback(self.plot_1_2d)
         except:
-            log_msg = "{}. stop".format(sys.exc_value)
+            log_msg = "{}. stop".format(sys.exc_info()[1])
             logging.info(log_msg)
         return
@@ -644,5 +644,5 @@
             self.graph_num += 1
             # TODO
-            print 'TRANSFER OF DATA TO MAIN PANEL TO BE IMPLEMENTED'
+            print('TRANSFER OF DATA TO MAIN PANEL TO BE IMPLEMENTED')
             return plot1D
         else:
@@ -662,5 +662,5 @@
             self.graph_num += 1
             # TODO
-            print 'TRANSFER OF DATA TO MAIN PANEL TO BE IMPLEMENTED'
+            print('TRANSFER OF DATA TO MAIN PANEL TO BE IMPLEMENTED')
             return plot2D
 
@@ -744,5 +744,5 @@
         # II. Plot selective points in color
         other_color = numpy.ones(len(pix_symbol), dtype='bool')
-        for key in color_dic.keys():
+        for key in list(color_dic.keys()):
             chosen_color = pix_symbol == key
             if numpy.any(chosen_color):
@@ -758,5 +758,5 @@
                 # Get atom names not in the list
                 a_names = [symb for symb in pix_symbol \
-                           if symb not in color_dic.keys()]
+                           if symb not in list(color_dic.keys())]
                 a_name = a_names[0]
                 for name in a_names:
Index: src/sas/qtgui/Calculators/KiessigPanel.py
===================================================================
--- src/sas/qtgui/Calculators/KiessigPanel.py	(revision b0c5e8c49a3e4e82f4f885ba7ad4d73fb8d6c59f)
+++ src/sas/qtgui/Calculators/KiessigPanel.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -3,5 +3,5 @@
 
 from sas.qtgui.UI import main_resources_rc
-from UI.KiessigPanel import Ui_KiessigPanel
+from .UI.KiessigPanel import Ui_KiessigPanel
 import sas.qtgui.Utilities.GuiUtils as GuiUtils
 
Index: src/sas/qtgui/Calculators/ResolutionCalculatorPanel.py
===================================================================
--- src/sas/qtgui/Calculators/ResolutionCalculatorPanel.py	(revision 170e95d7e328a0390445b138c413c72b4aa20f2d)
+++ src/sas/qtgui/Calculators/ResolutionCalculatorPanel.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -20,5 +20,5 @@
 import re
 
-from UI.ResolutionCalculatorPanelUI import Ui_ResolutionCalculatorPanel
+from .UI.ResolutionCalculatorPanelUI import Ui_ResolutionCalculatorPanel
 
 _SOURCE_MASS = {'Alpha': 6.64465620E-24,
@@ -318,5 +318,5 @@
                 self, "Choose a spectral distribution file", "",
                 "All files (*.*)",
-                None, QtGui.QFileDialog.DontUseNativeDialog)
+                QtGui.QFileDialog.DontUseNativeDialog)
 
             if datafile is None or str(datafile) == '':
@@ -328,5 +328,5 @@
             try:
                 basename = os.path.basename(datafile)
-                if basename not in self.spectrum_dic.keys():
+                if basename not in list(self.spectrum_dic.keys()):
                     self.cbCustomSpectrum.addItem(basename)
 
@@ -604,5 +604,5 @@
                 msg = "The numbers must be one or two (separated by ',')"
                 logging.info(msg)
-                raise RuntimeError, msg
+                raise RuntimeError(msg)
 
         return new_numbers_list
@@ -618,5 +618,5 @@
             new_list = [float(t) for t in string_split]
         except:
-            logging.error(sys.exc_value)
+            logging.error(sys.exc_info()[1])
         return new_list
 
@@ -658,5 +658,5 @@
                         return out
                 except:
-                    logging.error(sys.exc_value)
+                    logging.error(sys.exc_info()[1])
 
     def _validate_q_input(self, qx, qy):
Index: src/sas/qtgui/Calculators/SldPanel.py
===================================================================
--- src/sas/qtgui/Calculators/SldPanel.py	(revision b0c5e8c49a3e4e82f4f885ba7ad4d73fb8d6c59f)
+++ src/sas/qtgui/Calculators/SldPanel.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -15,5 +15,5 @@
 
 def enum(*sequential, **named):
-    enums = dict(zip(sequential, range(len(sequential))), **named)
+    enums = dict(list(zip(sequential, list(range(len(sequential))))), **named)
     return type('Enum', (), enums)
 
@@ -60,5 +60,5 @@
         if len(formula.atoms) != 1:
             raise NotImplementedError()
-        energy = xray_energy(formula.atoms.keys()[0].K_alpha)
+        energy = xray_energy(list(formula.atoms.keys())[0].K_alpha)
         return xray_sld_from_atoms(
             sld_formula.atoms,
@@ -142,5 +142,5 @@
         self.model.setItem(MODEL.WAVELENGTH       , QtGui.QStandardItem())
 
-        for key in self._getOutputs().keys():
+        for key in list(self._getOutputs().keys()):
             self.model.setItem(key, QtGui.QStandardItem())
 
@@ -161,5 +161,5 @@
         self.mapper.addMapping(self.ui.editWavelength      , MODEL.WAVELENGTH)
 
-        for key, edit in self._getOutputs().iteritems():
+        for key, edit in self._getOutputs().items():
             self.mapper.addMapping(edit, key)
 
@@ -168,5 +168,5 @@
     def dataChanged(self, top, bottom):
         update = False
-        for index in xrange(top.row(), bottom.row() + 1):
+        for index in range(top.row(), bottom.row() + 1):
             if (index == MODEL.MOLECULAR_FORMULA) or (index == MODEL.MASS_DENSITY) or (index == MODEL.WAVELENGTH):
                 update = True
@@ -202,5 +202,5 @@
                     pass
 
-            for key in self._getOutputs().keys():
+            for key in list(self._getOutputs().keys()):
                 self.model.item(key).setText("")
 
Index: src/sas/qtgui/Calculators/SlitSizeCalculator.py
===================================================================
--- src/sas/qtgui/Calculators/SlitSizeCalculator.py	(revision b0c5e8c49a3e4e82f4f885ba7ad4d73fb8d6c59f)
+++ src/sas/qtgui/Calculators/SlitSizeCalculator.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -11,5 +11,5 @@
 import sas.qtgui.Utilities.GuiUtils as GuiUtils
 
-from UI.SlitSizeCalculator import Ui_SlitSizeCalculator
+from .UI.SlitSizeCalculator import Ui_SlitSizeCalculator
 from sas.sascalc.dataloader.loader import Loader
 from sas.sascalc.calculator.slit_length_calculator import SlitlengthCalculator
@@ -76,5 +76,5 @@
         # But only with Qt built-in dialog (non-platform native)
         path = QtGui.QFileDialog.getOpenFileName(self, "Choose a file", "",
-                                                 "SAXSess 1D data (*.txt *.TXT *.dat *.DAT)", None,
+                                                 "SAXSess 1D data (*.txt *.TXT *.dat *.DAT)",
                                                  QtGui.QFileDialog.DontUseNativeDialog)
 
@@ -107,10 +107,10 @@
             self.clearResults()
             msg = "ERROR: Data hasn't been loaded correctly"
-            raise RuntimeError, msg
+            raise RuntimeError(msg)
 
         if data.__class__.__name__ == 'Data2D':
             self.clearResults()
             msg = "Slit Length cannot be computed for 2D Data"
-            raise RuntimeError, msg
+            raise RuntimeError(msg)
 
         #compute the slit size
@@ -120,5 +120,5 @@
             if xdata == [] or xdata is None or ydata == [] or ydata is None:
                 msg = "The current data is empty please check x and y"
-                raise ValueError, msg
+                raise ValueError(msg)
             slit_length_calculator = SlitlengthCalculator()
             slit_length_calculator.set_data(x=xdata, y=ydata)
@@ -126,6 +126,6 @@
         except:
             self.clearResults()
-            msg = "Slit Size Calculator: %s" % (sys.exc_value)
-            raise RuntimeError, msg
+            msg = "Slit Size Calculator: %s" % (sys.exc_info()[1])
+            raise RuntimeError(msg)
 
         slit_length_str = "{:.5f}".format(slit_length)
Index: src/sas/qtgui/Calculators/UnitTesting/SlitSizeCalculatorTest.py
===================================================================
--- src/sas/qtgui/Calculators/UnitTesting/SlitSizeCalculatorTest.py	(revision 8222f171ca8747f44ec53b2088e4cf8903026e84)
+++ src/sas/qtgui/Calculators/UnitTesting/SlitSizeCalculatorTest.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -84,10 +84,10 @@
         loader = Loader()
         data = loader.load(filename)[0]
-        self.assertRaisesRegexp(RuntimeError,
+        self.assertRaisesRegex(RuntimeError,
                                 "Slit Length cannot be computed for 2D Data",
                                 self.widget.calculateSlitSize, data)
 
         data = None
-        self.assertRaisesRegexp(RuntimeError,
+        self.assertRaisesRegex(RuntimeError,
                                 "ERROR: Data hasn't been loaded correctly",
                                 self.widget.calculateSlitSize, data)
Index: src/sas/qtgui/MainWindow/AboutBox.py
===================================================================
--- src/sas/qtgui/MainWindow/AboutBox.py	(revision cd2cc7458970e179039a783e9409f48c4c1fca0d)
+++ src/sas/qtgui/MainWindow/AboutBox.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -8,5 +8,5 @@
 from sas.qtgui.UI import main_resources_rc
 
-from UI.AboutUI import Ui_AboutUI
+from .UI.AboutUI import Ui_AboutUI
 
 class AboutBox(QtGui.QDialog, Ui_AboutUI):
Index: src/sas/qtgui/MainWindow/DataExplorer.py
===================================================================
--- src/sas/qtgui/MainWindow/DataExplorer.py	(revision 88e1f57e340b062a07d1e5693c8b7b8a4edc4b32)
+++ src/sas/qtgui/MainWindow/DataExplorer.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -155,5 +155,5 @@
         Populate the Perspective combobox and define callbacks
         """
-        available_perspectives = sorted([p for p in Perspectives.PERSPECTIVES.keys()])
+        available_perspectives = sorted([p for p in list(Perspectives.PERSPECTIVES.keys())])
         if available_perspectives:
             self.cbFitting.clear()
@@ -240,5 +240,5 @@
 
         self.manager.assign(manager)
-        for id, item in self.manager.get_all_data().iteritems():
+        for id, item in self.manager.get_all_data().items():
             self.updateModel(item.data, item.path)
 
@@ -345,5 +345,5 @@
         # Figure out which rows are checked
         selected_items = [self.model.item(index)
-                          for index in xrange(self.model.rowCount())
+                          for index in range(self.model.rowCount())
                           if isItemReady(index)]
 
@@ -400,5 +400,5 @@
         else:
             freeze_msg = "Unexpected number of theories copied: %i" % theories_copied
-            raise AttributeError, freeze_msg
+            raise AttributeError(freeze_msg)
         self.communicator.statusBarUpdateSignal.emit(freeze_msg)
         # Actively switch tabs
@@ -411,5 +411,5 @@
         new_item = item.clone()
         # clone doesn't do deepcopy :(
-        for child_index in xrange(item.rowCount()):
+        for child_index in range(item.rowCount()):
             child_item = self.recursivelyCloneItem(item.child(child_index))
             new_item.setChild(child_index, child_item)
@@ -435,5 +435,5 @@
             return
         new_plots = [PlotHelper.plotById(plot) for plot in graph_list]
-        active_plots_copy = self.active_plots.keys()
+        active_plots_copy = list(self.active_plots.keys())
         for plot in active_plots_copy:
             if self.active_plots[plot] in new_plots:
@@ -478,5 +478,5 @@
         for plot in plots:
             plot_id = plot.id
-            if plot_id in self.active_plots.keys():
+            if plot_id in list(self.active_plots.keys()):
                 self.active_plots[plot_id].replacePlot(plot_id, plot)
             else:
@@ -530,5 +530,5 @@
             else:
                 msg = "Incorrect data type passed to Plotting"
-                raise AttributeError, msg
+                raise AttributeError(msg)
 
         if 'new_plot' in locals() and \
@@ -597,5 +597,5 @@
 
         id = data.id
-        if data.id in self.active_plots.keys():
+        if data.id in list(self.active_plots.keys()):
             self.active_plots[id].replacePlot(id, data)
 
@@ -610,10 +610,10 @@
         # But only with Qt built-in dialog (non-platform native)
         paths = QtGui.QFileDialog.getOpenFileNames(self, "Choose a file", "",
-                wlist, None, QtGui.QFileDialog.DontUseNativeDialog)
+                wlist, QtGui.QFileDialog.DontUseNativeDialog)
         if paths is None:
             return
 
-        if isinstance(paths, QtCore.QStringList):
-            paths = [str(f) for f in paths]
+        #if isinstance(paths, QtCore.QStringList):
+        #    paths = [str(f) for f in paths]
 
         if not isinstance(paths, list):
@@ -687,5 +687,5 @@
 
             except Exception as ex:
-                logging.error(sys.exc_value)
+                logging.error(sys.exc_info()[1])
 
                 any_error = True
@@ -747,5 +747,5 @@
         if not isinstance(index, int):
             msg = "Incorrect type passed to DataExplorer.selectData()"
-            raise AttributeError, msg
+            raise AttributeError(msg)
 
         # Respond appropriately
@@ -773,5 +773,5 @@
                 except AttributeError:
                     msg = "Bad structure of the data model."
-                    raise RuntimeError, msg
+                    raise RuntimeError(msg)
 
                 if is1D:
@@ -787,5 +787,5 @@
                 except AttributeError:
                     msg = "Bad structure of the data model."
-                    raise RuntimeError, msg
+                    raise RuntimeError(msg)
 
                 if item.isCheckable() and item.checkState() == QtCore.Qt.Checked and is1D:
@@ -801,5 +801,5 @@
                 except AttributeError:
                     msg = "Bad structure of the data model."
-                    raise RuntimeError, msg
+                    raise RuntimeError(msg)
 
                 if is2D:
@@ -815,5 +815,5 @@
                 except AttributeError:
                     msg = "Bad structure of the data model."
-                    raise RuntimeError, msg
+                    raise RuntimeError(msg)
 
                 if item.isCheckable() and item.checkState() == QtCore.Qt.Checked and is2D:
@@ -823,5 +823,5 @@
             msg = "Incorrect value in the Selection Option"
             # Change this to a proper logging action
-            raise Exception, msg
+            raise Exception(msg)
 
     def contextMenu(self):
@@ -1016,5 +1016,5 @@
         # Add the actual Data1D/Data2D object
         object_item = QtGui.QStandardItem()
-        object_item.setData(QtCore.QVariant(data))
+        object_item.setData(data)
 
         checkbox_item.setChild(0, object_item)
@@ -1040,5 +1040,5 @@
         if not isinstance(model_item, QtGui.QStandardItem):
             msg = "Wrong data type returned from calculations."
-            raise AttributeError, msg
+            raise AttributeError(msg)
 
         # TODO: Assert other properties
@@ -1057,5 +1057,5 @@
         if not isinstance(model_item, QtGui.QStandardItem):
             msg = "Wrong data type returned from calculations."
-            raise AttributeError, msg
+            raise AttributeError(msg)
 
         # Check if there are any other items for this tab
@@ -1064,5 +1064,5 @@
         # 
         current_tab_name = model_item.text()[:2]
-        for current_index in xrange(self.theory_model.rowCount()):
+        for current_index in range(self.theory_model.rowCount()):
             if current_tab_name in self.theory_model.item(current_index).text():
                 self.theory_model.removeRow(current_index)
Index: src/sas/qtgui/MainWindow/DataManager.py
===================================================================
--- src/sas/qtgui/MainWindow/DataManager.py	(revision 7d9c83c92cef3381669815551c3850802b12abf0)
+++ src/sas/qtgui/MainWindow/DataManager.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -24,5 +24,5 @@
 import json
 import time
-from StringIO import StringIO
+from io import StringIO
 import numpy as np
 
@@ -66,5 +66,5 @@
         _str += "No of states  is %s \n" % str(len(self.stored_data))
         n_count = 0
-        for  value in self.stored_data.values():
+        for  value in list(self.stored_data.values()):
             n_count += 1
             _str += "State No %s \n"  % str(n_count)
@@ -146,5 +146,5 @@
         receive a list of
         """
-        for id, data in data_list.iteritems():
+        for id, data in data_list.items():
             if id  in self.stored_data:
                 msg = "Data manager already stores %s" % str(data.name)
@@ -162,10 +162,10 @@
         """
         """
-        if prev_data.id not in self.stored_data.keys():
+        if prev_data.id not in list(self.stored_data.keys()):
             return None, {}
         data_state = self.stored_data[prev_data.id]
         self.stored_data[new_data.id]  = data_state.clone()
         self.stored_data[new_data.id].data = new_data
-        if prev_data.id in self.stored_data.keys():
+        if prev_data.id in list(self.stored_data.keys()):
             del self.stored_data[prev_data.id]
         return prev_data.id, {new_data.id: self.stored_data[new_data.id]}
@@ -177,5 +177,5 @@
         if data_id is None and theory is not None:
             uid = theory.id
-        if uid in self.stored_data.keys():
+        if uid in list(self.stored_data.keys()):
              data_state = self.stored_data[uid]
         else:
@@ -207,5 +207,5 @@
                 if search_id == d_id:
                     _selected_data[search_id] = data
-                if search_id in theory_list.keys():
+                if search_id in list(theory_list.keys()):
                      _selected_theory_list[search_id] = theory_list[search_id]
 
@@ -216,5 +216,5 @@
         """
         """
-        return self.freeze_theory(self.stored_data.keys(), theory_id)
+        return self.freeze_theory(list(self.stored_data.keys()), theory_id)
 
     def freeze_theory(self, data_id, theory_id):
@@ -227,5 +227,5 @@
                 theory_list = data_state.get_theory()
                 for t_id in theory_id:
-                    if t_id in theory_list.keys():
+                    if t_id in list(theory_list.keys()):
                         theory_data, theory_state = theory_list[t_id]
                         new_theory = copy.deepcopy(theory_data)
@@ -247,5 +247,5 @@
         """
         for d_id in data_id:
-            if d_id in self.stored_data.keys():
+            if d_id in list(self.stored_data.keys()):
                 data_state = self.stored_data[d_id]
                 if data_state.data.name in self.data_name_dict:
@@ -265,5 +265,5 @@
                 data_state = self.stored_data[d_id]
                 theory_list = data_state.get_theory()
-                if theory_id in theory_list.keys():
+                if theory_id in list(theory_list.keys()):
                     del theory_list[theory_id]
         #del pure theory
@@ -284,5 +284,5 @@
         _selected_data = {}
         for selected_name in name_list:
-            for id, data_state in self.stored_data.iteritems():
+            for id, data_state in self.stored_data.items():
                 if data_state.data.name == selected_name:
                     _selected_data[id] = data_state.data
@@ -294,5 +294,5 @@
         """
         for selected_name in name_list:
-            for id, data_state in self.stored_data.iteritems():
+            for id, data_state in self.stored_data.items():
                 if data_state.data.name == selected_name:
                     del self.stored_data[id]
@@ -303,5 +303,5 @@
             # Take the copy of current, possibly shorter stored_data dict
             stored_data = copy.deepcopy(self.stored_data)
-            for idx in stored_data.keys():
+            for idx in list(stored_data.keys()):
                 if str(selected_name) in str(idx):
                     del self.stored_data[idx]
@@ -313,5 +313,5 @@
         _selected_data_state = {}
         for id in data_id:
-            if id in self.stored_data.keys():
+            if id in list(self.stored_data.keys()):
                 _selected_data_state[id] = self.stored_data[id]
         return _selected_data_state
@@ -396,5 +396,5 @@
             class Empty(object):
                 def __init__(self):
-                    for key, value in data.iteritems():
+                    for key, value in data.items():
                         setattr(self, key, generate(value, level))
 
@@ -451,5 +451,5 @@
                     # if dictionary doesn't have __type__ then it is assumed to be just an ordinary dictionary
                     o = {}
-                    for key, value in data.iteritems():
+                    for key, value in data.items():
                         o[key] = generate(value, level)
                     return o
@@ -463,5 +463,5 @@
 
         new_stored_data = {}
-        for id, data in json.load(fp).iteritems():
+        for id, data in json.load(fp).items():
             try:
                 new_stored_data[id] = generate(data, 0)
Index: src/sas/qtgui/MainWindow/DataState.py
===================================================================
--- src/sas/qtgui/MainWindow/DataState.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/MainWindow/DataState.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -37,5 +37,5 @@
         _str += "Theories available: %s \n" % len(self.theory_list)
         if self.theory_list:
-            for id, item in self.theory_list.iteritems():
+            for id, item in self.theory_list.items():
                 theory_data, theory_state = item
                 _str += "Theory name : %s \n" % str(theory_data.name)
@@ -53,5 +53,5 @@
         obj.message = self.message
         obj.id = self.id
-        for id, item in self.theory_list.iteritems():
+        for id, item in self.theory_list.items():
             theory_data, theory_state = item
             state = None
@@ -95,5 +95,5 @@
         """
         self.theory_list[theory_data.id] = [theory_data, theory_state]
-        data, state = self.theory_list.values()[0]
+        data, state = list(self.theory_list.values())[0]
        
     def get_theory(self):
Index: src/sas/qtgui/MainWindow/GuiManager.py
===================================================================
--- src/sas/qtgui/MainWindow/GuiManager.py	(revision f0bb71111cd83022768469968b3891e8656d0417)
+++ src/sas/qtgui/MainWindow/GuiManager.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -191,5 +191,5 @@
         workspace_height = self._workspace.workspace.sizeHint().height()
         perspective_size = self._current_perspective.sizeHint()
-        if workspace_height < perspective_size.height:
+        if workspace_height < perspective_size.height():
             perspective_width = perspective_size.width()
             self._current_perspective.resize(perspective_width, workspace_height-10)
@@ -202,5 +202,5 @@
         assert isinstance(data, list)
         if self._current_perspective is not None:
-            self._current_perspective.setData(data.values())
+            self._current_perspective.setData(list(data.values()))
         else:
             msg = "No perspective is currently active."
@@ -246,5 +246,5 @@
         """
         if self._current_perspective is not None:
-            self._current_perspective.setData(data.values())
+            self._current_perspective.setData(list(data.values()))
         else:
             msg = "Guiframe does not have a current perspective"
@@ -289,5 +289,5 @@
             version_info = json.loads(content)
             self.processVersion(version_info)
-        except ValueError, ex:
+        except ValueError as ex:
             logging.info("Failed to connect to www.sasview.org:", ex)
 
@@ -321,5 +321,5 @@
         except:
             msg = "guiframe: could not get latest application"
-            msg += " version number\n  %s" % sys.exc_value
+            msg += " version number\n  %s" % sys.exc_info()[1]
             logging.error(msg)
             msg = "Could not connect to the application server."
@@ -743,5 +743,5 @@
                 not isinstance(new_datalist_item, dict):
             msg = "Wrong data type returned from calculations."
-            raise AttributeError, msg
+            raise AttributeError(msg)
 
         self.filesWidget.model.appendRow(new_item)
Index: src/sas/qtgui/MainWindow/MainWindow.py
===================================================================
--- src/sas/qtgui/MainWindow/MainWindow.py	(revision 2a8bd7052cb942c4a5ebe1ba1549393142ca199f)
+++ src/sas/qtgui/MainWindow/MainWindow.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -5,5 +5,5 @@
 # Local UI
 from sas.qtgui.UI import main_resources_rc
-from UI.MainWindowUI import Ui_MainWindow
+from .UI.MainWindowUI import Ui_MainWindow
 
 # Initialize logging
@@ -21,5 +21,5 @@
 
         # Create the gui manager
-        from GuiManager import GuiManager
+        from .GuiManager import GuiManager
         self.guiManager = GuiManager(self)
 
Index: src/sas/qtgui/Perspectives/Fitting/FitThread.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FitThread.py	(revision ee18d3342afd576de16503265ff92e34821fca74)
+++ src/sas/qtgui/Perspectives/Fitting/FitThread.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -14,5 +14,5 @@
 
 def map_apply(arguments):
-    return apply(arguments[0], arguments[1:])
+    return arguments[0](*arguments[1:])
 
 class FitThread(CalcThread):
@@ -55,5 +55,5 @@
         except KeyboardInterrupt:
             msg = "Fitting: terminated by the user."
-            raise KeyboardInterrupt, msg
+            raise KeyboardInterrupt(msg)
 
     def compute(self):
@@ -71,8 +71,8 @@
             list_q = [None]*fitter_size
 
-            inputs = zip(list_map_get_attr, self.fitter, list_fit_function,
+            inputs = list(zip(list_map_get_attr, self.fitter, list_fit_function,
                          list_q, list_q, list_handler, list_curr_thread,
-                         list_reset_flag)
-            result = map(map_apply, inputs)
+                         list_reset_flag))
+            result = list(map(map_apply, inputs))
             results = (result, time.time()-self.starttime)
             if self.handler:
@@ -81,5 +81,5 @@
                 return (results)
 
-        except KeyboardInterrupt, msg:
+        except KeyboardInterrupt as msg:
             # Thread was interrupted, just proceed and re-raise.
             # Real code should not print, but this is an example...
Index: src/sas/qtgui/Perspectives/Fitting/FittingLogic.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingLogic.py	(revision ee18d3342afd576de16503265ff92e34821fca74)
+++ src/sas/qtgui/Perspectives/Fitting/FittingLogic.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -196,5 +196,5 @@
                 msg = "Unable to find min/max/length of \n data named %s" % \
                             self.data.filename
-                raise ValueError, msg
+                raise ValueError(msg)
 
         else:
@@ -206,5 +206,5 @@
                 msg = "Unable to find min/max of \n data named %s" % \
                             self.data.filename
-                raise ValueError, msg
+                raise ValueError(msg)
             qmax = np.sqrt(x * x + y * y)
             npts = len(data.data)
Index: src/sas/qtgui/Perspectives/Fitting/FittingOptions.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingOptions.py	(revision 377ade1f23aac6c56560870af2702bff99586386)
+++ src/sas/qtgui/Perspectives/Fitting/FittingOptions.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -80,5 +80,5 @@
         Use options.FIT_FIELDS to assert which line edit gets what validator
         """
-        for option in bumps.options.FIT_FIELDS.iterkeys():
+        for option in bumps.options.FIT_FIELDS.keys():
             (f_name, f_type) = bumps.options.FIT_FIELDS[option]
             validator = None
@@ -86,5 +86,5 @@
                 validator = QtGui.QIntValidator()
                 validator.setBottom(0)
-            elif f_type == types.FloatType:
+            elif f_type == float:
                 validator = QtGui.QDoubleValidator()
                 validator.setBottom(0)
@@ -153,5 +153,5 @@
 
         # Update the BUMPS singleton
-        [bumpsUpdate(o) for o in self.config.values[self.current_fitter_id].iterkeys()]
+        [bumpsUpdate(o) for o in self.config.values[self.current_fitter_id].keys()]
 
     def onHelp(self):
@@ -175,5 +175,5 @@
         if current_fitter is None:
             current_fitter = self.current_fitter_id
-        if option_id not in bumps.options.FIT_FIELDS.keys(): return None
+        if option_id not in list(bumps.options.FIT_FIELDS.keys()): return None
         option = option_id + '_' + current_fitter
         if not hasattr(self, option): return None
@@ -193,5 +193,5 @@
         """
         options = self.config.values[fitter_id]
-        for option in options.iterkeys():
+        for option in options.keys():
             # Find the widget name of the option
             # e.g. 'samples' for 'dream' is 'self.samples_dream'
Index: src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py	(revision 377ade1f23aac6c56560870af2702bff99586386)
+++ src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -11,5 +11,5 @@
 from sas.qtgui.Perspectives.Fitting.FittingWidget import FittingWidget
 from sas.qtgui.Perspectives.Fitting.FittingOptions import FittingOptions
-from sas.qtgui.Perspectives.Fitting import ModelUtilities
+#from sas.qtgui.Perspectives.Fitting import ModelUtilities
 
 class FittingWindow(QtGui.QTabWidget):
@@ -61,8 +61,8 @@
         self.fit_options_widget.fit_option_changed.connect(self.onFittingOptionsChange)
 
-        self.menu_manager = ModelUtilities.ModelManager()
-        # TODO: reuse these in FittingWidget properly
-        self.model_list_box = self.menu_manager.get_model_list()
-        self.model_dictionary = self.menu_manager.get_model_dictionary()
+        #self.menu_manager = ModelUtilities.ModelManager()
+        ## TODO: reuse these in FittingWidget properly
+        #self.model_list_box = self.menu_manager.get_model_list()
+        #self.model_dictionary = self.menu_manager.get_model_dictionary()
 
         #self.setWindowTitle('Fit panel - Active Fitting Optimizer: %s' % self.optimizer)
@@ -120,8 +120,9 @@
         Create a list if none exists and append if there's already a list
         """
-        if item_key in self.dataToFitTab.keys():
-            self.dataToFitTab[item_key].append(tab_name)
+        item_key_str = str(item_key)
+        if item_key_str in list(self.dataToFitTab.keys()):
+            self.dataToFitTab[item_key_str].append(tab_name)
         else:
-            self.dataToFitTab[item_key] = [tab_name]
+            self.dataToFitTab[item_key_str] = [tab_name]
 
         #print "CURRENT dict: ", self.dataToFitTab
@@ -169,5 +170,5 @@
         Given name of the fitting tab - close it
         """
-        for tab_index in xrange(len(self.tabs)):
+        for tab_index in range(len(self.tabs)):
             if self.tabText(tab_index) == tab_name:
                 self.tabCloses(tab_index)
@@ -181,9 +182,10 @@
             return
         for index_to_delete in index_list:
-            if index_to_delete in self.dataToFitTab.keys():
-                for tab_name in self.dataToFitTab[index_to_delete]:
+            index_to_delete_str = str(index_to_delete)
+            if index_to_delete_str in list(self.dataToFitTab.keys()):
+                for tab_name in self.dataToFitTab[index_to_delete_str]:
                     # delete tab #index after corresponding data got removed
                     self.closeTabByName(tab_name)
-                self.dataToFitTab.pop(index_to_delete)
+                self.dataToFitTab.pop(index_to_delete_str)
 
         #print "CURRENT dict: ", self.dataToFitTab
@@ -205,9 +207,9 @@
         if not isinstance(data_item, list):
             msg = "Incorrect type passed to the Fitting Perspective"
-            raise AttributeError, msg
+            raise AttributeError(msg)
 
         if not isinstance(data_item[0], QtGui.QStandardItem):
             msg = "Incorrect type passed to the Fitting Perspective"
-            raise AttributeError, msg
+            raise AttributeError(msg)
 
         items = [data_item] if is_batch else data_item
@@ -216,5 +218,5 @@
             # Find the first unassigned tab.
             # If none, open a new tab.
-            available_tabs = list(map(lambda tab: tab.acceptsData(), self.tabs))
+            available_tabs = list([tab.acceptsData() for tab in self.tabs])
 
             if numpy.any(available_tabs):
Index: src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py	(revision d0dfcb2f3d332694828ef7e96f4a7727397df4d1)
+++ src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -44,5 +44,5 @@
     Returns a list of all multi-shell parameters in 'model'
     """
-    return list(filter(lambda par: "[" in par.name, model.iq_parameters))
+    return list([par for par in model.iq_parameters if "[" in par.name])
 
 def getMultiplicity(model):
@@ -156,5 +156,6 @@
     """
     for i, item in enumerate(model_header_captions):
-        model.setHeaderData(i, QtCore.Qt.Horizontal, QtCore.QVariant(item))
+        #model.setHeaderData(i, QtCore.Qt.Horizontal, QtCore.QVariant(item))
+        model.setHeaderData(i, QtCore.Qt.Horizontal, item)
 
     model.header_tooltips = model_header_tooltips
@@ -167,5 +168,5 @@
     model_header_error_captions.insert(2, header_error_caption)
     for i, item in enumerate(model_header_error_captions):
-        model.setHeaderData(i, QtCore.Qt.Horizontal, QtCore.QVariant(item))
+        model.setHeaderData(i, QtCore.Qt.Horizontal, item)
 
     model_header_error_tooltips = model_header_tooltips
@@ -178,5 +179,5 @@
     """
     for i, item in enumerate(poly_header_captions):
-        model.setHeaderData(i, QtCore.Qt.Horizontal, QtCore.QVariant(item))
+        model.setHeaderData(i, QtCore.Qt.Horizontal, item)
 
     model.header_tooltips = poly_header_tooltips
@@ -190,5 +191,5 @@
     poly_header_error_captions.insert(2, header_error_caption)
     for i, item in enumerate(poly_header_error_captions):
-        model.setHeaderData(i, QtCore.Qt.Horizontal, QtCore.QVariant(item))
+        model.setHeaderData(i, QtCore.Qt.Horizontal, item)
 
     poly_header_error_tooltips = poly_header_tooltips
@@ -202,5 +203,5 @@
     multishell_parameters = getIterParams(parameters)
 
-    for i in xrange(index):
+    for i in range(index):
         for par in multishell_parameters:
             # Create the name: <param>[<i>], e.g. "sld1" for parameter "sld[n]"
@@ -396,5 +397,5 @@
 
 def binary_encode(i, digits):
-    return [i >> d & 1 for d in xrange(digits)]
+    return [i >> d & 1 for d in range(digits)]
 
 def getWeight(data, is2d, flag=None):
Index: src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision 88e1f57e340b062a07d1e5693c8b7b8a4edc4b32)
+++ src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -2,5 +2,5 @@
 import os
 from collections import defaultdict
-from itertools import izip
+
 
 import logging
@@ -69,5 +69,5 @@
         if role == QtCore.Qt.ToolTipRole:
             if orientation == QtCore.Qt.Horizontal:
-                return QtCore.QString(str(self.header_tooltips[section]))
+                return str(self.header_tooltips[section])
 
         return QtGui.QStandardItemModel.headerData(self, section, orientation, role)
@@ -353,5 +353,5 @@
         # Similarly on other tabs
         self.options_widget.setEnablementOnDataLoad()
-
+        self.onSelectModel()
         # Smearing tab
         self.smearing_widget.updateSmearing(self.data)
@@ -473,4 +473,7 @@
         model = str(self.cbModel.currentText())
 
+        # empty combobox forced to be read
+        if not model:
+            return
         # Reset structure factor
         self.cbStructureFactor.setCurrentIndex(0)
@@ -763,5 +766,5 @@
         """
         """
-        print "UPDATE FIT"
+        print("UPDATE FIT")
         pass
 
@@ -769,5 +772,5 @@
         """
         """
-        print "FIT FAILED: ", reason
+        print("FIT FAILED: ", reason)
         pass
 
@@ -814,6 +817,6 @@
         param_values = res.pvec     # array([ 0.36221662,  0.0146783 ])
         param_stderr = res.stderr   # array([ 1.71293015,  1.71294233])
-        params_and_errors = zip(param_values, param_stderr)
-        param_dict = dict(izip(param_list, params_and_errors))
+        params_and_errors = list(zip(param_values, param_stderr))
+        param_dict = dict(zip(param_list, params_and_errors))
 
         # Dictionary of fitted parameter: value, error
@@ -836,5 +839,5 @@
         Take func and throw it inside the model row loop
         """
-        for row_i in xrange(self._model_model.rowCount()):
+        for row_i in range(self._model_model.rowCount()):
             func(row_i)
 
@@ -851,5 +854,5 @@
             # internal so can use closure for param_dict
             param_name = str(self._model_model.item(row, 0).text())
-            if param_name not in param_dict.keys():
+            if param_name not in list(param_dict.keys()):
                 return
             # modify the param value
@@ -863,5 +866,5 @@
             # Utility function for updateof polydispersity part of the main model
             param_name = str(self._model_model.item(row, 0).text())+'.width'
-            if param_name not in param_dict.keys():
+            if param_name not in list(param_dict.keys()):
                 return
             # modify the param value
@@ -878,5 +881,5 @@
                 return str(self._model_model.item(row, 0).text())
 
-            [createItem(param_name) for param_name in param_dict.keys() if curr_param() == param_name]
+            [createItem(param_name) for param_name in list(param_dict.keys()) if curr_param() == param_name]
 
             error_column.append(item)
@@ -922,5 +925,5 @@
             Take func and throw it inside the poly model row loop
             """
-            for row_i in xrange(self._poly_model.rowCount()):
+            for row_i in range(self._poly_model.rowCount()):
                 func(row_i)
 
@@ -931,5 +934,5 @@
                 return
             param_name = str(self._poly_model.item(row_i, 0).text()).rsplit()[-1] + '.width'
-            if param_name not in param_dict.keys():
+            if param_name not in list(param_dict.keys()):
                 return
             # modify the param value
@@ -954,5 +957,5 @@
                 return str(self._poly_model.item(row_i, 0).text()).rsplit()[-1] + '.width'
 
-            [createItem(param_name) for param_name in param_dict.keys() if poly_param() == param_name]
+            [createItem(param_name) for param_name in list(param_dict.keys()) if poly_param() == param_name]
 
             error_column.append(item)
@@ -991,5 +994,5 @@
             Take func and throw it inside the magnet model row loop
             """
-            for row_i in xrange(self._model_model.rowCount()):
+            for row_i in range(self._model_model.rowCount()):
                 func(row_i)
 
@@ -998,5 +1001,5 @@
             # internal so can use closure for param_dict
             param_name = str(self._magnet_model.item(row, 0).text())
-            if param_name not in param_dict.keys():
+            if param_name not in list(param_dict.keys()):
                 return
             # modify the param value
@@ -1016,5 +1019,5 @@
                 return str(self._magnet_model.item(row, 0).text())
 
-            [createItem(param_name) for param_name in param_dict.keys() if curr_param() == param_name]
+            [createItem(param_name) for param_name in list(param_dict.keys()) if curr_param() == param_name]
 
             error_column.append(item)
@@ -1291,5 +1294,5 @@
             # Unparsable field
             return
-        parameter_name = str(self._model_model.data(name_index).toPyObject()) # sld, background etc.
+        parameter_name = str(self._model_model.data(name_index)) #.toPyObject()) # sld, background etc.
 
         # Update the parameter value - note: this supports +/-inf as well
@@ -1357,5 +1360,5 @@
 
         return [str(model.item(row_index, 0).text())
-                for row_index in xrange(model.rowCount())
+                for row_index in range(model.rowCount())
                 if isChecked(row_index)]
 
@@ -1398,5 +1401,5 @@
             fitted_data.symbol = 'Line'
         # Notify the GUI manager so it can update the main model in DataExplorer
-        GuiUtils.updateModelItemWithPlot(self._index, QtCore.QVariant(fitted_data), name)
+        GuiUtils.updateModelItemWithPlot(self._index, fitted_data, name)
 
     def createTheoryIndex(self, fitted_data):
@@ -1406,5 +1409,5 @@
         name = self.nameFromData(fitted_data)
         # Notify the GUI manager so it can create the theory model in DataExplorer
-        new_item = GuiUtils.createModelItemWithPlot(QtCore.QVariant(fitted_data), name=name)
+        new_item = GuiUtils.createModelItemWithPlot(fitted_data, name=name)
         self.communicate.updateTheoryFromPerspectiveSignal.emit(new_item)
 
@@ -1460,5 +1463,5 @@
         Thread returned error
         """
-        print "Calculate Data failed with ", reason
+        print("Calculate Data failed with ", reason)
 
     def complete1D(self, return_data):
@@ -1557,5 +1560,5 @@
             else:
                 # Create as many entries as current shells
-                for ishell in xrange(1, self.current_shell_displayed+1):
+                for ishell in range(1, self.current_shell_displayed+1):
                     # Remove [n] and add the shell numeral
                     name = param_name[0:param_name.index('[')] + str(ishell)
@@ -1585,5 +1588,5 @@
         # All possible polydisp. functions as strings in combobox
         func = QtGui.QComboBox()
-        func.addItems([str(name_disp) for name_disp in POLYDISPERSITY_MODELS.iterkeys()])
+        func.addItems([str(name_disp) for name_disp in POLYDISPERSITY_MODELS.keys()])
         # Set the default index
         func.setCurrentIndex(func.findText(DEFAULT_POLYDISP_FUNCTION))
@@ -1636,5 +1639,5 @@
                 lo = self.lstPoly.itemDelegate().poly_pd
                 hi = self.lstPoly.itemDelegate().poly_function
-                [self._poly_model.item(row_index, i).setEnabled(False) for i in xrange(lo, hi)]
+                [self._poly_model.item(row_index, i).setEnabled(False) for i in range(lo, hi)]
                 return
             except IOError:
@@ -1646,7 +1649,7 @@
         self._poly_model.blockSignals(True)
         max_range = self.lstPoly.itemDelegate().poly_filename
-        [self._poly_model.item(row_index, i).setEnabled(True) for i in xrange(7)]
+        [self._poly_model.item(row_index, i).setEnabled(True) for i in range(7)]
         file_index = self._poly_model.index(row_index, self.lstPoly.itemDelegate().poly_filename)
-        self._poly_model.setData(file_index, QtCore.QVariant(""))
+        self._poly_model.setData(file_index, "")
         self._poly_model.blockSignals(False)
 
@@ -1657,6 +1660,6 @@
         nsigs = POLYDISPERSITY_MODELS[str(combo_string)].default['nsigmas']
 
-        self._poly_model.setData(npts_index, QtCore.QVariant(npts))
-        self._poly_model.setData(nsigs_index, QtCore.QVariant(nsigs))
+        self._poly_model.setData(npts_index, npts)
+        self._poly_model.setData(nsigs_index, nsigs)
 
         self.iterateOverModel(updateFunctionCaption)
@@ -1669,5 +1672,5 @@
         datafile = QtGui.QFileDialog.getOpenFileName(
             self, "Choose a weight file", "", "All files (*.*)",
-            None, QtGui.QFileDialog.DontUseNativeDialog)
+            QtGui.QFileDialog.DontUseNativeDialog)
 
         if datafile is None or str(datafile)=='':
@@ -1698,5 +1701,5 @@
         fname = os.path.basename(str(datafile))
         fname_index = self._poly_model.index(row_index, self.lstPoly.itemDelegate().poly_filename)
-        self._poly_model.setData(fname_index, QtCore.QVariant(fname))
+        self._poly_model.setData(fname_index, fname)
 
     def setMagneticModel(self):
@@ -1720,5 +1723,5 @@
         top_index = self.kernel_module.multiplicity_info.number
         shell_names = []
-        for i in xrange(1, top_index+1):
+        for i in range(1, top_index+1):
             for name in multi_names:
                 shell_names.append(name+str(i))
@@ -1770,5 +1773,5 @@
         func = QtGui.QComboBox()
         # Available range of shells displayed in the combobox
-        func.addItems([str(i) for i in xrange(param_length+1)])
+        func.addItems([str(i) for i in range(param_length+1)])
 
         # Respond to index change
Index: src/sas/qtgui/Perspectives/Fitting/ModelThread.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/ModelThread.py	(revision 6964d440b3929d111f810b55d203c17e2f424e4b)
+++ src/sas/qtgui/Perspectives/Fitting/ModelThread.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -65,5 +65,5 @@
         if self.data is None:
             msg = "Compute Calc2D receive data = %s.\n" % str(self.data)
-            raise ValueError, msg
+            raise ValueError(msg)
 
         # Define matrix where data will be plotted
Index: src/sas/qtgui/Perspectives/Fitting/ModelUtilities.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/ModelUtilities.py	(revision 125c4be1f2a9bcc043693f90241343f185040dde)
+++ src/sas/qtgui/Perspectives/Fitting/ModelUtilities.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -2,5 +2,5 @@
     Utilities to manage models
 """
-from __future__ import print_function
+
 
 import traceback
@@ -68,5 +68,5 @@
     except:
         msg = "Plugin %s error in __init__ \n\t: %s %s\n" % (str(name),
-                                                             str(sys.exc_type),
+                                                             str(sys.exc_info()[0]),
                                                              sys.exc_info()[1])
         plugin_log(msg)
@@ -78,5 +78,5 @@
         except:
             msg = "Plugin %s: error writing function \n\t :%s %s\n " % \
-                    (str(name), str(sys.exc_type), sys.exc_info()[1])
+                    (str(name), str(sys.exc_info()[0]), sys.exc_info()[1])
             plugin_log(msg)
             return None
@@ -138,9 +138,9 @@
     Class to check for problems with specific values
     """
-    def __nonzero__(self):
+    def __bool__(self):
         type, value, tb = sys.exc_info()
         if type is not None and issubclass(type, py_compile.PyCompileError):
             print("Problem with", repr(value))
-            raise type, value, tb
+            raise type(value).with_traceback(tb)
         return 1
 
@@ -211,5 +211,5 @@
 
         """
-        if name not in self.mydict.keys():
+        if name not in list(self.mydict.keys()):
             self.reset_list(name, mylist)
 
@@ -292,6 +292,6 @@
         #Looking for plugins
         self.stored_plugins = self.findModels()
-        self.plugins = self.stored_plugins.values()
-        for name, plug in self.stored_plugins.iteritems():
+        self.plugins = list(self.stored_plugins.values())
+        for name, plug in self.stored_plugins.items():
             self.model_dictionary[name] = plug
         
@@ -322,6 +322,6 @@
         new_plugins = self.findModels()
         if len(new_plugins) > 0:
-            for name, plug in  new_plugins.iteritems():
-                if name not in self.stored_plugins.keys():
+            for name, plug in  new_plugins.items():
+                if name not in list(self.stored_plugins.keys()):
                     self.stored_plugins[name] = plug
                     self.plugins.append(plug)
@@ -338,6 +338,6 @@
         self.plugins = []
         new_plugins = _find_models()
-        for name, plug in  new_plugins.iteritems():
-            for stored_name, stored_plug in self.stored_plugins.iteritems():
+        for name, plug in  new_plugins.items():
+            for stored_name, stored_plug in self.stored_plugins.items():
                 if name == stored_name:
                     del self.stored_plugins[name]
@@ -358,5 +358,5 @@
 
         """
-        if int(evt.GetId()) in self.form_factor_dict.keys():
+        if int(evt.GetId()) in list(self.form_factor_dict.keys()):
             from sasmodels.sasview_model import MultiplicationModel
             self.model_dictionary[MultiplicationModel.__name__] = MultiplicationModel
@@ -417,6 +417,6 @@
     __modelmanager = ModelManagerBase()
     cat_model_list = [__modelmanager.model_dictionary[model_name] for model_name \
-                      in __modelmanager.model_dictionary.keys() \
-                      if model_name not in __modelmanager.stored_plugins.keys()]
+                      in list(__modelmanager.model_dictionary.keys()) \
+                      if model_name not in list(__modelmanager.stored_plugins.keys())]
 
     CategoryInstaller.check_install(model_list=cat_model_list)
Index: src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py	(revision 457d961a927e24e28718d1c1813be6b69130b5c1)
+++ src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -96,5 +96,5 @@
         """
         self.model = QtGui.QStandardItemModel()
-        for model_item in xrange(len(MODEL)):
+        for model_item in range(len(MODEL)):
             self.model.setItem(model_item, QtGui.QStandardItem())
         # Attach slot
Index: src/sas/qtgui/Perspectives/Fitting/SmearingWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/SmearingWidget.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Perspectives/Fitting/SmearingWidget.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -65,5 +65,5 @@
         """
         self.model = QtGui.QStandardItemModel()
-        for model_item in xrange(len(MODEL)):
+        for model_item in range(len(MODEL)):
             self.model.setItem(model_item, QtGui.QStandardItem())
         # Attach slot
Index: src/sas/qtgui/Perspectives/Invariant/InvariantDetails.py
===================================================================
--- src/sas/qtgui/Perspectives/Invariant/InvariantDetails.py	(revision 28cda698bb2df0eb630b2bfe3ab5ea06a99075f6)
+++ src/sas/qtgui/Perspectives/Invariant/InvariantDetails.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -5,6 +5,6 @@
 
 # local
-from UI.InvariantDetailsUI import Ui_Dialog
-from InvariantUtils import WIDGETS
+from .UI.InvariantDetailsUI import Ui_Dialog
+from .InvariantUtils import WIDGETS
 
 class DetailsDialog(QtGui.QDialog, Ui_Dialog):
Index: src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py
===================================================================
--- src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py	(revision 457d961a927e24e28718d1c1813be6b69130b5c1)
+++ src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -15,7 +15,7 @@
 
 # local
-from UI.TabbedInvariantUI import Ui_tabbedInvariantUI
-from InvariantDetails import DetailsDialog
-from InvariantUtils import WIDGETS
+from .UI.TabbedInvariantUI import Ui_tabbedInvariantUI
+from .InvariantDetails import DetailsDialog
+from .InvariantUtils import WIDGETS
 
 # The minimum q-value to be used when extrapolating
@@ -551,9 +551,9 @@
         if not isinstance(data_item, list):
             msg = "Incorrect type passed to the Invariant Perspective"
-            raise AttributeError, msg
+            raise AttributeError(msg)
 
         if not isinstance(data_item[0], QtGui.QStandardItem):
             msg = "Incorrect type passed to the Invariant Perspective"
-            raise AttributeError, msg
+            raise AttributeError(msg)
 
         self._model_item = data_item[0]
@@ -631,5 +631,5 @@
                     self.calculateInvariant()
                 except:
-                    msg = "Invariant Set_data: " + str(sys.exc_value)
+                    msg = "Invariant Set_data: " + str(sys.exc_info()[1])
                     #wx.PostEvent(self.parent, StatusEvent(status=msg, info="error"))
         else:
Index: src/sas/qtgui/Perspectives/Invariant/InvariantUtils.py
===================================================================
--- src/sas/qtgui/Perspectives/Invariant/InvariantUtils.py	(revision f721030e66e61dc6279aa8e024da03b25f8e0d42)
+++ src/sas/qtgui/Perspectives/Invariant/InvariantUtils.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -1,4 +1,4 @@
 def enum(*sequential, **named):
-    enums = dict(zip(sequential, range(len(sequential))), **named)
+    enums = dict(list(zip(sequential, list(range(len(sequential))))), **named)
     return type('Enum', (), enums)
 
Index: src/sas/qtgui/Perspectives/__init__.py
===================================================================
--- src/sas/qtgui/Perspectives/__init__.py	(revision 7adc2a84d2456b9691bc21cec9f25ad5a71b0aa5)
+++ src/sas/qtgui/Perspectives/__init__.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -2,6 +2,6 @@
 # When adding a new perspective, this dictionary needs to be updated
 
-from Fitting.FittingPerspective import FittingWindow
-from Invariant.InvariantPerspective import InvariantWindow
+from .Fitting.FittingPerspective import FittingWindow
+from .Invariant.InvariantPerspective import InvariantWindow
 
 PERSPECTIVES = {
Index: src/sas/qtgui/Plotting/Arrow3D.py
===================================================================
--- src/sas/qtgui/Plotting/Arrow3D.py	(revision fef38e8f19a097daafbdbdd6edb786c11fb2b995)
+++ src/sas/qtgui/Plotting/Arrow3D.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -59,5 +59,5 @@
             return
         xs3d, ys3d, zs3d = self._verts3d
-        for i in xrange(len(xs3d)):
+        for i in range(len(xs3d)):
             xs, ys, _ = proj3d.proj_transform(xs3d[i], ys3d[i], zs3d[i], renderer.M)
             self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))
Index: src/sas/qtgui/Plotting/Binder.py
===================================================================
--- src/sas/qtgui/Plotting/Binder.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Binder.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -24,5 +24,5 @@
         return self.artist is not other.artist
 
-    def __nonzero__(self):
+    def __bool__(self):
         return self.artist is not None
 
@@ -61,5 +61,5 @@
             ]
         except:
-            print "bypassing scroll_event: wrong matplotlib version"
+            print("bypassing scroll_event: wrong matplotlib version")
             self._connections = [
                 canvas.mpl_connect('motion_notify_event', self._onMotion),
@@ -121,5 +121,5 @@
             for cid in self._connections: self.canvas.mpl_disconnect(cid)
         except:
-            logging.error("Error disconnection canvas: %s" % sys.exc_value)
+            logging.error("Error disconnection canvas: %s" % sys.exc_info()[1])
         self._connections = []
 
@@ -185,6 +185,6 @@
         # Check that the trigger is valid
         if trigger not in self._actions:
-            raise ValueError, "%s invalid --- valid triggers are %s"\
-                 % (trigger, ", ".join(self.events))
+            raise ValueError("%s invalid --- valid triggers are %s"\
+                 % (trigger, ", ".join(self.events)))
 
         # Register the trigger callback
@@ -201,5 +201,5 @@
         """
         if action not in self.events:
-            raise ValueError, "Trigger expects " + ", ".join(self.events)
+            raise ValueError("Trigger expects " + ", ".join(self.events))
 
         # Tag the event with modifiers
Index: src/sas/qtgui/Plotting/ColorMap.py
===================================================================
--- src/sas/qtgui/Plotting/ColorMap.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/ColorMap.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -13,5 +13,5 @@
 from sas.qtgui.Plotting.PlotterData import Data2D
 from sas.qtgui.Utilities.GuiUtils import formatNumber
-from rangeSlider import RangeSlider
+from .rangeSlider import RangeSlider
 
 DEFAULT_MAP = 'jet'
Index: src/sas/qtgui/Plotting/ConvertUnits.py
===================================================================
--- src/sas/qtgui/Plotting/ConvertUnits.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/ConvertUnits.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -42,10 +42,10 @@
                             unit = toks[0] + "^{" + str(powerer) + "}"
                 else:
-                    raise ValueError, "missing } in unit expression"
+                    raise ValueError("missing } in unit expression")
         else:  # no powerer
             if  power != 1:
                 unit = "(" + unit + ")" + "^{" + str(power) + "}"
     else:
-        raise ValueError, "empty unit ,enter a powerer different from zero"
+        raise ValueError("empty unit ,enter a powerer different from zero")
     return unit
 
@@ -68,13 +68,13 @@
     unit8 = "m/s^{4}"  #         x^2               (m/s^{4})^{2}
 
-    print "this unit1 %s ,its powerer %s , and value %s" % (unit1, 1, convert_unit(1, unit1))
-    print "this unit2 %s ,its powerer %s , and value %s" % (unit2, 1, convert_unit(1, unit2))
-    print "this unit3 %s ,its powerer %s , and value %s" % (unit3, 2, convert_unit(2, unit3))
-    print "this unit4 %s ,its powerer %s , and value %s" % (unit4, -1, convert_unit(-1, unit4))
-    print "this unit5 %s ,its powerer %s , and value %s" % (unit5, 2, convert_unit(2, unit5))
-    print "this unit6 %s ,its powerer %s , and value %s" % (unit6, 2, convert_unit(2, unit6))
-    print "this unit7 %s ,its powerer %s , and value %s" % (unit7, -1, convert_unit(-1, unit7))
-    print "this unit8 %s ,its powerer %s , and value %s" % (unit8, 2, convert_unit(2, unit8))
-    print "this unit9 %s ,its powerer %s , and value %s" % (unit9, 2, convert_unit(2, unit9))
+    print("this unit1 %s ,its powerer %s , and value %s" % (unit1, 1, convert_unit(1, unit1)))
+    print("this unit2 %s ,its powerer %s , and value %s" % (unit2, 1, convert_unit(1, unit2)))
+    print("this unit3 %s ,its powerer %s , and value %s" % (unit3, 2, convert_unit(2, unit3)))
+    print("this unit4 %s ,its powerer %s , and value %s" % (unit4, -1, convert_unit(-1, unit4)))
+    print("this unit5 %s ,its powerer %s , and value %s" % (unit5, 2, convert_unit(2, unit5)))
+    print("this unit6 %s ,its powerer %s , and value %s" % (unit6, 2, convert_unit(2, unit6)))
+    print("this unit7 %s ,its powerer %s , and value %s" % (unit7, -1, convert_unit(-1, unit7)))
+    print("this unit8 %s ,its powerer %s , and value %s" % (unit8, 2, convert_unit(2, unit8)))
+    print("this unit9 %s ,its powerer %s , and value %s" % (unit9, 2, convert_unit(2, unit9)))
 
 
Index: src/sas/qtgui/Plotting/DataTransform.py
===================================================================
--- src/sas/qtgui/Plotting/DataTransform.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/DataTransform.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -24,5 +24,5 @@
     """
     if not x > 0:
-        raise ValueError, "Transformation only accepts positive values."
+        raise ValueError("Transformation only accepts positive values.")
     else:
         return x
@@ -50,5 +50,5 @@
     """
     if not x >= 0:
-        raise ValueError, "square root of a negative value "
+        raise ValueError("square root of a negative value ")
     else:
         return math.sqrt(x)
@@ -76,5 +76,5 @@
     """
     if not x >= 0:
-        raise ValueError, "double square root of a negative value "
+        raise ValueError("double square root of a negative value ")
     else:
         return math.sqrt(math.sqrt(x))
@@ -90,5 +90,5 @@
     """
     if not x > 0:
-        raise ValueError, "Log(x)of a negative value "
+        raise ValueError("Log(x)of a negative value ")
     else:
         return math.log(x)
@@ -100,5 +100,5 @@
         return 1 / x
     else:
-        raise ValueError, "cannot divide by zero"
+        raise ValueError("cannot divide by zero")
 
 
@@ -109,5 +109,5 @@
         return 1 / math.sqrt(y)
     else:
-        raise ValueError, "transform.toOneOverSqrtX: cannot be computed"
+        raise ValueError("transform.toOneOverSqrtX: cannot be computed")
 
 
@@ -118,5 +118,5 @@
         return math.log(y * (x ** 2))
     else:
-        raise ValueError, "transform.toLogYX2: cannot be computed"
+        raise ValueError("transform.toLogYX2: cannot be computed")
 
 
@@ -127,5 +127,5 @@
         return math.log(math.pow(x, 4) * y)
     else:
-        raise ValueError, "transform.toLogYX4: input error"
+        raise ValueError("transform.toLogYX4: input error")
 
 
@@ -149,5 +149,5 @@
     """
     if not (x * y) > 0:
-        raise ValueError, "Log(X*Y)of a negative value "
+        raise ValueError("Log(X*Y)of a negative value ")
     else:
         return math.log(x * y)
@@ -211,5 +211,5 @@
     else:
         msg = "transform.errFromX2: can't compute error of negative x"
-        raise ValueError, msg
+        raise ValueError(msg)
 
 
@@ -245,5 +245,5 @@
     else:
         msg = "transform.errFromX4: can't compute error of negative x"
-        raise ValueError, msg
+        raise ValueError(msg)
 
 
@@ -264,9 +264,9 @@
         msg = "Transformation does not accept"
         msg += " point that are consistent with zero."
-        raise ValueError, msg
+        raise ValueError(msg)
     if x != 0:
         dx = dx / (x * math.log(10))
     else:
-        raise ValueError, "errToLogX: divide by zero"
+        raise ValueError("errToLogX: divide by zero")
     return dx
 
@@ -287,5 +287,5 @@
         dx = dx / x
     else:
-        raise ValueError, "errToLogX: divide by zero"
+        raise ValueError("errToLogX: divide by zero")
     return dx
 
@@ -312,5 +312,5 @@
         msg = "Transformation does not accept point "
         msg += " that are consistent with zero."
-        raise ValueError, msg
+        raise ValueError(msg)
     if x != 0 and y != 0:
         if dx == None:
@@ -320,5 +320,5 @@
         err = (dx / x) ** 2 + (dy / y) ** 2
     else:
-        raise ValueError, "cannot compute this error"
+        raise ValueError("cannot compute this error")
 
     return math.sqrt(math.fabs(err))
@@ -335,5 +335,5 @@
         msg = "Transformation does not accept point"
         msg += " that are consistent with zero."
-        raise ValueError, msg
+        raise ValueError(msg)
     if x > 0 and y > 0:
         if dx == None:
@@ -343,5 +343,5 @@
         err = (2.0 * dx / x) ** 2 + (dy / y) ** 2
     else:
-        raise ValueError, "cannot compute this error"
+        raise ValueError("cannot compute this error")
     return math.sqrt(math.fabs(err))
 
@@ -357,5 +357,5 @@
         err = dx / x ** 2
     else:
-        raise ValueError, "Cannot compute this error"
+        raise ValueError("Cannot compute this error")
     return math.fabs(err)
 
@@ -371,5 +371,5 @@
         err = -1 / 2 * math.pow(x, -3.0 / 2.0) * dx
     else:
-        raise ValueError, "Cannot compute this error"
+        raise ValueError("Cannot compute this error")
     return math.fabs(err)
 
@@ -387,5 +387,5 @@
         msg = "Transformation does not accept point "
         msg += " that are consistent with zero."
-        raise ValueError, msg
+        raise ValueError(msg)
     if dx == None:
         dx = 0
Index: src/sas/qtgui/Plotting/Fittings.py
===================================================================
--- src/sas/qtgui/Plotting/Fittings.py	(revision adc49fc00f134eaa53065d970741288f321fcfec)
+++ src/sas/qtgui/Plotting/Fittings.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -97,5 +97,5 @@
     # Testing implementation
     # Fit a Line model
-    from LineModel import LineModel
+    from .LineModel import LineModel
     line = LineModel()
     cstA = Parameter(line, 'A', event.cstA)
@@ -104,5 +104,5 @@
     chisqr, out, cov = sasfit(line, [cstA, cstB], event.x, y, 0)
     # print "Output parameters:", out
-    print "The right answer is [70.0, 1.0]"
-    print chisqr, out, cov
+    print("The right answer is [70.0, 1.0]")
+    print(chisqr, out, cov)
 
Index: src/sas/qtgui/Plotting/LineModel.py
===================================================================
--- src/sas/qtgui/Plotting/LineModel.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/LineModel.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -81,5 +81,5 @@
         elif x.__class__.__name__ == 'tuple':
             msg = "Tuples are not allowed as input to BaseComponent models"
-            raise ValueError, msg
+            raise ValueError(msg)
         else:
             return self._line(x)
@@ -103,5 +103,5 @@
         elif x.__class__.__name__ == 'tuple':
             msg = "Tuples are not allowed as input to BaseComponent models"
-            raise ValueError, msg
+            raise ValueError(msg)
         else:
             return self._line(x)
Index: src/sas/qtgui/Plotting/LinearFit.py
===================================================================
--- src/sas/qtgui/Plotting/LinearFit.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/LinearFit.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -79,5 +79,5 @@
         Overwrite default fit range label to correspond to actual unit
         """
-        assert(isinstance(label, basestring))
+        assert(isinstance(label, str))
         self.lblRange.setText(label)
 
@@ -195,6 +195,6 @@
                          for i in range(len(x)) if x[i] >= xmin_check]
             else:
-                tempy = map(numpy.log10, y)
-                tempdy = map(lambda t1,t2:DataTransform.errToLogX(t1,0,t2,0),y,dy)
+                tempy = list(map(numpy.log10, y))
+                tempdy = list(map(lambda t1,t2:DataTransform.errToLogX(t1,0,t2,0),y,dy))
         else:
             tempy = y
Index: src/sas/qtgui/Plotting/PlotHelper.py
===================================================================
--- src/sas/qtgui/Plotting/PlotHelper.py	(revision 83eb5208b8acb86b064162274de583670f72da47)
+++ src/sas/qtgui/Plotting/PlotHelper.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -35,5 +35,5 @@
     Returns a list of IDs for all currently active plots
     """
-    return this._plots.keys()
+    return list(this._plots.keys())
 
 def plotById(plot_id):
@@ -48,5 +48,5 @@
     """
     plot_id = None
-    for key in this._plots.keys():
+    for key in list(this._plots.keys()):
         if this._plots[key] == plot:
             plot_id = key
Index: src/sas/qtgui/Plotting/PlotProperties.py
===================================================================
--- src/sas/qtgui/Plotting/PlotProperties.py	(revision cd2cc7458970e179039a783e9409f48c4c1fca0d)
+++ src/sas/qtgui/Plotting/PlotProperties.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -26,5 +26,5 @@
 
         # Fill out the color combobox
-        self.cbColor.addItems(COLORS.keys()[:-1])
+        self.cbColor.addItems(list(COLORS.keys())[:-1])
         # data1d.custom_color can now be a simple integer,
         # specifying COLORS dict index or a string containing
@@ -34,9 +34,9 @@
         else:
             # Need the Custom entry here. "Custom" is always last.
-            self.cbColor.addItems([COLORS.keys()[-1]])
-            self.cbColor.setCurrentIndex(COLORS.keys().index("Custom"))
+            self.cbColor.addItems([list(COLORS.keys())[-1]])
+            self.cbColor.setCurrentIndex(list(COLORS.keys()).index("Custom"))
 
         # Fill out the marker combobox
-        self.cbShape.addItems(SHAPES.keys())
+        self.cbShape.addItems(list(SHAPES.keys()))
         try:
             self.cbShape.setCurrentIndex(self._marker)
@@ -83,5 +83,5 @@
             # Add Custom to the color combo box
             self.cbColor.addItems(["Custom"])
-            self.cbColor.setCurrentIndex(COLORS.keys().index("Custom"))
+            self.cbColor.setCurrentIndex(list(COLORS.keys()).index("Custom"))
             # unblock currentIndexChanged
             self.cbColor.blockSignals(False)
Index: src/sas/qtgui/Plotting/PlotUtilities.py
===================================================================
--- src/sas/qtgui/Plotting/PlotUtilities.py	(revision 83eb5208b8acb86b064162274de583670f72da47)
+++ src/sas/qtgui/Plotting/PlotUtilities.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -273,5 +273,5 @@
         # Check if it's within the range
         if 0 <= color <=6:
-            color = COLORS.values()[color]
+            color = list(COLORS.values())[color]
     # Check if it's an RGB string
     elif isinstance(color, str):
Index: src/sas/qtgui/Plotting/Plottables.py
===================================================================
--- src/sas/qtgui/Plotting/Plottables.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Plottables.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -239,5 +239,5 @@
         selected_color = None
         selected_plottable = None
-        for p in self.plottables.keys():
+        for p in list(self.plottables.keys()):
             if plottable.id == p.id:
                 selected_plottable = p
@@ -384,5 +384,5 @@
 
         """
-        raise NotImplemented, "Not a valid transform"
+        raise NotImplemented("Not a valid transform")
 
     # Related issues
@@ -512,5 +512,5 @@
                 label_dict[collection[0]] = basename
             else:
-                for i in xrange(len(collection)):
+                for i in range(len(collection)):
                     label_dict[collection[i]] = "%s %d" % (basename, i)
         return label_dict
@@ -684,15 +684,15 @@
                 msg = "Plottable.View: Given x and dx are not"
                 msg += " of the same length"
-                raise ValueError, msg
+                raise ValueError(msg)
             # Check length of y array
             if not len(y) == len(x):
                 msg = "Plottable.View: Given y "
                 msg += "and x are not of the same length"
-                raise ValueError, msg
+                raise ValueError(msg)
 
             if not dy is None and not len(dy) == 0 and not len(y) == len(dy):
                 msg = "Plottable.View: Given y and dy are not of the same "
                 msg += "length: len(y)=%s, len(dy)=%s" % (len(y), len(dy))
-                raise ValueError, msg
+                raise ValueError(msg)
             self.x = []
             self.y = []
@@ -729,13 +729,13 @@
                 msg = "Plottable.View: transformed x "
                 msg += "and y are not of the same length"
-                raise ValueError, msg
+                raise ValueError(msg)
             if has_err_x and not (len(self.x) == len(self.dx)):
                 msg = "Plottable.View: transformed x and dx"
                 msg += " are not of the same length"
-                raise ValueError, msg
+                raise ValueError(msg)
             if has_err_y and not (len(self.y) == len(self.dy)):
                 msg = "Plottable.View: transformed y"
                 msg += " and dy are not of the same length"
-                raise ValueError, msg
+                raise ValueError(msg)
             # Check that negative values are not plot on x and y axis for
             # log10 transformation
@@ -809,5 +809,5 @@
                 except:
                     logging.error("check_data_logX: skipping point x %g", self.x[i])
-                    logging.error(sys.exc_value)
+                    logging.error(sys.exc_info()[1])
             self.x = tempx
             self.y = tempy
@@ -839,5 +839,5 @@
                 except:
                     logging.error("check_data_logY: skipping point %g", self.y[i])
-                    logging.error(sys.exc_value)
+                    logging.error(sys.exc_info()[1])
 
             self.x = tempx
@@ -1101,5 +1101,5 @@
         Plottable.__init__(self)
         msg = "Theory1D is no longer supported, please use Data1D and change symbol.\n"
-        raise DeprecationWarning, msg
+        raise DeprecationWarning(msg)
 
 class PlottableFit1D(Plottable):
Index: src/sas/qtgui/Plotting/Plotter.py
===================================================================
--- src/sas/qtgui/Plotting/Plotter.py	(revision f0bb71111cd83022768469968b3891e8656d0417)
+++ src/sas/qtgui/Plotting/Plotter.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -87,5 +87,5 @@
                 marker = PlotUtilities.SHAPES[marker]
             except KeyError:
-                marker = PlotUtilities.SHAPES.values()[marker]
+                marker = list(PlotUtilities.SHAPES.values())[marker]
 
         assert marker is not None
@@ -203,5 +203,5 @@
         Adds operations on all plotted sets of data to the context menu
         """
-        for id in self.plot_dict.keys():
+        for id in list(self.plot_dict.keys()):
             plot = self.plot_dict[id]
 
@@ -388,5 +388,5 @@
         Deletes the selected plot from the chart
         """
-        if id not in self.plot_dict.keys():
+        if id not in list(self.plot_dict.keys()):
             return
 
@@ -479,5 +479,5 @@
         """
         # Transform all the plots on the chart
-        for id in self.plot_dict.keys():
+        for id in list(self.plot_dict.keys()):
             current_plot = self.plot_dict[id]
             if current_plot.id == "fit":
Index: src/sas/qtgui/Plotting/SlicerModel.py
===================================================================
--- src/sas/qtgui/Plotting/SlicerModel.py	(revision 83eb5208b8acb86b064162274de583670f72da47)
+++ src/sas/qtgui/Plotting/SlicerModel.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -19,5 +19,5 @@
         self._model.removeRows( 0, self._model.rowCount() )
         # Crete/overwrite model items
-        for parameter in parameters.keys():
+        for parameter in list(parameters.keys()):
             item1 = QtGui.QStandardItem(parameter)
             item2 = QtGui.QStandardItem(GuiUtils.formatNumber(parameters[parameter]))
Index: src/sas/qtgui/Plotting/Slicers/AnnulusSlicer.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/AnnulusSlicer.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Slicers/AnnulusSlicer.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -4,5 +4,5 @@
 
 import sas.qtgui.Utilities.GuiUtils as GuiUtils
-from BaseInteractor import BaseInteractor
+from .BaseInteractor import BaseInteractor
 from sas.qtgui.Plotting.PlotterData import Data1D
 from sas.qtgui.Utilities.GuiUtils import formatNumber
Index: src/sas/qtgui/Plotting/Slicers/Arc.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/Arc.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Slicers/Arc.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -4,5 +4,5 @@
 import math
 
-from BaseInteractor import BaseInteractor
+from .BaseInteractor import BaseInteractor
 
 class ArcInteractor(BaseInteractor):
Index: src/sas/qtgui/Plotting/Slicers/AzimutSlicer.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/AzimutSlicer.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Slicers/AzimutSlicer.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -5,5 +5,5 @@
 #
 import math
-from BaseInteractor import BaseInteractor
+from .BaseInteractor import BaseInteractor
 
 class SectorInteractor(BaseInteractor):
@@ -26,5 +26,5 @@
 
         # Inner circle
-        from Arc import ArcInteractor
+        from .Arc import ArcInteractor
         self.inner_circle = ArcInteractor(self, self.base.subplot,
                                           zorder=zorder,
Index: src/sas/qtgui/Plotting/Slicers/BoxSlicer.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/BoxSlicer.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Slicers/BoxSlicer.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -3,5 +3,5 @@
 from PyQt4 import QtCore
 
-from BaseInteractor import BaseInteractor
+from .BaseInteractor import BaseInteractor
 from sas.qtgui.Plotting.PlotterData import Data1D
 import sas.qtgui.Utilities.GuiUtils as GuiUtils
@@ -136,5 +136,5 @@
             if new_slab is None:
                 msg = "post data:cannot average , averager is empty"
-                raise ValueError, msg
+                raise ValueError(msg)
             self.averager = new_slab
         if self.direction == "X":
@@ -152,5 +152,5 @@
         else:
             msg = "post data:no Box Average direction was supplied"
-            raise ValueError, msg
+            raise ValueError(msg)
         # # Average data2D given Qx or Qy
         box = self.averager(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max,
Index: src/sas/qtgui/Plotting/Slicers/BoxSum.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/BoxSum.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Slicers/BoxSum.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -8,5 +8,5 @@
 from sas.qtgui.Utilities.GuiUtils import formatNumber
 
-from BaseInteractor import BaseInteractor
+from .BaseInteractor import BaseInteractor
 from sas.sascalc.dataloader.manipulations import Boxavg
 from sas.sascalc.dataloader.manipulations import Boxsum
Index: src/sas/qtgui/Plotting/Slicers/SectorSlicer.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/SectorSlicer.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Slicers/SectorSlicer.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -6,5 +6,5 @@
 from PyQt4 import QtCore
 
-from BaseInteractor import BaseInteractor
+from .BaseInteractor import BaseInteractor
 from sas.qtgui.Plotting.PlotterData import Data1D
 import sas.qtgui.Utilities.GuiUtils as GuiUtils
@@ -230,5 +230,5 @@
             msg = "Phi left and phi right are different"
             msg += " %f, %f" % (self.left_line.phi, self.right_line.phi)
-            raise ValueError, msg
+            raise ValueError(msg)
         params["Phi [deg]"] = self.main_line.theta * 180 / numpy.pi
         params["Delta_Phi [deg]"] = numpy.fabs(self.left_line.phi * 180 / numpy.pi)
Index: src/sas/qtgui/Utilities/CategoryInstaller.py
===================================================================
--- src/sas/qtgui/Utilities/CategoryInstaller.py	(revision 125c4be1f2a9bcc043693f90241343f185040dde)
+++ src/sas/qtgui/Utilities/CategoryInstaller.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -103,5 +103,5 @@
                 master_category_dict[category].append(\
                     (model, model_enabled_dict[model]))
-        return OrderedDict(sorted(master_category_dict.items(), key=lambda t: t[0]))
+        return OrderedDict(sorted(list(master_category_dict.items()), key=lambda t: t[0]))
 
     @staticmethod
@@ -126,5 +126,5 @@
         """
         _model_dict = { model.name: model for model in model_list}
-        _model_list = _model_dict.keys()
+        _model_list = list(_model_dict.keys())
 
         serialized_file = None
@@ -143,5 +143,5 @@
         add_list = _model_list
         del_name = False
-        for cat in master_category_dict.keys():
+        for cat in list(master_category_dict.keys()):
             for ind in range(len(master_category_dict[cat])):
                 model_name, enabled = master_category_dict[cat][ind]
@@ -152,5 +152,5 @@
                         model_enabled_dict.pop(model_name)
                     except:
-                        logging.error("CategoryInstaller: %s", sys.exc_value)
+                        logging.error("CategoryInstaller: %s", sys.exc_info()[1])
                 else:
                     add_list.remove(model_name)
Index: src/sas/qtgui/Utilities/ConnectionProxy.py
===================================================================
--- src/sas/qtgui/Utilities/ConnectionProxy.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Utilities/ConnectionProxy.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 import sys
 import json
@@ -33,5 +33,5 @@
         if sys.platform == 'win32':
             try:
-                import _winreg as winreg  # used from python 2.0-2.6
+                import winreg as winreg  # used from python 2.0-2.6
             except:
                 import winreg  # used from python 2.7 onwards
@@ -45,5 +45,5 @@
                 this_name, this_val, this_type = winreg.EnumValue(net, i)
                 subkeys[this_name] = this_val
-            if 'AutoConfigURL' in subkeys.keys() and len(subkeys['AutoConfigURL']) > 0:
+            if 'AutoConfigURL' in list(subkeys.keys()) and len(subkeys['AutoConfigURL']) > 0:
                 pac_files.append(subkeys['AutoConfigURL'])
         elif sys.platform == 'darwin':
@@ -53,8 +53,8 @@
             networks = sys_prefs['NetworkServices']
             # loop through each possible network (e.g. Ethernet, Airport...)
-            for network in networks.items():
+            for network in list(networks.items()):
                 # the first part is a long identifier
                 net_key, network = network
-                if 'ProxyAutoConfigURLString' in network['Proxies'].keys():
+                if 'ProxyAutoConfigURLString' in list(network['Proxies'].keys()):
                     pac_files.append(
                         network['Proxies']['ProxyAutoConfigURLString'])
@@ -73,5 +73,5 @@
             logging.debug('Trying pac file (%s)...' % this_pac_url)
             try:
-                response = urllib2.urlopen(
+                response = urllib.request.urlopen(
                     this_pac_url, timeout=self.timeout)
                 logging.debug('Succeeded (%s)...' % this_pac_url)
@@ -101,11 +101,11 @@
             # information is retrieved from the OS X System Configuration
             # Framework.
-            proxy = urllib2.ProxyHandler()
+            proxy = urllib.request.ProxyHandler()
         else:
             # If proxies is given, it must be a dictionary mapping protocol names to
             # URLs of proxies.
-            proxy = urllib2.ProxyHandler(proxy_dic)
-        opener = urllib2.build_opener(proxy)
-        urllib2.install_opener(opener)
+            proxy = urllib.request.ProxyHandler(proxy_dic)
+        opener = urllib.request.build_opener(proxy)
+        urllib.request.install_opener(opener)
 
     def connect(self):
@@ -114,10 +114,10 @@
         @return: response object from urllib2.urlopen
         '''
-        req = urllib2.Request(self.url)
+        req = urllib.request.Request(self.url)
         response = None
         try:
             logging.debug("Trying Direct connection to %s..."%self.url)
-            response = urllib2.urlopen(req, timeout=self.timeout)
-        except Exception, e:
+            response = urllib.request.urlopen(req, timeout=self.timeout)
+        except Exception as e:
             logging.debug("Failed!")
             logging.debug(e)
@@ -125,6 +125,6 @@
                 logging.debug("Trying to use system proxy if it exists...")
                 self._set_proxy()
-                response = urllib2.urlopen(req, timeout=self.timeout)
-            except Exception, e:
+                response = urllib.request.urlopen(req, timeout=self.timeout)
+            except Exception as e:
                 logging.debug("Failed!")
                 logging.debug(e)
@@ -135,6 +135,6 @@
                         logging.debug("Trying to use the proxy %s found in proxy.pac configuration"%proxy)
                         self._set_proxy(proxy)
-                        response = urllib2.urlopen(req, timeout=self.timeout)
-                    except Exception, e:
+                        response = urllib.request.urlopen(req, timeout=self.timeout)
+                    except Exception as e:
                         logging.debug("Failed!")
                         logging.debug(e)
@@ -151,5 +151,5 @@
     response = c.connect()
     if response is not None:
-        print 50 * '-'
+        print(50 * '-')
         content = json.loads(response.read().strip())
         pprint(content)
Index: src/sas/qtgui/Utilities/GuiUtils.py
===================================================================
--- src/sas/qtgui/Utilities/GuiUtils.py	(revision 88e1f57e340b062a07d1e5693c8b7b8a4edc4b32)
+++ src/sas/qtgui/Utilities/GuiUtils.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -9,5 +9,5 @@
 import warnings
 import webbrowser
-import urlparse
+import urllib.parse
 
 warnings.simplefilter("ignore")
@@ -86,5 +86,5 @@
         #logging.error("Error loading %s/%s: %s" % (path, confg_file, sys.exc_value))
     except ValueError:
-        print "Value error"
+        print("Value error")
         pass
     finally:
@@ -242,6 +242,7 @@
     """
     assert isinstance(item, QtGui.QStandardItem)
-    assert isinstance(update_data, QtCore.QVariant)
-    py_update_data = update_data.toPyObject()
+    #assert isinstance(update_data, QtCore.QVariant)
+    #py_update_data = update_data.toPyObject()
+    py_update_data = update_data
 
     # Check if data with the same ID is already present
@@ -249,5 +250,5 @@
         plot_item = item.child(index)
         if plot_item.isCheckable():
-            plot_data = plot_item.child(0).data().toPyObject()
+            plot_data = plot_item.child(0).data() #.toPyObject()
             if plot_data.id is not None and plot_data.id == py_update_data.id:
                 # replace data section in item
@@ -270,6 +271,7 @@
     Adds QVariant 'update_data' to that row.
     """
-    assert isinstance(update_data, QtCore.QVariant)
-    py_update_data = update_data.toPyObject()
+    #assert isinstance(update_data, QtCore.QVariant)
+    #py_update_data = update_data.toPyObject()
+    py_update_data = update_data
 
     checkbox_item = QtGui.QStandardItem()
@@ -309,5 +311,6 @@
     object_item = QtGui.QStandardItem()
     object_item.setText(name)
-    object_item.setData(QtCore.QVariant(update_data))
+    #object_item.setData(QtCore.QVariant(update_data))
+    object_item.setData(update_data)
 
     # Append the new row to the main item
@@ -319,9 +322,8 @@
     """
     assert isinstance(model_item, QtGui.QStandardItemModel)
-    assert isinstance(filename, basestring)
+    assert isinstance(filename, str)
 
     # Iterate over model looking for named items
-    item = list(filter(lambda i: str(i.text()) == filename,
-                  [model_item.item(index) for index in range(model_item.rowCount())]))
+    item = list([i for i in [model_item.item(index) for index in range(model_item.rowCount())] if str(i.text()) == filename])
     return item[0] if len(item)>0 else None
 
@@ -331,5 +333,5 @@
     """
     assert isinstance(model_item, QtGui.QStandardItemModel)
-    assert isinstance(filename, basestring)
+    assert isinstance(filename, str)
 
     plot_data = []
@@ -339,5 +341,5 @@
         if str(item.text()) == filename:
             # TODO: assure item type is correct (either data1/2D or Plotter)
-            plot_data.append(item.child(0).data().toPyObject())
+            plot_data.append(item.child(0).data()) #.toPyObject())
             # Going 1 level deeper only
             for index_2 in range(item.rowCount()):
@@ -345,5 +347,5 @@
                 if item_2 and item_2.isCheckable():
                     # TODO: assure item type is correct (either data1/2D or Plotter)
-                    plot_data.append(item_2.child(0).data().toPyObject())
+                    plot_data.append(item_2.child(0).data()) #.toPyObject())
 
     return plot_data
@@ -361,5 +363,5 @@
         if item.isCheckable() and item.checkState() == QtCore.Qt.Checked:
             # TODO: assure item type is correct (either data1/2D or Plotter)
-            plot_data.append((item, item.child(0).data().toPyObject()))
+            plot_data.append((item, item.child(0).data())) #.toPyObject()))
         # Going 1 level deeper only
         for index_2 in range(item.rowCount()):
@@ -367,5 +369,5 @@
             if item_2 and item_2.isCheckable() and item_2.checkState() == QtCore.Qt.Checked:
                 # TODO: assure item type is correct (either data1/2D or Plotter)
-                plot_data.append((item_2, item_2.child(0).data().toPyObject()))
+                plot_data.append((item_2, item_2.child(0).data())) #.toPyObject()))
 
     return plot_data
@@ -419,10 +421,10 @@
     Check the URL first, though.
     """
-    parsed_url = urlparse.urlparse(url)
+    parsed_url = urllib.parse.urlparse(url)
     if parsed_url.scheme:
         webbrowser.open(url)
     else:
         msg = "Attempt at opening an invalid URL"
-        raise AttributeError, msg
+        raise AttributeError(msg)
 
 def retrieveData1d(data):
@@ -433,5 +435,5 @@
     if not isinstance(data, Data1D):
         msg = "Incorrect type passed to retrieveData1d"
-        raise AttributeError, msg
+        raise AttributeError(msg)
     try:
         xmin = min(data.x)
@@ -441,5 +443,5 @@
                     data.filename
         #logging.error(msg)
-        raise ValueError, msg
+        raise ValueError(msg)
 
     text = data.__str__()
@@ -485,5 +487,5 @@
     if not isinstance(data, Data2D):
         msg = "Incorrect type passed to retrieveData2d"
-        raise AttributeError, msg
+        raise AttributeError(msg)
 
     text = data.__str__()
@@ -499,5 +501,5 @@
     dy_val = 0.0
     len_data = len(data.qx_data)
-    for index in xrange(0, len_data):
+    for index in range(0, len_data):
         x_val = data.qx_data[index]
         y_val = data.qy_data[index]
@@ -756,5 +758,5 @@
     The assumption - data stored in SasView standard, in child 0
     """
-    return item.child(0).data().toPyObject()
+    return item.child(0).data() #.toPyObject()
 
 def formatNumber(value, high=False):
Index: src/sas/qtgui/Utilities/LocalConfig.py
===================================================================
--- src/sas/qtgui/Utilities/LocalConfig.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Utilities/LocalConfig.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -139,5 +139,5 @@
     """
     if __EVT_DEBUG__:
-        print "%g:  %s" % (time.clock(), message)
+        print("%g:  %s" % (time.clock(), message))
 
         if __EVT_DEBUG_2_FILE__:
Index: src/sas/qtgui/Utilities/ObjectLibrary.py
===================================================================
--- src/sas/qtgui/Utilities/ObjectLibrary.py	(revision 61a92d4c3e2e9b0410555517d59b1e8503c98ff4)
+++ src/sas/qtgui/Utilities/ObjectLibrary.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -9,5 +9,5 @@
 
 def deleteObjectByRef(obj):
-    for name, object in this._objects.iteritems():
+    for name, object in this._objects.items():
         if object == obj:
             del this._objects[name]
@@ -22,5 +22,5 @@
 
 def listObjects():
-    return this._objects.keys()
+    return list(this._objects.keys())
 
 
Index: src/sas/qtgui/Utilities/SasviewLogger.py
===================================================================
--- src/sas/qtgui/Utilities/SasviewLogger.py	(revision 83eb5208b8acb86b064162274de583670f72da47)
+++ src/sas/qtgui/Utilities/SasviewLogger.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -19,5 +19,5 @@
     def write(self, msg):
         if(not self.signalsBlocked()):
-            self.messageWritten.emit(unicode(msg))
+            self.messageWritten.emit(str(msg))
 
     @staticmethod
Index: src/sas/qtgui/convertUI.py
===================================================================
--- src/sas/qtgui/convertUI.py	(revision cd2cc7458970e179039a783e9409f48c4c1fca0d)
+++ src/sas/qtgui/convertUI.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -8,5 +8,5 @@
 
 def pyuic(in_file, out_file):
-    """ Run the pyuic4 script"""
+    """ Run the pyuic5 script"""
     execute = 'pyuic4 -o %s %s' % (out_file, in_file)
     os.system(execute)
Index: src/sas/sascalc/fit/expression.py
===================================================================
--- src/sas/sascalc/fit/expression.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/fit/expression.py	(revision b0b09b9740526b0b3838f642e43599409dfd8772)
@@ -210,5 +210,5 @@
 
     #print("Function: "+functiondef)
-    exec functiondef in globals,locals
+    exec (functiondef in globals,locals)
     retfn = locals['eval_expressions']
 
