New upstream version 0.4.13
Sophie Brun
6 years ago
0 | language: python | |
1 | ||
2 | # needed to use trusty | |
3 | sudo: required | |
4 | ||
5 | dist: trusty | |
6 | ||
7 | python: | |
8 | - "2.6" | |
9 | - "2.7" | |
10 | - "3.3" | |
11 | - "3.4" | |
12 | - "3.5" | |
13 | - "3.6" | |
14 | - "nightly" | |
15 | ||
16 | install: | |
17 | - pip install coveralls | |
18 | - pip install codecov | |
19 | - python setup.py install | |
20 | ||
21 | script: | |
22 | - coverage run setup.py test | |
23 | ||
24 | after_success: | |
25 | - coveralls | |
26 | - codecov |
0 | The MIT License (MIT) | |
1 | ||
2 | Copyright (c) 2001-2014 Adam Hupp | |
3 | ||
4 | Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 | of this software and associated documentation files (the "Software"), to deal | |
6 | in the Software without restriction, including without limitation the rights | |
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 | copies of the Software, and to permit persons to whom the Software is | |
9 | furnished to do so, subject to the following conditions: | |
10 | ||
11 | The above copyright notice and this permission notice shall be included in all | |
12 | copies or substantial portions of the Software. | |
13 | ||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
20 | SOFTWARE. |
0 | # python-magic | |
1 | [![PyPI version](https://badge.fury.io/py/python-magic.svg)](https://badge.fury.io/py/python-magic) | |
2 | [![Build Status](https://travis-ci.org/ahupp/python-magic.svg?branch=master)](https://travis-ci.org/ahupp/python-magic) | |
3 | ||
4 | python-magic is a python interface to the libmagic file type | |
5 | identification library. libmagic identifies file types by checking | |
6 | their headers according to a predefined list of file types. This | |
7 | functionality is exposed to the command line by the Unix command | |
8 | `file`. | |
9 | ||
10 | ## Usage | |
11 | ||
12 | ```python | |
13 | >>> import magic | |
14 | >>> magic.from_file("testdata/test.pdf") | |
15 | 'PDF document, version 1.2' | |
16 | >>> magic.from_buffer(open("testdata/test.pdf").read(1024)) | |
17 | 'PDF document, version 1.2' | |
18 | >>> magic.from_file("testdata/test.pdf", mime=True) | |
19 | 'application/pdf' | |
20 | ``` | |
21 | ||
22 | There is also a `Magic` class that provides more direct control, | |
23 | including overriding the magic database file and turning on character | |
24 | encoding detection. This is not recommended for general use. In | |
25 | particular, it's not safe for sharing across multiple threads and | |
26 | will fail throw if this is attempted. | |
27 | ||
28 | ```python | |
29 | >>> f = magic.Magic(uncompress=True) | |
30 | >>> f.from_file('testdata/test.gz') | |
31 | 'ASCII text (gzip compressed data, was "test", last modified: Sat Jun 28 | |
32 | 21:32:52 2008, from Unix)' | |
33 | ``` | |
34 | ||
35 | You can also combine the flag options: | |
36 | ||
37 | ```python | |
38 | >>> f = magic.Magic(mime=True, uncompress=True) | |
39 | >>> f.from_file('testdata/test.gz') | |
40 | 'text/plain' | |
41 | ``` | |
42 | ||
43 | ## Name Conflict | |
44 | ||
45 | There are, sadly, two libraries which use the module name `magic`. Both have been around for quite a while.If you are using this module and get an error using a method like `open`, your code is expecting the other one. Hopefully one day these will be reconciled. | |
46 | ||
47 | ## Installation | |
48 | ||
49 | The current stable version of python-magic is available on pypi and | |
50 | can be installed by running `pip install python-magic`. | |
51 | ||
52 | Other sources: | |
53 | ||
54 | - pypi: http://pypi.python.org/pypi/python-magic/ | |
55 | - github: https://github.com/ahupp/python-magic | |
56 | ||
57 | ### Dependencies | |
58 | ||
59 | On Windows, copy magic1.dll, regex2.dll, and zlib1.dll onto your PATH from the Binaries and Dependencies zipfiles provided by the [File for Windows](http://gnuwin32.sourceforge.net/packages/file.htm) project. You will need to copy the file `magic` out of `[binary-zip]\share\misc`, and pass it's location to `Magic(magic_file=...)`. If you are using a 64-bit build of python, you'll need 64-bit libmagic binaries which can be found here: https://github.com/pidydx/libmagicwin64 (note: untested) | |
60 | ||
61 | On OSX: | |
62 | ||
63 | - When using Homebrew: `brew install libmagic` | |
64 | - When using macports: `port install file` | |
65 | ||
66 | ### Troubleshooting | |
67 | ||
68 | - 'MagicException: could not find any magic files!': some | |
69 | installations of libmagic do not correctly point to their magic | |
70 | database file. Try specifying the path to the file explicitly in the | |
71 | constructor: `magic.Magic(magic_file="path_to_magic_file")`. | |
72 | ||
73 | - 'WindowsError: [Error 193] %1 is not a valid Win32 application': | |
74 | Attempting to run the 32-bit libmagic DLL in a 64-bit build of | |
75 | python will fail with this error. Here are 64-bit builds of libmagic for windows: https://github.com/pidydx/libmagicwin64 | |
76 | ||
77 | - 'WindowsError: exception: access violation writing 0x00000000 ' This may indicate you are mixing | |
78 | Windows Python and Cygwin Python. Make sure your libmagic and python builds are consistent. | |
79 | ||
80 | ## Author | |
81 | ||
82 | Written by Adam Hupp in 2001 for a project that never got off the | |
83 | ground. It originally used SWIG for the C library bindings, but | |
84 | switched to ctypes once that was part of the python standard library. | |
85 | ||
86 | You can contact me via my [website](http://hupp.org/adam) or | |
87 | [github](http://github.com/ahupp). | |
88 | ||
89 | ## Contributors | |
90 | ||
91 | Thanks to these folks on github who submitted features and bugfixes. | |
92 | ||
93 | - Amit Sethi | |
94 | - [bigben87](https://github.com/bigben87) | |
95 | - [fallgesetz](https://github.com/fallgesetz) | |
96 | - [FlaPer87](https://github.com/FlaPer87) | |
97 | - [lukenowak](https://github.com/lukenowak) | |
98 | - NicolasDelaby | |
99 | - [email protected] | |
100 | - SimpleSeb | |
101 | - [tehmaze](https://github.com/tehmaze) | |
102 | ||
103 | ## License | |
104 | ||
105 | python-magic is distributed under the MIT license. See the included | |
106 | LICENSE file for details. | |
107 | ||
108 |
0 | """ | |
1 | magic is a wrapper around the libmagic file identification library. | |
2 | ||
3 | See README for more information. | |
4 | ||
5 | Usage: | |
6 | ||
7 | >>> import magic | |
8 | >>> magic.from_file("testdata/test.pdf") | |
9 | 'PDF document, version 1.2' | |
10 | >>> magic.from_file("testdata/test.pdf", mime=True) | |
11 | 'application/pdf' | |
12 | >>> magic.from_buffer(open("testdata/test.pdf").read(1024)) | |
13 | 'PDF document, version 1.2' | |
14 | >>> | |
15 | ||
16 | ||
17 | """ | |
18 | ||
19 | import sys | |
20 | import glob | |
21 | import os.path | |
22 | import ctypes | |
23 | import ctypes.util | |
24 | import threading | |
25 | ||
26 | from ctypes import c_char_p, c_int, c_size_t, c_void_p | |
27 | ||
28 | ||
29 | class MagicException(Exception): | |
30 | def __init__(self, message): | |
31 | super(MagicException, self).__init__(message) | |
32 | self.message = message | |
33 | ||
34 | ||
35 | class Magic: | |
36 | """ | |
37 | Magic is a wrapper around the libmagic C library. | |
38 | ||
39 | """ | |
40 | ||
41 | def __init__(self, mime=False, magic_file=None, mime_encoding=False, | |
42 | keep_going=False, uncompress=False): | |
43 | """ | |
44 | Create a new libmagic wrapper. | |
45 | ||
46 | mime - if True, mimetypes are returned instead of textual descriptions | |
47 | mime_encoding - if True, codec is returned | |
48 | magic_file - use a mime database other than the system default | |
49 | keep_going - don't stop at the first match, keep going | |
50 | uncompress - Try to look inside compressed files. | |
51 | """ | |
52 | self.flags = MAGIC_NONE | |
53 | if mime: | |
54 | self.flags |= MAGIC_MIME | |
55 | if mime_encoding: | |
56 | self.flags |= MAGIC_MIME_ENCODING | |
57 | if keep_going: | |
58 | self.flags |= MAGIC_CONTINUE | |
59 | ||
60 | if uncompress: | |
61 | self.flags |= MAGIC_COMPRESS | |
62 | ||
63 | self.cookie = magic_open(self.flags) | |
64 | self.lock = threading.Lock() | |
65 | ||
66 | magic_load(self.cookie, magic_file) | |
67 | ||
68 | def from_buffer(self, buf): | |
69 | """ | |
70 | Identify the contents of `buf` | |
71 | """ | |
72 | with self.lock: | |
73 | try: | |
74 | return maybe_decode(magic_buffer(self.cookie, buf)) | |
75 | except MagicException as e: | |
76 | return self._handle509Bug(e) | |
77 | ||
78 | def from_file(self, filename): | |
79 | # raise FileNotFoundException or IOError if the file does not exist | |
80 | with open(filename): | |
81 | pass | |
82 | with self.lock: | |
83 | try: | |
84 | return maybe_decode(magic_file(self.cookie, filename)) | |
85 | except MagicException as e: | |
86 | return self._handle509Bug(e) | |
87 | ||
88 | def _handle509Bug(self, e): | |
89 | # libmagic 5.09 has a bug where it might fail to identify the | |
90 | # mimetype of a file and returns null from magic_file (and | |
91 | # likely _buffer), but also does not return an error message. | |
92 | if e.message is None and (self.flags & MAGIC_MIME): | |
93 | return "application/octet-stream" | |
94 | else: | |
95 | raise e | |
96 | ||
97 | def __del__(self): | |
98 | # no _thread_check here because there can be no other | |
99 | # references to this object at this point. | |
100 | ||
101 | # during shutdown magic_close may have been cleared already so | |
102 | # make sure it exists before using it. | |
103 | ||
104 | # the self.cookie check should be unnecessary and was an | |
105 | # incorrect fix for a threading problem, however I'm leaving | |
106 | # it in because it's harmless and I'm slightly afraid to | |
107 | # remove it. | |
108 | if self.cookie and magic_close: | |
109 | magic_close(self.cookie) | |
110 | self.cookie = None | |
111 | ||
112 | _instances = {} | |
113 | ||
114 | def _get_magic_type(mime): | |
115 | i = _instances.get(mime) | |
116 | if i is None: | |
117 | i = _instances[mime] = Magic(mime=mime) | |
118 | return i | |
119 | ||
120 | def from_file(filename, mime=False): | |
121 | """" | |
122 | Accepts a filename and returns the detected filetype. Return | |
123 | value is the mimetype if mime=True, otherwise a human readable | |
124 | name. | |
125 | ||
126 | >>> magic.from_file("testdata/test.pdf", mime=True) | |
127 | 'application/pdf' | |
128 | """ | |
129 | m = _get_magic_type(mime) | |
130 | return m.from_file(filename) | |
131 | ||
132 | def from_buffer(buffer, mime=False): | |
133 | """ | |
134 | Accepts a binary string and returns the detected filetype. Return | |
135 | value is the mimetype if mime=True, otherwise a human readable | |
136 | name. | |
137 | ||
138 | >>> magic.from_buffer(open("testdata/test.pdf").read(1024)) | |
139 | 'PDF document, version 1.2' | |
140 | """ | |
141 | m = _get_magic_type(mime) | |
142 | return m.from_buffer(buffer) | |
143 | ||
144 | ||
145 | ||
146 | ||
147 | libmagic = None | |
148 | # Let's try to find magic or magic1 | |
149 | dll = ctypes.util.find_library('magic') or ctypes.util.find_library('magic1') or ctypes.util.find_library('cygmagic-1') | |
150 | ||
151 | # This is necessary because find_library returns None if it doesn't find the library | |
152 | if dll: | |
153 | libmagic = ctypes.CDLL(dll) | |
154 | ||
155 | if not libmagic or not libmagic._name: | |
156 | windows_dlls = ['magic1.dll','cygmagic-1.dll'] | |
157 | platform_to_lib = {'darwin': ['/opt/local/lib/libmagic.dylib', | |
158 | '/usr/local/lib/libmagic.dylib'] + | |
159 | # Assumes there will only be one version installed | |
160 | glob.glob('/usr/local/Cellar/libmagic/*/lib/libmagic.dylib'), | |
161 | 'win32': windows_dlls, | |
162 | 'cygwin': windows_dlls, | |
163 | 'linux': ['libmagic.so.1'], # fallback for some Linuxes (e.g. Alpine) where library search does not work | |
164 | } | |
165 | platform = 'linux' if sys.platform.startswith('linux') else sys.platform | |
166 | for dll in platform_to_lib.get(platform, []): | |
167 | try: | |
168 | libmagic = ctypes.CDLL(dll) | |
169 | break | |
170 | except OSError: | |
171 | pass | |
172 | ||
173 | if not libmagic or not libmagic._name: | |
174 | # It is better to raise an ImportError since we are importing magic module | |
175 | raise ImportError('failed to find libmagic. Check your installation') | |
176 | ||
177 | magic_t = ctypes.c_void_p | |
178 | ||
179 | def errorcheck_null(result, func, args): | |
180 | if result is None: | |
181 | err = magic_error(args[0]) | |
182 | raise MagicException(err) | |
183 | else: | |
184 | return result | |
185 | ||
186 | def errorcheck_negative_one(result, func, args): | |
187 | if result is -1: | |
188 | err = magic_error(args[0]) | |
189 | raise MagicException(err) | |
190 | else: | |
191 | return result | |
192 | ||
193 | ||
194 | # return str on python3. Don't want to unconditionally | |
195 | # decode because that results in unicode on python2 | |
196 | def maybe_decode(s): | |
197 | if str == bytes: | |
198 | return s | |
199 | else: | |
200 | return s.decode('utf-8') | |
201 | ||
202 | def coerce_filename(filename): | |
203 | if filename is None: | |
204 | return None | |
205 | ||
206 | # ctypes will implicitly convert unicode strings to bytes with | |
207 | # .encode('ascii'). If you use the filesystem encoding | |
208 | # then you'll get inconsistent behavior (crashes) depending on the user's | |
209 | # LANG environment variable | |
210 | is_unicode = (sys.version_info[0] <= 2 and | |
211 | isinstance(filename, unicode)) or \ | |
212 | (sys.version_info[0] >= 3 and | |
213 | isinstance(filename, str)) | |
214 | if is_unicode: | |
215 | return filename.encode('utf-8') | |
216 | else: | |
217 | return filename | |
218 | ||
219 | magic_open = libmagic.magic_open | |
220 | magic_open.restype = magic_t | |
221 | magic_open.argtypes = [c_int] | |
222 | ||
223 | magic_close = libmagic.magic_close | |
224 | magic_close.restype = None | |
225 | magic_close.argtypes = [magic_t] | |
226 | ||
227 | magic_error = libmagic.magic_error | |
228 | magic_error.restype = c_char_p | |
229 | magic_error.argtypes = [magic_t] | |
230 | ||
231 | magic_errno = libmagic.magic_errno | |
232 | magic_errno.restype = c_int | |
233 | magic_errno.argtypes = [magic_t] | |
234 | ||
235 | _magic_file = libmagic.magic_file | |
236 | _magic_file.restype = c_char_p | |
237 | _magic_file.argtypes = [magic_t, c_char_p] | |
238 | _magic_file.errcheck = errorcheck_null | |
239 | ||
240 | def magic_file(cookie, filename): | |
241 | return _magic_file(cookie, coerce_filename(filename)) | |
242 | ||
243 | _magic_buffer = libmagic.magic_buffer | |
244 | _magic_buffer.restype = c_char_p | |
245 | _magic_buffer.argtypes = [magic_t, c_void_p, c_size_t] | |
246 | _magic_buffer.errcheck = errorcheck_null | |
247 | ||
248 | def magic_buffer(cookie, buf): | |
249 | return _magic_buffer(cookie, buf, len(buf)) | |
250 | ||
251 | ||
252 | _magic_load = libmagic.magic_load | |
253 | _magic_load.restype = c_int | |
254 | _magic_load.argtypes = [magic_t, c_char_p] | |
255 | _magic_load.errcheck = errorcheck_negative_one | |
256 | ||
257 | def magic_load(cookie, filename): | |
258 | return _magic_load(cookie, coerce_filename(filename)) | |
259 | ||
260 | magic_setflags = libmagic.magic_setflags | |
261 | magic_setflags.restype = c_int | |
262 | magic_setflags.argtypes = [magic_t, c_int] | |
263 | ||
264 | magic_check = libmagic.magic_check | |
265 | magic_check.restype = c_int | |
266 | magic_check.argtypes = [magic_t, c_char_p] | |
267 | ||
268 | magic_compile = libmagic.magic_compile | |
269 | magic_compile.restype = c_int | |
270 | magic_compile.argtypes = [magic_t, c_char_p] | |
271 | ||
272 | ||
273 | ||
274 | MAGIC_NONE = 0x000000 # No flags | |
275 | MAGIC_DEBUG = 0x000001 # Turn on debugging | |
276 | MAGIC_SYMLINK = 0x000002 # Follow symlinks | |
277 | MAGIC_COMPRESS = 0x000004 # Check inside compressed files | |
278 | MAGIC_DEVICES = 0x000008 # Look at the contents of devices | |
279 | MAGIC_MIME = 0x000010 # Return a mime string | |
280 | MAGIC_MIME_ENCODING = 0x000400 # Return the MIME encoding | |
281 | MAGIC_CONTINUE = 0x000020 # Return all matches | |
282 | MAGIC_CHECK = 0x000040 # Print warnings to stderr | |
283 | MAGIC_PRESERVE_ATIME = 0x000080 # Restore access time on exit | |
284 | MAGIC_RAW = 0x000100 # Don't translate unprintable chars | |
285 | MAGIC_ERROR = 0x000200 # Handle ENOENT etc as real errors | |
286 | ||
287 | MAGIC_NO_CHECK_COMPRESS = 0x001000 # Don't check for compressed files | |
288 | MAGIC_NO_CHECK_TAR = 0x002000 # Don't check for tar files | |
289 | MAGIC_NO_CHECK_SOFT = 0x004000 # Don't check magic entries | |
290 | MAGIC_NO_CHECK_APPTYPE = 0x008000 # Don't check application type | |
291 | MAGIC_NO_CHECK_ELF = 0x010000 # Don't check for elf details | |
292 | MAGIC_NO_CHECK_ASCII = 0x020000 # Don't check for ascii files | |
293 | MAGIC_NO_CHECK_TROFF = 0x040000 # Don't check ascii/troff | |
294 | MAGIC_NO_CHECK_FORTRAN = 0x080000 # Don't check ascii/fortran | |
295 | MAGIC_NO_CHECK_TOKENS = 0x100000 # Don't check ascii/tokens |
0 | #!/usr/bin/env python | |
1 | # -*- coding: utf-8 -*- | |
2 | ||
3 | from setuptools import setup | |
4 | ||
5 | setup(name='python-magic', | |
6 | description='File type identification using libmagic', | |
7 | author='Adam Hupp', | |
8 | author_email='[email protected]', | |
9 | url="http://github.com/ahupp/python-magic", | |
10 | version='0.4.13', | |
11 | py_modules=['magic'], | |
12 | long_description="""This module uses ctypes to access the libmagic file type | |
13 | identification library. It makes use of the local magic database and | |
14 | supports both textual and MIME-type output. | |
15 | """, | |
16 | keywords="mime magic file", | |
17 | license="MIT", | |
18 | test_suite='test', | |
19 | classifiers=[ | |
20 | 'Intended Audience :: Developers', | |
21 | 'License :: OSI Approved :: MIT License', | |
22 | 'Programming Language :: Python', | |
23 | 'Programming Language :: Python :: 2', | |
24 | 'Programming Language :: Python :: 3', | |
25 | ], | |
26 | ) |
0 | #!/bin/sh | |
1 | ||
2 | set -e | |
3 | ||
4 | # ensure we can use unicode filenames in the test | |
5 | export LC_ALL=en_US.UTF-8 | |
6 | THISDIR=`dirname $0` | |
7 | export PYTHONPATH=${THISDIR}/.. | |
8 | ||
9 | python2.6 ${THISDIR}/test.py | |
10 | python2.7 ${THISDIR}/test.py | |
11 | python3 ${THISDIR}/test.py |
0 | import os, sys | |
1 | # for output which reports a local time | |
2 | os.environ['TZ'] = 'GMT' | |
3 | import shutil | |
4 | import os.path | |
5 | import unittest | |
6 | ||
7 | import magic | |
8 | ||
9 | class MagicTest(unittest.TestCase): | |
10 | TESTDATA_DIR = os.path.join(os.path.dirname(__file__), 'testdata') | |
11 | ||
12 | def assert_values(self, m, expected_values): | |
13 | for filename, expected_value in expected_values.items(): | |
14 | try: | |
15 | filename = os.path.join(self.TESTDATA_DIR, filename) | |
16 | except TypeError: | |
17 | filename = os.path.join(self.TESTDATA_DIR.encode('utf-8'), filename) | |
18 | ||
19 | ||
20 | if type(expected_value) is not tuple: | |
21 | expected_value = (expected_value,) | |
22 | ||
23 | for i in expected_value: | |
24 | with open(filename, 'rb') as f: | |
25 | buf_value = m.from_buffer(f.read()) | |
26 | ||
27 | file_value = m.from_file(filename) | |
28 | if buf_value == i and file_value == i: | |
29 | break | |
30 | else: | |
31 | self.assertTrue(False, "no match for " + repr(expected_value)) | |
32 | ||
33 | def test_mime_types(self): | |
34 | dest = os.path.join(MagicTest.TESTDATA_DIR, b'\xce\xbb'.decode('utf-8')) | |
35 | shutil.copyfile(os.path.join(MagicTest.TESTDATA_DIR, 'lambda'), dest) | |
36 | try: | |
37 | m = magic.Magic(mime=True) | |
38 | self.assert_values(m, { | |
39 | 'magic.pyc': 'application/octet-stream', | |
40 | 'test.pdf': 'application/pdf', | |
41 | 'test.gz': 'application/gzip', | |
42 | 'text.txt': 'text/plain', | |
43 | b'\xce\xbb'.decode('utf-8'): 'text/plain', | |
44 | b'\xce\xbb': 'text/plain', | |
45 | }) | |
46 | finally: | |
47 | os.unlink(dest) | |
48 | ||
49 | def test_descriptions(self): | |
50 | m = magic.Magic() | |
51 | os.environ['TZ'] = 'UTC' # To get the last modified date of test.gz in UTC | |
52 | try: | |
53 | self.assert_values(m, { | |
54 | 'magic.pyc': 'python 2.4 byte-compiled', | |
55 | 'test.pdf': 'PDF document, version 1.2', | |
56 | 'test.gz': | |
57 | ('gzip compressed data, was "test", from Unix, last modified: Sun Jun 29 01:32:52 2008', | |
58 | 'gzip compressed data, was "test", last modified: Sun Jun 29 01:32:52 2008, from Unix'), | |
59 | 'text.txt': 'ASCII text', | |
60 | }) | |
61 | finally: | |
62 | del os.environ['TZ'] | |
63 | ||
64 | def test_mime_encodings(self): | |
65 | m = magic.Magic(mime_encoding=True) | |
66 | self.assert_values(m, { | |
67 | 'text-iso8859-1.txt': 'iso-8859-1', | |
68 | 'text.txt': 'us-ascii', | |
69 | }) | |
70 | ||
71 | def test_errors(self): | |
72 | m = magic.Magic() | |
73 | self.assertRaises(IOError, m.from_file, 'nonexistent') | |
74 | self.assertRaises(magic.MagicException, magic.Magic, | |
75 | magic_file='nonexistent') | |
76 | os.environ['MAGIC'] = 'nonexistent' | |
77 | try: | |
78 | self.assertRaises(magic.MagicException, magic.Magic) | |
79 | finally: | |
80 | del os.environ['MAGIC'] | |
81 | ||
82 | def test_keep_going(self): | |
83 | filename = os.path.join(self.TESTDATA_DIR, 'keep-going.jpg') | |
84 | ||
85 | m = magic.Magic(mime=True) | |
86 | self.assertEqual(m.from_file(filename), 'image/jpeg') | |
87 | ||
88 | m = magic.Magic(mime=True, keep_going=True) | |
89 | self.assertEqual(m.from_file(filename), 'image/jpeg') | |
90 | ||
91 | ||
92 | def test_rethrow(self): | |
93 | old = magic.magic_buffer | |
94 | try: | |
95 | def t(x,y): | |
96 | raise magic.MagicException("passthrough") | |
97 | magic.magic_buffer = t | |
98 | ||
99 | self.assertRaises(magic.MagicException, magic.from_buffer, "hello", True) | |
100 | finally: | |
101 | magic.magic_buffer = old | |
102 | if __name__ == '__main__': | |
103 | unittest.main() |
Binary diff not shown
0 | test |
Binary diff not shown
Binary diff not shown
0 | %PDF-1.2 | |
1 | 7 0 obj | |
2 | [5 0 R/XYZ 111.6 757.86] | |
3 | endobj | |
4 | 13 0 obj | |
5 | << | |
6 | /Title(About this document) | |
7 | /A<< | |
8 | /S/GoTo | |
9 | /D(subsection.1.1) | |
10 | >> | |
11 | /Parent 12 0 R | |
12 | /Next 14 0 R | |
13 | >> | |
14 | endobj | |
15 | 15 0 obj | |
16 | << | |
17 | /Title(Compiling with GHC) | |
18 | /A<< | |
19 | /S/GoTo | |
20 | /D(subsubsection.1.2.1) | |
21 | >> | |
22 | /Parent 14 0 R | |
23 | /Next 16 0 R | |
24 | >> | |
25 | endobj | |
26 | 16 0 obj | |
27 | << | |
28 | /Title(Compiling with Hugs) | |
29 | /A<< | |
30 | /S/GoTo | |
31 | /D(subsubsection.1.2.2) | |
32 | >> | |
33 | /Parent 14 0 R | |
34 | /Prev 15 0 R | |
35 | >> | |
36 | endobj | |
37 | 14 0 obj | |
38 | << | |
39 | /Title(Compatibility) | |
40 | /A<< | |
41 | /S/GoTo | |
42 | /D(subsection.1.2) | |
43 | >> | |
44 | /Parent 12 0 R | |
45 | /Prev 13 0 R | |
46 | /First 15 0 R | |
47 | /Last 16 0 R | |
48 | /Count -2 | |
49 | /Next 17 0 R | |
50 | >> | |
51 | endobj | |
52 | 17 0 obj | |
53 | << | |
54 | /Title(Reporting bugs) | |
55 | /A<< | |
56 | /S/GoTo | |
57 | /D(subsection.1.3) | |
58 | >> | |
59 | /Parent 12 0 R | |
60 | /Prev 14 0 R | |
61 | /Next 18 0 R | |
62 | >> | |
63 | endobj | |
64 | 18 0 obj | |
65 | << | |
66 | /Title(History) | |
67 | /A<< | |
68 | /S/GoTo | |
69 | /D(subsection.1.4) | |
70 | >> | |
71 | /Parent 12 0 R | |
72 | /Prev 17 0 R | |
73 | /Next 19 0 R | |
74 | >> | |
75 | endobj | |
76 | 19 0 obj | |
77 | << | |
78 | /Title(License) | |
79 | /A<< | |
80 | /S/GoTo | |
81 | /D(subsection.1.5) | |
82 | >> | |
83 | /Parent 12 0 R | |
84 | /Prev 18 0 R | |
85 | >> | |
86 | endobj | |
87 | 12 0 obj | |
88 | << | |
89 | /Title(Introduction) | |
90 | /A<< | |
91 | /S/GoTo | |
92 | /D(section.1) | |
93 | >> | |
94 | /Parent 11 0 R | |
95 | /First 13 0 R | |
96 | /Last 19 0 R | |
97 | /Count -5 | |
98 | /Next 20 0 R | |
99 | >> | |
100 | endobj | |
101 | 21 0 obj | |
102 | << | |
103 | /Title(Running a parser) | |
104 | /A<< | |
105 | /S/GoTo | |
106 | /D(subsection.2.1) | |
107 | >> | |
108 | /Parent 20 0 R | |
109 | /Next 22 0 R | |
110 | >> | |
111 | endobj | |
112 | 22 0 obj | |
113 | << | |
114 | /Title(Sequence and choice) | |
115 | /A<< | |
116 | /S/GoTo | |
117 | /D(subsection.2.2) | |
118 | >> | |
119 | /Parent 20 0 R | |
120 | /Prev 21 0 R | |
121 | /Next 23 0 R | |
122 | >> | |
123 | endobj | |
124 | 23 0 obj | |
125 | << | |
126 | /Title(Predictive parsers) | |
127 | /A<< | |
128 | /S/GoTo | |
129 | /D(subsection.2.3) | |
130 | >> | |
131 | /Parent 20 0 R | |
132 | /Prev 22 0 R | |
133 | /Next 24 0 R | |
134 | >> | |
135 | endobj | |
136 | 24 0 obj | |
137 | << | |
138 | /Title(Adding semantics) | |
139 | /A<< | |
140 | /S/GoTo | |
141 | /D(subsection.2.4) | |
142 | >> | |
143 | /Parent 20 0 R | |
144 | /Prev 23 0 R | |
145 | /Next 25 0 R | |
146 | >> | |
147 | endobj | |
148 | 25 0 obj | |
149 | << | |
150 | /Title(Sequences and seperators) | |
151 | /A<< | |
152 | /S/GoTo | |
153 | /D(subsection.2.5) | |
154 | >> | |
155 | /Parent 20 0 R | |
156 | /Prev 24 0 R | |
157 | /Next 26 0 R | |
158 | >> | |
159 | endobj | |
160 | 26 0 obj | |
161 | << | |
162 | /Title(Improving error messages) | |
163 | /A<< | |
164 | /S/GoTo | |
165 | /D(subsection.2.6) | |
166 | >> | |
167 | /Parent 20 0 R | |
168 | /Prev 25 0 R | |
169 | /Next 27 0 R | |
170 | >> | |
171 | endobj | |
172 | 27 0 obj | |
173 | << | |
174 | /Title(Expressions) | |
175 | /A<< | |
176 | /S/GoTo | |
177 | /D(subsection.2.7) | |
178 | >> | |
179 | /Parent 20 0 R | |
180 | /Prev 26 0 R | |
181 | /Next 28 0 R | |
182 | >> | |
183 | endobj | |
184 | 28 0 obj | |
185 | << | |
186 | /Title(Lexical analysis) | |
187 | /A<< | |
188 | /S/GoTo | |
189 | /D(subsection.2.8) | |
190 | >> | |
191 | /Parent 20 0 R | |
192 | /Prev 27 0 R | |
193 | /Next 29 0 R | |
194 | >> | |
195 | endobj | |
196 | 30 0 obj | |
197 | << | |
198 | /Title(Lexeme parsers⏎ |