diff --git a/doc/source/conf.py b/doc/source/conf.py
index 98d2c401804651380e27101374ef1fe6a917cc47..8514d0db295d6641493ce69f077c7c25e9c03cf8 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -42,8 +42,8 @@ source_suffix = '.rst'
 master_doc = 'index'
 
 # General information about the project.
-project = u'Kwant'
-copyright = u'2011-2015, C. W. Groth (CEA), M. Wimmer, A. R. Akhmerov, X. Waintal (CEA), and others'
+project = 'Kwant'
+copyright = '2011-2015, C. W. Groth (CEA), M. Wimmer, A. R. Akhmerov, X. Waintal (CEA), and others'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -208,7 +208,7 @@ r"""\makeatletter
 # We use "et al." as it is shorter and there's not much space left horizontally.
 latex_documents = [
   ('index', 'kwant.tex', 'Kwant {0} documentation'.format(release),
-   u'C. W. Groth, M. Wimmer, A. R. Akhmerov, X. Waintal, et al.',
+   'C. W. Groth, M. Wimmer, A. R. Akhmerov, X. Waintal, et al.',
    'manual'),
 ]
 
@@ -249,9 +249,9 @@ class BoundMethodDocumenter(autodoc.FunctionDocumenter):
         # Return True iff `member` is a bound method.  Taken from
         # <http://stackoverflow.com/a/1260881>.
         return (isinstance(member, types.MethodType) and
-                member.im_self is not None and
-                not issubclass(member.im_class, type) and
-                member.im_class is not types.ClassType)
+                member.__self__ is not None and
+                not issubclass(member.__self__.__class__, type) and
+                member.__self__.__class__ is not type)
 
     def format_args(self):
         args = super(BoundMethodDocumenter, self).format_args()
diff --git a/doc/source/tutorial/ab_ring.py b/doc/source/tutorial/ab_ring.py
index 5df7ecda6ef7f2331fc46b0756d7e5f5104cb126..33de87fbee803011e1222787d67577d95840e740 100644
--- a/doc/source/tutorial/ab_ring.py
+++ b/doc/source/tutorial/ab_ring.py
@@ -118,7 +118,7 @@ def main():
 
     # We should see a conductance that is periodic with the flux quantum
     plot_conductance(sys, energy=0.15, fluxes=[0.01 * i * 3 * 2 * pi
-                                                for i in xrange(100)])
+                                                for i in range(100)])
 
 
 # Call the main function if the script gets executed (as opposed to imported).
diff --git a/doc/source/tutorial/band_structure.py b/doc/source/tutorial/band_structure.py
index ddb9976482783bee6d5d8781d4f2a5d95ab7190c..5b223d3e96f0f474e7b684f2eae779c160698388 100644
--- a/doc/source/tutorial/band_structure.py
+++ b/doc/source/tutorial/band_structure.py
@@ -24,7 +24,7 @@ def make_lead(a=1, t=1.0, W=10):
 
     # build up one unit cell of the lead, and add the hoppings
     # to the next unit cell
-    for j in xrange(W):
+    for j in range(W):
         lead[lat(0, j)] = 4 * t
 
         if j > 0:
diff --git a/doc/source/tutorial/closed_system.py b/doc/source/tutorial/closed_system.py
index 2f54bf046023d678ec9d47873c0c238bccccb077..49d2dc1d460252bde38bf2499190958947a2d01e 100644
--- a/doc/source/tutorial/closed_system.py
+++ b/doc/source/tutorial/closed_system.py
@@ -106,7 +106,7 @@ def main():
     try:
         # We should observe energy levels that flow towards Landau
         # level energies with increasing magnetic field.
-        plot_spectrum(sys, [iB * 0.002 for iB in xrange(100)])
+        plot_spectrum(sys, [iB * 0.002 for iB in range(100)])
 
         # Plot an eigenmode of a circular dot. Here we create a larger system for
         # better spatial resolution.
@@ -114,8 +114,8 @@ def main():
         plot_wave_function(sys)
     except ValueError as e:
         if e.message == "Input matrix is not real-valued.":
-            print "The calculation of eigenvalues failed because of a bug in SciPy 0.9."
-            print "Please upgrade to a newer version of SciPy."
+            print("The calculation of eigenvalues failed because of a bug in SciPy 0.9.")
+            print("Please upgrade to a newer version of SciPy.")
         else:
             raise
 
diff --git a/doc/source/tutorial/graphene.py b/doc/source/tutorial/graphene.py
index cd0ec2e6939cbd2a54bf7ff87a6e444d0ac34126..31f2c578501323a16983b698e9776a7545c30fff 100644
--- a/doc/source/tutorial/graphene.py
+++ b/doc/source/tutorial/graphene.py
@@ -10,7 +10,6 @@
 #  - Application of all the aspects of tutorials 1-3 to a more complicated
 #    lattice, namely graphene
 
-from __future__ import division  # so that 1/2 == 0.5, and not 0
 from math import pi, sqrt, tanh
 
 import kwant
@@ -102,7 +101,7 @@ def compute_evs(sys):
     sparse_mat = sys.hamiltonian_submatrix(sparse=True)
 
     evs = sla.eigs(sparse_mat, 2)[0]
-    print evs.real
+    print(evs.real)
 #HIDDEN_END_zydk
 
 
@@ -166,11 +165,11 @@ def main():
     sys = sys.finalized()
 
     # Compute the band structure of lead 0.
-    momenta = [-pi + 0.02 * pi * i for i in xrange(101)]
+    momenta = [-pi + 0.02 * pi * i for i in range(101)]
     plot_bandstructure(sys.leads[0], momenta)
 
     # Plot conductance.
-    energies = [-2 * pot + 4. / 50. * pot * i for i in xrange(51)]
+    energies = [-2 * pot + 4. / 50. * pot * i for i in range(51)]
     plot_conductance(sys, energies)
 
 
diff --git a/doc/source/tutorial/quantum_well.py b/doc/source/tutorial/quantum_well.py
index 76ab616624bba5a5cf7cf30254ae9eef6745a102..98309437c614b47418846c04dc7e8167d3a2168b 100644
--- a/doc/source/tutorial/quantum_well.py
+++ b/doc/source/tutorial/quantum_well.py
@@ -43,7 +43,7 @@ def make_system(a=1, t=1.0, W=10, L=30, L_well=10):
 
     #### Define and attach the leads. ####
     lead = kwant.Builder(kwant.TranslationalSymmetry((-a, 0)))
-    lead[(lat(0, j) for j in xrange(W))] = 4 * t
+    lead[(lat(0, j) for j in range(W))] = 4 * t
     lead[lat.neighbors()] = -t
     sys.attach_lead(lead)
     sys.attach_lead(lead.reversed())
@@ -79,7 +79,7 @@ def main():
 
     # We should see conductance steps.
     plot_conductance(sys, energy=0.2,
-                     welldepths=[0.01 * i for i in xrange(100)])
+                     welldepths=[0.01 * i for i in range(100)])
 
 
 # Call the main function if the script gets executed (as opposed to imported).
diff --git a/doc/source/tutorial/quantum_wire.py b/doc/source/tutorial/quantum_wire.py
index d4d89956c27d9bb322b99660135e2bda1273986c..b32072123c2f65b492c6f5588103ad26cec3f55b 100644
--- a/doc/source/tutorial/quantum_wire.py
+++ b/doc/source/tutorial/quantum_wire.py
@@ -35,8 +35,8 @@ L = 30
 
 # Define the scattering region
 
-for i in xrange(L):
-    for j in xrange(W):
+for i in range(L):
+    for j in range(W):
         # On-site Hamiltonian
         sys[lat(i, j)] = 4 * t
 
@@ -59,7 +59,7 @@ left_lead = kwant.Builder(sym_left_lead)
 #HIDDEN_END_xcmc
 
 #HIDDEN_BEGIN_ndez
-for j in xrange(W):
+for j in range(W):
     left_lead[lat(0, j)] = 4 * t
     if j > 0:
         left_lead[lat(0, j), lat(0, j - 1)] = -t
@@ -75,7 +75,7 @@ sys.attach_lead(left_lead)
 sym_right_lead = kwant.TranslationalSymmetry((a, 0))
 right_lead = kwant.Builder(sym_right_lead)
 
-for j in xrange(W):
+for j in range(W):
     right_lead[lat(0, j)] = 4 * t
     if j > 0:
         right_lead[lat(0, j), lat(0, j - 1)] = -t
@@ -98,7 +98,7 @@ sys = sys.finalized()
 #HIDDEN_BEGIN_buzn
 energies = []
 data = []
-for ie in xrange(100):
+for ie in range(100):
     energy = ie * 0.01
 
     # compute the scattering matrix at a given energy
diff --git a/doc/source/tutorial/quantum_wire_revisited.py b/doc/source/tutorial/quantum_wire_revisited.py
index c42912ce10636e3d0f4a08d7015ef60b7df1487c..e21341576d0ed53807c46020ed763eec4cb547cc 100644
--- a/doc/source/tutorial/quantum_wire_revisited.py
+++ b/doc/source/tutorial/quantum_wire_revisited.py
@@ -39,7 +39,7 @@ def make_system(a=1, t=1.0, W=10, L=30):
     # Construct the left lead.
 #HIDDEN_BEGIN_iepx
     lead = kwant.Builder(kwant.TranslationalSymmetry((-a, 0)))
-    lead[(lat(0, j) for j in xrange(W))] = 4 * t
+    lead[(lat(0, j) for j in range(W))] = 4 * t
     lead[lat.neighbors()] = -t
 #HIDDEN_END_iepx
 
@@ -79,7 +79,7 @@ def main():
     sys = sys.finalized()
 
     # We should see conductance steps.
-    plot_conductance(sys, energies=[0.01 * i for i in xrange(100)])
+    plot_conductance(sys, energies=[0.01 * i for i in range(100)])
 #HIDDEN_END_cjel
 
 
diff --git a/doc/source/tutorial/spin_orbit.py b/doc/source/tutorial/spin_orbit.py
index 0112d3feb9874e184303327555c4c19c0898fdcb..e9d3f7f4ff73764c3c236d58ce3f60c6b3edab75 100644
--- a/doc/source/tutorial/spin_orbit.py
+++ b/doc/source/tutorial/spin_orbit.py
@@ -55,7 +55,7 @@ def make_system(a=1, t=1.0, alpha=0.5, e_z=0.08, W=10, L=30):
     lead = kwant.Builder(kwant.TranslationalSymmetry((-a, 0)))
 
 #HIDDEN_BEGIN_yliu
-    lead[(lat(0, j) for j in xrange(W))] = 4 * t * sigma_0 + e_z * sigma_z
+    lead[(lat(0, j) for j in range(W))] = 4 * t * sigma_0 + e_z * sigma_z
     # hoppings in x-direction
     lead[kwant.builder.HoppingKind((1, 0), lat, lat)] = \
         -t * sigma_0 - 1j * alpha * sigma_y
@@ -95,7 +95,7 @@ def main():
     sys = sys.finalized()
 
     # We should see non-monotonic conductance steps.
-    plot_conductance(sys, energies=[0.01 * i - 0.3 for i in xrange(100)])
+    plot_conductance(sys, energies=[0.01 * i - 0.3 for i in range(100)])
 
 
 # Call the main function if the script gets executed (as opposed to imported).
diff --git a/doc/source/tutorial/superconductor_band_structure.py b/doc/source/tutorial/superconductor_band_structure.py
index 9f8da5e274daf2dbd884a69099889772ac1cefd6..6a7928363e420abbee4f24c56ac14ebeebe4dcf5 100644
--- a/doc/source/tutorial/superconductor_band_structure.py
+++ b/doc/source/tutorial/superconductor_band_structure.py
@@ -35,7 +35,7 @@ def make_lead(a=1, t=1.0, mu=0.7, Delta=0.1, W=10):
 
     # build up one unit cell of the lead, and add the hoppings
     # to the next unit cell
-    for j in xrange(W):
+    for j in range(W):
         lead[lat(0, j)] = (4 * t - mu) * tau_z + Delta * tau_x
 
         if j > 0:
diff --git a/doc/source/tutorial/superconductor_transport.py b/doc/source/tutorial/superconductor_transport.py
index 505479e28a1989bd94521105d0bb90a70ce88cd6..a8184c95f3b4c5de4ce27855f7bb55fc360d994c 100644
--- a/doc/source/tutorial/superconductor_transport.py
+++ b/doc/source/tutorial/superconductor_transport.py
@@ -55,12 +55,12 @@ def make_system(a=1, W=10, L=10, barrier=1.5, barrierpos=(3, 4),
 
     # left electron lead
     lead0 = kwant.Builder(sym_left)
-    lead0[(lat_e(0, j) for j in xrange(W))] = 4 * t - mu
+    lead0[(lat_e(0, j) for j in range(W))] = 4 * t - mu
     lead0[lat_e.neighbors()] = -t
 
     # left hole lead
     lead1 = kwant.Builder(sym_left)
-    lead1[(lat_h(0, j) for j in xrange(W))] = mu - 4 * t
+    lead1[(lat_h(0, j) for j in range(W))] = mu - 4 * t
     lead1[lat_h.neighbors()] = t
 #HIDDEN_END_ttth
 
@@ -72,7 +72,7 @@ def make_system(a=1, W=10, L=10, barrier=1.5, barrierpos=(3, 4),
     lead2 = kwant.Builder(sym_right)
     lead2 += lead0
     lead2 += lead1
-    lead2[((lat_e(0, j), lat_h(0, j)) for j in xrange(W))] = Delta
+    lead2[((lat_e(0, j), lat_h(0, j)) for j in range(W))] = Delta
 #HIDDEN_END_mhiw
 
     #### Attach the leads and return the system. ####
@@ -113,7 +113,7 @@ def main():
     # Finalize the system.
     sys = sys.finalized()
 
-    plot_conductance(sys, energies=[0.002 * i for i in xrange(100)])
+    plot_conductance(sys, energies=[0.002 * i for i in range(100)])
 
 
 # Call the main function if the script gets executed (as opposed to imported).