# Path: s3transfer/compat.py
# SOCKET_ERROR = ConnectionError
# 
# def fallocate(fileobj, size):
#     if hasattr(os, 'posix_fallocate'):
#         os.posix_fallocate(fileobj.fileno(), 0, size)
#     else:
#         fileobj.truncate(size)
# 
# def rename_file(current_filename, new_filename):
#     try:
#         os.remove(new_filename)
#     except OSError as e:
#         if not e.errno == errno.ENOENT:
#             # We only want to a ignore trying to remove
#             # a file that does not exist.  If it fails
#             # for any other reason we should be propagating
#             # that exception.
#             raise
#     os.rename(current_filename, new_filename)


import functools
import logging
import math
import os
import random
import socket
import stat
import string
import threading
from collections import defaultdict
from botocore.exceptions import IncompleteReadError, ReadTimeoutError
from s3transfer.compat import SOCKET_ERROR, fallocate, rename_file


MAX_PARTS = 10000
# The maximum file size you can upload via S3 per request.
# See: http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html
# and: http://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html
MAX_SINGLE_UPLOAD_SIZE = 5 * (1024 ** 3)
MIN_UPLOAD_CHUNKSIZE = 5 * (1024 ** 2)
logger = logging.getLogger(__name__)


S3_RETRYABLE_DOWNLOAD_ERRORS = (
    socket.timeout,
    SOCKET_ERROR,
    ReadTimeoutError,
    IncompleteReadError,
)


def random_file_extension(num_digits=8):
    return ''.join(random.choice(string.hexdigits) for _ in range(num_digits))


def signal_not_transferring(request, operation_name, **kwargs):
    if operation_name in ['PutObject', 'UploadPart'] and hasattr(
        request.body, 'signal_not_transferring'
    ):
        request.body.signal_not_transferring()



# Path: s3transfer/compat.py
# SOCKET_ERROR = ConnectionError
# 
# def fallocate(fileobj, size):
#     if hasattr(os, 'posix_fallocate'):
#         os.posix_fallocate(fileobj.fileno(), 0, size)
#     else:
#         fileobj.truncate(size)
# 
# def rename_file(current_filename, new_filename):
#     try:
#         os.remove(new_filename)
#     except OSError as e:
#         if not e.errno == errno.ENOENT:
#             # We only want to a ignore trying to remove
#             # a file that does not exist.  If it fails
#             # for any other reason we should be propagating
#             # that exception.
#             raise
#     os.rename(current_filename, new_filename)


# Path: s3transfer/utils.py
import functools
import logging
import math
import os
import random
import socket
import stat
import string
import threading
from collections import defaultdict
from botocore.exceptions import IncompleteReadError, ReadTimeoutError
from s3transfer.compat import SOCKET_ERROR, fallocate, rename_file



MAX_PARTS = 10000
# The maximum file size you can upload via S3 per request.
# See: http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html
# and: http://docs.aws.amazon.com/AmazonS3/latest/dev/qfacts.html
MAX_SINGLE_UPLOAD_SIZE = 5 * (1024 ** 3)
MIN_UPLOAD_CHUNKSIZE = 5 * (1024 ** 2)
logger = logging.getLogger(__name__)


S3_RETRYABLE_DOWNLOAD_ERRORS = (
    socket.timeout,
    SOCKET_ERROR,
    ReadTimeoutError,
    IncompleteReadError,
)


def random_file_extension(num_digits=8):
    return ''.join(random.choice(string.hexdigits) for _ in range(num_digits))


def signal_not_transferring(request, operation_name, **kwargs):
    if operation_name in ['PutObject', 'UploadPart'] and hasattr(
        request.body, 'signal_not_transferring'
    ):
        request.body.signal_not_transferring()



def signal_transferring(request, operation_name, **kwargs):