Dev/Contribution

[RustPython] StopIteration 수정하기

TaeGit 2022. 8. 7. 00:30

Merged PR

  • Fix define_exception! of PyStopIteration to set value of value attribute
 

Fix define_exception! of PyStopIteration to set value of value attribute by tgsong827 · Pull Request #3869 · RustPython/RustPy

 

github.com

 

개요

CPythonStopIteration 클래스 생성자는 하나의 Argument를 받습니다. 그리고 이 Argumentvalue 속성에 할당됩니다.

RustPython에서는 StopIterationvalue를 호출 했을 때 값이 정상적으로 나오지만, value의 값을 수정하려고 하면 에러가 발생하는 현상이었습니다.

 

문제를 해결하기 위해 StopIterationreadonly_getter 확장 구현 제거하고, stop_interation_init() 함수를 구현했습니다.

결과적으로, StopIteration이 생성될 때 Argument 값이 value 속성에 할당될 수 있게 수정하여 문제를 해결했습니다.

 

과정

원인 분석

RustPythonStopIteration 클래스는 extend_exception!() 매크로를 통해 value 속성이 readonly_getset() 확장 구현되어 있었습니다.
value를 호출했을 때 첫번째 Argument를 가져오도록 getter를 구현하는 내용입니다.


이는 value 값을 호출했을 때 정상적으로 값이 나오기 때문에, 마치 value 속성에 값이 할당된 것처럼 보였습니다.
하지만, value에 새로운 값을 할당하려고 하면 에러가 발생했습니다.

 

수정

먼저, value 속성에 값 할당이 불가능하게하는 readonly_getset() 확장 구현을 제거했습니다.

value를 호출했을 때 첫번째 인자를 가져오는 getter 구현이 사라졌습니다.


다음으로, 원인 분석에서 언급했듯이 value에 실제 값을 할당하기 위해 define_exception()! 매크로에 초기화 함수를 추가했습니다.

결과적으로, StopIteration 생성 시 첫번째 인자 값이 value 속성에 할당되도록 변경했고,
readonly_getset의 확장 구현을 제거해, value 값 변경이 가능하게 했습니다.

 

해당 이슈의 테스트 케이스는 통과했지만, 전체 테스트 수행 시 기존에 성공하던 3개의 파일에서 실패 케이스가 나타났습니다.

  • 테스트 코드
    test_yield_from.pytest_**value**_attriute_of_StopIteration_exception

 

사이드이펙트 분석

문제는 새롭게 추가한 stop_iteration_init() 함수를 타지 않는 케이스에서 발생했습니다.
즉, StopIteration을 사용하는 다른 곳이 있었고, readonly_getset 확장 구현을 제거했기 때문에 value 값을 가져 오지 못해 실패하는 것이었습니다.

 

사이드이펙트 수정

분석한 내용대로, StopIteration을 사용하는 다른 곳에서 생성시 value 값을 할당해주는 로직이 필요했습니다.

 

vm_new.rs 파일의 new_stop_iteration() 에서도 사용하고 있었고,

마찬가지로, 생성 시 첫번째 인자 값을 value 속성에 할당하는 로직을 추가해 문제를 해결할 수 있었습니다.

 

결과적으로, 전체 테스트 케이스를 통과했고, PR CI도 정상적으로 통과되어 Merge될 수 있었습니다.