Как вы имитируете динамически добавляемые методы объектов?

#python

Вопрос:

Я пытаюсь имитировать внешние вызовы API в пакете pyonfleet. Мое желаемое использование-что-то вроде приведенного ниже.

 def get_task(id):
    from onfleet import Onfleet
    api = Onfleet()
    return api.tasks.get(id=id)

with patch('onleet.Onfleet.tasks.get', return_value={}):
    task = get_task(id='...')
 

Проблема tasks в том, что атрибут и его конечные точки API устанавливаются на Onfleet объекте, используемом setattr в его _initialize_resources методе. Из-за этого все мои тесты приводят к ошибке:

Ошибка атрибута: объект типа «Onfleet» не имеет атрибута «задачи».

 class Onfleet(object):
    # Loading config data
    data = Config.data
    # Look up local authentication JSON if no api_key was passed
    if (os.path.isfile(".auth.json")):
        with open(".auth.json") as json_secret_file:
            secret = json.load(json_secret_file)

    def __init__(self, api_key=None):
        self._session = requests.Session()
        # auth takes api_key and api_secret
        self._session.auth = (api_key if api_key else self.secret["API_KEY"], "")
        self._initialize_resources(self._session)

    def auth_test(self):
        path = self.data["URL"]["base_url"]   self.data["URL"]["version"]   self.data["URL"]["auth_test"]
        response = self._session.get(path)
        return response.json()

    def _initialize_resources(self, session):
        resources = self.data["RESOURCES"]
        # Go through the config module to create endpoints
        for endpoint, http_methods in resources.items():
            setattr(self, endpoint, Endpoint(http_methods, session))
 

Как исправить методы на объекте, которые добавляются динамически?

Комментарии:

1. tasks Действительно ли это атрибут класса или атрибут экземпляра? Вам, вероятно, придется поиздеваться Onfleet над собой. Я бы избавил себя от хлопот и переписал get_task , чтобы взять экземпляр Onfleet (или, по крайней мере Onfleet , сам класс) в качестве аргумента, а не заставлять вас прибегать к насмешкам, жестко кодируя ссылку Onfleet .

2. @chepner, да, это атрибут экземпляра. Мне нравится эта идея — спасибо.