Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revisit test_mimic_object_member_not_in_class_known_issue() is mimicking of __se... #206

Open
github-actions bot opened this issue Sep 16, 2024 · 0 comments
Labels

Comments

@github-actions
Copy link

implemented. Libraries like Pandas might also graft methods onto instances such as

DataFrames, which will not currently work with Omnipy. Dynamically added member variables

that are not bound methods do work, however.

# TODO: Revisit test_mimic_object_member_not_in_class_known_issue() is mimicking of __setattr__ is

    assert model.func.called is False


# TODO: Revisit test_mimic_object_member_not_in_class_known_issue() is mimicking of __setattr__ is
#       implemented. Libraries like Pandas might also graft methods onto instances such as
#       DataFrames, which will not currently work with Omnipy. Dynamically added member variables
#       that are not bound methods do work, however.
@pytest.mark.skipif(
    os.getenv('OMNIPY_FORCE_SKIPPED_TEST') != '1',
    reason="""
Known issue due to validation of the model contents before the calling of the method when
interactive_mode is set to True. Since the method is grafted onto the specific model instance, it
is bound to that instance only. However, validation shallow-copies the instance, including the
method, but does not rebind the method to the new instance. The result is that the method is
called on the old instance, and not the new one.

Conclusion: avoid grafting methods onto models instances. Dynamically grafting methods is in any
case an advanced operation and does not follow Python best practices. Grafting instance variables
or unbound methods should work as expected, see test_mimic_dynamically_bound_instance_variable.
""")
def test_mimic_dynamically_bound_instance_method_known_issue(
        runtime: Annotated[IsRuntime, pytest.fixture]) -> None:
    class MyClass:
        def __init__(self) -> None:
            self.called = False

    my_obj = MyClass()
    my_obj.method = MethodType(  # type: ignore[attr-defined]
        lambda self: setattr(self, 'called', True), my_obj)

    model = Model[MyClass](my_obj)
    assert model.called is False

    model.method()

    if runtime.config.data.interactive_mode:
        assert (my_obj.called, model.called) == (False, True)
    else:
        assert (my_obj.called, model.called) == (True, True)


def test_mimic_dynamically_bound_instance_variable(
        runtime: Annotated[IsRuntime, pytest.fixture]) -> None:
    class MyClass:
        def toggle_if_available(self) -> None:
            if hasattr(self, 'toggle'):
                self.toggle = not self.toggle  # type: ignore[has-type]

    my_obj = MyClass()
    my_obj.toggle = False

    model = Model[MyClass](my_obj)
    assert model.toggle is False

    model.toggle_if_available()

    if runtime.config.data.interactive_mode:
        assert (my_obj.toggle, model.toggle) == (False, True)
    else:
        assert (my_obj.toggle, model.toggle) == (True, True)


def test_literal_model_defaults() -> None:
    assert LiteralFiveModel().to_data() == 5
    assert LiteralFiveModel().outer_type(with_args=True) is Literal[5]
@github-actions github-actions bot added the todo label Sep 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

0 participants