Mercurial > hgrepos > Python2 > PyMuPDF
comparison tests/conftest.py @ 1:1d09e1dec1d9 upstream
ADD: PyMuPDF v1.26.4: the original sdist.
It does not yet contain MuPDF. This normally will be downloaded when
building PyMuPDF.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:37:51 +0200 |
| parents | |
| children | a6bc019ac0b2 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 1:1d09e1dec1d9 |
|---|---|
| 1 import copy | |
| 2 import os | |
| 3 import platform | |
| 4 import sys | |
| 5 | |
| 6 import pymupdf | |
| 7 | |
| 8 import pytest | |
| 9 | |
| 10 PYMUPDF_PYTEST_RESUME = os.environ.get('PYMUPDF_PYTEST_RESUME') | |
| 11 | |
| 12 @pytest.fixture(autouse=True) | |
| 13 def wrap(request): | |
| 14 ''' | |
| 15 Check that tests return with empty MuPDF warnings buffer. For example this | |
| 16 detects failure to call fz_close_output() before fz_drop_output(), which | |
| 17 (as of 2024-4-12) generates a warning from MuPDF. | |
| 18 | |
| 19 As of 2024-09-12 we also detect whether tests leave fds open; but for now | |
| 20 do not fail tests, because many tests need fixing. | |
| 21 ''' | |
| 22 global PYMUPDF_PYTEST_RESUME | |
| 23 if PYMUPDF_PYTEST_RESUME: | |
| 24 # Skip all tests until we reach a matching name. | |
| 25 if PYMUPDF_PYTEST_RESUME == request.function.__name__: | |
| 26 print(f'### {PYMUPDF_PYTEST_RESUME=}: resuming at {request.function.__name__=}.') | |
| 27 PYMUPDF_PYTEST_RESUME = None | |
| 28 else: | |
| 29 print(f'### {PYMUPDF_PYTEST_RESUME=}: Skipping {request.function.__name__=}.') | |
| 30 return | |
| 31 | |
| 32 wt = pymupdf.TOOLS.mupdf_warnings() | |
| 33 assert not wt, f'{wt=}' | |
| 34 if platform.python_implementation() == 'GraalVM': | |
| 35 pymupdf.TOOLS.set_small_glyph_heights() | |
| 36 else: | |
| 37 assert not pymupdf.TOOLS.set_small_glyph_heights() | |
| 38 next_fd_before = os.open(__file__, os.O_RDONLY) | |
| 39 os.close(next_fd_before) | |
| 40 | |
| 41 if platform.system() == 'Linux' and platform.python_implementation() != 'GraalVM': | |
| 42 test_fds = True | |
| 43 else: | |
| 44 test_fds = False | |
| 45 | |
| 46 if test_fds: | |
| 47 # Gather detailed information about leaked fds. | |
| 48 def get_fds(): | |
| 49 import subprocess | |
| 50 path = 'PyMuPDF-linx-fds' | |
| 51 path_l = 'PyMuPDF-linx-fds-l' | |
| 52 command = f'ls /proc/{os.getpid()}/fd > {path}' | |
| 53 command_l = f'ls -l /proc/{os.getpid()}/fd > {path_l}' | |
| 54 subprocess.run(command, shell=1) | |
| 55 subprocess.run(command_l, shell=1) | |
| 56 with open(path) as f: | |
| 57 ret = f.read() | |
| 58 ret = ret.replace('\n', ' ') | |
| 59 with open(path_l) as f: | |
| 60 ret_l = f.read() | |
| 61 return ret, ret_l | |
| 62 open_fds_before, open_fds_before_l = get_fds() | |
| 63 | |
| 64 pymupdf._log_items_clear() | |
| 65 pymupdf._log_items_active(True) | |
| 66 | |
| 67 JM_annot_id_stem = pymupdf.JM_annot_id_stem | |
| 68 | |
| 69 def get_members(a): | |
| 70 ret = dict() | |
| 71 for n in dir(a): | |
| 72 if not n.startswith('_'): | |
| 73 v = getattr(a, n) | |
| 74 ret[n] = v | |
| 75 return ret | |
| 76 | |
| 77 # Allow post-test checking that pymupdf._globals has not changed. | |
| 78 _globals_pre = get_members(pymupdf._globals) | |
| 79 | |
| 80 # Run the test. | |
| 81 rep = yield | |
| 82 | |
| 83 sys.stdout.flush() | |
| 84 | |
| 85 # Test has run; check it did not create any MuPDF warnings etc. | |
| 86 wt = pymupdf.TOOLS.mupdf_warnings() | |
| 87 if not hasattr(pymupdf, 'mupdf'): | |
| 88 print(f'Not checking mupdf_warnings on classic.') | |
| 89 else: | |
| 90 assert not wt, f'Warnings text not empty: {wt=}' | |
| 91 | |
| 92 assert not pymupdf.TOOLS.set_small_glyph_heights() | |
| 93 | |
| 94 _globals_post = get_members(pymupdf._globals) | |
| 95 if _globals_post != _globals_pre: | |
| 96 print(f'Test has changed pymupdf._globals from {_globals_pre=} to {_globals_post=}') | |
| 97 assert 0 | |
| 98 | |
| 99 log_items = pymupdf._log_items() | |
| 100 assert not log_items, f'log() was called; {len(log_items)=}.' | |
| 101 | |
| 102 assert pymupdf.JM_annot_id_stem == JM_annot_id_stem, \ | |
| 103 f'pymupdf.JM_annot_id_stem has changed from {JM_annot_id_stem!r} to {pymupdf.JM_annot_id_stem!r}' | |
| 104 | |
| 105 if test_fds: | |
| 106 # Show detailed information about leaked fds. | |
| 107 open_fds_after, open_fds_after_l = get_fds() | |
| 108 if open_fds_after != open_fds_before: | |
| 109 import textwrap | |
| 110 print(f'Test has changed process fds:') | |
| 111 print(f' {open_fds_before=}') | |
| 112 print(f' {open_fds_after=}') | |
| 113 print(f'open_fds_before_l:') | |
| 114 print(textwrap.indent(open_fds_before_l, ' ')) | |
| 115 print(f'open_fds_after_l:') | |
| 116 print(textwrap.indent(open_fds_after_l, ' ')) | |
| 117 #assert 0 | |
| 118 | |
| 119 next_fd_after = os.open(__file__, os.O_RDONLY) | |
| 120 os.close(next_fd_after) | |
| 121 | |
| 122 if test_fds and next_fd_after != next_fd_before: | |
| 123 print(f'Test has leaked fds, {next_fd_before=} {next_fd_after=}.') | |
| 124 #assert 0, f'Test has leaked fds, {next_fd_before=} {next_fd_after=}. {args=} {kwargs=}.' | |
| 125 | |
| 126 if 0: | |
| 127 # This code can be useful to track down test failures caused by other | |
| 128 # tests modifying global state. | |
| 129 # | |
| 130 # We run a particular test menually after each test returns. | |
| 131 sys.path.insert(0, os.path.dirname(__file__)) | |
| 132 try: | |
| 133 import test_tables | |
| 134 finally: | |
| 135 del sys.path[0] | |
| 136 print(f'### Calling test_tables.test_md_styles().') | |
| 137 try: | |
| 138 test_tables.test_md_styles() | |
| 139 except Exception as e: | |
| 140 print(f'### test_tables.test_md_styles() failed: {e}') | |
| 141 raise | |
| 142 else: | |
| 143 print(f'### test_tables.test_md_styles() passed.') |
