Ensures that filename is opened with correct encoding parameter. This function uses charset_normalizer package, when available, for determining the encoding of the file to be opened. When charset_normalizer is not available, the function detects only UTF encodings, otherwise, ASCII
(filename, mode)
| 299 | |
| 300 | |
| 301 | def openhook(filename, mode): |
| 302 | """Ensures that filename is opened with correct encoding parameter. |
| 303 | |
| 304 | This function uses charset_normalizer package, when available, for |
| 305 | determining the encoding of the file to be opened. When charset_normalizer |
| 306 | is not available, the function detects only UTF encodings, otherwise, ASCII |
| 307 | encoding is used as fallback. |
| 308 | """ |
| 309 | # Reads in the entire file. Robust detection of encoding. |
| 310 | # Correctly handles comments or late stage unicode characters |
| 311 | # gh-22871 |
| 312 | if charset_normalizer is not None: |
| 313 | encoding = charset_normalizer.from_path(filename).best().encoding |
| 314 | else: |
| 315 | # hint: install charset_normalizer for correct encoding handling |
| 316 | # No need to read the whole file for trying with startswith |
| 317 | nbytes = min(32, os.path.getsize(filename)) |
| 318 | with open(filename, 'rb') as fhandle: |
| 319 | raw = fhandle.read(nbytes) |
| 320 | if raw.startswith(codecs.BOM_UTF8): |
| 321 | encoding = 'UTF-8-SIG' |
| 322 | elif raw.startswith((codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE)): |
| 323 | encoding = 'UTF-32' |
| 324 | elif raw.startswith((codecs.BOM_LE, codecs.BOM_BE)): |
| 325 | encoding = 'UTF-16' |
| 326 | else: |
| 327 | # Fallback, without charset_normalizer |
| 328 | encoding = 'ascii' |
| 329 | return open(filename, mode, encoding=encoding) |
| 330 | |
| 331 | |
| 332 | def is_free_format(fname): |
no test coverage detected
searching dependent graphs…