오픈소스로 알아보는 Monkey Patch

오픈소스로 알아보는 Monkey Patch
Photo by Laura Cros / Unsplash

들어가며

어느날 azure-sdk-for-python의 한 PR 을 살펴보며 Monkey Patch 관련하여 궁금한 내용을 정리해보았습니다. 😄

👉 해당 PR 링크: https://github.com/Azure/azure-sdk-for-python/pull/31265

어떤 점이 궁금했나요?

PR을 쭉 읽어보던 중 아래 내용이 눈에 띄었습니다.

1
PR discussion 중

골자는 다음과 같습니다.

  1. Contributor가 어떤 기능을 개선하기 위해 작업을 진행
  2. 하지만 ServiceRequestError가 발생
  3. Maintainer는 ServiceRequestError를 해결하기 위해 monkey patch를 제안

여기서 바로 monkey patch라는 단어가 등장하는데요, 예전에 전공 수업에서 얼핏 들었던 경험이 있어 무엇인지 궁금하여 더욱 찾아보았습니다.

Monkey Patch란?

Monkey Patch는 런타임에 동적으로 코드를 수정하는 기법을 말합니다. 즉, 원본 소스코드를 변경하지 않고 실행 중인 프로그램의 인스턴스, 메서드 등을 동적으로 변경하는 것을 말합니다. 실제로 Monkey Patch는 테스트 코드 작성에 많이 활용되는데요, 테스트 코드 작성 시 실제 API 호출이 필요한 부분이나, 외부 서비스와의 연동이 필요한 부분을 가짜 객체 혹은 메서드로 대체하여 테스트를 진행할 수 있습니다.

해당 PR에서도 마찬가지로 client의 run 동작은 실제 API 호출이 필요한 부분이기 때문에, API 호출을 대체하는 가짜 메서드를 만드는 방식으로 monkey patch를 활용하였습니다. 관련 코드는 아래와 같습니다.

def patch_run(self, request: HTTPRequestType, **kwargs: Any) -> PipelineResponse[HTTPRequestType, HTTPResponseType]:
    response = Response()
    response.status_code = 405
    response._content = b"<!DOCTYPE html><html><head><title>UnsupportedHttpVerb</title></head><body><h1>The resource doesn't support specified Http Verb.</h1><p><ul><li>HttpStatusCode: 405</li><li>ErrorCode: UnsupportedHttpVerb</li><li>RequestId : 98adf858-a01e-0071-2580-bfe811000000</li><li>TimeStamp : 2023-07-26T05:19:26.9825582Z</li></ul></p></body></html>"
    response.url = 'https://<storage>.z6.web.core.windows.net/$batch'
    response.headers = {
        "x-ms-error-code": "UnsupportedHttpVerb",
        "content-type": "text/html"
    }
    return PipelineResponse(
        http_request=None,
        http_response=RequestsTransportResponse(
            requests_response=response,
            request=None,
        ),
        context=None,
    )


if __name__ == '__main__':
    client = TableClient(
        endpoint="https://<storage>.z6.web.core.windows.net/",
        credential=DefaultAzureCredential(),
        table_name="syncenabled"
    )
    client._client._client._pipeline.run = partial(patch_run, client)
    client.submit_transaction([
        (
            "upsert",
            {
                "PartitionKey": "test-partition",
                "RowKey": "test-key",
                "name": "test-name",
            },
        )
    ])

테스트 환경에서의 client.submit_transaction 동작을 위해 client._client._client._pipeline.run을 사용자가 임의로 정의한 patch_run으로 monkey patch 하였습니다.

이를 통해 client.submit_transaction 동작 시 client._client._client._pipeline.run이 호출되는데, 이는 위에서 정의한 patch_run 메서드를 호출하게 됩니다.

Partial은 또 뭐죠?

Monkey Patch를 수행하는 코드는 다음과 같은데요.

client._client._client._pipeline.run = partial(patch_run, client)

여기서 partial이라는 다소 생소한 함수가 등장합니다.
python의 functools.partial() 은 기존의 함수에서 일부 인자를 고정한 새로운 함수를 생성하는데 사용하는 함수입니다.
아래 코드 예시를 살펴보겠습니다.

from functools import partial

# 일반 함수 사용
def multiply(x, y):
    return x * y

double1 = partial(multiply, 2)
print(double1(4))  # 출력: 8

# 람다 함수 사용
double2 = partial(lambda x, y: x * y, 2)
print(double2(4))  # 출력: 8

partial을 통해 기존 multiply 함수에서 x 인자를 2로 고정한 double 함수를 생성한 것을 확인할 수 있습니다. 이를 통해 새로운 함수를 생성할 때 재사용성을 높일 수 있는 것이죠.

위 PR의 사례에서는 partial을 활용하여 client._client._client._pipeline.run에서 patch_run 메서드를 호출할 때 호출한 client 인자를 고정하여 전달 할 수 있도록 하여, 코드의 재사용성을 높인 것이죠.

오늘은 오픈소스의 PR을 통해 monkey patch 기법에 대해 알아보았습니다. 앞으로도 오픈소스를 통해 새로운 기술과 개념들을 많이 배울 수 있으면 좋겠네요 😄

Read more

[논문 리뷰] Learning Retrieval Augmentation for Personalized Dialogue Generation

[논문 리뷰] Learning Retrieval Augmentation for Personalized Dialogue Generation

이번 시간에는 Personalized dialogue generation을 RAG와 결합하여 시도한 "Learning Retrieval Augmentation for Personalized Dialogue Generation" 논문을 살펴봅니다. 특히 최근에 개인화된 AI가 주목 받고 있는데요, AI가 사용자의 페르소나, 정보, 성격 등을 반영한다면 더욱 풍성하고 도움이 되는 답변을 생성할 수 있습니다. 이를 Personalized dialogue generation이라고 하는데요. 연구팀은 어떻게 해당 문제를

By Yongwoo Song
[독서] 나는 왜 생각이 많을까?

[독서] 나는 왜 생각이 많을까?

✒️발상을 바꿔야 한다. 앞으로는 '불안해하지 말아야지'가 아니라 '불안과 더불어 살아가야지'라고 생각하자.나는 왜 생각이 많을까? | 홋타 슈고 | 서사원- 교보ebook머릿속의 스위치를 끄고 싶을 때 보는 뇌과학 이야기, 심플한 사고법은 아무나 가질 수 없다! 그러나 누구나 해 볼 수 있다! 짧게 생각하고 빠르게 행동하기 위한 필독서!

By Yongwoo Song
[독서] 자기 경영 노트 - 피터 드러커

[독서] 자기 경영 노트 - 피터 드러커

✒️성과를 올리는 모든 사람들은 목표를 달성하기 위한 실행 능력을 갖추고 있다. 이 실행 능력은 기업에서 일하든, 정부기관에서 일하든, 병원의 관리자이든, 대학의 학장이든 똑같다.피터 드러커 자기경영노트 | 피터 드러커 | 한국경제신문- 교보ebook어떻게 ‘성과를 내는 경영 리더’가 되는가 지식작업자를 위한 변화와 혁신의 5가지 법칙! 이 책의 주제는 성과를 내는 능력을 향상시키기 위한

By Yongwoo Song