Skip to content

Commit d033eb4

Browse files
committed
Support python 3
- various unicode/bytes test fixes - resolve an (undocumented?) change in how ctypes converts unicode strings to char string by always using the default filesystem encoding. Test Plan: adam@gaba:~/github/python-magic$ python test.py ..... ---------------------------------------------------------------------- Ran 5 tests in 0.010s OK adam@gaba:~/github/python-magic$ python3 test.py ..... ---------------------------------------------------------------------- Ran 5 tests in 0.016s OK adam@gaba:~/github/python-magic$ ~/opt/python3.3/bin/python3 test.py .. snip ... ---------------------------------------------------------------------- Ran 5 tests in 0.025s
1 parent 4d98bc0 commit d033eb4

2 files changed

Lines changed: 35 additions & 22 deletions

File tree

magic.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
1818
"""
1919

20+
import sys
2021
import os.path
2122
import ctypes
2223
import ctypes.util
@@ -139,6 +140,11 @@ def errorcheck(result, func, args):
139140
else:
140141
return result
141142

143+
def coerce_filename(filename):
144+
if filename is None:
145+
return None
146+
return filename.encode(sys.getfilesystemencoding())
147+
142148
magic_open = libmagic.magic_open
143149
magic_open.restype = magic_t
144150
magic_open.argtypes = [c_int]
@@ -155,11 +161,13 @@ def errorcheck(result, func, args):
155161
magic_errno.restype = c_int
156162
magic_errno.argtypes = [magic_t]
157163

158-
magic_file = libmagic.magic_file
159-
magic_file.restype = c_char_p
160-
magic_file.argtypes = [magic_t, c_char_p]
161-
magic_file.errcheck = errorcheck
164+
_magic_file = libmagic.magic_file
165+
_magic_file.restype = c_char_p
166+
_magic_file.argtypes = [magic_t, c_char_p]
167+
_magic_file.errcheck = errorcheck
162168

169+
def magic_file(cookie, filename):
170+
return _magic_file(cookie, coerce_filename(filename))
163171

164172
_magic_buffer = libmagic.magic_buffer
165173
_magic_buffer.restype = c_char_p
@@ -171,10 +179,13 @@ def magic_buffer(cookie, buf):
171179
return _magic_buffer(cookie, buf, len(buf))
172180

173181

174-
magic_load = libmagic.magic_load
175-
magic_load.restype = c_int
176-
magic_load.argtypes = [magic_t, c_char_p]
177-
magic_load.errcheck = errorcheck
182+
_magic_load = libmagic.magic_load
183+
_magic_load.restype = c_int
184+
_magic_load.argtypes = [magic_t, c_char_p]
185+
_magic_load.errcheck = errorcheck
186+
187+
def magic_load(cookie, filename):
188+
return _magic_load(cookie, coerce_filename(filename))
178189

179190
magic_setflags = libmagic.magic_setflags
180191
magic_setflags.restype = c_int

test.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,28 @@
22
import os.path
33
import unittest
44
import random
5-
from StringIO import StringIO
5+
import magic
66
from os import path
7-
from magic import Magic, MagicException
7+
88

99
testfile = [
10-
("magic.pyc", "python 2.4 byte-compiled", "application/octet-stream"),
11-
("test.pdf", "PDF document, version 1.2", "application/pdf"),
12-
("test.gz", 'gzip compressed data, was "test", from Unix, last modified: '
13-
'Sat Jun 28 18:32:52 2008', "application/x-gzip"),
14-
("text.txt", "ASCII text", "text/plain"),
10+
("magic.pyc", b"python 2.4 byte-compiled", b"application/octet-stream"),
11+
("test.pdf", b"PDF document, version 1.2", b"application/pdf"),
12+
("test.gz", b'gzip compressed data, was "test", from Unix, last modified: '
13+
b'Sat Jun 28 18:32:52 2008', b"application/x-gzip"),
14+
("text.txt", b"ASCII text", b"text/plain"),
15+
# is there no better way to encode a unicode literal across python2/3.[01]/3.3?
16+
(b"\xce\xbb".decode('utf-8'), b"empty", b"application/x-empty")
1517
]
1618

17-
testFileEncoding = [('text-iso8859-1.txt', 'iso-8859-1')]
19+
testFileEncoding = [('text-iso8859-1.txt', b'iso-8859-1')]
1820

1921
class TestMagic(unittest.TestCase):
2022

2123
mime = False
2224

2325
def setUp(self):
24-
self.m = Magic(mime=self.mime)
26+
self.m = magic.Magic(mime=self.mime)
2527

2628
def testFileTypes(self):
2729
for filename, desc, mime in testfile:
@@ -33,30 +35,30 @@ def testFileTypes(self):
3335
else:
3436
target = desc
3537

36-
self.assertEqual(target, self.m.from_buffer(open(filename).read(1024)))
38+
self.assertEqual(target, self.m.from_buffer(open(filename, 'rb').read(1024)))
3739
self.assertEqual(target, self.m.from_file(filename), filename)
3840

3941

4042
def testErrors(self):
4143
self.assertRaises(IOError, self.m.from_file, "nonexistent")
42-
self.assertRaises(MagicException, Magic, magic_file="noneexistent")
44+
self.assertRaises(magic.MagicException, magic.Magic, magic_file="noneexistent")
4345
os.environ['MAGIC'] = '/nonexistetn'
44-
self.assertRaises(MagicException, Magic)
46+
self.assertRaises(magic.MagicException, magic.Magic)
4547
del os.environ['MAGIC']
4648

4749
class TestMagicMime(TestMagic):
4850
mime = True
4951

5052
class TestMagicMimeEncoding(unittest.TestCase):
5153
def setUp(self):
52-
self.m = Magic(mime_encoding=True)
54+
self.m = magic.Magic(mime_encoding=True)
5355

5456
def testFileEncoding(self):
5557
for filename, encoding in testFileEncoding:
5658
filename = path.join(path.dirname(__file__),
5759
"testdata",
5860
filename)
59-
self.assertEqual(encoding, self.m.from_buffer(open(filename).read(1024)))
61+
self.assertEqual(encoding, self.m.from_buffer(open(filename, 'rb').read(1024)))
6062
self.assertEqual(encoding, self.m.from_file(filename), filename)
6163

6264

0 commit comments

Comments
 (0)