Skip to content

Commit 2a67455

Browse files
committed
Unbreak various things
* A merge to reduce error spam during loading broke .so loading in at least some (maybe all?) cases, where find_library doesn't return an absolute path. * Prematurely pushed some in-progress test changes that were super broken, all fixed now.
1 parent 36ecbf9 commit 2a67455

File tree

2 files changed

+136
-111
lines changed

2 files changed

+136
-111
lines changed

magic/loader.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
logger = logging.getLogger(__name__)
99

10+
1011
def _lib_candidates_linux():
1112
"""Yield possible libmagic library names on Linux.
1213
@@ -51,7 +52,7 @@ def _lib_candidates():
5152
"darwin": _lib_candidates_macos,
5253
"linux": _lib_candidates_linux,
5354
"win32": _lib_candidates_windows,
54-
"sunos5": _lib_candidates_linux,
55+
"sunos5": _lib_candidates_linux,
5556
}.get(sys.platform)
5657
if func is None:
5758
raise ImportError("python-magic: Unsupported platform: " + sys.platform)
@@ -61,17 +62,20 @@ def _lib_candidates():
6162

6263

6364
def load_lib():
65+
exc: list[Exception] = []
6466
for lib in _lib_candidates():
6567
# find_library returns None when lib not found
6668
if lib is None:
6769
continue
68-
if not os.path.exists(lib):
69-
continue
7070

7171
try:
7272
return ctypes.CDLL(lib)
73-
except OSError:
74-
logger.warning("Failed to load: " + lib, exc_info=True)
73+
except OSError as e:
74+
exc.append(e)
75+
76+
msg = "\n".join([str(e) for e in exc])
7577

7678
# It is better to raise an ImportError since we are importing magic module
77-
raise ImportError("python-magic: failed to find libmagic. Check your installation")
79+
raise ImportError(
80+
"python-magic: failed to find libmagic. Check your installation: \n" + msg
81+
)

test/python_magic_test.py

Lines changed: 126 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import magic
2121

22+
2223
@dataclass
2324
class TestFile:
2425
file_name: str
@@ -27,132 +28,153 @@ class TestFile:
2728
no_check_elf_results: list[str] | None
2829
buf_equals_file: bool = True
2930

31+
3032
# magic_descriptor is broken (?) in centos 7, so don't run those tests
3133
SKIP_FROM_DESCRIPTOR = bool(os.environ.get("SKIP_FROM_DESCRIPTOR"))
3234

3335

34-
COMMON_PLAIN = [
35-
{},
36-
{"check_soft": True},
37-
{"check_soft": False},
38-
{"check_json": True},
39-
{"check_json": False},
40-
]
41-
42-
NO_SOFT = {"check_soft": False}
43-
44-
COMMON_MIME = [{"mime": True, **k} for k in COMMON_PLAIN]
36+
COMMON_PLAIN = [{}]
37+
NO_SOFT = [{"check_soft": False}]
38+
COMMON_MIME = [{"mime": True}]
4539

4640
CASES = {
47-
"magic._pyc_": [
48-
(COMMON_MIME, [
49-
"application/octet-stream",
50-
"text/x-bytecode.python",
51-
"application/x-bytecode.python",
52-
]),
41+
b"magic._pyc_": [
42+
(
43+
COMMON_MIME,
44+
[
45+
"application/octet-stream",
46+
"text/x-bytecode.python",
47+
"application/x-bytecode.python",
48+
],
49+
),
5350
(COMMON_PLAIN, ["python 2.4 byte-compiled"]),
5451
(NO_SOFT, ["data"]),
5552
],
56-
"test.pdf": [
53+
b"test.pdf": [
5754
(COMMON_MIME, ["application/pdf"]),
58-
(COMMON_PLAIN, [
59-
"PDF document, version 1.2",
60-
"PDF document, version 1.2, 2 pages",
61-
"PDF document, version 1.2, 2 page(s)",
62-
]),
55+
(
56+
COMMON_PLAIN,
57+
[
58+
"PDF document, version 1.2",
59+
"PDF document, version 1.2, 2 pages",
60+
"PDF document, version 1.2, 2 page(s)",
61+
],
62+
),
6363
(NO_SOFT, ["ASCII text"]),
6464
],
65-
"test.gz": [
65+
b"test.gz": [
6666
(COMMON_MIME, ["application/gzip", "application/x-gzip"]),
67-
(COMMON_PLAIN, [
68-
'gzip compressed data, was "test", from Unix, last modified: Sun Jun 29 01:32:52 2008',
69-
'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix',
70-
'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, original size 15',
71-
'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, original size modulo 2^32 15',
72-
'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, truncated',
73-
]),
74-
({"extension": True}, [
75-
# some versions return '' for the extensions of a gz file,
76-
# including w/ the command line. Who knows...
77-
"gz/tgz/tpz/zabw/svgz/adz/kmy/xcfgz",
78-
"gz/tgz/tpz/zabw/svgz",
79-
"",
80-
"???",
81-
]),
67+
(
68+
COMMON_PLAIN,
69+
[
70+
'gzip compressed data, was "test", from Unix, last modified: Sun Jun 29 01:32:52 2008',
71+
'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix',
72+
'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, original size 15',
73+
'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, original size modulo 2^32 15',
74+
'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix, truncated',
75+
],
76+
),
77+
(
78+
[{"extension": True}],
79+
[
80+
# some versions return '' for the extensions of a gz file,
81+
# including w/ the command line. Who knows...
82+
"gz/tgz/tpz/zabw/svgz/adz/kmy/xcfgz",
83+
"gz/tgz/tpz/zabw/svgz",
84+
"",
85+
"???",
86+
],
87+
),
8288
(NO_SOFT, ["data"]),
8389
],
84-
"test.snappy.parquet": [
90+
b"test.snappy.parquet": [
8591
(COMMON_MIME, ["application/octet-stream"]),
8692
(COMMON_PLAIN, ["Apache Parquet", "Par archive data"]),
8793
(NO_SOFT, ["data"]),
8894
],
89-
"test.json": [
90-
# TODO: soft, no_json
95+
b"test.json": [
9196
(COMMON_MIME, ["application/json"]),
9297
(COMMON_PLAIN, ["JSON text data"]),
93-
({"mime": True, "check_json": False}, [
94-
"data",
95-
]),
96-
(NO_SOFT, ["JSON text data"])
98+
(
99+
[{"mime": True, "check_json": False}],
100+
[
101+
"text/plain",
102+
],
103+
),
104+
(NO_SOFT, ["JSON text data"]),
97105
],
98-
"elf-NetBSD-x86_64-echo": [
106+
b"elf-NetBSD-x86_64-echo": [
99107
# TODO: soft, no elf
100-
(COMMON_PLAIN, [
101-
"ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)",
102-
"ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /libexec/ld.elf_so, for NetBSD 8.0, not stripped",
103-
]),
104-
(COMMON_MIME, [
105-
"application/x-pie-executable",
106-
"application/x-sharedlib",
107-
]),
108-
({"check_elf": False}, [
109-
"ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)",
110-
]),
108+
(
109+
COMMON_PLAIN,
110+
[
111+
"ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)",
112+
"ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /libexec/ld.elf_so, for NetBSD 8.0, not stripped",
113+
],
114+
),
115+
(
116+
COMMON_MIME,
117+
[
118+
"application/x-pie-executable",
119+
"application/x-sharedlib",
120+
],
121+
),
122+
(
123+
[{"check_elf": False}],
124+
[
125+
"ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)",
126+
],
127+
),
111128
# TODO: sometimes
112129
# "ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /libexec/ld.elf_so, for NetBSD 8.0, not stripped",
113-
114130
(NO_SOFT, ["data"]),
115131
],
116-
"test.txt": [
132+
b"text.txt": [
117133
(COMMON_MIME, ["text/plain"]),
118134
(COMMON_PLAIN, ["ASCII text"]),
119-
({"mime_encoding": True}, [
120-
"us-ascii",
121-
]),
135+
(
136+
[{"mime_encoding": True}],
137+
[
138+
"us-ascii",
139+
],
140+
),
122141
(NO_SOFT, ["ASCII text"]),
123142
],
124-
"text-iso8859-1.txt": [
125-
({"mime_encoding": True}, [
126-
"iso-8859-1",
127-
]),
143+
b"text-iso8859-1.txt": [
144+
(
145+
[{"mime_encoding": True}],
146+
[
147+
"iso-8859-1",
148+
],
149+
),
128150
],
129151
b"\xce\xbb": [
130152
(COMMON_MIME, ["text/plain"]),
131153
],
132-
"b\xce\xbb".decode("utf-8"): [
133-
(COMMON_MIME, ["text/plain"]),
154+
b"name_use.jpg": [
155+
([{"extension": True}], ["jpeg/jpg/jpe/jfif"]),
134156
],
135-
"name_use.jpg": [
136-
({"extension": True}, [
137-
"jpeg/jpg/jpe/jfif"
138-
]),
157+
b"keep-going.jpg": [
158+
(COMMON_MIME, ["image/jpeg"]),
159+
(
160+
[{"mime": True, "keep_going": True}],
161+
[
162+
"image/jpeg\\012- application/octet-stream",
163+
],
164+
),
139165
],
140-
"keep-going.jpg": [
141-
(COMMON_MIME, [
142-
"image/jpeg"
143-
]),
144-
({"mime": True, "keep_going": True}, [
145-
"image/jpeg\\012- application/octet-stream",
146-
])
166+
b"../../magic/loader.py": [
167+
(
168+
COMMON_MIME,
169+
[
170+
"text/x-python",
171+
"text/x-script.python",
172+
],
173+
)
147174
],
148-
"test.py": [
149-
(COMMON_MIME, [
150-
"text/x-python",
151-
"text/x-script.python",
152-
])
153-
]
154175
}
155176

177+
156178
class MagicTest(unittest.TestCase):
157179
TESTDATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "testdata"))
158180

@@ -165,7 +187,6 @@ def test_version(self):
165187
def test_fs_encoding(self):
166188
self.assertEqual("utf-8", sys.getfilesystemencoding().lower())
167189

168-
169190
def test_from_file_str_and_bytes(self):
170191
filename = os.path.join(self.TESTDATA_DIR, "test.pdf")
171192

@@ -174,7 +195,6 @@ def test_from_file_str_and_bytes(self):
174195
"application/pdf", magic.from_file(filename.encode("utf-8"), mime=True)
175196
)
176197

177-
178198
def test_all_cases(self):
179199
# TODO:
180200
# * MAGIC_EXTENSION not supported
@@ -184,21 +204,24 @@ def test_all_cases(self):
184204
shutil.copyfile(os.path.join(MagicTest.TESTDATA_DIR, "lambda"), dest)
185205
os.environ["TZ"] = "UTC"
186206
try:
187-
for file_name, cases in CASES:
188-
filename = os.path.join(self.TESTDATA_DIR, file_name)
189-
for flags, outputs in cases:
190-
m = magic.Magic(**flags)
191-
with open(filename) as f:
192-
self.assertIn(m.from_descriptor(f.fileno()), outputs)
193-
194-
self.assertIn(m.from_file(filename), outputs)
195-
196-
fname_bytes = filename.encode("utf-8")
197-
self.assertIn(m.from_file(fname_bytes), outputs)
198-
199-
with open(file_name, "rb") as f:
200-
buf_result = m.from_buffer(f.read(1024))
201-
self.assertIn(buf_result, outputs)
207+
for filename, cases in CASES.items():
208+
filename = os.path.join(self.TESTDATA_DIR.encode("utf-8"), filename)
209+
print("test case ", filename, file=sys.stderr)
210+
for flag_variants, outputs in cases:
211+
for flags in flag_variants:
212+
print("flags", flags, file=sys.stderr)
213+
m = magic.Magic(**flags)
214+
with open(filename) as f:
215+
self.assertIn(m.from_descriptor(f.fileno()), outputs)
216+
217+
self.assertIn(m.from_file(filename), outputs)
218+
219+
fname_str = filename.decode("utf-8")
220+
self.assertIn(m.from_file(fname_str), outputs)
221+
222+
with open(filename, "rb") as f:
223+
buf_result = m.from_buffer(f.read(1024))
224+
self.assertIn(buf_result, outputs)
202225
finally:
203226
del os.environ["TZ"]
204227
os.unlink(dest)
@@ -222,7 +245,6 @@ def test_unicode_result_raw(self):
222245
else:
223246
raise unittest.SkipTest("Magic file doesn't return expected type.")
224247

225-
226248
def test_errors(self):
227249
m = magic.Magic()
228250
self.assertRaises(IOError, m.from_file, "nonexistent")
@@ -233,7 +255,6 @@ def test_errors(self):
233255
finally:
234256
del os.environ["MAGIC"]
235257

236-
237258
def test_rethrow(self):
238259
old = magic.magic_buffer
239260
try:

0 commit comments

Comments
 (0)