# Buggy code
def write_xattr(path, key, value):
    # This mess below finds the best xattr tool for the job
    try:
        # try the pyxattr module...
        import xattr

        # Unicode arguments are not supported in python-pyxattr until
        # version 0.5.0
        # See https://github.com/rg3/youtube-dl/issues/5498
        pyxattr_required_version = "0.5.0"
        if version_tuple(xattr.__version__) < version_tuple(pyxattr_required_version):
            # TODO: fallback to CLI tools
            raise XAttrUnavailableError(
                "python-pyxattr is detected but is too old. "
                "youtube-dl requires %s or above while your version is %s. "
                "Falling back to other xattr implementations"
                % (pyxattr_required_version, xattr.__version__)
            )

        try:
            xattr.set(path, key, value)
        except EnvironmentError as e:
            raise XAttrMetadataError(e.errno, e.strerror)

    except ImportError:
        if compat_os_name == "nt":
            # Write xattrs to NTFS Alternate Data Streams:
            # http://en.wikipedia.org/wiki/NTFS#Alternate_data_streams_.28ADS.29
            assert ":" not in key
            assert os.path.exists(path)

            ads_fn = path + ":" + key
            try:
                with open(ads_fn, "wb") as f:
                    f.write(value)
            except EnvironmentError as e:
                raise XAttrMetadataError(e.errno, e.strerror)
        else:
            user_has_setfattr = check_executable("setfattr", ["--version"])
            user_has_xattr = check_executable("xattr", ["-h"])

            if user_has_setfattr or user_has_xattr:
                value = value.decode("utf-8")
                if user_has_setfattr:
                    executable = "setfattr"
                    opts = ["-n", key, "-v", value]
                elif user_has_xattr:
                    executable = "xattr"
                    opts = ["-w", key, value]

                cmd = (
                    [encodeFilename(executable, True)]
                    + [encodeArgument(o) for o in opts]
                    + [encodeFilename(path, True)]
                )

                try:
                    p = subprocess.Popen(
                        cmd,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE,
                        stdin=subprocess.PIPE,
                    )
                except EnvironmentError as e:
                    raise XAttrMetadataError(e.errno, e.strerror)
                stdout, stderr = p.communicate()
                stderr = stderr.decode("utf-8", "replace")
                if p.returncode != 0:
                    raise XAttrMetadataError(p.returncode, stderr)

            else:
                # On Unix, and can't find pyxattr, setfattr, or xattr.
                if sys.platform.startswith("linux"):
                    raise XAttrUnavailableError(
                        "Couldn't find a tool to set the xattrs. "
                        "Install either the python 'pyxattr' or 'xattr' "
                        "modules, or the GNU 'attr' package "
                        "(which contains the 'setfattr' tool)."
                    )
                else:
                    raise XAttrUnavailableError(
                        "Couldn't find a tool to set the xattrs. "
                        "Install either the python 'xattr' module, "
                        "or the 'xattr' binary."
                    )


# Traceback (AttributeError)
$ youtube-dl --write-auto-sub --sub-format srt --include-ads --console-title --newline --embed-subs --xattrs --add-metadata -v https://www.youtube.com/watch?v=Bfktt22nUG4
[debug] System config: []
[debug] User config: []
[debug] Command-line args: [u'--write-auto-sub', u'--sub-format', u'srt', u'--include-ads', u'--console-title', u'--newline', u'--embed-subs', u'--xattrs', u'--add-metadata', u'-v', u'https://www.youtube.com/watch?v=Bfktt22nUG4']
[debug] Encodings: locale UTF-8, fs utf-8, out UTF-8, pref UTF-8
[debug] youtube-dl version 2016.04.01
[debug] Python version 2.7.10 - Darwin-14.5.0-x86_64-i386-64bit
[debug] exe versions: ffmpeg 2.7.1, ffprobe 2.7.1
[debug] Proxy map: {}
[youtube] Bfktt22nUG4: Downloading webpage
[youtube] Bfktt22nUG4: Downloading video info webpage
[youtube] Bfktt22nUG4: Extracting video information
[youtube] Bfktt22nUG4: Looking for automatic captions
[youtube] Bfktt22nUG4: Downloading MPD manifest
WARNING: No subtitle format found matching "srt" for language en, using vtt
[info] Writing video subtitles to: iPhone SE (parody)-Bfktt22nUG4.en.vtt
WARNING: Requested formats are incompatible for merge and will be merged into mkv.
[download] iPhone SE (parody)-Bfktt22nUG4.mkv has already been downloaded and merged
[ffmpeg] Adding metadata to 'iPhone SE (parody)-Bfktt22nUG4.mkv'
[debug] ffmpeg command line: ffmpeg -y -i 'file:iPhone SE (parody)-Bfktt22nUG4.mkv' -c copy -metadata 'comment=Previous sketch: https://www.youtube.com/watch?v=--Fg3YbwG8E&amp;index=1&amp;list=PLiWL8lZPZ2_kafFTewyr06GuSPFd0m8hf

Help me make fun of everything! http://bit.ly/1A0Crdb
TWITTER: http://www.twitter.com/jacksfilms
FACEBOOK: http://www.facebook.com/jacksfilmsfans
LIVE CHAT every FRIDAY: http://www.younow.com/jacksfilms
SNAPCHAT: realjacksfilms
MERCH: http://www.jacksfilms.spreadshirt.com
PERISCOPE: http://www.periscope.tv/jacksfilms' -metadata 'description=Previous sketch: https://www.youtube.com/watch?v=--Fg3YbwG8E&amp;index=1&amp;list=PLiWL8lZPZ2_kafFTewyr06GuSPFd0m8hf

Help me make fun of everything! http://bit.ly/1A0Crdb
TWITTER: http://www.twitter.com/jacksfilms
FACEBOOK: http://www.facebook.com/jacksfilmsfans
LIVE CHAT every FRIDAY: http://www.younow.com/jacksfilms
SNAPCHAT: realjacksfilms
MERCH: http://www.jacksfilms.spreadshirt.com
PERISCOPE: http://www.periscope.tv/jacksfilms' -metadata artist=jacksfilms -metadata 'title=iPhone SE (parody)' -metadata date=20160321 -metadata 'purl=https://www.youtube.com/watch?v=Bfktt22nUG4' 'file:iPhone SE (parody)-Bfktt22nUG4.temp.mkv'
[ffmpeg] Embedding subtitles in 'iPhone SE (parody)-Bfktt22nUG4.mkv'
[debug] ffmpeg command line: ffmpeg -y -i 'file:iPhone SE (parody)-Bfktt22nUG4.mkv' -i 'file:iPhone SE (parody)-Bfktt22nUG4.en.vtt' -map 0 -c copy -map -0:s -map 1:0 -metadata:s:s:0 language=eng 'file:iPhone SE (parody)-Bfktt22nUG4.temp.mkv'
Deleting original file iPhone SE (parody)-Bfktt22nUG4.en.vtt (pass -k to keep)
[metadata] Writing metadata to file's xattrs
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/usr/local/bin/youtube-dl/__main__.py", line 19, in <module>
File "/usr/local/bin/youtube-dl/youtube_dl/__init__.py", line 419, in main
File "/usr/local/bin/youtube-dl/youtube_dl/__init__.py", line 409, in _real_main
File "/usr/local/bin/youtube-dl/youtube_dl/YoutubeDL.py", line 1725, in download
File "/usr/local/bin/youtube-dl/youtube_dl/YoutubeDL.py", line 680, in extract_info
File "/usr/local/bin/youtube-dl/youtube_dl/YoutubeDL.py", line 725, in process_ie_result
File "/usr/local/bin/youtube-dl/youtube_dl/YoutubeDL.py", line 1371, in process_video_result
File "/usr/local/bin/youtube-dl/youtube_dl/YoutubeDL.py", line 1707, in process_info
File "/usr/local/bin/youtube-dl/youtube_dl/YoutubeDL.py", line 1771, in post_process
File "/usr/local/bin/youtube-dl/youtube_dl/postprocessor/xattrpp.py", line 158, in run
File "/usr/local/bin/youtube-dl/youtube_dl/postprocessor/xattrpp.py", line 72, in write_xattr
AttributeError: 'module' object has no attribute 'set'

# Fixed code
def write_xattr(path, key, value):
    # This mess below finds the best xattr tool for the job
    try:
        # try the pyxattr module...
        import xattr

        if hasattr(xattr, "set"):  # pyxattr
            # Unicode arguments are not supported in python-pyxattr until
            # version 0.5.0
            # See https://github.com/rg3/youtube-dl/issues/5498
            pyxattr_required_version = "0.5.0"
            if version_tuple(xattr.__version__) < version_tuple(
                pyxattr_required_version
            ):
                # TODO: fallback to CLI tools
                raise XAttrUnavailableError(
                    "python-pyxattr is detected but is too old. "
                    "youtube-dl requires %s or above while your version is %s. "
                    "Falling back to other xattr implementations"
                    % (pyxattr_required_version, xattr.__version__)
                )

            setxattr = xattr.set
        else:  # xattr
            setxattr = xattr.setxattr

        try:
            setxattr(path, key, value)
        except EnvironmentError as e:
            raise XAttrMetadataError(e.errno, e.strerror)

    except ImportError:
        if compat_os_name == "nt":
            # Write xattrs to NTFS Alternate Data Streams:
            # http://en.wikipedia.org/wiki/NTFS#Alternate_data_streams_.28ADS.29
            assert ":" not in key
            assert os.path.exists(path)

            ads_fn = path + ":" + key
            try:
                with open(ads_fn, "wb") as f:
                    f.write(value)
            except EnvironmentError as e:
                raise XAttrMetadataError(e.errno, e.strerror)
        else:
            user_has_setfattr = check_executable("setfattr", ["--version"])
            user_has_xattr = check_executable("xattr", ["-h"])

            if user_has_setfattr or user_has_xattr:
                value = value.decode("utf-8")
                if user_has_setfattr:
                    executable = "setfattr"
                    opts = ["-n", key, "-v", value]
                elif user_has_xattr:
                    executable = "xattr"
                    opts = ["-w", key, value]

                cmd = (
                    [encodeFilename(executable, True)]
                    + [encodeArgument(o) for o in opts]
                    + [encodeFilename(path, True)]
                )

                try:
                    p = subprocess.Popen(
                        cmd,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE,
                        stdin=subprocess.PIPE,
                    )
                except EnvironmentError as e:
                    raise XAttrMetadataError(e.errno, e.strerror)
                stdout, stderr = p.communicate()
                stderr = stderr.decode("utf-8", "replace")
                if p.returncode != 0:
                    raise XAttrMetadataError(p.returncode, stderr)

            else:
                # On Unix, and can't find pyxattr, setfattr, or xattr.
                if sys.platform.startswith("linux"):
                    raise XAttrUnavailableError(
                        "Couldn't find a tool to set the xattrs. "
                        "Install either the python 'pyxattr' or 'xattr' "
                        "modules, or the GNU 'attr' package "
                        "(which contains the 'setfattr' tool)."
                    )
                else:
                    raise XAttrUnavailableError(
                        "Couldn't find a tool to set the xattrs. "
                        "Install either the python 'xattr' module, "
                        "or the 'xattr' binary."
                    )