Index: src/sas/sascalc/calculator/instrument.py
===================================================================
--- src/sas/sascalc/calculator/instrument.py	(revision f4775563fe889a4e12295a145627987e7a33ab93)
+++ src/sas/sascalc/calculator/instrument.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -128,5 +128,9 @@
             self.size = 0
         else:
-            self.size = size
+            # TODO: Make sure detector size is number of pixels
+            # Could be detector dimensions in e.g., mm, but
+            # the resolution calculator assumes it is pixels.
+            # Being pixels, it has to be integers rather than float
+            self.size = [int(s) for s in size]
             validate(size[0])
 
Index: src/sas/sascalc/calculator/resolution_calculator.py
===================================================================
--- src/sas/sascalc/calculator/resolution_calculator.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/calculator/resolution_calculator.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -1007,6 +1007,6 @@
         try:
             detector_offset = self.sample2detector_distance[1]
-        except:
-            logger.error(sys.exc_value)
+        except Exception as exc:
+            logger.error(exc)
 
         # detector size in [no of pix_x,no of pix_y]
@@ -1094,6 +1094,6 @@
             output.qx_data = qx_value
             output.qy_data = qy_value
-        except:
-            logger.error(sys.exc_value)
+        except Exception as exc:
+            logger.error(exc)
 
         return output
Index: src/sas/sascalc/corfunc/corfunc_calculator.py
===================================================================
--- src/sas/sascalc/corfunc/corfunc_calculator.py	(revision a26f67f1457e7e39b79d4c3800c03bcaa208dff7)
+++ src/sas/sascalc/corfunc/corfunc_calculator.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -30,11 +30,11 @@
             self.start = start
             self.stop = stop
-            self._lastx = []
-            self._lasty = []
+            self._lastx = np.empty(0, dtype='d')
+            self._lasty = None
 
         def __call__(self, x):
             # If input is a single number, evaluate the function at that number
             # and return a single number
-            if type(x) == float or type(x) == int:
+            if isinstance(x, (float, int)):
                 return self._smoothed_function(np.array([x]))[0]
             # If input is a list, and is different to the last input, evaluate
@@ -42,7 +42,6 @@
             # the function was called, return the result that was calculated
             # last time instead of explicity evaluating the function again.
-            elif self._lastx == [] or x.tolist() != self._lastx.tolist():
-                self._lasty = self._smoothed_function(x)
-                self._lastx = x
+            if not np.array_equal(x, self._lastx):
+                self._lastx, self._lasty = x, self._smoothed_function(x)
             return self._lasty
 
@@ -88,5 +87,5 @@
         # Only process data of the class Data1D
         if not issubclass(data.__class__, Data1D):
-            raise ValueError("Data must be of the type DataLoader.Data1D")
+            raise ValueError("Correlation function cannot be computed with 2D data.")
 
         # Prepare the data
@@ -246,5 +245,5 @@
         """Fit the Guinier region of the curve"""
         A = np.vstack([q**2, np.ones(q.shape)]).T
-        return lstsq(A, np.log(iq))
+        return lstsq(A, np.log(iq), rcond=None)
 
     def _fit_porod(self, q, iq):
Index: src/sas/sascalc/data_util/calcthread.py
===================================================================
--- src/sas/sascalc/data_util/calcthread.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/data_util/calcthread.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -6,27 +6,22 @@
 from __future__ import print_function
 
-import traceback
 import sys
 import logging
+import traceback
+from time import sleep
+
 try:
     import _thread as thread
 except ImportError: # CRUFT: python 2 support
     import thread
-
-if sys.platform.count("darwin") > 0:
-    import time
-    stime = time.time()
-
-    def clock():
-        return time.time() - stime
-
-    def sleep(t):
-        return time.sleep(t)
-else:
-    from time import clock
-    from time import sleep
+try:
+    from time import perf_counter as clock
+except ImportError: # CRUFT: python < 3.3
+    if sys.platform.count("darwin") > 0:
+        from time import time as clock
+    else:
+        from time import clock
 
 logger = logging.getLogger(__name__)
-
 
 class CalcThread:
@@ -248,5 +243,5 @@
                 self.exception_handler(*sys.exc_info())
                 return
-            except Exception:
+            except Exception as exc:
                 pass
         logger.error(traceback.format_exc())
Index: src/sas/sascalc/data_util/nxsunit.py
===================================================================
--- src/sas/sascalc/data_util/nxsunit.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/data_util/nxsunit.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -99,9 +99,8 @@
     Strip '^' from unit names.
 
-    * WARNING * this will incorrect transform 10^3 to 103.
-    """
-    s.update((k.replace('^',''),v)
-             for k, v in list(s.items())
-             if '^' in k)
+    * WARNING * this will incorrectly transform 10^3 to 103.
+    """
+    stripped = [(k.replace('^',''),v) for k, v in s.items() if '^' in k]
+    s.update(stripped)
 
 def _build_all_units():
Index: src/sas/sascalc/data_util/ordereddicttest.py
===================================================================
--- src/sas/sascalc/data_util/ordereddicttest.py	(revision b699768550de9d4b35b087234ec1d2a461922bab)
+++ src/sas/sascalc/data_util/ordereddicttest.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -147,8 +147,8 @@
                     ]):
             self.assert_(dup is not od)
-            self.assertEquals(dup, od)
-            self.assertEquals(list(dup.items()), list(od.items()))
-            self.assertEquals(len(dup), len(od))
-            self.assertEquals(type(dup), type(od))
+            self.assertEqual(dup, od)
+            self.assertEqual(list(dup.items()), list(od.items()))
+            self.assertEqual(len(dup), len(od))
+            self.assertEqual(type(dup), type(od))
 
     def test_repr(self):
Index: src/sas/sascalc/data_util/registry.py
===================================================================
--- src/sas/sascalc/data_util/registry.py	(revision a26f67f1457e7e39b79d4c3800c03bcaa208dff7)
+++ src/sas/sascalc/data_util/registry.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -148,3 +148,3 @@
             # If file has associated loader(s) and they;ve failed
             raise last_exc
-        raise NoKnownLoaderException(e.message)  # raise generic exception
+        raise NoKnownLoaderException(str(message))  # raise generic exception
Index: src/sas/sascalc/data_util/uncertainty.py
===================================================================
--- src/sas/sascalc/data_util/uncertainty.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/data_util/uncertainty.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -19,5 +19,5 @@
 import numpy as np
 
-from .import err1d
+from . import err1d
 from .formatnum import format_uncertainty
 
Index: src/sas/sascalc/dataloader/data_info.py
===================================================================
--- src/sas/sascalc/dataloader/data_info.py	(revision deaa0c6b324db1003ba4999149364cd82185294e)
+++ src/sas/sascalc/dataloader/data_info.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -26,4 +26,5 @@
 import numpy as np
 import math
+from math import fabs
 
 class plottable_1D(object):
@@ -656,5 +657,5 @@
         return self._perform_operation(other, operation)
 
-    def __div__(self, other):
+    def __truediv__(self, other):
         """
         Divided a data set by another
@@ -667,6 +668,7 @@
             return a/b
         return self._perform_operation(other, operation)
-
-    def __rdiv__(self, other):
+    __div__ = __truediv__
+
+    def __rtruediv__(self, other):
         """
         Divided a data set by another
@@ -679,4 +681,5 @@
             return b/a
         return self._perform_operation(other, operation)
+    __rdiv__ = __rtruediv__
 
     def __or__(self, other):
@@ -800,5 +803,5 @@
             TOLERANCE = 0.01
             for i in range(len(self.x)):
-                if math.fabs((self.x[i] - other.x[i])/self.x[i]) > TOLERANCE:
+                if fabs(self.x[i] - other.x[i]) > self.x[i]*TOLERANCE:
                     msg = "Incompatible data sets: x-values do not match"
                     raise ValueError(msg)
@@ -1022,8 +1025,8 @@
                 raise ValueError(msg)
             for ind in range(len(self.data)):
-                if math.fabs((self.qx_data[ind] - other.qx_data[ind])/self.qx_data[ind]) > TOLERANCE:
+                if fabs(self.qx_data[ind] - other.qx_data[ind]) > fabs(self.qx_data[ind])*TOLERANCE:
                     msg = "Incompatible data sets: qx-values do not match: %s %s" % (self.qx_data[ind], other.qx_data[ind])
                     raise ValueError(msg)
-                if math.fabs((self.qy_data[ind] - other.qy_data[ind])/self.qy_data[ind]) > TOLERANCE:
+                if fabs(self.qy_data[ind] - other.qy_data[ind]) > fabs(self.qy_data[ind])*TOLERANCE:
                     msg = "Incompatible data sets: qy-values do not match: %s %s" % (self.qy_data[ind], other.qy_data[ind])
                     raise ValueError(msg)
Index: src/sas/sascalc/dataloader/loader.py
===================================================================
--- src/sas/sascalc/dataloader/loader.py	(revision 4a8d55c05d1355e27bf5afa880633879b6178acc)
+++ src/sas/sascalc/dataloader/loader.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -169,7 +169,7 @@
                         if self._identify_plugin(module):
                             readers_found += 1
-                    except:
+                    except Exception as exc:
                         msg = "Loader: Error importing "
-                        msg += "%s\n  %s" % (item, sys.exc_value)
+                        msg += "%s\n  %s" % (item, exc)
                         logger.error(msg)
 
@@ -191,12 +191,12 @@
                                 if self._identify_plugin(module):
                                     readers_found += 1
-                            except:
+                            except Exception as exc:
                                 msg = "Loader: Error importing"
-                                msg += " %s\n  %s" % (mfile, sys.exc_value)
+                                msg += " %s\n  %s" % (mfile, exc)
                                 logger.error(msg)
 
-                    except:
+                    except Exception as exc:
                         msg = "Loader: Error importing "
-                        msg += " %s\n  %s" % (item, sys.exc_value)
+                        msg += " %s\n  %s" % (item, exc)
                         logger.error(msg)
 
@@ -242,7 +242,7 @@
                     self.writers[ext].append(loader.write)
 
-            except:
+            except Exception as exc:
                 msg = "Loader: Error accessing"
-                msg += " Reader in %s\n  %s" % (module.__name__, sys.exc_value)
+                msg += " Reader in %s\n  %s" % (module.__name__, exc)
                 logger.error(msg)
         return reader_found
@@ -275,7 +275,7 @@
                     self.wildcards.append(wcard)
 
-        except:
+        except Exception as exc:
             msg = "Loader: Error accessing Reader "
-            msg += "in %s\n  %s" % (loader.__name__, sys.exc_value)
+            msg += "in %s\n  %s" % (loader.__name__, exc)
             logger.error(msg)
         return reader_found
@@ -320,7 +320,7 @@
                         self.writers[ext].insert(0, loader.write)
 
-            except:
+            except Exception as exc:
                 msg = "Loader: Error accessing Reader"
-                msg += " in %s\n  %s" % (module.__name__, sys.exc_value)
+                msg += " in %s\n  %s" % (module.__name__, exc)
                 logger.error(msg)
         return reader_found
Index: src/sas/sascalc/dataloader/manipulations.py
===================================================================
--- src/sas/sascalc/dataloader/manipulations.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/dataloader/manipulations.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -928,13 +928,12 @@
 
         # Organize the results
-        for i in range(self.nbins):
-            y[i] = y[i] / y_counts[i]
-            y_err[i] = math.sqrt(y_err[i]) / y_counts[i]
-
+        with np.errstate(divide='ignore', invalid='ignore'):
+            y = y/y_counts
+            y_err = np.sqrt(y_err)/y_counts
             # The type of averaging: phi,q2, or q
             # Calculate x[i]should be at the center of the bin
             if run.lower() == 'phi':
-                x[i] = (self.phi_max - self.phi_min) / self.nbins * \
-                    (1.0 * i + 0.5) + self.phi_min
+                step  = (self.phi_max - self.phi_min) / self.nbins
+                x = (np.arange(self.nbins) + 0.5) * step + self.phi_min
             else:
                 # We take the center of ring area, not radius.
@@ -944,6 +943,6 @@
                 # r_outer = r_inner + delta_r
                 # x[i] = math.sqrt((r_inner * r_inner + r_outer * r_outer) / 2)
-                x[i] = x[i] / y_counts[i]
-        y_err[y_err == 0] = np.average(y_err)
+                x = x/y_counts
+
         idx = (np.isfinite(y) & np.isfinite(y_err))
         if x_err is not None:
Index: src/sas/sascalc/dataloader/readers/associations.py
===================================================================
--- src/sas/sascalc/dataloader/readers/associations.py	(revision a32c19cb7f71822dacb02a8dd8c1e4967af341a7)
+++ src/sas/sascalc/dataloader/readers/associations.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -53,6 +53,6 @@
                 exec("loader.associate_file_type('%s', %s)"
                      % (ext.upper(), reader))
-            except:
+            except Exception as exc:
                 msg = "read_associations: skipping association"
-                msg += " for %s\n  %s" % (ext.lower(), sys.exc_value)
+                msg += " for %s\n  %s" % (ext.lower(), exc)
                 logger.error(msg)
Index: src/sas/sascalc/dataloader/readers/cansas_reader.py
===================================================================
--- src/sas/sascalc/dataloader/readers/cansas_reader.py	(revision 2469df7fc9ffa047115c5bffe589ed307b12c363)
+++ src/sas/sascalc/dataloader/readers/cansas_reader.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -1239,9 +1239,8 @@
                         conv = Converter(units)
                         setattrchain(storage, variable, conv(value, units=local_unit))
-                    except Exception:
-                        _, exc_value, _ = sys.exc_info()
+                    except Exception as exc:
                         err_mess = "CanSAS reader: could not convert"
                         err_mess += " %s unit [%s]; expecting [%s]\n  %s" \
-                            % (variable, units, local_unit, exc_value)
+                            % (variable, units, local_unit, exc)
                         self.errors.add(err_mess)
                         if optional:
Index: src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py
===================================================================
--- src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py	(revision 61f329f00cdb8b300656d1c1feb4e78f35e59745)
+++ src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -475,6 +475,6 @@
                 for i in range(0, dataset.mask.size - 1):
                     zeros[i] = dataset.mask[i]
-            except:
-                self.errors.add(sys.exc_value)
+            except Exception as exc:
+                self.errors.add(exc)
             dataset.mask = zeros
             # Calculate the actual Q matrix
Index: src/sas/sascalc/fit/expression.py
===================================================================
--- src/sas/sascalc/fit/expression.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/fit/expression.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -210,5 +210,5 @@
 
     #print("Function: "+functiondef)
-    exec functiondef in globals,locals
+    exec(functiondef, globals, locals)
     retfn = locals['eval_expressions']
 
Index: src/sas/sascalc/fit/models.py
===================================================================
--- src/sas/sascalc/fit/models.py	(revision b963b2066d6a76fe5073000c5a596a6fd0130ac4)
+++ src/sas/sascalc/fit/models.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -12,4 +12,6 @@
 import py_compile
 import shutil
+
+from six import reraise
 
 from sasmodels.sasview_model import load_custom_model, load_standard_models
@@ -62,8 +64,7 @@
     try:
         new_instance = model()
-    except Exception:
-        msg = "Plugin %s error in __init__ \n\t: %s %s\n" % (str(name),
-                                                             str(sys.exc_type),
-                                                             sys.exc_info()[1])
+    except Exception as exc:
+        msg = ("Plugin %s error in __init__ \n\t: %s %s\n"
+               % (name, type(exc), exc))
         plugin_log(msg)
         return None
@@ -72,7 +73,7 @@
         try:
             value = new_instance.function()
-        except Exception:
+        except Exception as exc:
             msg = "Plugin %s: error writing function \n\t :%s %s\n " % \
-                    (str(name), str(sys.exc_type), sys.exc_info()[1])
+                    (str(name), str(type(exc)), exc)
             plugin_log(msg)
             return None
@@ -139,5 +140,5 @@
         if type is not None and issubclass(type, py_compile.PyCompileError):
             print("Problem with", repr(value))
-            raise type, value, tb
+            reraise(type, value, tb)
         return 1
 
@@ -153,6 +154,6 @@
         compileall.compile_dir(dir=dir, ddir=dir, force=0,
                                quiet=report_problem)
-    except Exception:
-        return sys.exc_info()[1]
+    except Exception as exc:
+        return exc
     return None
 
@@ -185,5 +186,5 @@
                     model.name = PLUGIN_NAME_BASE + model.name
                 plugins[model.name] = model
-            except Exception:
+            except Exception as exc:
                 msg = traceback.format_exc()
                 msg += "\nwhile accessing model in %r" % path
Index: src/sas/sascalc/fit/pagestate.py
===================================================================
--- src/sas/sascalc/fit/pagestate.py	(revision 863ac2c13917d1e25dc3fe0061ef11ef07b02366)
+++ src/sas/sascalc/fit/pagestate.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -650,7 +650,7 @@
                     #Truncating string so print doesn't complain of being outside margins
                     if sys.platform != "win32":
-                        MAX_STRING_LENGHT = 50
-                        if len(file_value) > MAX_STRING_LENGHT:
-                            file_value = "File name:.."+file_value[-MAX_STRING_LENGHT+10:]
+                        MAX_STRING_LENGTH = 50
+                        if len(file_value) > MAX_STRING_LENGTH:
+                            file_value = "File name:.."+file_value[-MAX_STRING_LENGTH+10:]
                     file_name = CENTRE % file_value
                     if len(title) == 0:
@@ -905,5 +905,5 @@
                 doc_model = newdoc.createElement('model_list_item')
                 doc_model.setAttribute('checked', str(model[0].GetValue()))
-                keys = model[1].keys()
+                keys = list(model[1].keys())
                 doc_model.setAttribute('name', str(keys[0]))
                 values = model[1].get(keys[0])
@@ -964,5 +964,5 @@
         if node.get('version'):
             # Get the version for model conversion purposes
-            x = re.sub('[^\d.]', '', node.get('version'))
+            x = re.sub(r'[^\d.]', '', node.get('version'))
             self.version = tuple(int(e) for e in str.split(x, "."))
             # The tuple must be at least 3 items long
@@ -984,7 +984,7 @@
                 try:
                     self.timestamp = float(entry.get('epoch'))
-                except Exception:
+                except Exception as exc:
                     msg = "PageState.fromXML: Could not"
-                    msg += " read timestamp\n %s" % sys.exc_value
+                    msg += " read timestamp\n %s" % exc
                     logger.error(msg)
 
@@ -1282,5 +1282,5 @@
                         if isinstance(data.run_name, dict):
                             # Note: key order in dict is not guaranteed, so sort
-                            name = data.run_name.keys()[0]
+                            name = list(data.run_name.keys())[0]
                         else:
                             name = data.run_name
Index: src/sas/sascalc/invariant/invariant.py
===================================================================
--- src/sas/sascalc/invariant/invariant.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/invariant/invariant.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -344,5 +344,6 @@
         else:
             A = np.vstack([linearized_data.x / linearized_data.dy, 1.0 / linearized_data.dy]).T
-            (p, residuals, _, _) = np.linalg.lstsq(A, linearized_data.y / linearized_data.dy)
+            p, residuals, _, _ = np.linalg.lstsq(A, linearized_data.y / linearized_data.dy,
+                                                 rcond=None)
 
             # Get the covariance matrix, defined as inv_cov = a_transposed * a
Index: src/sas/sascalc/pr/distance_explorer.py
===================================================================
--- src/sas/sascalc/pr/distance_explorer.py	(revision 959eb0181ad06828a748f04512f953aad5b31659)
+++ src/sas/sascalc/pr/distance_explorer.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -99,8 +99,8 @@
                 results.pos_err.append(pos_err)
                 results.osc.append(osc)
-            except:
+            except Exception as exc:
                 # This inversion failed, skip this D_max value
                 msg = "ExploreDialog: inversion failed for "
-                msg += "D_max=%s\n %s" % (str(d), sys.exc_value)
+                msg += "D_max=%s\n %s" % (str(d), exc)
                 results.errors.append(msg)
 
Index: src/sas/sascalc/pr/fit/expression.py
===================================================================
--- src/sas/sascalc/pr/fit/expression.py	(revision 574adc767a9e86744546f8edd6a23dc4f81914ad)
+++ src/sas/sascalc/pr/fit/expression.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -210,5 +210,5 @@
 
     #print("Function: "+functiondef)
-    exec functiondef in globals,locals
+    exec(functiondef, globals, locals)
     retfn = locals['eval_expressions']
 
Index: src/sas/sascalc/pr/num_term.py
===================================================================
--- src/sas/sascalc/pr/num_term.py	(revision 2469df7fc9ffa047115c5bffe589ed307b12c363)
+++ src/sas/sascalc/pr/num_term.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -182,6 +182,6 @@
                 data_y = np.append(data_y, test_y)
                 data_err = np.append(data_err, err)
-            except:
-                logger.error(sys.exc_value)
+            except Exception as exc:
+                logger.error(exc)
 
     return data_x, data_y, data_err
Index: src/sas/sascalc/realspace/VolumeCanvas.py
===================================================================
--- src/sas/sascalc/realspace/VolumeCanvas.py	(revision 98e3f24eb417c960360e014aae48605345a05266)
+++ src/sas/sascalc/realspace/VolumeCanvas.py	(revision e090ba909aeb28ce2f0504a77e5a800070907873)
@@ -472,5 +472,5 @@
             Return a list of the shapes
         """
-        return self.shapes.keys()
+        return list(self.shapes.keys())
 
     def _addSingleShape(self, shapeDesc):
