Commit ce8f714f authored by Jérome Perrin's avatar Jérome Perrin

add python3 support and modernize

parent 6561c395
0.8.1.8 (2022/09/14)
--------------------
* Support python3
0.8.1.7 (2015/04/23) 0.8.1.7 (2015/04/23)
-------------------- --------------------
* Fix a regression that was introduced in 0.8.1.6. * Fix a regression that was introduced in 0.8.1.6.
......
include *.py
include *.rst
include MANIFEST.in
...@@ -5,13 +5,18 @@ This is a XUpdate Generator to compare any XML document. ...@@ -5,13 +5,18 @@ This is a XUpdate Generator to compare any XML document.
See <http://xmldb-org.sourceforge.net/xupdate/> for information on See <http://xmldb-org.sourceforge.net/xupdate/> for information on
XUpdate. XUpdate.
Installation
============
python setup install
Test Testing
==== =======
python setup test
To run tests::
python -m unittest discover src
or, using ``zc.buildout`` with ``zope.testrunner``::
buildout
./bin/test
Usage Usage
===== =====
......
##############################################################################
#
# Copyright (c) 2006 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
$Id: bootstrap.py 77225 2007-06-29 09:20:13Z dobe $
"""
import os, shutil, sys, tempfile, urllib2
tmpeggs = tempfile.mkdtemp()
try:
import pkg_resources
except ImportError:
ez = {}
exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
).read() in ez
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
import pkg_resources
cmd = 'from setuptools.command.easy_install import main; main()'
if sys.platform == 'win32':
cmd = '"%s"' % cmd # work around spawn lamosity on windows
ws = pkg_resources.working_set
assert os.spawnle(
os.P_WAIT, sys.executable, sys.executable,
'-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
dict(os.environ,
PYTHONPATH=
ws.find(pkg_resources.Requirement.parse('setuptools')).location
),
) == 0
ws.add_entry(tmpeggs)
ws.require('zc.buildout')
import zc.buildout.buildout
zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
shutil.rmtree(tmpeggs)
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import
from setuptools import setup, find_packages from setuptools import setup, find_packages
import re import re
api_version = re.search(r'\s*__version__\s*=\s*(\S+)', api_version = re.search(r'\s*__version__\s*=\s*(\S+)',
open('src/ERP5Diff/ERP5Diff.py').read()).group(1).strip() open('src/ERP5Diff/ERP5Diff.py').read()).group(1).strip()
revision = 7 revision = 8
version = '%s.%s' % (api_version.replace("'", ''), revision) version = '%s.%s' % (api_version.replace("'", ''), revision)
def read(name): def read(name):
...@@ -15,7 +16,7 @@ def read(name): ...@@ -15,7 +16,7 @@ def read(name):
long_description=( long_description=(
read('README') read('README')
+ '\n' + + '\n' +
read('CHANGES.txt') read('CHANGES.rst')
) )
setup(name="erp5diff", setup(name="erp5diff",
...@@ -24,18 +25,17 @@ setup(name="erp5diff", ...@@ -24,18 +25,17 @@ setup(name="erp5diff",
long_description=long_description, long_description=long_description,
author="Yoshinori OKUJI", author="Yoshinori OKUJI",
author_email="yo@nexedi.com", author_email="yo@nexedi.com",
url="http://www.erp5.org/", url="https://lab.nexedi.com/nexedi/erp5diff/",
license="GPL", license="GPL",
packages=find_packages('src'), packages=find_packages('src'),
package_dir={'': 'src'}, package_dir={'': 'src'},
entry_points={'console_scripts': ["erp5diff = ERP5Diff:main"]}, entry_points={'console_scripts': ["erp5diff = ERP5Diff:main"]},
data_files=[('share/man/man1', ['src/erp5diff.1'])], data_files=[('share/man/man1', ['src/erp5diff.1'])],
install_requires=['lxml'], install_requires=['lxml', 'six', 'zope.interface'],
classifiers=['License :: OSI Approved :: GNU General Public License (GPL)', classifiers=['License :: OSI Approved :: GNU General Public License (GPL)',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Topic :: Text Processing :: Markup :: XML', 'Topic :: Text Processing :: Markup :: XML',
'Topic :: Utilities'], 'Topic :: Utilities'],
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
test_suite='tests',
) )
...@@ -21,16 +21,18 @@ ...@@ -21,16 +21,18 @@
# #
############################################################################## ##############################################################################
from __future__ import absolute_import
from __future__ import print_function
from lxml import etree from lxml import etree
import six
from six.moves import range
from six.moves import zip
parser = etree.XMLParser(remove_blank_text=True) parser = etree.XMLParser(remove_blank_text=True)
import sys import sys
import getopt import getopt
import os import os
try: from six import StringIO
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
import re import re
import codecs import codecs
from copy import deepcopy from copy import deepcopy
...@@ -49,6 +51,7 @@ def isNodeEquals(old, new): ...@@ -49,6 +51,7 @@ def isNodeEquals(old, new):
return False return False
return True return True
@zope.interface.implementer(IERP5Diff)
class ERP5Diff: class ERP5Diff:
""" """
Make a difference between two XML documents using XUpdate. Make a difference between two XML documents using XUpdate.
...@@ -65,9 +68,6 @@ class ERP5Diff: ...@@ -65,9 +68,6 @@ class ERP5Diff:
used in ERP5 XML documents. used in ERP5 XML documents.
""" """
# Declarative interfaces
zope.interface.implements(IERP5Diff,)
__version__ = '0.8.1' __version__ = '0.8.1'
def __init__(self): def __init__(self):
...@@ -137,7 +137,7 @@ class ERP5Diff: ...@@ -137,7 +137,7 @@ class ERP5Diff:
if namespace_uri == 'http://www.w3.org/XML/1998/namespace': if namespace_uri == 'http://www.w3.org/XML/1998/namespace':
prefix = 'xml' prefix = 'xml'
else: else:
prefix = [t[0] for t in element.nsmap.iteritems() if t[1] == namespace_uri][0] prefix = [t[0] for t in six.iteritems(element.nsmap) if t[1] == namespace_uri][0]
return '%s:%s' % (prefix, local_name,), namespace_uri return '%s:%s' % (prefix, local_name,), namespace_uri
else: else:
return attr_name, None return attr_name, None
...@@ -149,10 +149,7 @@ class ERP5Diff: ...@@ -149,10 +149,7 @@ class ERP5Diff:
root = self._getResultRoot() root = self._getResultRoot()
append_element = etree.Element('{%s}append' % self._ns, nsmap=root.nsmap) append_element = etree.Element('{%s}append' % self._ns, nsmap=root.nsmap)
append_element.attrib['select'] = path append_element.attrib['select'] = path
key_list = attr_dict.keys() for name, val in sorted(six.iteritems(attr_dict)):
key_list.sort()
for name in key_list:
val = attr_dict[name]
attr_element = etree.Element('{%s}attribute' % self._ns, nsmap=nsmap) attr_element = etree.Element('{%s}attribute' % self._ns, nsmap=nsmap)
name, namespace_uri = name name, namespace_uri = name
attr_element.attrib['name'] = name attr_element.attrib['name'] = name
...@@ -380,10 +377,7 @@ class ERP5Diff: ...@@ -380,10 +377,7 @@ class ERP5Diff:
# Find all added or removed or changed attrib. # Find all added or removed or changed attrib.
#sort key list to stick expected output #sort key list to stick expected output
key_list1 = dict1.keys() for name1, val1 in sorted(six.iteritems(dict1)):
key_list1.sort()
for name1 in key_list1:
val1 = dict1[name1]
if name1 in dict2: if name1 in dict2:
if val1 != dict2[name1]: if val1 != dict2[name1]:
# The value is different. # The value is different.
...@@ -394,7 +388,7 @@ class ERP5Diff: ...@@ -394,7 +388,7 @@ class ERP5Diff:
# This attribute is removed. # This attribute is removed.
self._xupdateRemoveAttribute(name1, path, nsmap=element.nsmap) self._xupdateRemoveAttribute(name1, path, nsmap=element.nsmap)
d = {} d = {}
for name2, val2 in dict2.iteritems(): for name2, val2 in six.iteritems(dict2):
if val2 is not None: if val2 is not None:
# This attribute is added. # This attribute is added.
d[name2] = val2 d[name2] = val2
...@@ -547,7 +541,7 @@ class ERP5Diff: ...@@ -547,7 +541,7 @@ class ERP5Diff:
else: else:
misplaced_node_dict = {} misplaced_node_dict = {}
for k, v in misplaced_node_dict.items(): for k, v in list(misplaced_node_dict.items()):
if k in old_new_index_mapping: if k in old_new_index_mapping:
value = misplaced_node_dict[k] value = misplaced_node_dict[k]
misplaced_node_dict[old_new_index_mapping[k]] = value misplaced_node_dict[old_new_index_mapping[k]] = value
...@@ -705,9 +699,9 @@ def main(): ...@@ -705,9 +699,9 @@ def main():
""" """
try: try:
opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output=", "verbose"]) opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output=", "verbose"])
except getopt.GetoptError, msg: except getopt.GetoptError as msg:
print msg print(msg)
print "Try ``erp5diff --help'' for more information." print("Try ``erp5diff --help'' for more information.")
sys.exit(2) sys.exit(2)
output = None output = None
verbose = 0 verbose = 0
...@@ -715,24 +709,24 @@ def main(): ...@@ -715,24 +709,24 @@ def main():
if o == "-v": if o == "-v":
verbose = 1 verbose = 1
elif o in ("-h", "--help"): elif o in ("-h", "--help"):
print '''Usage: erp5diff [OPTION]... OLD_XML NEW_XML print('''Usage: erp5diff [OPTION]... OLD_XML NEW_XML
Make a difference between two XML documents in XUpdate format. Make a difference between two XML documents in XUpdate format.
-h, --help display this message and exit -h, --help display this message and exit
-o, --output=FILE output the result to the file FILE -o, --output=FILE output the result to the file FILE
-v, --verbose print verbose messages -v, --verbose print verbose messages
Report bugs to <yo@nexedi.com>.''' ''')
sys.exit() sys.exit()
elif o in ("-o", "--output"): elif o in ("-o", "--output"):
output = a output = a
if len(args) != 2: if len(args) != 2:
if len(args) > 2: if len(args) > 2:
print "Too many arguments." print("Too many arguments.")
else: else:
print "Too few arguments." print("Too few arguments.")
print "Try ``erp5diff --help'' for more information." print("Try ``erp5diff --help'' for more information.")
sys.exit(2) sys.exit(2)
d = ERP5Diff() d = ERP5Diff()
......
# for backward compatibility with old import path # for backward compatibility with old import path
from ERP5Diff import main from __future__ import absolute_import
from ERP5Diff import ERP5Diff as ERP5Diff from .ERP5Diff import main
from .ERP5Diff import ERP5Diff
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import
import doctest
import unittest import unittest
import pkg_resources import lxml.doctestcompare
from lxml import etree
from ERP5Diff import ERP5Diff from ERP5Diff import ERP5Diff
from lxml import etree
from cStringIO import StringIO
erp5diff = ERP5Diff() erp5diff = ERP5Diff()
class TestERP5Diff(unittest.TestCase): class TestERP5Diff(unittest.TestCase):
...@@ -16,10 +18,15 @@ class TestERP5Diff(unittest.TestCase): ...@@ -16,10 +18,15 @@ class TestERP5Diff(unittest.TestCase):
""" """
erp5diff.compare(old_xml, new_xml) erp5diff.compare(old_xml, new_xml)
result_tree = erp5diff._result result_tree = erp5diff._result
result_string = etree.tostring(result_tree, pretty_print=True) result_string = etree.tostring(result_tree, pretty_print=True, encoding='unicode')
self.assertEquals(result_string, expected_result_string,
'\n%s\n\n%s' % (result_string, expected_result_string)) checker = lxml.doctestcompare.LXMLOutputChecker()
if not checker.check_output(expected_result_string, result_string, 0):
self.fail(
checker.output_difference(
doctest.Example("", expected_result_string),
result_string,
0))
def test_textNodes(self): def test_textNodes(self):
"""update the texts of the three elements """update the texts of the three elements
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment