Skip to content
Open
Show file tree
Hide file tree
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
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.coverage*
.eggs/
.tox/
bin/
htmlcov/
lib/
pip-selfcheck.json
pyvenv.cfg
11 changes: 8 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
language: python
python:
- 2.6
- 2.7
- 3.2
- 3.3
- 3.4
- 3.5
- 3.6
- pypy
- pypy3
matrix:
fast_finish: true
allow_failures:
- python: pypy
install:
- pip install -r requirements/development.txt -r requirements/production.txt
- python setup.py install
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Next release 1.7
````````````````
* Improved warning message when closing magic.Magic at garbage collection.
* Published Python wheel packages to PyPI to improve install times.
* Update Python versions, provide Tox runner

1.6 (2013-05-29)
````````````````
Expand Down
4 changes: 4 additions & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ erhudy
``````
* added a small patch to correct import behavior on Solaris,
where ctypes.util.find_library does not function correctly.

gyst
````
* Update Python versions, provide Tox runner
6 changes: 3 additions & 3 deletions magic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@

See http://filemagic.readthedocs.org for detailed documentation.
"""
from magic.flags import *
from magic.identify import Magic, MagicError
from magic.version import __version__
from magic.flags import * # flake8:noqa
from magic.identify import Magic, MagicError # flake8:noqa
from magic.version import __version__ # flake8:noqa
5 changes: 4 additions & 1 deletion magic/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import platform
import warnings

libname = ctypes.util.find_library('magic') or ctypes.util.find_library('magic1')
libname = (ctypes.util.find_library('magic')
or ctypes.util.find_library('magic1'))
if not libname:
if platform.system() == 'SunOS':
libname = 'libmagic.so'
Expand All @@ -31,6 +32,7 @@
class Cookie(ctypes.Structure):
"Magic data structure"


c_cookie_p = ctypes.POINTER(Cookie)


Expand Down Expand Up @@ -58,6 +60,7 @@ def errcheck_null(result, func, arguments):
raise MagicError(errno, error)
return result


# dynamically load library
lib.magic_open.argtypes = [ctypes.c_int]
lib.magic_open.restype = c_cookie_p
Expand Down
4 changes: 2 additions & 2 deletions magic/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ def parse_command_line(arguments):
usage = "usage: python -m magic [options] file ..."
parser = OptionParser(usage=usage)
parser.add_option("-m", "--magic", dest="paths",
help="A colon separated list of magic files to use")
help="A colon separated list of magic files to use")
parser.add_option("--json", action="store_true", default=False,
help="Format output in JSON")
help="Format output in JSON")
return parser.parse_args(arguments)


Expand Down
4 changes: 3 additions & 1 deletion magic/compatability.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
bytes_t = bytes
decode_result = True
else:
unicode_t = unicode
unicode_t = unicode # flake8:noqa
bytes_t = str
decode_result = False

Expand All @@ -19,6 +19,7 @@ def byte_args(positions):
"""
def decorator(func):
ordinals = set(positions)

@wraps(func)
def wrapper(*args, **kwargs):
def encoder(args):
Expand Down Expand Up @@ -50,6 +51,7 @@ def str_return(func):
"""
if not decode_result:
return func

@wraps(func)
def wrapper(*args, **kwargs):
value = func(*args, **kwargs)
Expand Down
11 changes: 6 additions & 5 deletions magic/identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ def __init__(self, paths=None, flags=MAGIC_NONE):
"""
self._repr = "Magic(paths={0!r}, flags={1!r})".format(paths, flags)
cookie = api.magic_open(flags)

def cleanup(_):
warnings.warn("magic.Magic() not closed before being garbage "
"collected. Magic.close() should be called when finished"
"with",
CleanupWarning)
"collected. Magic.close() should be called when "
"finished with",
CleanupWarning)
api.magic_close(cookie)
self.weakref = weakref.ref(self, cleanup)
self.cookie = cookie
Expand Down Expand Up @@ -103,8 +104,8 @@ def consistent(self):
def id_buffer(self, buffer):
"Return a textual description of the contents of buffer"
return api.magic_buffer(self.cookie,
api.ctypes.c_char_p(buffer),
len(buffer))
api.ctypes.c_char_p(buffer),
len(buffer))

@raise_if_none('cookie', MagicError, 'object has already been closed')
@byte_args(positions=[1])
Expand Down
10 changes: 6 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def load_rst(filename='docs/source/guide_content'):
author="Aaron Iles",
author_email="aaron.iles@gmail.com",
url="http://filemagic.readthedocs.org",
description="A Python API for libmagic, the library behind the Unix file command",
description="A Python API for libmagic, the library behind the "
"Unix file command",
long_description=load_rst(),
license="ASL",
classifiers=[
Expand All @@ -43,14 +44,15 @@ def load_rst(filename='docs/source/guide_content'):
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries :: Python Modules'
],
tests_require=['mock'] + [] if PYTHON3K else ['unittest2'],
tests_require=['mock'] if PYTHON3K else ['mock', 'unittest2'],
test_suite="tests" if PYTHON3K else "unittest2.collector"
)
22 changes: 13 additions & 9 deletions tests/test_magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_consistent_database(self):

def test_invalid_database(self):
self.assertRaises(magic.MagicError, magic.Magic,
paths=['test/magic/_false_'])
paths=['test/magic/_false_'])

def test_use_after_closed(self):
with magic.Magic() as m:
Expand All @@ -41,43 +41,47 @@ def test_id_buffer(self):

def test_mime_type_file(self):
with magic.Magic(paths=['tests/magic/python'],
flags=magic.MAGIC_MIME_TYPE) as m:
flags=magic.MAGIC_MIME_TYPE) as m:
id = m.id_filename('setup.py')
self.assertEqual(id, 'text/x-python')

def test_mime_type_desc(self):
with magic.Magic(paths=['tests/magic/python'],
flags=magic.MAGIC_MIME_TYPE) as m:
flags=magic.MAGIC_MIME_TYPE) as m:
id = m.id_buffer('#!/usr/bin/env python\n')
self.assertEqual(id, 'text/x-python')

def test_mime_encoding_file(self):
with magic.Magic(paths=['tests/magic/python'],
flags=magic.MAGIC_MIME_ENCODING) as m:
flags=magic.MAGIC_MIME_ENCODING) as m:
id = m.id_filename('setup.py')
self.assertEqual(id, 'us-ascii')

def test_mime_encoding_desc(self):
with magic.Magic(paths=['tests/magic/python'],
flags=magic.MAGIC_MIME_ENCODING) as m:
flags=magic.MAGIC_MIME_ENCODING) as m:
id = m.id_buffer('#!/usr/bin/env python\n')
self.assertEqual(id, 'us-ascii')

def test_repr(self):
with magic.Magic(paths=['tests/magic/python'],
flags=magic.MAGIC_MIME_ENCODING) as m:
flags=magic.MAGIC_MIME_ENCODING) as m:
n = eval(repr(m), {'Magic': magic.Magic})
n.close()

@unittest.skipIf(hasattr(sys, 'pypy_version_info'),
'garbarge collection on PyPy is not deterministic')
@unittest.skipIf(sys.version_info[0] == 2 or sys.version_info[1] < 2,
'ResourceWarning was introduced in python 3.2')
@unittest.skipIf(not hasattr(unittest.TestCase, 'assertWarns'),
'unittest does not support assertWarns')
'unittest does not support assertWarns')
def test_resource_warning(self):
with self.assertWarns(ResourceWarning):
m = magic.Magic()
del m

@unittest.skipIf(hasattr(sys, 'pypy_version_info'),
'garbarge collection on PyPy is not deterministic')
'garbarge collection on PyPy is not deterministic')
def test_weakref(self):
magic_close = magic.api.magic_close
with mock.patch('magic.api.magic_close') as close_mock:
Expand All @@ -87,7 +91,7 @@ def test_weakref(self):
m = magic.Magic()
del m
gc.collect()
self.assertEqual(close_mock.call_count, 1)
self.assertEqual(close_mock.call_count, 1)


if __name__ == '__main__':
Expand Down
39 changes: 39 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[tox]
envlist =
coverage-clean,
py27,
py34,
py35,
py36,
pypy,
pypy3,
coverage-report


[testenv]
commands =
coverage run setup.py test
setenv =
COVERAGE_FILE=.coverage.{envname}
deps =
.[test]
zope.testrunner
coverage

[testenv:coverage-clean]
deps = coverage
setenv =
COVERAGE_FILE=.coverage
skip_install = true
commands = coverage erase

[testenv:coverage-report]
deps = coverage
setenv =
COVERAGE_FILE=.coverage
skip_install = true
commands =
coverage combine
coverage report
coverage html
coverage