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

Add support for pytest-freezegun #29

Closed
lyz-code opened this issue Feb 16, 2022 · 6 comments
Closed

Add support for pytest-freezegun #29

lyz-code opened this issue Feb 16, 2022 · 6 comments

Comments

@lyz-code
Copy link
Contributor

lyz-code commented Feb 16, 2022

Hi @Goldziher, I'm having issues using pydantic_factories with pytest_freezegun, the problem is that pytest_factories is not able to find the factory function for the datetime attributes

tests/unit/test_source.py:16: in test_cant_merge_if_url_is_not_equal
    original = SourceFactory.build()
../../.venvs/airss/lib/python3.9/site-packages/pydantic_factories/factory.py:495: in build
    kwargs[field_name] = cls.get_field_value(model_field=model_field)
../../.venvs/airss/lib/python3.9/site-packages/pydantic_factories/factory.py:438: in get_field_value
    return cls.get_mock_value(field_type=field_type)
../../.venvs/airss/lib/python3.9/site-packages/pydantic_factories/factory.py:339: in get_mock_value
    raise ParameterError(
E   pydantic_factories.exceptions.ParameterError: Unsupported type: <class 'datetime.datetime'>
E
E   Either extend the providers map or add a factory function for this model field

Adding a pdb trace on line 339 I get the next result:

(Pdb) cls.get_provider_map().get(field_type)
(Pdb) cls.get_provider_map().get(datetime)
<bound method Provider.date_time_between of <faker.providers.date_time.en_US.Provider object at 0x7f004133b580>>
(Pdb) type(field_type)
<class 'type'>
(Pdb) field_type
<class 'datetime.datetime'>
(Pdb) datetime
<class 'freezegun.api.FakeDatetime'>

If you feel it's a corner case and you don't want to support pytest-freezegun, can you point me in the direction on how to extend the providers map locally?

Thanks! :)

@lyz-code lyz-code changed the title 1.2.4 broke the datetime generator for Python 3.9 Add support for pytest-freezegun Feb 16, 2022
@Goldziher
Copy link
Contributor

Goldziher commented Feb 16, 2022

Hi there,

Its not a fringe use, but its a 3rd party dependency. So I don't see how it can be done in the scope of the library. But you're welcome to see if you do find a way to do.this neatly.

To extend the providers map you simply need to subclass ModelFactory, override the method and extend the base value.

This should resolve you issue I hope.

lyz-code added a commit to lyz-code/blue-book that referenced this issue Feb 17, 2022
[Roguelynn tutorial](https://www.roguelynn.com/words/asyncio-we-did-it-wrong/)

feat(feedparser#issues): Add issue when using `updated_parser`

[Deprecation warning when using `updated_parsed`](kurtmckee/feedparser#151)

fix(pytest): update the tmpdir_factory type hints

You should now use `TempPathFactory` instead of `TempdirFactory`

fix(pytest#global-usage): Use `pytest-freezegun` globally

[Most of the tests](https://medium.com/@boxed/flaky-tests-part-3-freeze-the-world-e4929a0da00e)
work with frozen time, so it's better to freeze it by default and unfreeze it on
the ones that actually need time to move.

To do that set in your `tests/conftest.py` a globally used fixture:

```python
if TYPE_CHECKING:
    from freezegun.api import FrozenDateTimeFactory

@pytest.fixture(autouse=True)
def frozen_time() -> Generator['FrozenDateTimeFactory', None, None]:
    """Freeze all tests time"""
    with freezegun.freeze_time() as freeze:
        yield freeze
```

feat(pytest): Ignore a warning of a specific package

In the `pyproject.toml`

```toml
filterwarnings = [
  "error",
  # Until ktosiek/pytest-freezegun#35 is merged
  "ignore::DeprecationWarning:pytest_freezegun.*"
]
```

feat(python_snippets#How to raise a warning): How to raise a warning

Warning messages are typically issued in situations where it is useful to alert
the user of some condition in a program, where that condition (normally) doesn’t
warrant raising an exception and terminating the program. For example, one might
want to issue a warning when a program uses an obsolete module.

```python
import warnings

def f():
    warnings.warn('Message', DeprecationWarning)
```

To test the function with pytest you can use
[`pytest.warns`](https://docs.pytest.org/en/stable/how-to/capture-warnings.html#warns):

```python
import warnings
import pytest

def test_warning():
    with pytest.warns(UserWarning, match='my warning'):
        warnings.warn("my warning", UserWarning)
```

feat(python_snippets#Parse XML file with beautifulsoup): Parse XML file with beautifulsoup

You need both `beautifulsoup4` and `lxml`:

```python
bs = BeautifulSoup(requests.get(url), "lxml")
```

feat(python_snippets#Get a traceback from an exception): Get a traceback from an exception

```python
import traceback

traceback_str = ''.join(traceback.format_tb(e.__traceback__))
```

feat(flakeheaven): Deprecate flakehell in favour of flakeheaven

It's a fork maintained by the community, instead of an absent code
dictator.

feat(fastapi#Resolve the 307 error): Resolve the 307 error

Probably you've introduced an ending `/` to the endpoint, so instead of asking
for `/my/endpoint` you tried to do `/my/endpoint/`.

feat(pdm): Version overriding now supports constrains

Before you had to pin specific versions, which is not maintainable, now
you can use constrains

```toml
[tool.pdm.overrides]
asgiref = ">=3.2.10"
```

feat(pdm#Show outdated packages): Show outdated packages

```bash
pdm update --dry-run --unconstrained
```

fix(pydantic_factories): correct the type hints of the factory

Use `Any`

```python
class PersonFactory(ModelFactory[Any]):
    ...
```

feat(pydantic_factories#issues): Track issue when using with
`pytest-freezegun`

[Use pydantic-factories with pytest-freezegun](litestar-org/polyfactory#29)

feat(python#install): Install a specific version

* Install dependencies
    ```bash
    sudo apt install wget software-properties-common build-essential libnss3-dev zlib1g-dev libgdbm-dev libncurses5-dev libssl-dev libffi-dev libreadline-dev libsqlite3-dev libbz2-dev
    ```

* Select the version in https://www.python.org/ftp/python/ and download it
    ```bash
    wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz
    cd Python-3.9.2/
    ./configure --enable-optimizations
    sudo make altinstall
    ```

perf(regicide): fix typos

fix(wallabag): Remove Wallabag rss issue as it's solved

Rss feeds linked to the wallabag instance instead to the referenced article, not anymore.
@Goldziher
Copy link
Contributor

Can I close this issue? Or do you intend to add a PR?

@lyz-code
Copy link
Contributor Author

lyz-code commented Mar 4, 2022

Hi @Goldziher , sorry for the delay, what do you think if we add an optional argument to ModelFactory called additional_mappers where the user can pass a dictionary of mappers that gets merged with the default one?

That way it would be easier for the users to extend the existent mapping without the need of subclassing and overriding the method. Furthermore, if you do that, it's difficult to stay updated with the changes in the default mapping

@Goldziher
Copy link
Contributor

hi @lyz-code - how is this relevant to this issue?

@lyz-code
Copy link
Contributor Author

lyz-code commented Mar 4, 2022

Because then It would be easier for me to extend the ModelFactory with something like:

from freezegun.api import FakeDatetime
class CustomModelFactory(ModelFactory):
    additional_mappers = { FakeDateTime: cls._get_faker().date_time_between }

And I wouldn't need to subclass ModelFactory, copy and paste the whole get_provider_map and append FakeDateTime: faker.date_time_between to the returned dictionary.

@Goldziher
Copy link
Contributor

Ok. Please create an issue with some examples of what you want to add, lets discuss it in a non-closed ticket.

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

No branches or pull requests

2 participants