summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Hupp <adam@hupp.org>2021-10-04 14:46:37 -0700
committerAdam Hupp <adam@hupp.org>2021-10-04 16:04:28 -0700
commit7f7542fcbc192fef6e4939f4eb748e941a720b2c (patch)
tree8a1bebe0cfa08dd0148aa5120f9768cdfcfe50a1
parent73bcc7482bf3e6d1f6a74a91bf9689b289a88910 (diff)
downloadpython-magic-7f7542fcbc192fef6e4939f4eb748e941a720b2c.tar.gz
Support os.PathLike types
See https://github.com/ahupp/python-magic/pull/251
-rw-r--r--CHANGELOG3
-rw-r--r--magic/__init__.py17
-rw-r--r--magic/__init__.pyi5
-rwxr-xr-xtest/test.py8
-rwxr-xr-xtest_docker.sh14
5 files changed, 41 insertions, 6 deletions
diff --git a/CHANGELOG b/CHANGELOG
index c578572..26e01f4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+Changes to 0.4.25:
+ - Support os.PathLike values in Magic.from_file and magic.from_file
+
Changes to 0.4.24:
- Fix regression in library loading on some Alpine docker images.
diff --git a/magic/__init__.py b/magic/__init__.py
index 363e88f..bab7c7b 100644
--- a/magic/__init__.py
+++ b/magic/__init__.py
@@ -100,6 +100,7 @@ class Magic:
# if we're on python3, convert buf to bytes
# otherwise this string is passed as wchar*
# which is not what libmagic expects
+ # NEXTBREAK: only take bytes
if type(buf) == str and str != bytes:
buf = buf.encode('utf-8', errors='replace')
return maybe_decode(magic_buffer(self.cookie, buf))
@@ -229,6 +230,7 @@ def errorcheck_negative_one(result, func, args):
# return str on python3. Don't want to unconditionally
# decode because that results in unicode on python2
def maybe_decode(s):
+ # NEXTBREAK: remove
if str == bytes:
return s
else:
@@ -237,13 +239,28 @@ def maybe_decode(s):
return s.decode('utf-8', 'backslashreplace')
+try:
+ from os import PathLike
+ def unpath(filename):
+ if isinstance(filename, PathLike):
+ return filename.__fspath__()
+ else:
+ return filename
+except ImportError:
+ def unpath(filename):
+ return filename
+
def coerce_filename(filename):
if filename is None:
return None
+
+ filename = unpath(filename)
+
# ctypes will implicitly convert unicode strings to bytes with
# .encode('ascii'). If you use the filesystem encoding
# then you'll get inconsistent behavior (crashes) depending on the user's
# LANG environment variable
+ # NEXTBREAK: remove
is_unicode = (sys.version_info[0] <= 2 and
isinstance(filename, unicode)) or \
(sys.version_info[0] >= 3 and
diff --git a/magic/__init__.pyi b/magic/__init__.pyi
index 8d5f38f..b6b5489 100644
--- a/magic/__init__.pyi
+++ b/magic/__init__.pyi
@@ -1,6 +1,7 @@
import ctypes.util
import threading
from typing import Any, Text, Optional, Union
+from os import PathLike
class MagicException(Exception):
message: Any = ...
@@ -12,13 +13,13 @@ class Magic:
lock: threading.Lock = ...
def __init__(self, mime: bool = ..., magic_file: Optional[Any] = ..., mime_encoding: bool = ..., keep_going: bool = ..., uncompress: bool = ..., raw: bool = ...) -> None: ...
def from_buffer(self, buf: Union[bytes, str]) -> Text: ...
- def from_file(self, filename: Union[bytes, str]) -> Text: ...
+ def from_file(self, filename: Union[bytes, str, PathLike]) -> Text: ...
def from_descriptor(self, fd: int, mime: bool = ...) -> Text: ...
def setparam(self, param: Any, val: Any): ...
def getparam(self, param: Any): ...
def __del__(self) -> None: ...
-def from_file(filename: Union[bytes, str], mime: bool = ...) -> Text: ...
+def from_file(filename: Union[bytes, str, PathLike], mime: bool = ...) -> Text: ...
def from_buffer(buffer: Union[bytes, str], mime: bool = ...) -> Text: ...
def from_descriptor(fd: int, mime: bool = ...) -> Text: ...
diff --git a/test/test.py b/test/test.py
index 0cd12fd..0c4621c 100755
--- a/test/test.py
+++ b/test/test.py
@@ -219,6 +219,14 @@ class MagicTest(unittest.TestCase):
with open(os.path.join(self.TESTDATA_DIR, 'name_use.jpg'), 'rb') as f:
m.from_buffer(f.read())
+ def test_pathlike(self):
+ if sys.version_info < (3, 6):
+ return
+ from pathlib import Path
+ path = Path(self.TESTDATA_DIR, "test.pdf")
+ m = magic.Magic(mime=True)
+ self.assertEqual('application/pdf', m.from_file(path))
+
if __name__ == '__main__':
unittest.main()
diff --git a/test_docker.sh b/test_docker.sh
index 59d6b7c..ad2bc5d 100755
--- a/test_docker.sh
+++ b/test_docker.sh
@@ -5,8 +5,14 @@
set -e
-NAME=`basename $1`
-TAG="python_magic/${NAME}:latest"
-docker build -t $TAG -f $1 .
-docker run $TAG
+DEFAULT_TARGETS="xenial bionic focal centos7 centos8 archlinux alpine"
+TARGETS=${1:-${DEFAULT_TARGETS}}
+
+HERE=`dirname $0`
+
+for i in $TARGETS; do
+ TAG="python_magic/${i}:latest"
+ docker build -t $TAG -f ${HERE}/test/docker/$i .
+ docker run $TAG
+done