joke2k / faker

Faker is a Python package that generates fake data for you.
https://faker.readthedocs.io
MIT License
17.57k stars 1.92k forks source link

Faker adds path objects to sys.path_importer_cache, breaking other packages #1421

Closed mgorny closed 3 years ago

mgorny commented 3 years ago

After importing faker, entries with PosixPath objects are added as keys to sys.path_importer_cache. However, the keys are supposed to be regular strs there, and the wrong type breaks software relying on str methods being available, e.g. astroid:

___________________________________________ ClassNodeTest.test_slots_added_dynamically_still_inferred ____________________________________________

self = <tests.unittest_scoped_nodes.ClassNodeTest testMethod=test_slots_added_dynamically_still_inferred>

    def tearDown(self):
        del sys.path[0]
        datadir = find("")
        for key in list(sys.path_importer_cache):
>           if key.startswith(datadir):
E           AttributeError: 'PosixPath' object has no attribute 'startswith'

tests/resources.py:41: AttributeError

Note that since Faker installs a pytest plugin, it is autoloaded by default in all programs' test suites.

Steps to reproduce

import sys
import faker
print(sys.path_importer_cache)

Expected behavior

The printed dict should only contain str keys.

Actual behavior

[...] PosixPath('/usr/lib/python3.9/site-packages/faker/providers/address'): FileFinder(PosixPath('/usr/lib/python3.9/site-packages/faker/providers/address')), PosixPath('/usr/lib/python3.9/site-packages/faker/providers/automotive'): FileFinder(PosixPath('/usr/lib/python3.9/site-packages/faker/providers/automotive')), [...]
fcurella commented 3 years ago

Thank you for the repot @mgorny ! Would you mind submitting a Pull Request?

mgorny commented 3 years ago

I actually hoped you know the code better and know where these paths are added. If you can tell me that, I can try. However, I'm really short on time these days.

fcurella commented 3 years ago

@mgorny

I think the root of the problem is this line, where we're returning a Path objects instead of a string.

I can write the Pull Request, but I'd like for you to try my changes to see if they fix your issue.

levrik commented 3 years ago

@fcurella We've started seeing this issue today the first time without any code changes or upgrades on Faker. The only change was the upgrade from Python 3.8.9 to 3.8.10 after which this issue started to happen.

mike-oakley commented 3 years ago

Can confirm pinning Python to 3.8.9 (instead of 3.8.10) was a workaround for us too

mike-oakley commented 3 years ago

After looking into it, we were running Faker 6.6.3 which didn't include the patch referenced by this issue. Pinning Faker to 8.1.2 fixed this for us on Python 3.8.10 (previously we didn't have Faker pinned as we're using it as a peer dependency of Factory Boy)