Open KAWAHARA-souta opened 3 weeks ago
immudb-wrapper: https://github.com/AlmaLinux/immudb-wrapper file-magic(python3-file-magic): https://pypi.org/project/file-magic/ https://www.darwinsys.com/file/ (ソースコードは http://ftp.astron.com/pub/file/)
detect_from_filenameはFileMagicを返す. FileMagicはnamedtupleで定義されている.
62 FileMagic = namedtuple('FileMagic', ('mime_type', 'encoding', 'name'))
:
321 def _create_filemagic(mime_detected, type_detected):
322 try:
323 mime_type, mime_encoding = mime_detected.split('; ')
324 except ValueError:
325 raise ValueError(mime_detected)
326
327 return FileMagic(name=type_detected, mime_type=mime_type,
328 encoding=mime_encoding.replace('charset=', ''))
329
330
331 def detect_from_filename(filename):
332 '''Detect mime type, encoding and file type from a filename
333
334 Returns a `FileMagic` namedtuple.
335 '''
336 x = _detect_make()
337 return _create_filemagic(x.mime_magic.file(filename),
338 x.none_magic.file(filename))
エラーメッセージは,MagicDetectのデストラクタが呼びだされたときでほぼ間違いないと思う. detect_from_filenameの中でも呼び出されている_detect_makeはMagicDetectのインスタンスを返す. たぶんここで生成されたMagicDetectインスタンスの掃除でなにか起こっている.
ところで,312行目でthreadingを動かしているので,これたぶんマルチスレッド? pdbでステップ実行すると問題は発生しないので,マルチスレッドの時のダブルフリーの問題とか? ただ,そうだとしても,なぜimmudb_wrapperをインポートした時しかこれが発生しないのかが結構疑問
285 class MagicDetect(object):
286 def __init__(self):
287 self.mime_magic = open(MAGIC_MIME)
288 if self.mime_magic is None:
289 raise error
290 if self.mime_magic.load() == -1:
291 self.mime_magic.close()
292 self.mime_magic = None
293 raise error
294 self.none_magic = open(MAGIC_NONE)
295 if self.none_magic is None:
296 self.mime_magic.close()
297 self.mime_magic = None
298 raise error
299 if self.none_magic.load() == -1:
300 self.none_magic.close()
301 self.none_magic = None
302 self.mime_magic.close()
303 self.mime_magic = None
304 raise error
305
306 def __del__(self):
307 if self.mime_magic is not None:
308 self.mime_magic.close()
309 if self.none_magic is not None:
310 self.none_magic.close()
311
312 threadlocal = threading.local()
313
314 def _detect_make():
315 v = getattr(threadlocal, "magic_instance", None)
316 if v is None:
317 v = MagicDetect()
318 setattr(threadlocal, "magic_instance", v)
319 return v
threading.local() はスレッド固有の変数を定義する スレッド固有のMagicDetectインスタンスをthreadlocal.magic_instanceに保管しているという感じかな
312 threadlocal = threading.local()
313
314 def _detect_make():
315 v = getattr(threadlocal, "magic_instance", None)
316 if v is None:
317 v = MagicDetect()
318 setattr(threadlocal, "magic_instance", v)
319 return v
Reproducer:
test_python3-file-magic.py
step to reproduce
このエラーが発生する条件