# Buggy code
def create_archive(root, files=None, fileobj=None, gzip=False):
    if not fileobj:
        fileobj = tempfile.NamedTemporaryFile()
    t = tarfile.open(mode="w:gz" if gzip else "w", fileobj=fileobj)
    if files is None:
        files = build_file_list(root)
    for path in files:
        full_path = os.path.join(root, path)

        if os.lstat(full_path).st_mode & os.R_OK == 0:
            raise IOError("Can not access file in context: {}".format(full_path))
        i = t.gettarinfo(full_path, arcname=path)
        if i is None:
            # This happens when we encounter a socket file. We can safely
            # ignore it and proceed.
            continue

        # Workaround https://bugs.python.org/issue32713
        if i.mtime < 0 or i.mtime > 8**11 - 1:
            i.mtime = int(i.mtime)

        if constants.IS_WINDOWS_PLATFORM:
            # Windows doesn't keep track of the execute bit, so we make files
            # and directories executable by default.
            i.mode = i.mode & 0o755 | 0o111

        if i.isfile():
            try:
                with open(full_path, "rb") as f:
                    t.addfile(i, f)
            except IOError:
                t.addfile(i, None)
        else:
            # Directories, FIFOs, symlinks... don't need to be read.
            t.addfile(i, None)
    t.close()
    fileobj.seek(0)
    return fileobj


# Traceback (OSError)
tim@mbp ~/C/d/docker_archive python3 test_dockerpy_tar.py
Traceback (most recent call last):
File "test_dockerpy_tar.py", line 20, in <module>
CLIENT.build(path=str(CWD), dockerfile=str(DOCKER_FILE))
File "/Users/tim/Code/dockerpy_bug/dockerpy_env/lib/python3.6/site-packages/docker/api/build.py", line 149, in build
path, exclude=exclude, dockerfile=dockerfile, gzip=gzip
File "/Users/tim/Code/dockerpy_bug/dockerpy_env/lib/python3.6/site-packages/docker/utils/build.py", line 14, in tar
root=root, fileobj=fileobj, gzip=gzip
File "/Users/tim/Code/dockerpy_bug/dockerpy_env/lib/python3.6/site-packages/docker/utils/utils.py", line 102, in create_archive
'Can not access file in context: {}'.format(full_path)
OSError: Can not access file in context: /Users/tim/Code/dockerpy_bug/docker_archive/testfile
tim@mbp ~/C/d/docker_archive ls -l
total 8
-rw-r--r-- 1 tim staff 18 Feb  4 00:24 Dockerfile
-rw-r--r-- 1 tim staff 421 Feb  4 00:24 test_dockerpy_tar.py
-r-------- 1 tim staff 0 Feb  4 00:24 testfile
tim@mbp ~/C/d/docker_archive

# Fixed code
def create_archive(root, files=None, fileobj=None, gzip=False):
    if not fileobj:
        fileobj = tempfile.NamedTemporaryFile()
    t = tarfile.open(mode="w:gz" if gzip else "w", fileobj=fileobj)
    if files is None:
        files = build_file_list(root)
    for path in files:
        full_path = os.path.join(root, path)

        i = t.gettarinfo(full_path, arcname=path)
        if i is None:
            # This happens when we encounter a socket file. We can safely
            # ignore it and proceed.
            continue

        # Workaround https://bugs.python.org/issue32713
        if i.mtime < 0 or i.mtime > 8**11 - 1:
            i.mtime = int(i.mtime)

        if constants.IS_WINDOWS_PLATFORM:
            # Windows doesn't keep track of the execute bit, so we make files
            # and directories executable by default.
            i.mode = i.mode & 0o755 | 0o111

        if i.isfile():
            try:
                with open(full_path, "rb") as f:
                    t.addfile(i, f)
            except IOError:
                raise IOError("Can not read file in context: {}".format(full_path))
        else:
            # Directories, FIFOs, symlinks... don't need to be read.
            t.addfile(i, None)
    t.close()
    fileobj.seek(0)
    return fileobj