1

Below is my code and it works with python 2 and not with python 3, minor changes have been added to make syntax compaitable with python3. Please help with this. ANd i get the error as

TypeError: get() missing 1 required positional argument: 'self'

import collections
from types import MethodType

_ApiMethod = collections.namedtuple('_ApiMethod', ['name', 'path', 'http_method', 'query_params'])

API = [
    _ApiMethod('print_hello', 'api/hello', "GET", ['limit']),

]

class HelloClient(object):

    def __repr__(self):
        return "HelloClient(%s)" % ', '.join('%s=%s' % (a, repr(getattr(self, a))) for a in ['url', 'headers'])

    def get(self, path,query_params=None, headers=None, **kwargs):

        return "I am Hello Get Method"


def _add_methods():

    def _build_method(path, http_method, expected_query_params):

        if http_method == "GET":

            def _method(self, **kwargs):
                query_params = kwargs.setdefault('query_params', {})
                query_params.update({qp: kwargs[qp] for qp in expected_query_params if qp in kwargs})
                return self.get(path=path, **kwargs)

        return _method

    for api_method in API:        
        setattr(HelloClient, api_method.name, MethodType(_build_method(api_method.path, api_method.http_method, api_method.query_params or []), HelloClient))

_add_methods()

and i would call this method as

client = HelloClient()
response = client.print_hello()
2
  • You are adding the method to the class object. I could not find a way to add an instance method to the class, so I used metaclasses, as you can see from gist.github.com/fcracker79/bec718d0214db7c1b7bb67b31e1c605a Commented Jan 3, 2019 at 8:36
  • Thanks for the suggestion Commented Jan 3, 2019 at 9:11

1 Answer 1

4

The main issue here is that you are mixing the old unbound methods from python 2 which were dropped in python 3. Since python 3 classes no longer expose their function as unbound methods, running the following snippet:

class A:
  def f(self):
    pass

type(A.f)

Gives function in python 3 and <type 'instancemethod'> in python2. With this simplification in python 3 classes no longer have the correct mechanism to deal with MethodType as you'd expect.

The solution would be to just add a simple function (_build_method result) to the class.


The solution in this specific case would be changing:

setattr(HelloClient, api_method.name, MethodType(_build_method(api_method.path, api_method.http_method, api_method.query_params or []), HelloClient)

into:

setattr(HelloClient, api_method.name, _build_method(api_method.path, api_method.http_method, api_method.query_params or [])
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the info. Bit confused with this, please help with an example and will be really helpful

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.