Skip to content

Commit 7f7542f

Browse files
committed
Support os.PathLike types
See #251
1 parent 73bcc74 commit 7f7542f

File tree

5 files changed

+41
-6
lines changed

5 files changed

+41
-6
lines changed

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
Changes to 0.4.25:
2+
- Support os.PathLike values in Magic.from_file and magic.from_file
3+
14
Changes to 0.4.24:
25
- Fix regression in library loading on some Alpine docker images.
36

magic/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def from_buffer(self, buf):
100100
# if we're on python3, convert buf to bytes
101101
# otherwise this string is passed as wchar*
102102
# which is not what libmagic expects
103+
# NEXTBREAK: only take bytes
103104
if type(buf) == str and str != bytes:
104105
buf = buf.encode('utf-8', errors='replace')
105106
return maybe_decode(magic_buffer(self.cookie, buf))
@@ -229,6 +230,7 @@ def errorcheck_negative_one(result, func, args):
229230
# return str on python3. Don't want to unconditionally
230231
# decode because that results in unicode on python2
231232
def maybe_decode(s):
233+
# NEXTBREAK: remove
232234
if str == bytes:
233235
return s
234236
else:
@@ -237,13 +239,28 @@ def maybe_decode(s):
237239
return s.decode('utf-8', 'backslashreplace')
238240

239241

242+
try:
243+
from os import PathLike
244+
def unpath(filename):
245+
if isinstance(filename, PathLike):
246+
return filename.__fspath__()
247+
else:
248+
return filename
249+
except ImportError:
250+
def unpath(filename):
251+
return filename
252+
240253
def coerce_filename(filename):
241254
if filename is None:
242255
return None
256+
257+
filename = unpath(filename)
258+
243259
# ctypes will implicitly convert unicode strings to bytes with
244260
# .encode('ascii'). If you use the filesystem encoding
245261
# then you'll get inconsistent behavior (crashes) depending on the user's
246262
# LANG environment variable
263+
# NEXTBREAK: remove
247264
is_unicode = (sys.version_info[0] <= 2 and
248265
isinstance(filename, unicode)) or \
249266
(sys.version_info[0] >= 3 and

magic/__init__.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ctypes.util
22
import threading
33
from typing import Any, Text, Optional, Union
4+
from os import PathLike
45

56
class MagicException(Exception):
67
message: Any = ...
@@ -12,13 +13,13 @@ class Magic:
1213
lock: threading.Lock = ...
1314
def __init__(self, mime: bool = ..., magic_file: Optional[Any] = ..., mime_encoding: bool = ..., keep_going: bool = ..., uncompress: bool = ..., raw: bool = ...) -> None: ...
1415
def from_buffer(self, buf: Union[bytes, str]) -> Text: ...
15-
def from_file(self, filename: Union[bytes, str]) -> Text: ...
16+
def from_file(self, filename: Union[bytes, str, PathLike]) -> Text: ...
1617
def from_descriptor(self, fd: int, mime: bool = ...) -> Text: ...
1718
def setparam(self, param: Any, val: Any): ...
1819
def getparam(self, param: Any): ...
1920
def __del__(self) -> None: ...
2021

21-
def from_file(filename: Union[bytes, str], mime: bool = ...) -> Text: ...
22+
def from_file(filename: Union[bytes, str, PathLike], mime: bool = ...) -> Text: ...
2223
def from_buffer(buffer: Union[bytes, str], mime: bool = ...) -> Text: ...
2324
def from_descriptor(fd: int, mime: bool = ...) -> Text: ...
2425

test/test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ def test_name_count(self):
219219
with open(os.path.join(self.TESTDATA_DIR, 'name_use.jpg'), 'rb') as f:
220220
m.from_buffer(f.read())
221221

222+
def test_pathlike(self):
223+
if sys.version_info < (3, 6):
224+
return
225+
from pathlib import Path
226+
path = Path(self.TESTDATA_DIR, "test.pdf")
227+
m = magic.Magic(mime=True)
228+
self.assertEqual('application/pdf', m.from_file(path))
229+
222230

223231
if __name__ == '__main__':
224232
unittest.main()

test_docker.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@
55

66
set -e
77

8-
NAME=`basename $1`
9-
TAG="python_magic/${NAME}:latest"
10-
docker build -t $TAG -f $1 .
11-
docker run $TAG
8+
DEFAULT_TARGETS="xenial bionic focal centos7 centos8 archlinux alpine"
129

10+
TARGETS=${1:-${DEFAULT_TARGETS}}
11+
12+
HERE=`dirname $0`
13+
14+
for i in $TARGETS; do
15+
TAG="python_magic/${i}:latest"
16+
docker build -t $TAG -f ${HERE}/test/docker/$i .
17+
docker run $TAG
18+
done

0 commit comments

Comments
 (0)