diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c6bfd59..11f265e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,10 @@ Release History --------------- +2.2.1 +- Python source is now always read using utf-8, even if default encoding for + reading files is set otherwise. + 2.2.0 - Added `--skip-incompatible` flag to `pip-extra-reqs`, which makes it ignore diff --git a/pip_check_reqs/__init__.py b/pip_check_reqs/__init__.py index 04188a1..36a511e 100644 --- a/pip_check_reqs/__init__.py +++ b/pip_check_reqs/__init__.py @@ -1 +1 @@ -__version__ = '2.2.0' +__version__ = '2.2.1' diff --git a/pip_check_reqs/common.py b/pip_check_reqs/common.py index c72a25d..9d6d479 100644 --- a/pip_check_reqs/common.py +++ b/pip_check_reqs/common.py @@ -119,7 +119,7 @@ def find_imported_modules(options): log.info('ignoring: %s', os.path.relpath(filename)) continue log.debug('scanning: %s', os.path.relpath(filename)) - with open(filename) as f: + with open(filename, encoding='utf-8') as f: content = f.read() vis.set_location(filename) vis.visit(ast.parse(content)) diff --git a/tests/test_common.py b/tests/test_common.py index 3666770..69892d6 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -106,7 +106,7 @@ class FakeFile(): 'from . import friend', ] - def __init__(self, filename): + def __init__(self, filename, encoding=None): pass def read(self): @@ -196,3 +196,32 @@ def ignore_reqs(self, modname): requirements_filename=str(fake_requirements_file), ) assert not reqs + + +def test_find_imported_modules_sets_encoding_to_utf8_when_reading(tmp_path): + (tmp_path / 'module.py').touch() + + class options: + paths = [tmp_path] + + def ignore_files(*_): + return False + + expected_encoding = 'utf-8' + used_encoding = None + + original_open = common.__builtins__['open'] + + def mocked_open(*args, **kwargs): + # As of Python 3.9, the args to open() are as follows: + # file, mode, buffering, encoding, erorrs, newline, closedf, opener + nonlocal used_encoding + if 'encoding' in kwargs: + used_encoding = kwargs['encoding'] + return original_open(*args, **kwargs) + + common.__builtins__['open'] = mocked_open + common.find_imported_modules(options) + common.__builtins__['open'] = original_open + + assert used_encoding == expected_encoding