以下のコードで再現すればGitHubのIssueへレポートするのがいいんじゃないでしょうか。
python
1from io import BytesIO
2from os import environ
3from boto3 import Session
4
5
6creds = dict(aws_access_key_id=environ.get("AWS_ACCESS_KEY_ID"),
7 aws_secret_access_key=environ.get("AWS_SECRET_ACCESS_KEY"),
8 region_name=environ.get("AWS_DEFAULT_REGION "))
9
10
11with Session(**creds) as sess, BytesIO("DUMMY") as fp:
12 client = sess.resource("s3").meta.client
13 for i in range(10):
14 fp.seek(0)
15 client.upload_fileobj(fp, "my-test-bucket-2018-11-06", "obj-%d" % i)
ちなみにWindows環境でハンドルまわりをPythonで扱うためのコードは以下みたいになります。ご興味があれば。
python
1'''
2Created on 2017/11/07
3
4@author: sakurai
5'''
6from ctypes import byref
7from ctypes import cast
8from ctypes import create_string_buffer
9from ctypes import create_unicode_buffer
10from ctypes import POINTER
11from ctypes import Structure
12from ctypes import windll
13from ctypes import WinDLL
14from ctypes import WinError
15from ctypes import wintypes
16from ctypes.wintypes import LPVOID as PVOID
17from os.path import isfile
18
19
20NTDLL = WinDLL("ntdll")
21KERNEL32 = windll.kernel32
22NTSTATUS = wintypes.LONG
23SYSTEM_INFORMATION_CLASS = wintypes.ULONG
24
25
26####
27# C structures
28####
29class SYSTEM_HANDLE(Structure):
30 """https://stackoverflow.com/a/5163277"""
31 _fields_ = (("dwProcessId", wintypes.DWORD),
32 ("bObjectType", wintypes.BYTE),
33 ("bFlags", wintypes.BYTE),
34 ("wValue", wintypes.WORD),
35 ("pAddress", PVOID),
36 ("GrantedAccess", wintypes.DWORD))
37
38
39class SYSTEM_HANDLE_INFORMATION(Structure):
40 _fields_ = (("dwCount", wintypes.DWORD),
41 ("Handles", SYSTEM_HANDLE * 1))
42
43
44####
45# C error checks
46####
47def assertZero(result, _, args):
48 if result != 0:
49 raise WinError(NTDLL.RtlNtStatusToDosError(result))
50 return args
51
52
53def assertNotZero(result, _, args):
54 if result == 0:
55 raise WinError()
56 return args
57
58
59def assertTrue(result, _, args):
60 if not result:
61 raise WinError()
62 return args
63
64
65####
66# C functions
67####
68NtQuerySystemInformation = NTDLL.NtQuerySystemInformation
69NtQuerySystemInformation.restype = NTSTATUS
70NtQuerySystemInformation.argtypes = (SYSTEM_INFORMATION_CLASS,
71 PVOID,
72 wintypes.ULONG,
73 wintypes.PULONG)
74NtQuerySystemInformation.errcheck = assertZero
75
76GetFinalPathNameByHandle = KERNEL32.GetFinalPathNameByHandleW
77GetFinalPathNameByHandle.restype = wintypes.DWORD
78GetFinalPathNameByHandle.argtypes = (wintypes.HANDLE,
79 wintypes.LPWSTR,
80 wintypes.DWORD,
81 wintypes.DWORD)
82GetFinalPathNameByHandle.errcheck = assertNotZero
83
84CloseHandle = KERNEL32.CloseHandle
85CloseHandle.restype = wintypes.BOOL
86CloseHandle.argtypes = (wintypes.HANDLE, )
87CloseHandle.errcheck = assertTrue
88
89
90####
91# Wrappers
92####
93def system_handles():
94 dwSize = wintypes.DWORD(0)
95 pInfo = create_string_buffer(dwSize.value)
96 while True:
97 try:
98 NtQuerySystemInformation(0x10, # SystemHandleInformation
99 pInfo, dwSize, byref(dwSize))
100 break
101 except OSError as e:
102 if e.errno == 13:
103 pInfo = create_string_buffer(dwSize.value)
104 else:
105 raise e
106
107 info = cast(pInfo, POINTER(SYSTEM_HANDLE_INFORMATION)).contents
108 yield from cast(info.Handles,
109 POINTER(SYSTEM_HANDLE * info.dwCount)).contents
110
111
112def get_path(handle: wintypes.HANDLE):
113 szPath = create_unicode_buffer(wintypes.MAX_PATH)
114 GetFinalPathNameByHandle(handle, szPath, wintypes.MAX_PATH, 0)
115 return szPath.value
116
117
118def open_files(pid: int):
119 for handle in system_handles():
120 if handle.dwProcessId == pid:
121 try:
122 fname = get_path(handle.wValue)
123 if isfile(fname):
124 yield (get_path(handle.wValue), handle.wValue)
125 except OSError:
126 pass