From 35af43352b9d9f609c2cd4cfed8e4455d957d6e2 Mon Sep 17 00:00:00 2001 From: Joseph Weston <joseph.weston@cea.fr> Date: Fri, 7 Aug 2015 19:43:00 +0200 Subject: [PATCH] add workaround for Python 3's lack of unbound methods Unbound methods are not longer a thing in Python 3 [1]. Instead, functions use the descriptor protocol [2] to properly bind the `self` argument if they are being called as a method. Cython functions do not have a `__get__` attribute and so don't satisfy the descriptor protocol. They therefore can't be used as methods. As a workaround we create a wrapper class with the proper __get__ method. The advantage of this over creating a Python wrapper is that the function signature is preserved. [1]: https://docs.python.org/3.0/whatsnew/3.0.html [2]: https://docs.python.org/3/howto/descriptor.html --- kwant/_system.pyx | 11 +++++++++++ kwant/system.py | 3 +-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/kwant/_system.pyx b/kwant/_system.pyx index dc3e665d..396b9175 100644 --- a/kwant/_system.pyx +++ b/kwant/_system.pyx @@ -11,6 +11,7 @@ import tinyarray as ta import numpy as np from scipy import sparse as sp from itertools import chain +import types from .graph.core cimport CGraph, gintArraySlice from .graph.defs cimport gint @@ -327,3 +328,13 @@ def hamiltonian_submatrix(self, args=(), to_sites=None, from_sites=None, mat = func(ham, args, self.graph, diag, from_sites, n_by_to_site, to_norb, to_off, from_norb, from_off) return (mat, to_norb, from_norb) if return_norb else mat + +# workaround for Cython functions not having __get__ and +# Python 3 getting rid of unbound methods +cdef class HamiltonianSubmatrix: + + def __get__(self, obj, objtype): + if obj is None: + return hamiltonian_submatrix + else: + return types.MethodType(hamiltonian_submatrix, obj) diff --git a/kwant/system.py b/kwant/system.py index ec68b9bf..45d0b473 100644 --- a/kwant/system.py +++ b/kwant/system.py @@ -48,8 +48,7 @@ class System(object, metaclass=abc.ABCMeta): pass # Add a C-implemented function as an unbound method to class System. -System.hamiltonian_submatrix = types.MethodType( - _system.hamiltonian_submatrix, None, System) +System.hamiltonian_submatrix = _system.HamiltonianSubmatrix() class FiniteSystem(System, metaclass=abc.ABCMeta): -- GitLab