Hello community,

here is the log from the commit of package python-xattr for openSUSE:Factory 
checked in at 2016-06-07 23:48:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-xattr (Old)
 and      /work/SRC/openSUSE:Factory/.python-xattr.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-xattr"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-xattr/python-xattr.changes        
2015-10-22 12:59:03.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-xattr.new/python-xattr.changes   
2016-06-07 23:48:54.000000000 +0200
@@ -1,0 +2,9 @@
+Wed Jun  1 13:09:27 UTC 2016 - [email protected]
+
+- update to 0.8.0:
+  * Use os.fsencode where available to better handle filesystem quirks related
+    to surrogates
+  * Options bugfix and compatibility module for pyxattr API
+  * Added xattr/tests/*.py to MANIFEST.in
+
+-------------------------------------------------------------------

Old:
----
  v0.7.8.tar.gz

New:
----
  v0.8.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-xattr.spec ++++++
--- /var/tmp/diff_new_pack.c8afnh/_old  2016-06-07 23:48:55.000000000 +0200
+++ /var/tmp/diff_new_pack.c8afnh/_new  2016-06-07 23:48:55.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-xattr
 #
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           python-xattr
-Version:        0.7.8
+Version:        0.8.0
 Release:        0
 Summary:        Python wrapper for extended filesystem attributes
 License:        MIT
@@ -27,7 +27,12 @@
 BuildRequires:  python-cffi
 BuildRequires:  python-devel
 BuildRequires:  python-setuptools
+%if 0%{?suse_version} && 0%{?suse_version} <= 1310
+BuildRequires:  update-alternatives
+%endif
 %requires_eq    python-cffi
+Requires(post): update-alternatives
+Requires(postun): update-alternatives
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 Provides:       pyxattr = %{version}
 Obsoletes:      pyxattr < %{version}
@@ -52,12 +57,30 @@
 
 %install
 python setup.py install --prefix=%{_prefix} --root=%{buildroot}
+mv %{buildroot}%{_bindir}/xattr %{buildroot}%{_bindir}/xattr-%{py_ver}
+
+%if 0%{?suse_version} && 0%{?suse_version} > 1310
+mkdir -p %{buildroot}%{_sysconfdir}/alternatives
+ln -s -f %{_sysconfdir}/alternatives/xattr %{buildroot}%{_bindir}/xattr
+%endif
+
+%post
+%{_sbindir}/update-alternatives \
+    --install %_bindir/xattr xattr %_bindir/xattr-%{py_ver} 10
+
+%preun
+%{_sbindir}/update-alternatives \
+    --remove xattr %_bindir/xattr
 
 %files
 %defattr(-,root,root)
 %doc README.txt
-%{_bindir}/xattr
+%{_bindir}/xattr-%{py_ver}
 %{python_sitelib}/xattr
 %{python_sitelib}/xattr-*egg-info
+%if 0%{?suse_version} && 0%{?suse_version} > 1310
+%{_bindir}/xattr
+%ghost %_sysconfdir/alternatives/xattr
+%endif
 
 %changelog

++++++ v0.7.8.tar.gz -> v0.8.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/.travis/install.sh 
new/xattr-0.8.0/.travis/install.sh
--- old/xattr-0.7.8/.travis/install.sh  1970-01-01 01:00:00.000000000 +0100
+++ new/xattr-0.8.0/.travis/install.sh  2016-02-28 20:10:07.000000000 +0100
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+set -x
+
+if [[ -n "$PYENV_VERSION" ]]; then
+    if [ ! -e "$HOME/.pyenv" ]; then
+      git clone https://github.com/yyuu/pyenv.git ~/.pyenv
+    fi
+    PYENV_ROOT="$HOME/.pyenv"
+    PATH="$PYENV_ROOT/bin:$PATH"
+    eval "$(pyenv init -)"
+    hash -r
+    pyenv install --list
+    pyenv install -s $PYENV_VERSION
+    pip install wheel
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/.travis/run.sh 
new/xattr-0.8.0/.travis/run.sh
--- old/xattr-0.7.8/.travis/run.sh      1970-01-01 01:00:00.000000000 +0100
+++ new/xattr-0.8.0/.travis/run.sh      2016-02-28 20:10:07.000000000 +0100
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+set -x
+
+if [[ -n "$PYENV_VERSION" ]]; then
+    PYENV_ROOT="$HOME/.pyenv"
+    PATH="$PYENV_ROOT/bin:$PATH"
+    eval "$(pyenv init -)"
+fi
+
+python setup.py build_ext -i
+python -m compileall -f .
+python setup.py test
+
+if [[ -n "$PYENV_VERSION" && $TRAVIS_OS_NAME == 'osx' ]]; then
+  python setup.py bdist_wheel
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/.travis.yml new/xattr-0.8.0/.travis.yml
--- old/xattr-0.7.8/.travis.yml 2015-06-25 19:25:42.000000000 +0200
+++ new/xattr-0.8.0/.travis.yml 2016-02-28 20:10:07.000000000 +0100
@@ -1,5 +1,35 @@
-language: objective-c
+language: python
+cache:
+  directories:
+  - "$HOME/.cache/pip"
+  - "$HOME/.pyenv"
+matrix:
+  include:
+  - os: osx
+    language: objective-c
+  - os: osx
+    language: objective-c
+    env: PYENV_VERSION=pypy3-2.4.0
+  - os: osx
+    language: objective-c
+    env: PYENV_VERSION=pypy-4.0.1
+  - os: osx
+    language: objective-c
+    env: PYENV_VERSION=2.7.11
+  - os: osx
+    language: objective-c
+    env: PYENV_VERSION=3.5.1
+install:
+- "./.travis/install.sh"
 script:
-  - ARCHFLAGS="-Wno-error=unused-command-line-argument-hard-error-in-future" 
python setup.py build_ext -i
-  - python -m compileall -f xattr
-  - python setup.py test
+- "./.travis/run.sh"
+deploy:
+  provider: releases
+  api_key:
+    secure: 
Z5m7K1UVq0812nNtR+QAkUE3lxUwhMjM3EDWUOyPmfh0rmOsU2RgQ8oBfT1vatYfY8ExnrG4rRNWmwUqPEIzZmRLmw9zv+ixA3gcVPn6WbbMkwoeIurOPsC9wjgCckDFKYhMda8a92FSL2hVto3JPcRNTZnsKBR35Queray55SM=
+  file: dist/*.whl
+  file_glob: true
+  on:
+    repo: xattr/xattr
+    tags: true
+  skip_cleanup: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/CHANGES.txt new/xattr-0.8.0/CHANGES.txt
--- old/xattr-0.7.8/CHANGES.txt 2015-06-25 19:25:42.000000000 +0200
+++ new/xattr-0.8.0/CHANGES.txt 2016-02-28 20:10:07.000000000 +0100
@@ -1,3 +1,16 @@
+Version 0.8.0 released 2016-02-28
+
+* Use os.fsencode where available to better handle filesystem quirks related
+  to surrogates
+  https://github.com/xattr/xattr/pull/46
+* Options bugfix and compatibility module for pyxattr API
+  https://github.com/xattr/xattr/pull/38
+
+Version 0.7.9 released 2016-02-12
+
+* Added xattr/tests/*.py to MANIFEST.in
+  https://github.com/xattr/xattr/issues/43
+
 Version 0.7.8 released 2015-06-25
 
 * Added MANIFEST.in to ensure that the .txt files are included
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/MANIFEST.in new/xattr-0.8.0/MANIFEST.in
--- old/xattr-0.7.8/MANIFEST.in 2015-06-25 19:25:42.000000000 +0200
+++ new/xattr-0.8.0/MANIFEST.in 2016-02-28 20:10:07.000000000 +0100
@@ -1,3 +1,4 @@
 include *.py
 include *.txt
 include MANIFEST.in
+include xattr/tests/*.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/scripts/artifacts.py 
new/xattr-0.8.0/scripts/artifacts.py
--- old/xattr-0.7.8/scripts/artifacts.py        1970-01-01 01:00:00.000000000 
+0100
+++ new/xattr-0.8.0/scripts/artifacts.py        2016-02-28 20:10:07.000000000 
+0100
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+try:
+    from urllib.request import urlopen
+except ImportError:
+    from urllib import urlopen
+
+import io
+import json
+import subprocess
+
+
+def get_json(url):
+    return json.loads(urlopen(url).read().decode('utf-8'))
+
+
+def download_file(src_url, dest_path):
+    print(dest_path)
+    subprocess.call(
+        ['curl', '-L', '-#', '-o', dest_path, src_url])
+
+
+def download_appveyor_artifacts():
+    api_url = 'https://ci.appveyor.com/api'
+    builds = get_json(
+        '{}/projects/etrepum/xattr'.format(api_url))
+
+    for job in builds['build']['jobs']:
+        url = '{api_url}/buildjobs/{jobId}/artifacts'.format(
+            api_url=api_url, **job)
+        for artifact in get_json(url):
+            download_file(
+                '{url}/{fileName}'.format(url=url, **artifact),
+                artifact['fileName'])
+
+
+def download_github_artifacts():
+    release = get_json(
+        'https://api.github.com/repos/xattr/xattr/releases/latest')
+    for asset in release['assets']:
+        download_file(asset['browser_download_url'], 
'dist/{name}'.format(**asset))
+
+
+def main():
+    #download_appveyor_artifacts()
+    download_github_artifacts()
+
+
+if __name__ == '__main__':
+    main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/setup.py new/xattr-0.8.0/setup.py
--- old/xattr-0.7.8/setup.py    2015-06-25 19:25:42.000000000 +0200
+++ new/xattr-0.8.0/setup.py    2016-02-28 20:10:07.000000000 +0100
@@ -16,7 +16,7 @@
         self.distribution.ext_modules = [ffi.verifier.get_extension()]
         build.finalize_options(self)
 
-VERSION = '0.7.8'
+VERSION = '0.8.0'
 DESCRIPTION = "Python wrapper for extended filesystem attributes"
 LONG_DESCRIPTION = """
 Extended attributes extend the basic attributes of files and directories
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/xattr/__init__.py 
new/xattr-0.8.0/xattr/__init__.py
--- old/xattr-0.7.8/xattr/__init__.py   2015-06-25 19:25:42.000000000 +0200
+++ new/xattr-0.8.0/xattr/__init__.py   2016-02-28 20:10:07.000000000 +0100
@@ -7,7 +7,7 @@
 that exposes these extended attributes.
 """
 
-__version__ = '0.7.8'
+__version__ = '0.8.0'
 
 from .lib import (XATTR_NOFOLLOW, XATTR_CREATE, XATTR_REPLACE,
     XATTR_NOSECURITY, XATTR_MAXNAMELEN, XATTR_FINDERINFO_NAME,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/xattr/lib.py new/xattr-0.8.0/xattr/lib.py
--- old/xattr-0.7.8/xattr/lib.py        2015-06-25 19:25:42.000000000 +0200
+++ new/xattr-0.8.0/xattr/lib.py        2016-02-28 20:10:07.000000000 +0100
@@ -5,10 +5,10 @@
 
 ffi = cffi.FFI()
 ffi.cdef("""
-#define XATTR_NOFOLLOW ...
-#define XATTR_CREATE ...
-#define XATTR_REPLACE ...
-#define XATTR_NOSECURITY ...
+#define XATTR_XATTR_NOFOLLOW ...
+#define XATTR_XATTR_CREATE ...
+#define XATTR_XATTR_REPLACE ...
+#define XATTR_XATTR_NOSECURITY ...
 #define XATTR_MAXNAMELEN ...
 
 ssize_t xattr_getxattr(const char *, const char *, void *, ssize_t, uint32_t, 
int);
@@ -543,7 +543,7 @@
     } else if (options != 0) {
         return -1;
     }
-    if (options & XATTR_XATTR_NOFOLLOW) {
+    if (nofollow) {
         return -1;
     } else {
         return fsetxattr(fd, name, value, size, options);
@@ -582,36 +582,42 @@
 #define xattr_fsetxattr fsetxattr
 #define xattr_listxattr listxattr
 #define xattr_flistxattr flistxattr
+
+/* define these for use in python (see below) */
+#define XATTR_XATTR_NOFOLLOW   XATTR_NOFOLLOW
+#define XATTR_XATTR_CREATE     XATTR_CREATE
+#define XATTR_XATTR_REPLACE    XATTR_REPLACE
+#define XATTR_XATTR_NOSECURITY XATTR_NOSECURITY
 #endif
 
 #ifndef XATTR_MAXNAMELEN
 #define XATTR_MAXNAMELEN 127
 #endif
-
-#ifndef XATTR_NOFOLLOW
-#define XATTR_NOFOLLOW 0x0001
-#endif
-
-#ifndef XATTR_NOSECURITY
-#define XATTR_NOSECURITY 0x0008
-#endif
 """, ext_package='xattr')
 
-XATTR_NOFOLLOW = lib.XATTR_NOFOLLOW
-XATTR_CREATE = lib.XATTR_CREATE
-XATTR_REPLACE = lib.XATTR_REPLACE
-XATTR_NOSECURITY = lib.XATTR_NOSECURITY
+XATTR_NOFOLLOW = lib.XATTR_XATTR_NOFOLLOW
+XATTR_CREATE = lib.XATTR_XATTR_CREATE
+XATTR_REPLACE = lib.XATTR_XATTR_REPLACE
+XATTR_NOSECURITY = lib.XATTR_XATTR_NOSECURITY
 XATTR_MAXNAMELEN = lib.XATTR_MAXNAMELEN
 
 XATTR_FINDERINFO_NAME = "com.apple.FinderInfo"
 XATTR_RESOURCEFORK_NAME = "com.apple.ResourceFork"
 
-
-def fs_encode(val):
-    if not isinstance(val, bytes):
-        return val.encode(sys.getfilesystemencoding())
-    else:
-        return val
+try:
+    fs_encode = os.fsencode
+except AttributeError:
+    def fs_encode(val):
+        encoding = sys.getfilesystemencoding()
+        if encoding == 'mbcs':
+            errors = 'strict'
+        else:
+            errors = 'surrogateescape'
+
+        if not isinstance(val, bytes):
+            return val.encode(encoding, errors)
+        else:
+            return val
 
 
 def _check_bytes(val):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/xattr/pyxattr_compat.py 
new/xattr-0.8.0/xattr/pyxattr_compat.py
--- old/xattr-0.7.8/xattr/pyxattr_compat.py     1970-01-01 01:00:00.000000000 
+0100
+++ new/xattr-0.8.0/xattr/pyxattr_compat.py     2016-02-28 20:10:07.000000000 
+0100
@@ -0,0 +1,110 @@
+"""
+pyxattr and xattr have differing API, for example xattr assumes
+that (like on OSX) attribute keys are valid UTF-8, while pyxattr
+just passes through the raw bytestring.
+
+This module provides compatibility for the pyxattr API.
+"""
+
+import sys
+
+from .lib import (XATTR_NOFOLLOW, XATTR_CREATE, XATTR_REPLACE,
+    XATTR_NOSECURITY, XATTR_MAXNAMELEN, XATTR_FINDERINFO_NAME,
+    XATTR_RESOURCEFORK_NAME, _getxattr, _fgetxattr, _setxattr, _fsetxattr,
+    _removexattr, _fremovexattr, _listxattr, _flistxattr)
+
+__all__ = [
+    "NS_SECURITY", "NS_USER", "NS_SYSTEM", "NS_TRUSTED",
+    "getxattr", "get", "get_all", "setxattr", "set",
+    "removexattr", "remove", "listxattr", "list"
+]
+
+NS_SECURITY = "security"
+NS_USER = "user"
+NS_SYSTEM = "system"
+NS_TRUSTED = "trusted"
+
+_NO_NS = object()
+
+_fsencoding = sys.getfilesystemencoding()
+
+def _call(item, name_func, fd_func, *args):
+    if isinstance(item, int):
+        return fd_func(item, *args)
+    elif hasattr(item, 'fileno'):
+        return fd_func(item.fileno(), *args)
+    elif isinstance(item, str):
+        return name_func(item, *args)
+    elif isinstance(item, unicode):
+        item = item.encode(_fsencoding)
+        return name_func(item, *args)
+    else:
+        raise TypeError("argument must be string, int or file object")
+
+def _add_ns(item, ns):
+    if ns is None:
+        raise TypeError("namespace must not be None")
+    if ns == _NO_NS:
+        return item
+    return "%s.%s" % (ns, item)
+
+def getxattr(item, attribute, nofollow=False):
+    options = nofollow and XATTR_NOFOLLOW or 0
+    return _call(item, _getxattr, _fgetxattr, attribute, 0, 0, options)
+
+def get(item, name, nofollow=False, namespace=_NO_NS):
+    name = _add_ns(name, namespace)
+    return getxattr(item, name, nofollow=nofollow)
+
+def get_all(item, nofollow=False, namespace=_NO_NS):
+    if namespace is not None and namespace != _NO_NS:
+        namespace = '%s.' % namespace
+    l = listxattr(item, nofollow=nofollow)
+    result = []
+    for name in l:
+        try:
+            if namespace is not None and namespace != _NO_NS:
+                if not name.startswith(namespace):
+                    continue
+                result.append((name[len(namespace):],
+                               getxattr(item, name, nofollow=nofollow)))
+            else:
+                result.append((name, getxattr(item, name, nofollow=nofollow)))
+        except IOError:
+            pass
+    return result
+
+def setxattr(item, name, value, flags=0, nofollow=False):
+    options = nofollow and XATTR_NOFOLLOW or 0
+    options |= flags
+    return _call(item, _setxattr, _fsetxattr, name, value, 0, options)
+
+def set(item, name, value, nofollow=False, flags=0, namespace=_NO_NS):
+    name = _add_ns(name, namespace)
+    return setxattr(item, name, value, flags=flags, nofollow=nofollow)
+
+def removexattr(item, name, nofollow=False):
+    options = nofollow and XATTR_NOFOLLOW or 0
+    return _call(item, _removexattr, _fremovexattr, name, options)
+
+def remove(item, name, nofollow=False, namespace=_NO_NS):
+    name = _add_ns(name, namespace)
+    return removexattr(item, name, nofollow=nofollow)
+
+def listxattr(item, nofollow=False):
+    options = nofollow and XATTR_NOFOLLOW or 0
+    res = _call(item, _listxattr, _flistxattr, options).split(b'\x00')
+    res.pop()
+    return res
+
+def list(item, nofollow=False, namespace=_NO_NS):
+    if not namespace or namespace == _NO_NS:
+        return listxattr(item, nofollow=nofollow)
+    namespace = "%s." % namespace
+    l = listxattr(item, nofollow=nofollow)
+    result = []
+    for name in l:
+        if not name.startswith(namespace):
+            continue
+        result.append(name[len(namespace):])
+    return result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xattr-0.7.8/xattr/tests/test_xattr.py 
new/xattr-0.8.0/xattr/tests/test_xattr.py
--- old/xattr-0.7.8/xattr/tests/test_xattr.py   2015-06-25 19:25:42.000000000 
+0200
+++ new/xattr-0.8.0/xattr/tests/test_xattr.py   2016-02-28 20:10:07.000000000 
+0100
@@ -1,5 +1,6 @@
 import os
 import sys
+import unittest
 from unittest import TestCase
 from tempfile import mkdtemp, NamedTemporaryFile
 
@@ -96,3 +97,17 @@
 
     def tearDown(self):
         os.rmdir(self.tempfile)
+
+
+try:
+    # SkipTest is only available in Python 2.7+
+    unittest.SkipTest
+except AttributeError:
+    pass
+else:
+    class TestFileWithSurrogates(TestFile):
+        def setUp(self):
+            if sys.platform != 'linux':
+                raise unittest.SkipTest('Files with invalid encoded names are 
only supported under linux')
+            self.tempfile = 
NamedTemporaryFile(prefix=b'invalid-\xe9'.decode('utf8','surrogateescape'))
+            self.tempfilename = self.tempfile.name


Reply via email to