Package: python3-augeas Version: 0.5.0-1 Severity: wishlist Tags: patch -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512
Dear Maintainer, The newer version of package available in upstream git repository use cffi library instead of ctypes to load the C augeas library. This sidesteps the problem described in #944364. One could also take this opportunity to migrate the git repository to Salsa (perhaps under the python-team). I have done the necessary work for the new release, the patches are attached with following changes: * control: Update list of dependencies * control: Remove unnecessary python version fields * control: Specify that rules file does not require root * control: Update standards version to 4.4.1. No changes required. * control: Enable autopkgtest-pkg-python * control: Update debhelper compatibility level to 12 * rules: Run tests during build Thank you, - -- Sunil - -- System Information: Debian Release: 10.2 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable') Architecture: amd64 (x86_64) Kernel: Linux 4.19.0-6-amd64 (SMP w/4 CPU cores) Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_IN.UTF-8, LC_CTYPE=en_IN.UTF-8 (charmap=UTF-8), LANGUAGE=en_IN.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages python3-augeas depends on: ii libaugeas0 1.11.0-3 ii python3 3.7.3-1 python3-augeas recommends no packages. python3-augeas suggests no packages. - -- no debconf information -----BEGIN PGP SIGNATURE----- iQJFBAEBCgAvFiEE5xPDY9ZyWnWupXSBQ+oc/wqnxfIFAl39hzoRHHN1bmlsQG1l ZGhhcy5vcmcACgkQQ+oc/wqnxfJoYA/+NOZEDuYybEq9g1CfHNx23xUINGysjxAp qNEpuUYWRkvtHHDKjuCtaKeUsim0TQ4tWcbCpv7xNzMIOZY6PuZv75Jm3Kn8hAo7 ocO9c4osIVUhj05+hkaBA5xVXDFnulZDqn63LY69Df6PKN/0k4ov1kLsBpZ/Wle0 cUFynK5018ticnDVTaI/F6Lzu6gOr6+0H4TABW4PV+pRAMHz0l286rRMOFurid5A MlmQlAug3yyrKwDP7WQiuujTxGisNWJYmIqkfETe/ibExkNNbUaJF73gyrmJu2e/ lIrtG4E+ysJrmGXAR+eoP/HNRczbjnXdwgdexD2A26RTyVB5lSi1kMS0COZRf0PE /EckOm7hOXtk2IHmNHJJyIwlXTGjuA6kqo9Jnt6gKvWzwRdTaAfLmI4rh8mEIELG 1n5OUKXDNrJUNEQlWzqBNbNV7L876qSLcAHlSc0/1FatFMvGqsosggnmDyCuTkQN TzM1xuAksbiUfOKUN9z+rsx9sjCwIewDWuoG5oL5NVHWskijTOrcK6Sowo3ukV3D t1RxCF34nHWpsBy54E4kYOXs+IcUOnU8fztSfbI2M77XGuVUWQeTU3LyryTPMESd 1v1461vorHTa1+WwSEeZ3EQusOCzWWO3CdRdy0uJbTBS7ljqplIMbwo+O0obaOps CTnyx2IAyig= =ePp7 -----END PGP SIGNATURE-----
>From 7f8cb9c9adbb8cc0bf16f394ff0bae23db9f1a8d Mon Sep 17 00:00:00 2001 From: Sandro Tosi <mo...@debian.org> Date: Fri, 20 Dec 2019 16:30:56 -0800 Subject: [PATCH 01/10] Release 0.5.0-1.1, non-maintainer upload --- debian/changelog | 7 +++++++ debian/control | 15 --------------- debian/rules | 3 +-- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/debian/changelog b/debian/changelog index 465320f..cabcd63 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-augeas (0.5.0-1.1) unstable; urgency=medium + + * Non-maintainer upload. + * Drop python2 support; Closes: #937588, #734557 + + -- Sandro Tosi <mo...@debian.org> Wed, 16 Oct 2019 22:17:14 -0400 + python-augeas (0.5.0-1) unstable; urgency=low * New upstream release diff --git a/debian/control b/debian/control index 2e7be81..f2e571e 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,6 @@ Build-Depends: debhelper (>= 9~), dh-python, libaugeas0 (>= 0.7.2), - python-all (>= 2.6.5), python3-all Standards-Version: 3.9.6 X-Python-Version: >= 2.6 @@ -15,20 +14,6 @@ Homepage: http://augeas.net/ Vcs-Git: git://anonscm.debian.org/collab-maint/python-augeas.git Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/python-augeas.git -Package: python-augeas -Architecture: all -Depends: - libaugeas0 (>= 0.7.2), - ${misc:Depends}, - ${python:Depends} -Description: Python bindings for Augeas - Augeas is a library and command line tool that focuses - on the most basic problem in handling Linux configurations - programmatically: editing actual configuration files in a - controlled manner. - . - This module provides a Python interface to the Augeas API. - Package: python3-augeas Architecture: all Depends: diff --git a/debian/rules b/debian/rules index 9b2702b..94d7f97 100755 --- a/debian/rules +++ b/debian/rules @@ -2,8 +2,7 @@ export DH_VERBOSE=1 export PYBUILD_NAME=augeas -export PYBUILD_DESTDIR_python2=debian/python-augeas/ export PYBUILD_DESTDIR_python3=debian/python3-augeas/ %: - dh $@ --buildsystem=pybuild --with python2,python3 + dh $@ --buildsystem=pybuild --with python3 -- 2.20.1
>From 45c94f8f71d8db4bba7bd308fa3bc83e68275758 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 16:35:38 -0800 Subject: [PATCH 02/10] New upstream version 1.0.3 --- .gitignore | 101 +++++++++++++++++ .travis.yml | 31 ++++-- Makefile | 5 +- augeas.py => augeas/__init__.py | 192 ++++++++++++++++---------------- augeas/ffi.py | 45 ++++++++ setup.py | 11 +- test/test_augeas.py | 60 ++++++++-- 7 files changed, 326 insertions(+), 119 deletions(-) rename augeas.py => augeas/__init__.py (83%) create mode 100644 augeas/ffi.py mode change 100644 => 100755 setup.py diff --git a/.gitignore b/.gitignore index b408e6c..02c0586 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,102 @@ /.pc + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# augeas logs +*.out diff --git a/.travis.yml b/.travis.yml index 5102158..634ef4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,26 @@ language: python python: - - 2.6 - - 2.7 - - 3.2 - - 3.3 +- 2.6 +- 2.7 +- 3.3 +- 3.4 +- 3.5 +- pypy notifications: email: - - raphael.pin...@camptocamp.com + - raphael.pin...@camptocamp.com install: - # Use latest Augeas - - sudo add-apt-repository -y ppa:raphink/augeas-dev - - sudo apt-get update - - sudo apt-get install libaugeas-dev libxml2-dev -script: make && make check +- sudo add-apt-repository -y ppa:raphink/augeas +- sudo apt-get update +- sudo apt-get install libaugeas-dev +- pip install . +script: make check +deploy: + provider: pypi + user: the_drow + password: + secure: FAsA8tIeTBhQQsJflaUwlE8XLIBjPMdmoT8WRVNkFght6ANdaW7+W9HznQvPc8qMbOpT8/K6ToTd8bIb678VRPhzxBkmpStj78wPPET5Q8MANakik73azqfvu6OMKXwpbcLtbaeeqZkRE5LP0ueYyGKtyyvR7iGtBmJbawYiEjo= + on: + tags: true + distributions: sdist bdist_wheel + repo: hercules-team/python-augeas diff --git a/Makefile b/Makefile index 7c7b9bf..cfd40b6 100644 --- a/Makefile +++ b/Makefile @@ -6,12 +6,13 @@ all: build clean: PREFIX=$(PREFIX) python setup.py clean - rm -f augeas.py* + rm -f augeas.py* distclean: clean rm -fr build dist MANIFEST -build: augeas.py +build: + PREFIX=$(PREFIX) python setup.py build install: PREFIX=$(PREFIX) python setup.py install diff --git a/augeas.py b/augeas/__init__.py similarity index 83% rename from augeas.py rename to augeas/__init__.py index ca5e191..b9e75f4 100644 --- a/augeas.py +++ b/augeas/__init__.py @@ -37,18 +37,16 @@ __credits__ = """Jeff Schroeder <jeffschroe...@computer.org> Harald Hoyer <har...@redhat.com> - initial python bindings, packaging Nils Philippsen <n...@redhat.com> """ - -import types -import ctypes -import ctypes.util -from sys import version_info as _pyver from functools import reduce +from sys import version_info as _pyver +import cffi +import types +from augeas.ffi import ffi, lib PY3 = _pyver >= (3,) AUGENC = 'utf8' - if PY3: string_types = str else: @@ -58,30 +56,19 @@ else: def enc(st): if st: return st.encode(AUGENC) + else: + return b'' def dec(st): if st: return st.decode(AUGENC) + else: + return b'' -def _dlopen(*args): - """Search for one of the libraries given as arguments and load it. - Returns the library. - """ - libs = [l for l in [ ctypes.util.find_library(a) for a in args ] if l] - lib = reduce(lambda x, y: x or ctypes.cdll.LoadLibrary(y), libs, None) - if not lib: - raise ImportError("Unable to import lib%s!" % args[0]) - return lib - class Augeas(object): "Class wrapper for the augeas library" - - # Load libaugeas - _libaugeas = _dlopen("augeas") - _libaugeas.aug_init.restype = ctypes.c_void_p - # Augeas Flags NONE = 0 SAVE_BACKUP = 1 << 0 @@ -114,15 +101,13 @@ class Augeas(object): if not isinstance(flags, int): raise TypeError("flag MUST be a flag!") + root = enc(root) if root else ffi.NULL + loadpath = enc(loadpath) if loadpath else ffi.NULL + # Create the Augeas object - self.__handle = Augeas._libaugeas.aug_init(enc(root), enc(loadpath), flags) + self.__handle = ffi.gc(lib.aug_init(root, loadpath, flags), lambda x: self.close) if not self.__handle: raise RuntimeError("Unable to create Augeas object!") - # Make sure self.__handle is a void*, not an integer - self.__handle = ctypes.c_void_p(self.__handle) - - def __del__(self): - self.close() def get(self, path): """Lookup the value associated with 'path'. @@ -136,15 +121,14 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Create the char * value - value = ctypes.c_char_p() + value = ffi.new("char*[]", 1) # Call the function and pass value by reference (char **) - ret = Augeas._libaugeas.aug_get(self.__handle, enc(path), - ctypes.byref(value)) - if ret > 1: - raise ValueError("path specified had too many matches!") + ret = lib.aug_get(self.__handle, enc(path), value) + if ret < 0: + raise ValueError("path specified had too many matches or is illegal!") - return dec(value.value) + return dec(ffi.string(value[0])) if value[0] != ffi.NULL else None def label(self, path): """Lookup the label associated with 'path'. @@ -158,15 +142,14 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Create the char * value - label = ctypes.c_char_p() + label = ffi.new("char*[]", 1) # Call the function and pass value by reference (char **) - ret = Augeas._libaugeas.aug_label(self.__handle, enc(path), - ctypes.byref(label)) - if ret > 1: - raise ValueError("path specified had too many matches!") + ret = lib.aug_label(self.__handle, enc(path), label) + if ret < 0: + raise ValueError("path specified had too many matches or is illegal!") - return dec(label.value) + return dec(ffi.string(label[0])) if label[0] != ffi.NULL else None def set(self, path, value): """Set the value associated with 'path' to 'value'. @@ -182,7 +165,7 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_set(self.__handle, enc(path), enc(value)) + ret = lib.aug_set(self.__handle, enc(path), enc(value)) if ret != 0: raise ValueError("Unable to set value to path!") @@ -198,13 +181,13 @@ class Augeas(object): raise TypeError("base MUST be a string!") if type(sub) != str and sub != None: raise TypeError("sub MUST be a string or None!") - if type(value) != str: - raise TypeError("value MUST be a string!") + if type(value) != str and value != None: + raise TypeError("value MUST be a string or None!") if not self.__handle: raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_setm( + ret = lib.aug_setm( self.__handle, enc(base), enc(sub), enc(value)) if ret < 0: raise ValueError("Unable to set value to path!") @@ -226,7 +209,7 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_text_store( + ret = lib.aug_text_store( self.__handle, enc(lens), enc(node), enc(path)) if ret != 0: raise ValueError("Unable to store text at node!") @@ -250,7 +233,7 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_text_retrieve( + ret = lib.aug_text_retrieve( self.__handle, enc(lens), enc(node_in), enc(path), enc(node_out)) if ret != 0: raise ValueError("Unable to store text at node!") @@ -260,10 +243,10 @@ class Augeas(object): """Define a variable 'name' whose value is the result of evaluating 'expr'. If a variable 'name' already exists, its name will be replaced with the result of evaluating 'expr'. - + If 'expr' is None, the variable 'name' will be removed if it is defined. - + Path variables can be used in path expressions later on by prefixing them with '$'.""" @@ -276,7 +259,7 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_defvar(self.__handle, enc(name), enc(expr)) + ret = lib.aug_defvar(self.__handle, enc(name), enc(expr)) if ret < 0: raise ValueError("Unable to register variable!") return ret @@ -286,7 +269,7 @@ class Augeas(object): evaluating 'expr', which must not be None and evaluate to a nodeset. If a variable 'name' already exists, its name will be replaced with the result of evaluating 'expr'. - + If 'expr' evaluates to an empty nodeset, a node is created, equivalent to calling set(expr, value) and 'name' will be the nodeset containing that single node.""" @@ -302,8 +285,8 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_defnode( - self.__handle, enc(name), enc(expr), enc(value), None) + ret = lib.aug_defnode( + self.__handle, enc(name), enc(expr), enc(value), ffi.NULL) if ret < 0: raise ValueError("Unable to register node!") return ret @@ -324,10 +307,30 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_mv(self.__handle, enc(src), enc(dst)) + ret = lib.aug_mv(self.__handle, enc(src), enc(dst)) if ret != 0: raise ValueError("Unable to move src to dst!") + def copy(self, src, dst): + """Copy the node 'src' to 'dst'. 'src' must match exactly one node + in the tree. 'dst' must either match exactly one node in the + tree, or may not exist yet. If 'dst' exists already, it and all + its descendants are deleted before copying 'src' there. If 'dst' + does not exist yet, it and all its missing ancestors are created.""" + + # Sanity checks + if not isinstance(src, string_types): + raise TypeError("src MUST be a string!") + if not isinstance(dst, string_types): + raise TypeError("dst MUST be a string!") + if not self.__handle: + raise RuntimeError("The Augeas object has already been closed!") + + # Call the function + ret = lib.aug_cp(self.__handle, enc(src), enc(dst)) + if ret != 0: + raise ValueError("Unable to copy src to dst!") + def rename(self, src, dst): """Rename the label of all nodes matching 'src' to 'lbl'.""" @@ -340,7 +343,7 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_rename(self.__handle, enc(src), enc(dst)) + ret = lib.aug_rename(self.__handle, enc(src), enc(dst)) if ret < 0: raise ValueError("Unable to rename src as dst!") return ret @@ -363,8 +366,8 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_insert(self.__handle, enc(path), - enc(label), before and 1 or 0) + ret = lib.aug_insert(self.__handle, enc(path), + enc(label), before and 1 or 0) if ret != 0: raise ValueError("Unable to insert label!") @@ -380,7 +383,7 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - return Augeas._libaugeas.aug_rm(self.__handle, enc(path)) + return lib.aug_rm(self.__handle, enc(path)) def match(self, path): """Return the matches of the path expression 'path'. The returned paths @@ -404,31 +407,22 @@ class Augeas(object): if not self.__handle: raise RuntimeError("The Augeas object has already been closed!") - # Create a void ** (this is so python won't mangle the char **, - # when we free it) - array = ctypes.POINTER(ctypes.c_void_p)() + parray = ffi.new('char***') - # Call the function and pass the void ** by reference (void ***) - ret = Augeas._libaugeas.aug_match(self.__handle, enc(path), - ctypes.byref(array)) + ret = lib.aug_match(self.__handle, enc(path), parray) if ret < 0: raise RuntimeError("Error during match procedure!", path) # Loop through the string array + array = parray[0] matches = [] for i in range(ret): - if array[i]: + if array[i] != ffi.NULL: # Create a python string and append it to our matches list - matches.append(dec(ctypes.cast(array[i], - ctypes.c_char_p).value)) - - # Free the string at this point in the array - # Wrap the string as a void* as it was not allocated by Python - ctypes.pythonapi.PyMem_Free(ctypes.c_void_p(array[i])) - - # Free the array itself - ctypes.pythonapi.PyMem_Free(array) - + item = ffi.string(array[i]) + matches.append(dec(item)) + lib.free(array[i]) + lib.free(array) return matches def span(self, path): @@ -444,26 +438,26 @@ class Augeas(object): if not self.__handle: raise RuntimeError("The Augeas object has already been closed!") - filename = ctypes.c_char_p() - label_start = ctypes.c_uint() - label_end = ctypes.c_uint() - value_start = ctypes.c_uint() - value_end = ctypes.c_uint() - span_start = ctypes.c_uint() - span_end = ctypes.c_uint() + # TODO: Rewrite this - r = ctypes.byref + filename = ffi.new('char **') + label_start = ffi.new('unsigned int *') + label_end = ffi.new('unsigned int *') + value_start = ffi.new('unsigned int *') + value_end = ffi.new('unsigned int *') + span_start = ffi.new('unsigned int *') + span_end = ffi.new('unsigned int *') - ret = Augeas._libaugeas.aug_span(self.__handle, enc(path), r(filename), - r(label_start), r(label_end), - r(value_start), r(value_end), - r(span_start), r(span_end)) + ret = lib.aug_span(self.__handle, enc(path), filename, + label_start, label_end, + value_start, value_end, + span_start, span_end) if (ret < 0): raise ValueError("Error during span procedure") - - return (dec(filename.value), label_start.value, label_end.value, - value_start.value, value_end.value, - span_start.value, span_end.value) + fname = dec(ffi.string(filename[0])) if filename != ffi.NULL else None + return (fname, int(label_start[0]), int(label_end[0]), + int(value_start[0]), int(value_end[0]), + int(span_start[0]), int(span_end[0])) def save(self): """Write all pending changes to disk. Only files that had any changes @@ -483,7 +477,7 @@ class Augeas(object): raise RuntimeError("The Augeas object has already been closed!") # Call the function - ret = Augeas._libaugeas.aug_save(self.__handle) + ret = lib.aug_save(self.__handle) if ret != 0: raise IOError("Unable to save to file!") @@ -515,7 +509,7 @@ class Augeas(object): if not self.__handle: raise RuntimeError("The Augeas object has already been closed!") - ret = Augeas._libaugeas.aug_load(self.__handle) + ret = lib.aug_load(self.__handle) if ret != 0: raise RuntimeError("aug_load() failed!") @@ -537,9 +531,9 @@ class Augeas(object): import warnings warnings.warn("name is now deprecated in this function", DeprecationWarning, stacklevel=2) - if isinstance (incl, string_types): + if isinstance(incl, string_types): incl = [incl] - if isinstance (excl, string_types): + if isinstance(excl, string_types): excl = [excl] for i in range(len(incl)): @@ -564,7 +558,7 @@ class Augeas(object): if not self.__handle: raise RuntimeError("The Augeas object has already been closed!") - ret = Augeas._libaugeas.aug_transform(self.__handle, enc(lens), enc(file), excl) + ret = lib.aug_transform(self.__handle, enc(lens), enc(file), excl) if ret != 0: raise RuntimeError("Unable to add transform!") @@ -574,15 +568,16 @@ class Augeas(object): for any more operations.""" # If we are already closed, return - if not self.__handle: + if not self.__handle or self.__handle == ffi.NULL: return # Call the function - Augeas._libaugeas.aug_close(self.__handle) + lib.aug_close(self.__handle) # Mark the object as closed self.__handle = None + # for backwards compatibility # pylint: disable-msg=C0103 class augeas(Augeas): @@ -591,5 +586,8 @@ class augeas(Augeas): def __init__(self, *p, **k): import warnings warnings.warn("use Augeas instead of augeas", DeprecationWarning, - stacklevel=2) + stacklevel=2) super(augeas, self).__init__(*p, **k) + + +__all__ = ['Augeas', 'augeas'] diff --git a/augeas/ffi.py b/augeas/ffi.py new file mode 100644 index 0000000..6bc7719 --- /dev/null +++ b/augeas/ffi.py @@ -0,0 +1,45 @@ +from cffi import FFI + +ffi = FFI() +ffi.set_source("augeas", + None, + libraries=['augeas']) + +ffi.cdef(""" +typedef struct augeas augeas; + +augeas *aug_init(const char *root, const char *loadpath, unsigned int flags); +int aug_defvar(augeas *aug, const char *name, const char *expr); +int aug_defnode(augeas *aug, const char *name, const char *expr, + const char *value, int *created); +int aug_get(const augeas *aug, const char *path, const char **value); +int aug_label(const augeas *aug, const char *path, const char **label); +int aug_set(augeas *aug, const char *path, const char *value); +int aug_setm(augeas *aug, const char *base, const char *sub, const char *value); +int aug_span(augeas *aug, const char *path, char **filename, + unsigned int *label_start, unsigned int *label_end, + unsigned int *value_start, unsigned int *value_end, + unsigned int *span_start, unsigned int *span_end); +int aug_insert(augeas *aug, const char *path, const char *label, int before); +int aug_rm(augeas *aug, const char *path); +int aug_mv(augeas *aug, const char *src, const char *dst); +int aug_cp(augeas *aug, const char *src, const char *dst); +int aug_rename(augeas *aug, const char *src, const char *lbl); +int aug_match(const augeas *aug, const char *path, char ***matches); +int aug_save(augeas *aug); +int aug_load(augeas *aug); +int aug_text_store(augeas *aug, const char *lens, const char *node, + const char *path); +int aug_text_retrieve(struct augeas *aug, const char *lens, + const char *node_in, const char *path, + const char *node_out); +int aug_transform(augeas *aug, const char *lens, const char *file, int excl); +void aug_close(augeas *aug); + +void free(void *); +""") + +lib = ffi.dlopen("augeas") + +if __name__ == "__main__": + ffi.compile(verbose=True) diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index 4f7554d..aaa5be4 --- a/setup.py +++ b/setup.py @@ -5,15 +5,20 @@ setup.py file for augeas """ import os + +from setuptools import setup, find_packages + prefix = os.environ.get("prefix", "/usr") -from distutils.core import setup setup (name = 'python-augeas', - version = '0.5.0', + version = '1.0.3', author = "Harald Hoyer", author_email = "augeas-de...@redhat.com", description = """Python bindings for Augeas""", - py_modules = [ "augeas" ], + packages=find_packages(exclude=('test')), + setup_requires=["cffi>=1.0.0"], + cffi_modules=["augeas/ffi.py:ffi"], + install_requires=["cffi>=1.0.0"], url = "http://augeas.net/", ) diff --git a/test/test_augeas.py b/test/test_augeas.py index 10edbe6..68bdc2e 100644 --- a/test/test_augeas.py +++ b/test/test_augeas.py @@ -1,8 +1,8 @@ from __future__ import print_function -import unittest -import sys import os +import sys +import unittest __mydir = os.path.dirname(sys.argv[0]) if not os.path.isdir(__mydir): @@ -33,10 +33,22 @@ def recurmatch(aug, path): yield x class TestAugeas(unittest.TestCase): - def test01Get(self): - "test aug_get" + def test01aGetNone(self): + "test aug_get with non-existing path" + a = augeas.Augeas(root=MYROOT) + self.failUnless(a.get("/wrong/path") is None) + del a + + def test01bGetValue(self): + "test aug_get with existing path" a = augeas.Augeas(root=MYROOT) - self.failUnless(a.get("/wrong/path") == None) + self.assertEqual(a.get("/files/etc/hosts/1/ipaddr"), "127.0.0.1") + del a + + def test01cGetException(self): + "test aug_get with incorrect path" + a = augeas.Augeas(root=MYROOT) + self.assertRaises(ValueError, a.get, "/files//[1]/") del a def test02Match(self): @@ -86,7 +98,7 @@ class TestAugeas(unittest.TestCase): for attr in a.match(i+"/*"): self.failUnless(a.get(attr) != None) del a - + def test06Defnode(self): "test defnode" a = augeas.Augeas(root=MYROOT) @@ -158,6 +170,10 @@ class TestAugeas(unittest.TestCase): error = e self.assertTrue(isinstance(error, ValueError)) + def testSetNone(self): + a = augeas.Augeas(root=MYROOT) + r = a.set("/raw/hosts", None); + def test10TextRetrieve(self): hosts = "192.168.0.1 rtr.example.com router\n" a = augeas.Augeas(root=MYROOT) @@ -212,12 +228,42 @@ class TestAugeas(unittest.TestCase): excl = a.get("/augeas/load/Foo/excl") self.assertEqual(excl, "/tmp/baz") - def test14Label(self): + def test14aLabelOk(self): + """test aug_label with valid input""" a = augeas.Augeas(root=MYROOT) lbl = a.label("/augeas/version") self.assertEqual(lbl, "version") + def test14bLabelException(self): + """test aug_label with invalid input""" + a = augeas.Augeas(root=MYROOT) + + self.assertRaises(ValueError, a.label, "/augeas/version/[1]/") + + def test15Copy(self): + a = augeas.Augeas(root=MYROOT) + + orig_path = '/tmp/src/copy_test/a' + copy_path = '/tmp/dst/copy_test/a' + orig_value = 'test value' + + a.set(orig_path, orig_value) + + matches = a.match(orig_path) + self.failUnless(matches) + + a.copy(orig_path, copy_path) + + matches = a.match(copy_path) + self.failUnless(matches) + self.assertEqual(a.get(copy_path), a.get(orig_path)) + + def testClose(self): + a = augeas.Augeas(root=MYROOT) + a.close() + + def getsuite(): suite = unittest.TestSuite() suite = unittest.makeSuite(TestAugeas, 'test') -- 2.20.1
>From 4ee4b627d7b6892667023717cea462d42f55199e Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 16:40:13 -0800 Subject: [PATCH 03/10] Prepare for release 1.0.3-1 Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index cabcd63..ddf874f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-augeas (1.0.3-1) UNRELEASED; urgency=medium + + * New upstream release + + -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 + python-augeas (0.5.0-1.1) unstable; urgency=medium * Non-maintainer upload. -- 2.20.1
>From ce69a6c36309439d811076f6e5f1eea710c9e79f Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 16:43:59 -0800 Subject: [PATCH 04/10] control: Update list of dependencies Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 1 + debian/control | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index ddf874f..c0e5cc7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ python-augeas (1.0.3-1) UNRELEASED; urgency=medium * New upstream release + * control: Update list of dependencies -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 diff --git a/debian/control b/debian/control index f2e571e..360eb9a 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,9 @@ Build-Depends: debhelper (>= 9~), dh-python, libaugeas0 (>= 0.7.2), - python3-all + python3-all, + python3-cffi (>= 1.0.0), + python3-setuptools Standards-Version: 3.9.6 X-Python-Version: >= 2.6 X-Python3-Version: >= 3.3 -- 2.20.1
>From d7c5abcbeb252be62222111970184315c277a46e Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 16:48:54 -0800 Subject: [PATCH 05/10] control: Remove unnecessary python version fields Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 1 + debian/control | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index c0e5cc7..146fed9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ python-augeas (1.0.3-1) UNRELEASED; urgency=medium * New upstream release * control: Update list of dependencies + * control: Remove unnecessary python version fields -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 diff --git a/debian/control b/debian/control index 360eb9a..c494a71 100644 --- a/debian/control +++ b/debian/control @@ -10,8 +10,6 @@ Build-Depends: python3-cffi (>= 1.0.0), python3-setuptools Standards-Version: 3.9.6 -X-Python-Version: >= 2.6 -X-Python3-Version: >= 3.3 Homepage: http://augeas.net/ Vcs-Git: git://anonscm.debian.org/collab-maint/python-augeas.git Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/python-augeas.git -- 2.20.1
>From d7c5abcbeb252be62222111970184315c277a46e Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 16:48:54 -0800 Subject: [PATCH 05/10] control: Remove unnecessary python version fields Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 1 + debian/control | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index c0e5cc7..146fed9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ python-augeas (1.0.3-1) UNRELEASED; urgency=medium * New upstream release * control: Update list of dependencies + * control: Remove unnecessary python version fields -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 diff --git a/debian/control b/debian/control index 360eb9a..c494a71 100644 --- a/debian/control +++ b/debian/control @@ -10,8 +10,6 @@ Build-Depends: python3-cffi (>= 1.0.0), python3-setuptools Standards-Version: 3.9.6 -X-Python-Version: >= 2.6 -X-Python3-Version: >= 3.3 Homepage: http://augeas.net/ Vcs-Git: git://anonscm.debian.org/collab-maint/python-augeas.git Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/python-augeas.git -- 2.20.1
>From 5d5379c03593349b43cda799650869fe993c3d51 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 17:12:23 -0800 Subject: [PATCH 06/10] control: Specify that rules file does not require root Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 1 + debian/control | 1 + 2 files changed, 2 insertions(+) diff --git a/debian/changelog b/debian/changelog index 146fed9..ea7336f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ python-augeas (1.0.3-1) UNRELEASED; urgency=medium * New upstream release * control: Update list of dependencies * control: Remove unnecessary python version fields + * control: Specify that rules file does not require root -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 diff --git a/debian/control b/debian/control index c494a71..aa8aa6b 100644 --- a/debian/control +++ b/debian/control @@ -11,6 +11,7 @@ Build-Depends: python3-setuptools Standards-Version: 3.9.6 Homepage: http://augeas.net/ +Rules-Requires-Root: no Vcs-Git: git://anonscm.debian.org/collab-maint/python-augeas.git Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/python-augeas.git -- 2.20.1
>From 7597c7b57d6ea410a2d0c996a7b65cf96bec7abd Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 17:17:35 -0800 Subject: [PATCH 07/10] control: Update standards version to 4.4.1. No changes required Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 1 + debian/control | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index ea7336f..05c0bb8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ python-augeas (1.0.3-1) UNRELEASED; urgency=medium * control: Update list of dependencies * control: Remove unnecessary python version fields * control: Specify that rules file does not require root + * control: Update standards version to 4.4.1. No changes required. -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 diff --git a/debian/control b/debian/control index aa8aa6b..55bf0cb 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,7 @@ Build-Depends: python3-all, python3-cffi (>= 1.0.0), python3-setuptools -Standards-Version: 3.9.6 +Standards-Version: 4.4.1 Homepage: http://augeas.net/ Rules-Requires-Root: no Vcs-Git: git://anonscm.debian.org/collab-maint/python-augeas.git -- 2.20.1
>From 6e55a4747d3773324d97db774259f59d8eefeb8d Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 17:23:15 -0800 Subject: [PATCH 08/10] control: Enable autopkgtest-pkg-python Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 1 + debian/control | 1 + 2 files changed, 2 insertions(+) diff --git a/debian/changelog b/debian/changelog index 05c0bb8..ad4841d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ python-augeas (1.0.3-1) UNRELEASED; urgency=medium * control: Remove unnecessary python version fields * control: Specify that rules file does not require root * control: Update standards version to 4.4.1. No changes required. + * control: Enable autopkgtest-pkg-python -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 diff --git a/debian/control b/debian/control index 55bf0cb..82114e6 100644 --- a/debian/control +++ b/debian/control @@ -12,6 +12,7 @@ Build-Depends: Standards-Version: 4.4.1 Homepage: http://augeas.net/ Rules-Requires-Root: no +Testsuite: autopkgtest-pkg-python Vcs-Git: git://anonscm.debian.org/collab-maint/python-augeas.git Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/python-augeas.git -- 2.20.1
>From ef221fe1a78c8c16bfac17abdedbd079656ff83f Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 17:25:07 -0800 Subject: [PATCH 09/10] control: Update debhelper compatibility level to 12 Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 1 + debian/compat | 1 - debian/control | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 debian/compat diff --git a/debian/changelog b/debian/changelog index ad4841d..2fc4ae6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,7 @@ python-augeas (1.0.3-1) UNRELEASED; urgency=medium * control: Specify that rules file does not require root * control: Update standards version to 4.4.1. No changes required. * control: Enable autopkgtest-pkg-python + * control: Update debhelper compatibility level to 12 -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec63514..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control index 82114e6..ca50068 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: python Priority: optional Maintainer: Free Ekanayaka <fr...@debian.org> Build-Depends: - debhelper (>= 9~), + debhelper-compat (= 12), dh-python, libaugeas0 (>= 0.7.2), python3-all, -- 2.20.1
>From 813a419f16c380fc98b1a871c30c2227727a62f3 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa <su...@medhas.org> Date: Fri, 20 Dec 2019 18:28:53 -0800 Subject: [PATCH 10/10] rules: Run tests during build Signed-off-by: Sunil Mohan Adapa <su...@medhas.org> --- debian/changelog | 1 + debian/rules | 3 +++ 2 files changed, 4 insertions(+) diff --git a/debian/changelog b/debian/changelog index 2fc4ae6..3ec575e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ python-augeas (1.0.3-1) UNRELEASED; urgency=medium * control: Update standards version to 4.4.1. No changes required. * control: Enable autopkgtest-pkg-python * control: Update debhelper compatibility level to 12 + * rules: Run tests during build -- Sunil Mohan Adapa <su...@medhas.org> Fri, 20 Dec 2019 16:39:33 -0800 diff --git a/debian/rules b/debian/rules index 94d7f97..8b9cd61 100755 --- a/debian/rules +++ b/debian/rules @@ -6,3 +6,6 @@ export PYBUILD_DESTDIR_python3=debian/python3-augeas/ %: dh $@ --buildsystem=pybuild --with python3 + +override_dh_auto_test: + python3 test/test_augeas.py -- 2.20.1