I'm trying to write a simple script to move files from one folder to another and filter unnecessary stuff out. I'm using the code below, but receiving an error
import shutil
import errno
def copy(src, dest):
try:
shutil.copytree(src, dest, ignore=shutil.ignore_patterns('*.mp4', '*.bak'))
except OSError:
if OSError.errno == errno.ENOTDIR:
shutil.copy(src, dest)
else:
print("Directory not copied. Error: %s" % OSError)
src = raw_input("Please enter a source: ")
dest = raw_input("Please enter a destination: ")
copy(src, dest)
The error I get is:
Traceback (most recent call last):
File "/Users/XXX/PycharmProjects/Folders/Fold.py", line 29,
in <module>
copy(src, dest)
File "/Users/XXX/PycharmProjects/Folders/Fold.py", line 17,
in copy
ignore_pat = shutil.ignore_patterns('*.mp4', '*.bak')
AttributeError: 'module' object has no attribute 'ignore_patterns'
Your Python version is too old. From the shutil.ignore_patterns()
documentation:
New in version 2.6.
It is easy enough to replicate the method on older Python versions:
import fnmatch
def ignore_patterns(*patterns):
"""Function that can be used as copytree() ignore parameter.
Patterns is a sequence of glob-style patterns
that are used to exclude files"""
def _ignore_patterns(path, names):
ignored_names = []
for pattern in patterns:
ignored_names.extend(fnmatch.filter(names, pattern))
return set(ignored_names)
return _ignore_patterns
This'll work on Python 2.4 and newer.
To simplify this down to your specific code:
def copy(src, dest):
def ignore(path, names):
ignored = set()
for name in names:
if name.endswith('.mp4') or name.endswith('.bak'):
ignored.add(name)
return ignored
try:
shutil.copytree(src, dest, ignore=ignore)
except OSError:
if OSError.errno == errno.ENOTDIR:
shutil.copy(src, dest)
else:
print("Directory not copied. Error: %s" % OSError)
This doesn't use fnmatch
at all anymore (since you are only testing for specific extensions) and uses syntax compatible with older Python versions.