summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristos Zoulas <christos@zoulas.com>2021-09-09 17:48:54 +0000
committerChristos Zoulas <christos@zoulas.com>2021-09-09 17:48:54 +0000
commitc8deb32eab1089d1841482fb2e91833f114b6712 (patch)
treea6c63ec9466f777913c31ad1574d9a8ca529d871
parent0e6b4a09765cf3ad46a374172df52258c4e3fb97 (diff)
downloadfile-git-c8deb32eab1089d1841482fb2e91833f114b6712.tar.gz
PR/285: Benjamin: python detect functions don't work in a multi-threaded
context.
-rw-r--r--python/CHANGELOG.md5
-rw-r--r--python/magic.py43
2 files changed, 35 insertions, 13 deletions
diff --git a/python/CHANGELOG.md b/python/CHANGELOG.md
index ac3c0c0e..2634986b 100644
--- a/python/CHANGELOG.md
+++ b/python/CHANGELOG.md
@@ -1,5 +1,10 @@
# Python `file-magic` Log of Changes
+## `0.4.1`
+
+- Create threadlocal objects so that the `detect_from_*` methods work properly
+
+
## `0.4.0`
- Sync with current version of file:
diff --git a/python/magic.py b/python/magic.py
index 0c17caf2..4b074f31 100644
--- a/python/magic.py
+++ b/python/magic.py
@@ -5,6 +5,7 @@ Python bindings for libmagic
'''
import ctypes
+import threading
from collections import namedtuple
@@ -250,7 +251,7 @@ class Magic(object):
def getparam(self, param):
"""
Returns the param value if successful and -1 if the parameter
- was unknown.
+ was unknown.
"""
v = c_int()
i = _getparam(self._magic_t, param, byref(v))
@@ -275,11 +276,25 @@ def open(flags):
# Objects used by `detect_from_` functions
-mime_magic = Magic(_open(MAGIC_MIME))
-mime_magic.load()
-none_magic = Magic(_open(MAGIC_NONE))
-none_magic.load()
-
+class MagicDetect(object):
+ def __init__(self):
+ self.mime_magic = Magic(_open(MAGIC_MIME))
+ self.mime_magic.load()
+ self.none_magic = Magic(_open(MAGIC_NONE))
+ self.none_magic.load()
+
+ def __del__(self):
+ self.mime_magic.close()
+ self.none_magic.close()
+
+threadlocal = threading.local()
+
+def _detect_make():
+ v = getattr(threadlocal, "magic_instance", None)
+ if v is None:
+ v = MagicDetect()
+ setattr(threadlocal, "magic_instance", v)
+ return v
def _create_filemagic(mime_detected, type_detected):
try:
@@ -296,9 +311,9 @@ def detect_from_filename(filename):
Returns a `FileMagic` namedtuple.
'''
-
- return _create_filemagic(mime_magic.file(filename),
- none_magic.file(filename))
+ x = _detect_make()
+ return _create_filemagic(x.mime_magic.file(filename),
+ x.none_magic.file(filename))
def detect_from_fobj(fobj):
@@ -308,8 +323,9 @@ def detect_from_fobj(fobj):
'''
file_descriptor = fobj.fileno()
- return _create_filemagic(mime_magic.descriptor(file_descriptor),
- none_magic.descriptor(file_descriptor))
+ x = _detect_make()
+ return _create_filemagic(x.mime_magic.descriptor(file_descriptor),
+ x.none_magic.descriptor(file_descriptor))
def detect_from_content(byte_content):
@@ -318,5 +334,6 @@ def detect_from_content(byte_content):
Returns a `FileMagic` namedtuple.
'''
- return _create_filemagic(mime_magic.buffer(byte_content),
- none_magic.buffer(byte_content))
+ x = _detect_make()
+ return _create_filemagic(x.mime_magic.buffer(byte_content),
+ x.none_magic.buffer(byte_content))