clearml/trains/utilities/lowlevel/file_access.py

90 lines
3.3 KiB
Python
Raw Normal View History

import os
import sys
from functools import partial
import six
from typing import Optional, Any, Callable
def __buffer_writer_close_patch(self):
self._trains_org_close()
# noinspection PyBroadException
try:
self._trains_close_cb(self)
except Exception:
pass
def buffer_writer_close_cb(bufferwriter, callback, overwrite=False):
# type: (Any, Callable[[Any], None], bool) -> ()
# noinspection PyBroadException
try:
if not hasattr(bufferwriter, '_trains_org_close'):
bufferwriter._trains_org_close = bufferwriter.close
bufferwriter.close = partial(__buffer_writer_close_patch, bufferwriter)
elif not overwrite and hasattr(bufferwriter, '_trains_close_cb'):
return
bufferwriter._trains_close_cb = callback
except Exception:
pass
def get_filename_from_file_object(file_object, flush=False, analyze_file_handle=False):
# type: (object, bool, bool) -> Optional[str]
"""
Return a string of the file location, extracted from any file object
:param file_object: str, file, stream, FileIO etc.
:param flush: If True, flush file object before returning (default: False)
:param analyze_file_handle: If True try to retrieve filename from file handler object (default: False)
:return: string full path of file location or None if filename cannot be extract
"""
if isinstance(file_object, six.string_types):
# noinspection PyBroadException
try:
return os.path.abspath(file_object) if file_object else file_object
except Exception:
return file_object
elif hasattr(file_object, 'name'):
filename = file_object.name
if flush:
# noinspection PyBroadException
try:
file_object.flush()
except Exception:
pass
return os.path.abspath(filename)
elif analyze_file_handle and isinstance(file_object, int) or hasattr(file_object, 'fileno'):
# noinspection PyBroadException
try:
fileno = file_object if isinstance(file_object, int) else file_object.fileno()
if sys.platform == 'win32':
import msvcrt
from ctypes import windll, create_string_buffer
handle = msvcrt.get_osfhandle(fileno)
name = create_string_buffer(2050)
windll.kernel32.GetFinalPathNameByHandleA(handle, name, 2048, 0)
filename = name.value.decode('utf-8')
if filename.startswith('\\\\?\\'):
filename = filename[4:]
if flush:
os.fsync(fileno)
return os.path.abspath(filename)
elif sys.platform == 'linux':
filename = os.readlink('/proc/self/fd/{}'.format(fileno))
if flush:
os.fsync(fileno)
return os.path.abspath(filename)
elif sys.platform == 'darwin':
import fcntl
name = b' ' * 1024
# F_GETPATH = 50
name = fcntl.fcntl(fileno, 50, name)
filename = name.split(b'\x00')[0].decode()
if flush:
os.fsync(fileno)
return os.path.abspath(filename)
except Exception:
return None
return None