Files
MoviePilot/tests/test_object.py
2026-09-28 02:53:00 +08:00

102 lines
2.6 KiB
Python

import functools
import linecache
from app.foundation import reflection
from app.foundation.reflection import ObjectUtils
def test_check_method():
def implemented_function():
return "Hello"
def pass_function():
pass
def docstring_function():
"""This is a docstring."""
def ellipsis_function():
...
def not_implemented_function():
raise NotImplementedError
def not_implemented_function_with_call():
raise NotImplementedError()
async def multiple_lines_async_def(_param1: str,
_param2: str):
pass
def empty_function():
return
assert ObjectUtils.check_method(implemented_function)
assert not ObjectUtils.check_method(pass_function)
assert not ObjectUtils.check_method(docstring_function)
assert not ObjectUtils.check_method(ellipsis_function)
assert not ObjectUtils.check_method(not_implemented_function)
assert not ObjectUtils.check_method(not_implemented_function_with_call)
assert not ObjectUtils.check_method(multiple_lines_async_def)
assert ObjectUtils.check_method(empty_function)
class _Module:
"""模拟模块类:占位方法与已实现方法并存,并经装饰器包装。"""
def placeholder(self):
"""未实现"""
@staticmethod
def _wrap(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@_wrap
def decorated_placeholder(self):
pass
def implemented(self):
return 1
def test_check_method_handles_bound_and_decorated_methods():
module = _Module()
assert not ObjectUtils.check_method(module.placeholder)
assert not ObjectUtils.check_method(module.decorated_placeholder)
assert ObjectUtils.check_method(module.implemented)
def test_check_method_does_not_leave_source_in_linecache():
linecache.clearcache()
def pass_function():
pass
assert not ObjectUtils.check_method(pass_function)
assert __file__ not in linecache.cache
def test_check_method_caches_result_per_code_object(monkeypatch):
calls = []
original = reflection._read_function_source
monkeypatch.setattr(
reflection, "_read_function_source", lambda code: calls.append(code) or original(code)
)
def make():
def pass_function():
pass
return pass_function
# 两个闭包共享同一代码对象,只读取一次源码
first, second = make(), make()
assert not ObjectUtils.check_method(first)
assert not ObjectUtils.check_method(second)
assert calls == [first.__code__]