1from __future__ import absolute_import, division, print_function 2 3from stripe import util 4from stripe.six.moves.urllib.parse import quote_plus 5 6 7def custom_method(name, http_verb, http_path=None): 8 if http_verb not in ["get", "post", "delete"]: 9 raise ValueError( 10 "Invalid http_verb: %s. Must be one of 'get', 'post' or 'delete'" 11 % http_verb 12 ) 13 if http_path is None: 14 http_path = name 15 16 def wrapper(cls): 17 def custom_method_request(cls, sid, **params): 18 url = "%s/%s/%s" % ( 19 cls.class_url(), 20 quote_plus(util.utf8(sid)), 21 http_path, 22 ) 23 return cls._static_request(http_verb, url, **params) 24 25 existing_method = getattr(cls, name, None) 26 if existing_method is None: 27 setattr(cls, name, classmethod(custom_method_request)) 28 else: 29 # If a method with the same name we want to use already exists on 30 # the class, we assume it's an instance method. In this case, the 31 # new class method is prefixed with `_cls_`, and the original 32 # instance method is decorated with `util.class_method_variant` so 33 # that the new class method is called when the original method is 34 # called as a class method. 35 setattr(cls, "_cls_" + name, classmethod(custom_method_request)) 36 instance_method = util.class_method_variant("_cls_" + name)( 37 existing_method 38 ) 39 setattr(cls, name, instance_method) 40 41 return cls 42 43 return wrapper 44