Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/magic/compat.py: 74%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# coding: utf-8
3'''
4Python bindings for libmagic
5'''
7import ctypes
9from collections import namedtuple
11from ctypes import *
12from ctypes.util import find_library
15from . import loader
17_libraries = {}
18_libraries['magic'] = loader.load_lib()
20# Flag constants for open and setflags
21MAGIC_NONE = NONE = 0
22MAGIC_DEBUG = DEBUG = 1
23MAGIC_SYMLINK = SYMLINK = 2
24MAGIC_COMPRESS = COMPRESS = 4
25MAGIC_DEVICES = DEVICES = 8
26MAGIC_MIME_TYPE = MIME_TYPE = 16
27MAGIC_CONTINUE = CONTINUE = 32
28MAGIC_CHECK = CHECK = 64
29MAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128
30MAGIC_RAW = RAW = 256
31MAGIC_ERROR = ERROR = 512
32MAGIC_MIME_ENCODING = MIME_ENCODING = 1024
33MAGIC_MIME = MIME = 1040 # MIME_TYPE + MIME_ENCODING
34MAGIC_APPLE = APPLE = 2048
36MAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096
37MAGIC_NO_CHECK_TAR = NO_CHECK_TAR = 8192
38MAGIC_NO_CHECK_SOFT = NO_CHECK_SOFT = 16384
39MAGIC_NO_CHECK_APPTYPE = NO_CHECK_APPTYPE = 32768
40MAGIC_NO_CHECK_ELF = NO_CHECK_ELF = 65536
41MAGIC_NO_CHECK_TEXT = NO_CHECK_TEXT = 131072
42MAGIC_NO_CHECK_CDF = NO_CHECK_CDF = 262144
43MAGIC_NO_CHECK_TOKENS = NO_CHECK_TOKENS = 1048576
44MAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152
46MAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824
48FileMagic = namedtuple('FileMagic', ('mime_type', 'encoding', 'name'))
51class magic_set(Structure):
52 pass
55magic_set._fields_ = []
56magic_t = POINTER(magic_set)
58_open = _libraries['magic'].magic_open
59_open.restype = magic_t
60_open.argtypes = [c_int]
62_close = _libraries['magic'].magic_close
63_close.restype = None
64_close.argtypes = [magic_t]
66_file = _libraries['magic'].magic_file
67_file.restype = c_char_p
68_file.argtypes = [magic_t, c_char_p]
70_descriptor = _libraries['magic'].magic_descriptor
71_descriptor.restype = c_char_p
72_descriptor.argtypes = [magic_t, c_int]
74_buffer = _libraries['magic'].magic_buffer
75_buffer.restype = c_char_p
76_buffer.argtypes = [magic_t, c_void_p, c_size_t]
78_error = _libraries['magic'].magic_error
79_error.restype = c_char_p
80_error.argtypes = [magic_t]
82_setflags = _libraries['magic'].magic_setflags
83_setflags.restype = c_int
84_setflags.argtypes = [magic_t, c_int]
86_load = _libraries['magic'].magic_load
87_load.restype = c_int
88_load.argtypes = [magic_t, c_char_p]
90_compile = _libraries['magic'].magic_compile
91_compile.restype = c_int
92_compile.argtypes = [magic_t, c_char_p]
94_check = _libraries['magic'].magic_check
95_check.restype = c_int
96_check.argtypes = [magic_t, c_char_p]
98_list = _libraries['magic'].magic_list
99_list.restype = c_int
100_list.argtypes = [magic_t, c_char_p]
102_errno = _libraries['magic'].magic_errno
103_errno.restype = c_int
104_errno.argtypes = [magic_t]
107class Magic(object):
108 def __init__(self, ms):
109 self._magic_t = ms
111 def close(self):
112 """
113 Closes the magic database and deallocates any resources used.
114 """
115 _close(self._magic_t)
117 @staticmethod
118 def __tostr(s):
119 if s is None:
120 return None
121 if isinstance(s, str):
122 return s
123 try: # keep Python 2 compatibility
124 return str(s, 'utf-8')
125 except TypeError:
126 return str(s)
128 @staticmethod
129 def __tobytes(b):
130 if b is None:
131 return None
132 if isinstance(b, bytes):
133 return b
134 try: # keep Python 2 compatibility
135 return bytes(b, 'utf-8')
136 except TypeError:
137 return bytes(b)
139 def file(self, filename):
140 """
141 Returns a textual description of the contents of the argument passed
142 as a filename or None if an error occurred and the MAGIC_ERROR flag
143 is set. A call to errno() will return the numeric error code.
144 """
145 return Magic.__tostr(_file(self._magic_t, Magic.__tobytes(filename)))
147 def descriptor(self, fd):
148 """
149 Returns a textual description of the contents of the argument passed
150 as a file descriptor or None if an error occurred and the MAGIC_ERROR
151 flag is set. A call to errno() will return the numeric error code.
152 """
153 return Magic.__tostr(_descriptor(self._magic_t, fd))
155 def buffer(self, buf):
156 """
157 Returns a textual description of the contents of the argument passed
158 as a buffer or None if an error occurred and the MAGIC_ERROR flag
159 is set. A call to errno() will return the numeric error code.
160 """
161 return Magic.__tostr(_buffer(self._magic_t, buf, len(buf)))
163 def error(self):
164 """
165 Returns a textual explanation of the last error or None
166 if there was no error.
167 """
168 return Magic.__tostr(_error(self._magic_t))
170 def setflags(self, flags):
171 """
172 Set flags on the magic object which determine how magic checking
173 behaves; a bitwise OR of the flags described in libmagic(3), but
174 without the MAGIC_ prefix.
176 Returns -1 on systems that don't support utime(2) or utimes(2)
177 when PRESERVE_ATIME is set.
178 """
179 return _setflags(self._magic_t, flags)
181 def load(self, filename=None):
182 """
183 Must be called to load entries in the colon separated list of database
184 files passed as argument or the default database file if no argument
185 before any magic queries can be performed.
187 Returns 0 on success and -1 on failure.
188 """
189 return _load(self._magic_t, Magic.__tobytes(filename))
191 def compile(self, dbs):
192 """
193 Compile entries in the colon separated list of database files
194 passed as argument or the default database file if no argument.
195 The compiled files created are named from the basename(1) of each file
196 argument with ".mgc" appended to it.
198 Returns 0 on success and -1 on failure.
199 """
200 return _compile(self._magic_t, Magic.__tobytes(dbs))
202 def check(self, dbs):
203 """
204 Check the validity of entries in the colon separated list of
205 database files passed as argument or the default database file
206 if no argument.
208 Returns 0 on success and -1 on failure.
209 """
210 return _check(self._magic_t, Magic.__tobytes(dbs))
212 def list(self, dbs):
213 """
214 Check the validity of entries in the colon separated list of
215 database files passed as argument or the default database file
216 if no argument.
218 Returns 0 on success and -1 on failure.
219 """
220 return _list(self._magic_t, Magic.__tobytes(dbs))
222 def errno(self):
223 """
224 Returns a numeric error code. If return value is 0, an internal
225 magic error occurred. If return value is non-zero, the value is
226 an OS error code. Use the errno module or os.strerror() can be used
227 to provide detailed error information.
228 """
229 return _errno(self._magic_t)
232def open(flags):
233 """
234 Returns a magic object on success and None on failure.
235 Flags argument as for setflags.
236 """
237 return Magic(_open(flags))
240# Objects used by `detect_from_` functions
241mime_magic = Magic(_open(MAGIC_MIME))
242mime_magic.load()
243none_magic = Magic(_open(MAGIC_NONE))
244none_magic.load()
247def _create_filemagic(mime_detected, type_detected):
248 splat = mime_detected.split('; ')
249 mime_type = splat[0]
250 if len(splat) == 2:
251 mime_encoding = splat[1]
252 else:
253 mime_encoding = ''
255 return FileMagic(name=type_detected, mime_type=mime_type,
256 encoding=mime_encoding.replace('charset=', ''))
259def detect_from_filename(filename):
260 '''Detect mime type, encoding and file type from a filename
262 Returns a `FileMagic` namedtuple.
263 '''
265 return _create_filemagic(mime_magic.file(filename),
266 none_magic.file(filename))
269def detect_from_fobj(fobj):
270 '''Detect mime type, encoding and file type from file-like object
272 Returns a `FileMagic` namedtuple.
273 '''
275 file_descriptor = fobj.fileno()
276 return _create_filemagic(mime_magic.descriptor(file_descriptor),
277 none_magic.descriptor(file_descriptor))
280def detect_from_content(byte_content):
281 '''Detect mime type, encoding and file type from bytes
283 Returns a `FileMagic` namedtuple.
284 '''
286 return _create_filemagic(mime_magic.buffer(byte_content),
287 none_magic.buffer(byte_content))