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

TypeError: object.__new__() takes exactly one argument (the type to instantiate) #5

Open
satheler opened this issue Dec 23, 2023 · 6 comments · May be fixed by #40
Open

TypeError: object.__new__() takes exactly one argument (the type to instantiate) #5

satheler opened this issue Dec 23, 2023 · 6 comments · May be fixed by #40

Comments

@satheler
Copy link
Contributor

When I run the test in isolation it works. But when I run the entire battery of tests it gives the following error:

TypeError: object.__new__() takes exactly one argument (the type to instantiate)
@oussjarrousse
Copy link
Owner

Hello @satheler. After me and my team, you are the first user of the package that I know of.

The package is still in its infancy, and I am adding features as soon as I need them, and I am fixing bugs as soon as they are discovered. So Bug reports or Feature requests are very welcomed.

Maybe if you share more details. like the snippet of the code, or more of the error log. I will be able to help...

@satheler
Copy link
Contributor Author

Hello @oussjarrousse. I'm trying to find the root cause and plan to open a PR with the possible fix.
Thanks!!

@satheler
Copy link
Contributor Author

satheler commented Dec 23, 2023

I found the problem, the order of the fixtures matters.

I had this code and it presented the error I mentioned in this issue

import pytest
from pytest_minio_mock.plugin import MockMinioClient

from my_package.storage import StorageProvider

@pytest.fixture()
def system_under_test(storage_provider_stub: StorageProvider, minio_mock: MockMinioClient):
    ...

But when I declare the minio_mock first the tests pass

import pytest
from pytest_minio_mock.plugin import MockMinioClient

from my_package.storage import StorageProvider

@pytest.fixture()
def system_under_test(minio_mock: MockMinioClient, storage_provider_stub: StorageProvider):
    ...

My suggestion is to create a decorator that decorates the function that's always run before the fixture loads. Something like this.

import pytest
from pytest_minio_mock.plugin import MockMinioClient

from my_package.storage import StorageProvider

@pytest.fixture()
@mock_minio()
def system_under_test(storage_provider_stub: StorageProvider):
    ...

@oussjarrousse
Copy link
Owner

That's interesting.

Most likely the storage provider initiate a MinioClient before the class has been patched with MockMinioClient.
Maybe the fixture should retrospectively patch all instances of MinioClient... not only newly created ones...

For now, I will add a note about that in the README.md...

@chrishart0
Copy link

I've just run into the same issue. I've created some new tests mocking one of my own functions which call MinIO later down the line. No need to mock MinIO, since I am mocking something over the top of it. My new tests work fine when run in isolation, as soon as I run any test calling MinIO mock along with the other tests I get the same error TypeError: object.__new__() takes exactly one argument (the type to instantiate)

I resolved the issue by adding minio_mock to my new tests. I don't love that, but it works.

@oussjarrousse and @satheler if either of you can outline how to implement a solution to this please let me know and I can try to take a shot at it.

@oussjarrousse oussjarrousse reopened this Jun 13, 2024
@bernd-k1337
Copy link

@oussjarrousse @satheler
The problem is that when mocking __new__ is somehow reset to object.__new__, which only takes one argument cls.
This is discussed in @ymyke's post in pytest-dev/pytest#8009.
So the mock_minio fixture needs to be changed to something like this which is proposed in this Stack Overflow Post

@pytest.fixture
def minio_mock(mocker: MockerFixture, minio_mock_servers):
    """
    Pytest fixture to patch the Minio client with a mock.

    Args:
        mocker: The pytest-mock fixture.
        minio_mock_servers: The fixture providing a Servers instance.

    Yields:
        MockMinioClient: The patched Minio client.
    """

    def minio_mock_init(
        cls,
        *args,
        **kwargs,
    ):
        client = MockMinioClient(*args, **kwargs)
        client.connect(minio_mock_servers)
        return client
    
    patched = mocker.patch.object(Minio, "__new__", new=minio_mock_init, create=True)
    try:
        yield patched
        mocker.stop(patched)
    finally:
        Minio.__new__ = lambda cls, *args, **kw: object.__new__(cls)

The question is whether Mocker will still be needed at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants