Index: extra/pylint.rc
===================================================================
--- extra/pylint.rc	(revision 803f8354f3fdd4c40b749b45e39404acb013d66b)
+++ extra/pylint.rc	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -10,5 +10,5 @@
 
 # Profiled execution.
-profile=no
+#profile=no
 
 # Add files or directories to the blacklist. They should be base names, not
@@ -92,5 +92,5 @@
 # Add a comment according to your evaluation note. This is used by the global
 # evaluation report (RP0004).
-comment=no
+#comment=no
 
 # Template used to display messages. This is a python new-style format string
@@ -101,5 +101,5 @@
 
 # Required attributes for module, separated by a comma
-required-attributes=
+#required-attributes=
 
 # List of builtins function names that should not be used, separated by a comma
@@ -280,5 +280,6 @@
 # (useful for modules/projects where namespaces are manipulated during runtime
 # and thus existing member attributes cannot be deduced by static analysis
-ignored-modules=numpy,np
+ignored-modules=numpy,np,numpy.random,
+    bumps,sas,
 
 # List of classes names for which member attributes should not be checked
@@ -288,5 +289,5 @@
 # When zope mode is activated, add a predefined set of Zope acquired attributes
 # to generated-members.
-zope=no
+#zope=no
 
 # List of members which are set dynamically and missed by pylint inference
@@ -318,5 +319,5 @@
 # List of interface methods to ignore, separated by a comma. This is used for
 # instance to not check methods defines in Zope's Interface base class.
-ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+#ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
 
 # List of method names used to declare (i.e. assign) instance attributes.
Index: extra/pylint_numpy.py
===================================================================
--- extra/pylint_numpy.py	(revision 63b32bbc85e7dea7a022cf604ac020dee56d7a88)
+++ extra/pylint_numpy.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -8,5 +8,8 @@
     #print("processing",module.name)
     if module.name.startswith('numpy'):
-        if module.name == 'numpy':  import numpy
-        elif module.name == 'numpy.random': import numpy.random
+        if module.name == 'numpy':
+            import numpy
+        elif module.name == 'numpy.random':
+            import numpy.random
+            from numpy.random import seed, get_state, set_state
 
Index: extra/pylint_pyopencl.py
===================================================================
--- extra/pylint_pyopencl.py	(revision 3c56da87f0995bdde77f4183b68e77b81584dde0)
+++ extra/pylint_pyopencl.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -9,2 +9,3 @@
     if module.name == 'pyopencl':
         import pyopencl
+        import pyopencl as cl
Index: extra/run-pylint.py
===================================================================
--- extra/run-pylint.py	(revision f01e53d5a96b16346f85048d4f125bc41f154611)
+++ extra/run-pylint.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -6,11 +6,21 @@
 
 def main():
+    extra = abspath(dirname(__file__))
+    root = abspath(joinpath(extra, '..'))
+
     envpath = os.environ.get('PYTHONPATH',None)
     path = [envpath] if envpath else []
-    path.append(abspath(dirname(__file__))) # so we can find the plugins
+    path.append(extra)
+
+    #bumps = abspath(joinpath(root, "..", "bumps"))
+    #periodictable = abspath(joinpath(root, "..", "periodictable"))
+    #sasview = abspath(joinpath(root, "..", "sasview", "src"))
+    #path.extend((bumps, periodictable, sasview))
+
     os.environ['PYTHONPATH'] = ':'.join(path)
-    root = abspath(joinpath(dirname(__file__), '..'))
+
+    # Run the lint command
+    cmd = "pylint --rcfile extra/pylint.rc -f parseable sasmodels"
     os.chdir(root)
-    cmd = "pylint --rcfile extra/pylint.rc -f parseable sasmodels"
     status = os.system(cmd)
     sys.exit(status)
Index: sasmodels/exception.py
===================================================================
--- sasmodels/exception.py	(revision eaca9ebe6d0022b8ac658c30e21ef334fb4f3861)
+++ sasmodels/exception.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -8,4 +8,7 @@
 except NameError:
     class WindowsError(Exception):
+        """
+        Fake WindowsException when not on Windows.
+        """
         pass
 
@@ -31,5 +34,5 @@
     # TODO: try to incorporate current stack trace in the raised exception
     if isinstance(exc, WindowsError):
-        raise OSError(str(exc)+" "+msg)
+        raise OSError(str(exc) + " " + msg)
 
     args = exc.args
@@ -38,6 +41,6 @@
     else:
         try:
-            arg0 = " ".join((args[0],msg))
+            arg0 = " ".join((args[0], msg))
             exc.args = tuple([arg0] + list(args[1:]))
         except:
-            exc.args = (" ".join((str(exc),msg)),)
+            exc.args = (" ".join((str(exc), msg)),)
Index: sasmodels/generate.py
===================================================================
--- sasmodels/generate.py	(revision 190fc2b167d3d89ca9c3b7d3128bdf8bde9f67d0)
+++ sasmodels/generate.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -7,5 +7,5 @@
     particular dimensions averaged over all orientations.
 
-    *Iqxy(qx, qy, p1, p2, ...)* returns the scattering at qx,qy for a form
+    *Iqxy(qx, qy, p1, p2, ...)* returns the scattering at qx, qy for a form
     with particular dimensions for a single orientation.
 
@@ -47,5 +47,5 @@
 the *sin* and *cos* values are needed for a particular argument.  Since
 this function does not exist in C99, all use of *sincos* should be
-replaced by the macro *SINCOS(value,sn,cn)* where *sn* and *cn* are
+replaced by the macro *SINCOS(value, sn, cn)* where *sn* and *cn* are
 previously declared *double* variables.  When compiled for systems without
 OpenCL, *SINCOS* will be replaced by *sin* and *cos* calls.   If *value* is
@@ -194,4 +194,5 @@
 returns a list of files required by the model.
 """
+from __future__ import print_function
 
 # TODO: identify model files which have changed since loading and reload them.
@@ -372,9 +373,9 @@
 
 
-def kernel_name(info, is_2D):
+def kernel_name(info, is_2d):
     """
     Name of the exported kernel symbol.
     """
-    return info['name'] + "_" + ("Iqxy" if is_2D else "Iq")
+    return info['name'] + "_" + ("Iqxy" if is_2d else "Iq")
 
 
@@ -419,15 +420,15 @@
 
 
-def build_polydispersity_loops(pd_pars):
-    """
-    Build polydispersity loops
-
-    Returns loop opening and loop closing
-    """
-    LOOP_OPEN = """\
+LOOP_OPEN = """\
 for (int %(name)s_i=0; %(name)s_i < N%(name)s; %(name)s_i++) {
   const double %(name)s = loops[2*(%(name)s_i%(offset)s)];
   const double %(name)s_w = loops[2*(%(name)s_i%(offset)s)+1];\
 """
+def build_polydispersity_loops(pd_pars):
+    """
+    Build polydispersity loops
+
+    Returns loop opening and loop closing
+    """
     depth = 4
     offset = ""
@@ -572,9 +573,9 @@
 
     #for d in defines: print(d)
-    DEFINES = '\n'.join('#define %s %s' % (k, v) for k, v in defines)
-    SOURCES = '\n\n'.join(source)
+    defines = '\n'.join('#define %s %s' % (k, v) for k, v in defines)
+    sources = '\n\n'.join(source)
     return C_KERNEL_TEMPLATE % {
-        'DEFINES':DEFINES,
-        'SOURCES':SOURCES,
+        'DEFINES': defines,
+        'SOURCES': sources,
         }
 
@@ -590,5 +591,5 @@
     demo_parameters = getattr(kernel_module, 'demo', None)
     if demo_parameters is None:
-        demo_parameters = dict((p[0],p[2]) for p in parameters)
+        demo_parameters = dict((p[0], p[2]) for p in parameters)
     filename = abspath(kernel_module.__file__)
     kernel_id = splitext(basename(filename))[0]
@@ -597,5 +598,5 @@
         name = " ".join(w.capitalize() for w in kernel_id.split('_'))
     info = dict(
-        id = kernel_id,  # string used to load the kernel
+        id=kernel_id,  # string used to load the kernel
         filename=abspath(kernel_module.__file__),
         name=name,
@@ -643,5 +644,5 @@
         elif section_marker.match(line):
             if len(line) >= len(prior):
-                yield "".join( ("**",prior,"**") )
+                yield "".join(("**", prior, "**"))
                 prior = None
             else:
Index: sasmodels/kernelcl.py
===================================================================
--- sasmodels/kernelcl.py	(revision cde11f0f857d1861f37ded681777699e3aa91738)
+++ sasmodels/kernelcl.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -241,5 +241,5 @@
         self.info = info
         self.source = source
-        self.dtype = generate.F32 if dtype=='fast' else np.dtype(dtype)
+        self.dtype = generate.F32 if dtype == 'fast' else np.dtype(dtype)
         self.fast = (dtype == 'fast')
         self.program = None # delay program creation
Index: sasmodels/kerneldll.py
===================================================================
--- sasmodels/kerneldll.py	(revision 74667d322dd33e8f42805e77bc688d1a9a99b4fa)
+++ sasmodels/kerneldll.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -122,5 +122,5 @@
     models are allowed as DLLs.
     """
-    if callable(info.get('Iq',None)):
+    if callable(info.get('Iq', None)):
         return PyModel(info)
 
@@ -140,10 +140,10 @@
     source = generate.convert_type(source, dtype)
     source_files = generate.sources(info) + [info['filename']]
-    dll= dll_path(info, dtype)
+    dll = dll_path(info, dtype)
     newest = max(os.path.getmtime(f) for f in source_files)
-    if not os.path.exists(dll) or os.path.getmtime(dll)<newest:
+    if not os.path.exists(dll) or os.path.getmtime(dll) < newest:
         # Replace with a proper temp file
-        fid, filename = tempfile.mkstemp(suffix=".c",prefix=tempfile_prefix)
-        os.fdopen(fid,"w").write(source)
+        fid, filename = tempfile.mkstemp(suffix=".c", prefix=tempfile_prefix)
+        os.fdopen(fid, "w").write(source)
         command = COMPILE%{"source":filename, "output":dll}
         print("Compile command: "+command)
@@ -160,5 +160,5 @@
 def load_dll(source, info, dtype="double"):
     """
-    Create and load a dll corresponding to the source,info pair returned
+    Create and load a dll corresponding to the source, info pair returned
     from :func:`sasmodels.generate.make` compiled for the target precision.
 
@@ -199,5 +199,5 @@
         Npd2d = len(self.info['partype']['pd-2d'])
 
-        #print("dll",self.dllpath)
+        #print("dll", self.dllpath)
         try:
             self.dll = ct.CDLL(self.dllpath)
@@ -210,5 +210,5 @@
               else c_longdouble)
         pd_args_1d = [c_void_p, fp] + [c_int]*Npd1d if Npd1d else []
-        pd_args_2d= [c_void_p, fp] + [c_int]*Npd2d if Npd2d else []
+        pd_args_2d = [c_void_p, fp] + [c_int]*Npd2d if Npd2d else []
         self.Iq = self.dll[generate.kernel_name(self.info, False)]
         self.Iq.argtypes = IQ_ARGS + pd_args_1d + [fp]*Nfixed1d
@@ -257,5 +257,5 @@
 
     The resulting call method takes the *pars*, a list of values for
-    the fixed parameters to the kernel, and *pd_pars*, a list of (value,weight)
+    the fixed parameters to the kernel, and *pd_pars*, a list of (value, weight)
     vectors for the polydisperse parameters.  *cutoff* determines the
     integration limits: any points with combined weight less than *cutoff*
Index: sasmodels/list_pars.py
===================================================================
--- sasmodels/list_pars.py	(revision 1d4017acdee637c269c7cb48bf160858361f4128)
+++ sasmodels/list_pars.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -31,5 +31,5 @@
         print(columnize(list(sorted(partable.keys()))))
     else:
-        for k,v in sorted(partable.items()):
+        for k, v in sorted(partable.items()):
             print("%s: %s"%(k, ", ".join(v)))
 
Index: sasmodels/model_test.py
===================================================================
--- sasmodels/model_test.py	(revision 9404dd3f599fcbe72790aae8a6d176e64f292ea6)
+++ sasmodels/model_test.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -9,5 +9,5 @@
     if model1 is 'all', then all except the remaining models will be tested
 
-Each model is tested using the default parameters at q=0.1, (qx,qy)=(0.1,0.1),
+Each model is tested using the default parameters at q=0.1, (qx, qy)=(0.1, 0.1),
 and the ER and VR are computed.  The return values at these points are not
 considered.  The test is only to verify that the models run to completion,
@@ -30,5 +30,5 @@
         [ {parameters}, (qx, qy), I(qx, Iqy)],
         [ {parameters}, [(qx1, qy1), (qx2, qy2), ...],
-                        [I(qx1,qy1), I(qx2,qy2), ...]],
+                        [I(qx1, qy1), I(qx2, qy2), ...]],
 
         [ {parameters}, 'ER', ER(pars) ],
@@ -75,5 +75,5 @@
         # don't try to call cl kernel since it will not be
         # available in some environmentes.
-        is_py = callable(getattr(model_definition,'Iq', None))
+        is_py = callable(getattr(model_definition, 'Iq', None))
 
         if is_py:  # kernel implemented in python
@@ -123,8 +123,8 @@
         def _runTest(self):
             smoke_tests = [
-                [{},0.1,None],
-                [{},(0.1,0.1),None],
-                [{},'ER',None],
-                [{},'VR',None],
+                [{}, 0.1, None],
+                [{}, (0.1, 0.1), None],
+                [{}, 'ER', None],
+                [{}, 'VR', None],
                 ]
 
@@ -163,5 +163,5 @@
                 actual = [call_VR(model.info, pars)]
             elif isinstance(x[0], tuple):
-                Qx,Qy = zip(*x)
+                Qx, Qy = zip(*x)
                 q_vectors = [np.array(Qx), np.array(Qy)]
                 kernel = make_kernel(model, q_vectors)
@@ -179,10 +179,11 @@
                     # smoke test --- make sure it runs and produces a value
                     self.assertTrue(np.isfinite(actual_yi),
-                        'invalid f(%s): %s' % (xi, actual_yi))
+                                    'invalid f(%s): %s' % (xi, actual_yi))
                 else:
                     err = abs(yi - actual_yi)
                     nrm = abs(yi)
                     self.assertLess(err * 10**5, nrm,
-                        'f(%s); expected:%s; actual:%s' % (xi, yi, actual_yi))
+                                    'f(%s); expected:%s; actual:%s'
+                                    % (xi, yi, actual_yi))
 
     return ModelTestCase
@@ -237,5 +238,5 @@
     Run "nosetests sasmodels" on the command line to invoke it.
     """
-    tests = make_suite(['opencl','dll'],['all'])
+    tests = make_suite(['opencl', 'dll'], ['all'])
     for test_i in tests:
         yield test_i._runTest
Index: sasmodels/resolution.py
===================================================================
--- sasmodels/resolution.py	(revision 190fc2b167d3d89ca9c3b7d3128bdf8bde9f67d0)
+++ sasmodels/resolution.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -14,5 +14,5 @@
            "pinhole_extend_q", "slit_extend_q", "bin_edges",
            "interpolate", "linear_extrapolation", "geometric_extrapolation",
-           ]
+          ]
 
 MINIMUM_RESOLUTION = 1e-8
@@ -80,8 +80,8 @@
         # default to Perfect1D if the pinhole geometry is not defined.
         self.q, self.q_width = q, q_width
-        self.q_calc = pinhole_extend_q(q, q_width, nsigma=nsigma) \
-            if q_calc is None else np.sort(q_calc)
-        self.weight_matrix = pinhole_resolution(self.q_calc,
-                self.q, np.maximum(q_width, MINIMUM_RESOLUTION))
+        self.q_calc = (pinhole_extend_q(q, q_width, nsigma=nsigma)
+                       if q_calc is None else np.sort(q_calc))
+        self.weight_matrix = pinhole_resolution(
+            self.q_calc, self.q, np.maximum(q_width, MINIMUM_RESOLUTION))
 
     def apply(self, theory):
Index: sasmodels/resolution2d.py
===================================================================
--- sasmodels/resolution2d.py	(revision 841753cbac7824298effa1aec88a7ee977eb257f)
+++ sasmodels/resolution2d.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -143,11 +143,11 @@
         if self.coords == 'polar':
             q_r = sqrt(qx**2 + qy**2)
-            qx_res = ((dqx*cos(dphi) + q_r) * cos(-q_phi) +
-                           dqy*sin(dphi) * sin(-q_phi))
-            qy_res = (-(dqx*cos(dphi) + q_r) * sin(-q_phi) +
-                           dqy*sin(dphi) * cos(-q_phi))
+            qx_res = ((dqx*cos(dphi) + q_r) * cos(-q_phi)
+                      + dqy*sin(dphi) * sin(-q_phi))
+            qy_res = (-(dqx*cos(dphi) + q_r) * sin(-q_phi)
+                      + dqy*sin(dphi) * cos(-q_phi))
         else:
-            qx_res = qx +  dqx*cos(dphi)
-            qy_res = qy +  dqy*sin(dphi)
+            qx_res = qx + dqx*cos(dphi)
+            qy_res = qy + dqy*sin(dphi)
 
 
@@ -162,5 +162,5 @@
             theory = np.reshape(theory, (nbins, nq))
             ## Averaging with Gaussian weighting: normalization included.
-            value =np.average(theory, axis=0, weights=self.q_calc_weights)
+            value = np.average(theory, axis=0, weights=self.q_calc_weights)
             ## Return the smeared values in the range of self.index
             return value
Index: sasmodels/weights.py
===================================================================
--- sasmodels/weights.py	(revision 3c56da87f0995bdde77f4183b68e77b81584dde0)
+++ sasmodels/weights.py	(revision 823e6204f35d6c2bf32f27a3a3c137a369a973cf)
@@ -36,5 +36,5 @@
         *center* is the center of the distribution
 
-        *lb*,*ub* are the min and max allowed values
+        *lb*, *ub* are the min and max allowed values
 
         *relative* is True if the distribution width is proportional to the
@@ -84,5 +84,5 @@
     default = dict(npts=80, width=0, nsigmas=8)
     def _weights(self, center, sigma, lb, ub):
-        x = self._linspace(center, sigma, max(lb,1e-8), max(ub,1e-8))
+        x = self._linspace(center, sigma, max(lb, 1e-8), max(ub, 1e-8))
         px = np.exp(-0.5*(np.log(x)-center)**2)/sigma**2/(x*sigma)
         return x, px
@@ -93,6 +93,6 @@
     default = dict(npts=80, width=0, nsigmas=8)
     def _weights(self, center, sigma, lb, ub):
-        x = self._linspace(center, sigma, max(lb,1e-8), max(ub,1e-8))
-        R= x/center
+        x = self._linspace(center, sigma, max(lb, 1e-8), max(ub, 1e-8))
+        R = x/center
         z = (center/sigma)**2
         arg = z*np.log(z) + (z-1)*np.log(R) - R*z - np.log(center) - gammaln(z)
@@ -117,5 +117,5 @@
         # TODO: interpolate into the array dispersion using npts
         x = center + self.values*sigma
-        idx = (x>=lb)&(x<=ub)
+        idx = (x >= lb) & (x <= ub)
         x = x[idx]
         px = self.weights[idx]
@@ -124,5 +124,5 @@
 
 # dispersion name -> disperser lookup table.
-models = dict((d.type,d) for d in (
+models = dict((d.type, d) for d in (
     GaussianDispersion, RectangleDispersion,
     ArrayDispersion, SchulzDispersion, LogNormalDispersion
@@ -149,13 +149,13 @@
     of the parameter, and false if it is an absolute width.
 
-    Returns *(value,weight)*, where *value* and *weight* are vectors.
+    Returns *(value, weight)*, where *value* and *weight* are vectors.
     """
     cls = models[disperser]
     obj = cls(n, width, nsigmas)
-    v,w = obj.get_weights(value, limits[0], limits[1], relative)
-    return v,w
+    v, w = obj.get_weights(value, limits[0], limits[1], relative)
+    return v, w
 
 # Hack to allow sasview dispersion objects to interoperate with sasmodels
-dispersers = dict((v.__name__,k) for k,v in models.items())
+dispersers = dict((v.__name__, k) for k, v in models.items())
 dispersers['DispersionModel'] = RectangleDispersion.type
 
