Recursively move a file or directory to another location. This is similar to the Unix "mv" command. Return the file or directory's destination. If dst is an existing directory or a symlink to a directory, then src is moved inside that directory. The destination path in that dir
(src, dst, copy_function=copy2)
| 809 | return os.path.basename(path.rstrip(sep)) |
| 810 | |
| 811 | def move(src, dst, copy_function=copy2): |
| 812 | """Recursively move a file or directory to another location. This is |
| 813 | similar to the Unix "mv" command. Return the file or directory's |
| 814 | destination. |
| 815 | |
| 816 | If dst is an existing directory or a symlink to a directory, then src is |
| 817 | moved inside that directory. The destination path in that directory must |
| 818 | not already exist. |
| 819 | |
| 820 | If dst already exists but is not a directory, it may be overwritten |
| 821 | depending on os.rename() semantics. |
| 822 | |
| 823 | If the destination is on our current filesystem, then rename() is used. |
| 824 | Otherwise, src is copied to the destination and then removed. Symlinks are |
| 825 | recreated under the new name if os.rename() fails because of cross |
| 826 | filesystem renames. |
| 827 | |
| 828 | The optional `copy_function` argument is a callable that will be used |
| 829 | to copy the source or it will be delegated to `copytree`. |
| 830 | By default, copy2() is used, but any function that supports the same |
| 831 | signature (like copy()) can be used. |
| 832 | |
| 833 | A lot more could be done here... A look at a mv.c shows a lot of |
| 834 | the issues this implementation glosses over. |
| 835 | |
| 836 | """ |
| 837 | sys.audit("shutil.move", src, dst) |
| 838 | real_dst = dst |
| 839 | if os.path.isdir(dst): |
| 840 | if _samefile(src, dst) and not os.path.islink(src): |
| 841 | # We might be on a case insensitive filesystem, |
| 842 | # perform the rename anyway. |
| 843 | os.rename(src, dst) |
| 844 | return |
| 845 | |
| 846 | # Using _basename instead of os.path.basename is important, as we must |
| 847 | # ignore any trailing slash to avoid the basename returning '' |
| 848 | real_dst = os.path.join(dst, _basename(src)) |
| 849 | |
| 850 | if os.path.exists(real_dst): |
| 851 | raise Error("Destination path '%s' already exists" % real_dst) |
| 852 | try: |
| 853 | os.rename(src, real_dst) |
| 854 | except OSError: |
| 855 | if os.path.islink(src): |
| 856 | linkto = os.readlink(src) |
| 857 | os.symlink(linkto, real_dst) |
| 858 | os.unlink(src) |
| 859 | elif os.path.isdir(src): |
| 860 | if _destinsrc(src, dst): |
| 861 | raise Error("Cannot move a directory '%s' into itself" |
| 862 | " '%s'." % (src, dst)) |
| 863 | if (_is_immutable(src) |
| 864 | or (not os.access(src, os.W_OK) and os.listdir(src) |
| 865 | and sys.platform == 'darwin')): |
| 866 | raise PermissionError("Cannot move the non-empty directory " |
| 867 | "'%s': Lacking write permission to '%s'." |
| 868 | % (src, src)) |
nothing calls this directly
no test coverage detected