Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 48 additions & 30 deletions magic/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,65 @@
import glob
import os.path

def _lib_candidates():

yield find_library('magic')
def _lib_candidates_linux():
"""Yield possible libmagic library names on Linux.
This is necessary because alpine is bad
"""
yield "libmagic.so.1"

if sys.platform == 'darwin':

def _lib_candidates_macos():
"""Yield possible libmagic library names on macOS."""
paths = [
'/opt/local/lib',
'/usr/local/lib',
'/opt/homebrew/lib',
] + glob.glob('/usr/local/Cellar/libmagic/*/lib')
"/opt/homebrew/lib",
"/opt/local/lib",
"/usr/local/lib",
] + glob.glob("/usr/local/Cellar/libmagic/*/lib")
for path in paths:
yield os.path.join(path, "libmagic.dylib")

for i in paths:
yield os.path.join(i, 'libmagic.dylib')

elif sys.platform in ('win32', 'cygwin'):
def _lib_candidates_windows():
"""Yield possible libmagic library names on Windows."""
prefixes = (
"libmagic",
"magic1",
"magic-1",
"cygmagic-1",
"libmagic-1",
"msys-magic-1",
)
for prefix in prefixes:
# find_library searches in %PATH% but not the current directory,
# so look for both
yield "./%s.dll" % (prefix,)
yield find_library(prefix)

prefixes = ['libmagic', 'magic1', 'magic-1', 'cygmagic-1', 'libmagic-1', 'msys-magic-1']

for i in prefixes:
# find_library searches in %PATH% but not the current directory,
# so look for both
yield './%s.dll' % (i,)
yield find_library(i)
def _lib_candidates():
yield find_library("magic")

elif sys.platform == 'linux':
# This is necessary because alpine is bad
yield 'libmagic.so.1'
func = {
"cygwin": _lib_candidates_windows,
"darwin": _lib_candidates_macos,
"linux": _lib_candidates_linux,
"win32": _lib_candidates_windows,
}[sys.platform]
# When we drop legacy Python, we can just `yield from func()`
for path in func():
yield path


def load_lib():
for lib in _lib_candidates():
# find_library returns None when lib not found
if lib:
try:
return ctypes.CDLL(lib)
except OSError:
pass

for lib in _lib_candidates():
# find_library returns None when lib not found
if lib is None:
continue
try:
return ctypes.CDLL(lib)
except OSError:
pass
else:
# It is better to raise an ImportError since we are importing magic module
raise ImportError('failed to find libmagic. Check your installation')

raise ImportError("failed to find libmagic. Check your installation")