bpo-45234: Fix FileNotFound exception raised instead of IsADirectoryError in shutil.copyfile() (GH-28421) (GH-28508)

This was a regression from fixing BPO-43219.
(cherry picked from commit b7eac52b466f697d3e89f47508e0df0196a98970)

Co-authored-by: andrei kulakov <andrei.avk@gmail.com>
diff --git a/Lib/shutil.py b/Lib/shutil.py
index d749b84..0056a1b 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -251,36 +251,37 @@ def copyfile(src, dst, *, follow_symlinks=True):
     if not follow_symlinks and _islink(src):
         os.symlink(os.readlink(src), dst)
     else:
-        try:
-            with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
-                # macOS
-                if _HAS_FCOPYFILE:
-                    try:
-                        _fastcopy_fcopyfile(fsrc, fdst, posix._COPYFILE_DATA)
+        with open(src, 'rb') as fsrc:
+            try:
+                with open(dst, 'wb') as fdst:
+                    # macOS
+                    if _HAS_FCOPYFILE:
+                        try:
+                            _fastcopy_fcopyfile(fsrc, fdst, posix._COPYFILE_DATA)
+                            return dst
+                        except _GiveupOnFastCopy:
+                            pass
+                    # Linux
+                    elif _USE_CP_SENDFILE:
+                        try:
+                            _fastcopy_sendfile(fsrc, fdst)
+                            return dst
+                        except _GiveupOnFastCopy:
+                            pass
+                    # Windows, see:
+                    # https://github.com/python/cpython/pull/7160#discussion_r195405230
+                    elif _WINDOWS and file_size > 0:
+                        _copyfileobj_readinto(fsrc, fdst, min(file_size, COPY_BUFSIZE))
                         return dst
-                    except _GiveupOnFastCopy:
-                        pass
-                # Linux
-                elif _USE_CP_SENDFILE:
-                    try:
-                        _fastcopy_sendfile(fsrc, fdst)
-                        return dst
-                    except _GiveupOnFastCopy:
-                        pass
-                # Windows, see:
-                # https://github.com/python/cpython/pull/7160#discussion_r195405230
-                elif _WINDOWS and file_size > 0:
-                    _copyfileobj_readinto(fsrc, fdst, min(file_size, COPY_BUFSIZE))
-                    return dst
 
-                copyfileobj(fsrc, fdst)
+                    copyfileobj(fsrc, fdst)
 
-        # Issue 43219, raise a less confusing exception
-        except IsADirectoryError as e:
-            if os.path.exists(dst):
-                raise
-            else:
-                raise FileNotFoundError(f'Directory does not exist: {dst}') from e
+            # Issue 43219, raise a less confusing exception
+            except IsADirectoryError as e:
+                if not os.path.exists(dst):
+                    raise FileNotFoundError(f'Directory does not exist: {dst}') from e
+                else:
+                    raise
 
     return dst