Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package proteus for openSUSE:Factory checked 
in at 2022-03-07 17:48:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/proteus (Old)
 and      /work/SRC/openSUSE:Factory/.proteus.new.1958 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "proteus"

Mon Mar  7 17:48:08 2022 rev:21 rq:959984 version:6.0.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/proteus/proteus.changes  2022-01-26 
21:27:07.585933679 +0100
+++ /work/SRC/openSUSE:Factory/.proteus.new.1958/proteus.changes        
2022-03-07 17:48:55.967085333 +0100
@@ -1,0 +2,10 @@
+Wed Mar  2 11:34:12 UTC 2022 - Axel Braun <axel.br...@gmx.de>
+
+- Version 6.0.5 - Bugfix Release
+
+-------------------------------------------------------------------
+Sat Feb 12 17:17:24 UTC 2022 - Axel Braun <axel.br...@gmx.de>
+
+- Version bump to Tryton 6.0 series
+
+-------------------------------------------------------------------

Old:
----
  proteus-5.0.11.tar.gz
  proteus-5.0.11.tar.gz.asc

New:
----
  proteus-6.0.5.tar.gz
  proteus-6.0.5.tar.gz.asc

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

Other differences:
------------------
++++++ proteus.spec ++++++
--- /var/tmp/diff_new_pack.z2ARCv/_old  2022-03-07 17:48:56.623085143 +0100
+++ /var/tmp/diff_new_pack.z2ARCv/_new  2022-03-07 17:48:56.627085142 +0100
@@ -1,8 +1,8 @@
 #
 # spec file for package proteus
 #
-# Copyright (c) 2022 SUSE LLC
-# Copyright (c) 2019 Dr. Axel Braun
+# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2014-2021 Dr. Axel Braun
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,9 +17,9 @@
 #
 
 
-%define majorver 5.0
+%define majorver 6.0
 Name:           proteus
-Version:        %{majorver}.11
+Version:        %{majorver}.5
 Release:        0
 Summary:        A library to access Tryton's modules like a client
 License:        GPL-3.0-or-later
@@ -30,7 +30,6 @@
 Source2:        
https://keybase.io/cedrickrier/pgp_keys.asc?fingerprint=7C5A4360F6DF81ABA91FD54D6FF50AFE03489130#/%{name}.keyring
 # List of additional build dependencies
 BuildRequires:  fdupes
-BuildRequires:  python-rpm-macros
 BuildRequires:  python3-devel
 BuildRequires:  python3-lxml
 BuildRequires:  python3-psycopg2
@@ -38,7 +37,7 @@
 BuildRequires:  python3-setuptools
 Requires:       python3-dateutil
 Requires:       trytond
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+
 BuildArch:      noarch
 
 %description
@@ -48,15 +47,15 @@
 %setup -q
 
 %build
-python3 setup.py build
+%python3_build
 
 %install
-python3 setup.py install --prefix=%_prefix --root=%buildroot
+%python3_install --prefix=%_prefix --root=%buildroot
 %fdupes -s %{buildroot}
 
 %files
 %defattr(-,root,root)
-%doc README
+%doc README.rst
 %license LICENSE
 %{python3_sitelib}/*
 

++++++ proteus-5.0.11.tar.gz -> proteus-6.0.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/.drone.yml 
new/proteus-6.0.5/.drone.yml
--- old/proteus-5.0.11/.drone.yml       2021-06-06 09:19:28.000000000 +0200
+++ new/proteus-6.0.5/.drone.yml        2021-09-27 23:36:47.000000000 +0200
@@ -1,21 +1,40 @@
 clone:
     hg:
         image: plugins/hg
+        environment:
+            - HG_SHARE_POOL=/root/.cache/hg
+        volumes:
+            - cache:/root/.cache
 
 pipeline:
     tox:
         image: ${IMAGE}
+        environment:
+            - CFLAGS=-O0
+            - TOX_TESTENV_PASSENV=CFLAGS CI_BUILD_NUMBER CI_JOB_NUMBER 
CI_JOB_ID
         commands:
+            - echo "[extensions]" >> /root/.hgrc
+            - echo "hgext.share =" >> /root/.hgrc
+            - echo "[share]" >> /root/.hgrc
+            - echo "pool = /root/.cache/hg" >> /root/.hgrc
             - pip install tox pydot
             - tox -e "${TOXENV}"
         volumes:
              - cache:/root/.cache
+    check_dist:
+        image: ${IMAGE}
+        commands:
+            - pip install twine
+            - python setup.py sdist
+            - twine check dist/*
 
 matrix:
     include:
-        - IMAGE: python:3.5
-          TOXENV: py35
         - IMAGE: python:3.6
           TOXENV: py36
         - IMAGE: python:3.7
           TOXENV: py37
+        - IMAGE: python:3.8
+          TOXENV: py38
+        - IMAGE: python:3.9
+          TOXENV: py39
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/.flake8 new/proteus-6.0.5/.flake8
--- old/proteus-5.0.11/.flake8  1970-01-01 01:00:00.000000000 +0100
+++ new/proteus-6.0.5/.flake8   2021-09-27 23:36:47.000000000 +0200
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/.hgtags new/proteus-6.0.5/.hgtags
--- old/proteus-5.0.11/.hgtags  2022-01-15 16:19:08.000000000 +0100
+++ new/proteus-6.0.5/.hgtags   2022-03-01 19:23:18.000000000 +0100
@@ -15,14 +15,13 @@
 cd4731fb373698d480a625a286de776a0b9bdc6e 4.6.0
 3867b51d50056fda52882150a017a9dce6811264 4.8.0
 e86f9d540f29dfcd39e8f198b50940c8b91250d6 5.0.0
-0835c94a8c6d24a067ffdda19fc9e09b8ec7489b 5.0.1
-7189865cf26973984b5ec6b2056caa2de0c1d2ab 5.0.2
-7e1fcdd39ecf86ae7e825b86822d4840f91725b8 5.0.3
-21a1c19303aefb60f54fe27ca5189071d856213c 5.0.4
-4ef3c1a7214f00a7e96a606bc2396acfb94aa2a7 5.0.5
-a5aabc18347d6b635ae3a57a7ec2ae4faa24aacf 5.0.6
-12da615377eb694e54bfbd0c12aa36779bb33b27 5.0.7
-df21f1e8edd84079d0619ef84b2f663e5a1c87e4 5.0.8
-a49aa4240d49a817c4d98bdc146a31f23722016d 5.0.9
-de793cd5456707bf07e76af2e04aeeb6c733460a 5.0.10
-d6494835473801df14b3c358a05119607a94443b 5.0.11
+f4a0b0e282f39c013c44e5012e6b85e4b8a4ae40 5.2.0
+03daaf3994610fde107d98d8458b2731e03c5306 5.4.0
+a8061a1d268776766c44ceb97094d229dbe31962 5.6.0
+8bc88e82ff9edc33725d08bc0c6f2862f221a127 5.8.0
+ac15e7f1881fd78d30eac0d7c772638265830c77 6.0.0
+14cd94a3e75463a9e4ab4c562cce82470070731b 6.0.1
+b579da9fa80282eaf0657e6d2826147c2c6c2f3d 6.0.2
+dc3d781b552d24dcfb7b0ced4322b1ba17e6ca09 6.0.3
+8e6d0969604981e6d024b203424b1b3f0bcd4cb3 6.0.4
+c20749d242200840432ab0b87ce7c0072ee1be34 6.0.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/CHANGELOG new/proteus-6.0.5/CHANGELOG
--- old/proteus-5.0.11/CHANGELOG        2022-01-15 16:19:08.000000000 +0100
+++ new/proteus-6.0.5/CHANGELOG 2022-03-01 19:23:17.000000000 +0100
@@ -1,35 +1,42 @@
-Version 5.0.11 - 2022-01-15
+Version 6.0.5 - 2022-03-01
 * Bug fixes (see mercurial logs for details)
+* Use defusedxml to parse XML (11244)
 
-Version 5.0.10 - 2021-10-01
+Version 6.0.4 - 2022-01-15
 * Bug fixes (see mercurial logs for details)
 
-Version 5.0.9 - 2021-07-01
+Version 6.0.3 - 2021-10-01
 * Bug fixes (see mercurial logs for details)
 
-Version 5.0.8 - 2020-11-11
+Version 6.0.2 - 2021-07-01
 * Bug fixes (see mercurial logs for details)
 
-Version 5.0.7 - 2019-12-02
+Version 6.0.1 - 2021-05-15
 * Bug fixes (see mercurial logs for details)
 
-Version 5.0.6 - 2019-11-08
+Version 6.0.0 - 2021-05-03
 * Bug fixes (see mercurial logs for details)
+* Add support for Python 3.9
+* Unify PYSON string format
 
-Version 5.0.5 - 2019-10-23
+Version 5.8.0 - 2020-11-02
 * Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+* Support PYSON comparison of date and datetime
 
-Version 5.0.4 - 2019-09-15
+Version 5.6.0 - 2020-05-04
 * Bug fixes (see mercurial logs for details)
+* Add support for Python 3.8
+* Use same __str__ as trytond instances
 
-Version 5.0.3 - 2019-04-22
+Version 5.4.0 - 2019-11-04
 * Bug fixes (see mercurial logs for details)
+* Support dot notation on PYSON Eval
+* Add __slots__
 
-Version 5.0.2 - 2019-02-19
-* Bug fixes (see mercurial logs for details)
-
-Version 5.0.1 - 2018-12-02
+Version 5.2.0 - 2019-05-06
 * Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.4
 
 Version 5.0.0 - 2018-10-01
 * Bug fixes (see mercurial logs for details)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/INSTALL new/proteus-6.0.5/INSTALL
--- old/proteus-5.0.11/INSTALL  2019-10-23 13:12:22.000000000 +0200
+++ new/proteus-6.0.5/INSTALL   1970-01-01 01:00:00.000000000 +0100
@@ -1,27 +0,0 @@
-Installing proteus
-==================
-
-Prerequisites
--------------
-
- * Python 3.4 or later (http://www.python.org/)
- * python-dateutil (http://labix.org/python-dateutil)
- * Optional: trytond (http://www.tryton.org/)
-
-Installation
-------------
-
-Once you've downloaded and unpacked the proteus source release, enter the
-directory where the archive was unpacked, and run:
-
-    python setup.py install
-
-Note that you may need administrator/root privileges for this step, as
-this command will by default attempt to install module to the Python
-site-packages directory on your system.
-
-For advanced options, please refer to the easy_install and/or the distutils
-documentation:
-
-  http://setuptools.readthedocs.io/en/latest/easy_install.html
-  http://docs.python.org/inst/inst.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/MANIFEST.in 
new/proteus-6.0.5/MANIFEST.in
--- old/proteus-5.0.11/MANIFEST.in      2019-10-23 13:12:22.000000000 +0200
+++ new/proteus-6.0.5/MANIFEST.in       2021-09-27 23:36:47.000000000 +0200
@@ -1,5 +1,5 @@
-include LICENSE
-include COPYRIGHT
-include README
-include INSTALL
 include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include doc/*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/PKG-INFO new/proteus-6.0.5/PKG-INFO
--- old/proteus-5.0.11/PKG-INFO 2022-01-15 16:19:10.074019700 +0100
+++ new/proteus-6.0.5/PKG-INFO  2022-03-01 19:23:19.383111000 +0100
@@ -1,22 +1,22 @@
 Metadata-Version: 2.1
 Name: proteus
-Version: 5.0.11
+Version: 6.0.5
 Summary: Library to access Tryton server as a client
 Home-page: http://www.tryton.org/
 Author: Tryton
-Author-email: issue_trac...@tryton.org
+Author-email: b...@tryton.org
 License: LGPL-3
-Download-URL: http://downloads.tryton.org/5.0/
-Description: proteus
-        =======
+Download-URL: http://downloads.tryton.org/6.0/
+Project-URL: Bug Tracker, https://bugs.tryton.org/
+Project-URL: Documentation, https://docs.tryton.org/
+Project-URL: Forum, https://www.tryton.org/forum
+Project-URL: Source Code, https://hg.tryton.org/proteus
+Description: =======================
+        Tryton Scripting Client
+        =======================
         
         A library to access Tryton's models like a client.
         
-        Installing
-        ----------
-        
-        See INSTALL
-        
         Example of usage
         ----------------
         
@@ -29,7 +29,7 @@
         
             >>> config = config.set_trytond('sqlite:///:memory:')
         
-        Installing a module
+        Activating a module
         ~~~~~~~~~~~~~~~~~~~
         
         Find the module, call the activate button and run the upgrade wizard.
@@ -80,7 +80,7 @@
         Addresses are store on party with a `One2Many` field. So the new 
address just
         needs to be appended to the list `addresses`.
         
-            >>> address = party.addresses.new(zip='42')
+            >>> address = party.addresses.new(postal_code='42')
             >>> party.save()
             >>> party.addresses #doctest: +ELLIPSIS
             [proteus.Model.get('party.address')(...)]
@@ -121,9 +121,9 @@
         Addresses are ordered by sequence which means they can be stored 
following a
         specific order. The `set_sequence` method stores the current order.
         
-            >>> address = party.addresses.new(zip='69')
+            >>> address = party.addresses.new(postal_code='69')
             >>> party.save()
-            >>> address = party.addresses.new(zip='23')
+            >>> address = party.addresses.new(postal_code='23')
             >>> party.save()
         
         Now changing the order.
@@ -137,32 +137,6 @@
             >>> party.addresses == reversed_addresses
             True
         
-        Support
-        -------
-        
-        If you encounter any problems with Tryton, please don't hesitate to ask
-        questions on the Tryton bug tracker, mailing list, wiki or IRC channel:
-        
-          http://bugs.tryton.org/
-          http://groups.tryton.org/
-          http://wiki.tryton.org/
-          irc://irc.freenode.net/tryton
-        
-        License
-        -------
-        
-        See LICENSE
-        
-        Copyright
-        ---------
-        
-        See COPYRIGHT
-        
-        
-        For more information please visit the Tryton web site:
-        
-          http://www.tryton.org/
-        
 Keywords: tryton library cli
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
@@ -173,12 +147,13 @@
 Classifier: Intended Audience :: Legal Industry
 Classifier: License :: OSI Approved :: GNU Library or Lesser General Public 
License (LGPL)
 Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Office/Business
-Requires-Python: >=3.4
+Requires-Python: >=3.6
 Provides-Extra: trytond
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/README new/proteus-6.0.5/README
--- old/proteus-5.0.11/README   2019-10-23 13:12:22.000000000 +0200
+++ new/proteus-6.0.5/README    1970-01-01 01:00:00.000000000 +0100
@@ -1,155 +0,0 @@
-proteus
-=======
-
-A library to access Tryton's models like a client.
-
-Installing
-----------
-
-See INSTALL
-
-Example of usage
-----------------
-
-    >>> from proteus import config, Model, Wizard, Report
-
-Configuration
-~~~~~~~~~~~~~
-
-Configuration to connect to a sqlite memory database using trytond as module.
-
-    >>> config = config.set_trytond('sqlite:///:memory:')
-
-Installing a module
-~~~~~~~~~~~~~~~~~~~
-
-Find the module, call the activate button and run the upgrade wizard.
-
-    >>> Module = Model.get('ir.module')
-    >>> party_module, = Module.find([('name', '=', 'party')])
-    >>> party_module.click('activate')
-    >>> Wizard('ir.module.activate_upgrade').execute('upgrade')
-
-Creating a party
-~~~~~~~~~~~~~~~~
-
-First instanciate a new Party:
-
-    >>> Party = Model.get('party.party')
-    >>> party = Party()
-    >>> party.id < 0
-    True
-
-Fill the fields:
-
-    >>> party.name = 'ham'
-
-Save the instance into the server:
-
-    >>> party.save()
-    >>> party.name
-    'ham'
-    >>> party.id > 0
-    True
-
-Setting the language of the party
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The language on party is a `Many2One` relation field. So it requires to get a
-`Model` instance as value.
-
-    >>> Lang = Model.get('ir.lang')
-    >>> en, = Lang.find([('code', '=', 'en')])
-    >>> party.lang = en
-    >>> party.save()
-    >>> party.lang.code
-    'en'
-
-Creating an address for the party
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Addresses are store on party with a `One2Many` field. So the new address just
-needs to be appended to the list `addresses`.
-
-    >>> address = party.addresses.new(zip='42')
-    >>> party.save()
-    >>> party.addresses #doctest: +ELLIPSIS
-    [proteus.Model.get('party.address')(...)]
-
-Adding category to the party
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Categories are linked to party with a `Many2Many` field.
-
-So first create a category
-
-    >>> Category = Model.get('party.category')
-    >>> category = Category()
-    >>> category.name = 'spam'
-    >>> category.save()
-
-Append it to categories of the party
-
-    >>> party.categories.append(category)
-    >>> party.save()
-    >>> party.categories #doctest: +ELLIPSIS
-    [proteus.Model.get('party.category')(...)]
-
-Print party label
-~~~~~~~~~~~~~~~~~
-
-There is a label report on `Party`.
-
-    >>> label = Report('party.label')
-
-The report is executed with a list of records and some extra data.
-
-    >>> type_, data, print_, name = label.execute([party], {})
-
-Sorting addresses and register order
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Addresses are ordered by sequence which means they can be stored following a
-specific order. The `set_sequence` method stores the current order.
-
-    >>> address = party.addresses.new(zip='69')
-    >>> party.save()
-    >>> address = party.addresses.new(zip='23')
-    >>> party.save()
-
-Now changing the order.
-
-    >>> reversed_addresses = list(reversed(party.addresses))
-    >>> while party.addresses:
-    ...     _ = party.addresses.pop()
-    >>> party.addresses.extend(reversed_addresses)
-    >>> party.addresses.set_sequence()
-    >>> party.save()
-    >>> party.addresses == reversed_addresses
-    True
-
-Support
--------
-
-If you encounter any problems with Tryton, please don't hesitate to ask
-questions on the Tryton bug tracker, mailing list, wiki or IRC channel:
-
-  http://bugs.tryton.org/
-  http://groups.tryton.org/
-  http://wiki.tryton.org/
-  irc://irc.freenode.net/tryton
-
-License
--------
-
-See LICENSE
-
-Copyright
----------
-
-See COPYRIGHT
-
-
-For more information please visit the Tryton web site:
-
-  http://www.tryton.org/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/README.rst 
new/proteus-6.0.5/README.rst
--- old/proteus-5.0.11/README.rst       1970-01-01 01:00:00.000000000 +0100
+++ new/proteus-6.0.5/README.rst        2021-09-27 23:36:47.000000000 +0200
@@ -0,0 +1,125 @@
+=======================
+Tryton Scripting Client
+=======================
+
+A library to access Tryton's models like a client.
+
+Example of usage
+----------------
+
+    >>> from proteus import config, Model, Wizard, Report
+
+Configuration
+~~~~~~~~~~~~~
+
+Configuration to connect to a sqlite memory database using trytond as module.
+
+    >>> config = config.set_trytond('sqlite:///:memory:')
+
+Activating a module
+~~~~~~~~~~~~~~~~~~~
+
+Find the module, call the activate button and run the upgrade wizard.
+
+    >>> Module = Model.get('ir.module')
+    >>> party_module, = Module.find([('name', '=', 'party')])
+    >>> party_module.click('activate')
+    >>> Wizard('ir.module.activate_upgrade').execute('upgrade')
+
+Creating a party
+~~~~~~~~~~~~~~~~
+
+First instanciate a new Party:
+
+    >>> Party = Model.get('party.party')
+    >>> party = Party()
+    >>> party.id < 0
+    True
+
+Fill the fields:
+
+    >>> party.name = 'ham'
+
+Save the instance into the server:
+
+    >>> party.save()
+    >>> party.name
+    'ham'
+    >>> party.id > 0
+    True
+
+Setting the language of the party
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The language on party is a `Many2One` relation field. So it requires to get a
+`Model` instance as value.
+
+    >>> Lang = Model.get('ir.lang')
+    >>> en, = Lang.find([('code', '=', 'en')])
+    >>> party.lang = en
+    >>> party.save()
+    >>> party.lang.code
+    'en'
+
+Creating an address for the party
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Addresses are store on party with a `One2Many` field. So the new address just
+needs to be appended to the list `addresses`.
+
+    >>> address = party.addresses.new(postal_code='42')
+    >>> party.save()
+    >>> party.addresses #doctest: +ELLIPSIS
+    [proteus.Model.get('party.address')(...)]
+
+Adding category to the party
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Categories are linked to party with a `Many2Many` field.
+
+So first create a category
+
+    >>> Category = Model.get('party.category')
+    >>> category = Category()
+    >>> category.name = 'spam'
+    >>> category.save()
+
+Append it to categories of the party
+
+    >>> party.categories.append(category)
+    >>> party.save()
+    >>> party.categories #doctest: +ELLIPSIS
+    [proteus.Model.get('party.category')(...)]
+
+Print party label
+~~~~~~~~~~~~~~~~~
+
+There is a label report on `Party`.
+
+    >>> label = Report('party.label')
+
+The report is executed with a list of records and some extra data.
+
+    >>> type_, data, print_, name = label.execute([party], {})
+
+Sorting addresses and register order
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Addresses are ordered by sequence which means they can be stored following a
+specific order. The `set_sequence` method stores the current order.
+
+    >>> address = party.addresses.new(postal_code='69')
+    >>> party.save()
+    >>> address = party.addresses.new(postal_code='23')
+    >>> party.save()
+
+Now changing the order.
+
+    >>> reversed_addresses = list(reversed(party.addresses))
+    >>> while party.addresses:
+    ...     _ = party.addresses.pop()
+    >>> party.addresses.extend(reversed_addresses)
+    >>> party.addresses.set_sequence()
+    >>> party.save()
+    >>> party.addresses == reversed_addresses
+    True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/doc/index.rst 
new/proteus-6.0.5/doc/index.rst
--- old/proteus-5.0.11/doc/index.rst    2019-10-23 13:12:22.000000000 +0200
+++ new/proteus-6.0.5/doc/index.rst     2021-09-27 23:36:47.000000000 +0200
@@ -1 +1,125 @@
-.. include:: ../README
+=======================
+Tryton Scripting Client
+=======================
+
+A library to access Tryton's models like a client.
+
+Example of usage
+----------------
+
+    >>> from proteus import config, Model, Wizard, Report
+
+Configuration
+~~~~~~~~~~~~~
+
+Configuration to connect to a sqlite memory database using trytond as module.
+
+    >>> config = config.set_trytond('sqlite:///:memory:')
+
+Activating a module
+~~~~~~~~~~~~~~~~~~~
+
+Find the module, call the activate button and run the upgrade wizard.
+
+    >>> Module = Model.get('ir.module')
+    >>> party_module, = Module.find([('name', '=', 'party')])
+    >>> party_module.click('activate')
+    >>> Wizard('ir.module.activate_upgrade').execute('upgrade')
+
+Creating a party
+~~~~~~~~~~~~~~~~
+
+First instanciate a new Party:
+
+    >>> Party = Model.get('party.party')
+    >>> party = Party()
+    >>> party.id < 0
+    True
+
+Fill the fields:
+
+    >>> party.name = 'ham'
+
+Save the instance into the server:
+
+    >>> party.save()
+    >>> party.name
+    'ham'
+    >>> party.id > 0
+    True
+
+Setting the language of the party
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The language on party is a `Many2One` relation field. So it requires to get a
+`Model` instance as value.
+
+    >>> Lang = Model.get('ir.lang')
+    >>> en, = Lang.find([('code', '=', 'en')])
+    >>> party.lang = en
+    >>> party.save()
+    >>> party.lang.code
+    'en'
+
+Creating an address for the party
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Addresses are store on party with a `One2Many` field. So the new address just
+needs to be appended to the list `addresses`.
+
+    >>> address = party.addresses.new(postal_code='42')
+    >>> party.save()
+    >>> party.addresses #doctest: +ELLIPSIS
+    [proteus.Model.get('party.address')(...)]
+
+Adding category to the party
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Categories are linked to party with a `Many2Many` field.
+
+So first create a category
+
+    >>> Category = Model.get('party.category')
+    >>> category = Category()
+    >>> category.name = 'spam'
+    >>> category.save()
+
+Append it to categories of the party
+
+    >>> party.categories.append(category)
+    >>> party.save()
+    >>> party.categories #doctest: +ELLIPSIS
+    [proteus.Model.get('party.category')(...)]
+
+Print party label
+~~~~~~~~~~~~~~~~~
+
+There is a label report on `Party`.
+
+    >>> label = Report('party.label')
+
+The report is executed with a list of records and some extra data.
+
+    >>> type_, data, print_, name = label.execute([party], {})
+
+Sorting addresses and register order
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Addresses are ordered by sequence which means they can be stored following a
+specific order. The `set_sequence` method stores the current order.
+
+    >>> address = party.addresses.new(postal_code='69')
+    >>> party.save()
+    >>> address = party.addresses.new(postal_code='23')
+    >>> party.save()
+
+Now changing the order.
+
+    >>> reversed_addresses = list(reversed(party.addresses))
+    >>> while party.addresses:
+    ...     _ = party.addresses.pop()
+    >>> party.addresses.extend(reversed_addresses)
+    >>> party.addresses.set_sequence()
+    >>> party.save()
+    >>> party.addresses == reversed_addresses
+    True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/proteus/__init__.py 
new/proteus-6.0.5/proteus/__init__.py
--- old/proteus-5.0.11/proteus/__init__.py      2022-01-06 01:03:41.000000000 
+0100
+++ new/proteus-6.0.5/proteus/__init__.py       2022-01-15 16:17:52.000000000 
+0100
@@ -10,7 +10,7 @@
 
 import proteus.config
 
-__version__ = "5.0.11"
+__version__ = "6.0.5"
 __all__ = ['Model', 'Wizard', 'Report']
 
 _MODELS = threading.local()
@@ -18,6 +18,8 @@
 
 class _EvalEnvironment(dict):
     'Dictionary for evaluation'
+    __slots__ = ('parent', 'eval_type')
+
     def __init__(self, parent, eval_type='eval'):
         super(_EvalEnvironment, self).__init__()
         self.parent = parent
@@ -55,7 +57,8 @@
     def __str__(self):
         return str(self.parent)
 
-    __repr__ = __str__
+    def __repr__(self):
+        return repr(self.parent)
 
     def __contains__(self, item):
         if item == 'id':
@@ -86,6 +89,8 @@
     >>> Example().method()
     1
     """
+    __slots__ = ('func')
+
     def __init__(self, func):
         self.func = func
 
@@ -175,6 +180,22 @@
         super(NumericDescriptor, self).__set__(instance, value)
 
 
+class SelectionDescriptor(FieldDescriptor):
+
+    def __set__(self, instance, value):
+        assert isinstance(value, str) or value is None
+        # TODO add selection validation
+        super().__set__(instance, value)
+
+
+class MultiSelectionDescriptor(FieldDescriptor):
+
+    def __set__(self, instance, value):
+        assert isinstance(value, (list, type(None)))
+        # TODO add selection validation
+        super().__set__(instance, value)
+
+
 class ReferenceDescriptor(FieldDescriptor):
     def __get__(self, instance, owner):
         value = super(ReferenceDescriptor, self).__get__(instance, owner)
@@ -407,7 +428,8 @@
         'char': CharDescriptor,
         'text': CharDescriptor,
         'binary': BinaryDescriptor,
-        'selection': CharDescriptor,  # TODO implement its own descriptor
+        'selection': SelectionDescriptor,
+        'multiselection': MultiSelectionDescriptor,
         'integer': IntegerDescriptor,
         'biginteger': IntegerDescriptor,
         'float': FloatDescriptor,
@@ -451,6 +473,8 @@
 
         class MetaModel(type):
             'Meta class for Model'
+            __slots__ = ()
+
             def __new__(mcs, name, bases, dict):
                 if self.model_name in getattr(_MODELS, models_key):
                     return getattr(_MODELS, models_key)[self.model_name]
@@ -485,6 +509,9 @@
 
 class ModelList(list):
     'List for Model'
+    __slots__ = ('model_name', 'parent', 'parent_field_name', 'parent_name',
+        'domain', 'context', 'add_remove', 'search_order', 'search_context',
+        'record_removed', 'record_deleted')
 
     def __init__(self, definition, sequence=None, parent=None,
             parent_field_name=''):
@@ -567,11 +594,12 @@
         raise NotImplementedError
     insert.__doc__ = list.insert.__doc__
 
-    def pop(self, index=-1):
+    def pop(self, index=-1, _changed=True):
         self.record_removed.add(self[index])
         self[index]._group = None
         res = super(ModelList, self).pop(index)
-        self._changed()
+        if _changed:
+            self._changed()
         return res
     pop.__doc__ = list.pop.__doc__
 
@@ -654,6 +682,7 @@
 
 class Model(object):
     'Model class for Tryton records'
+    __slots__ = ('__id', '_values', '_changed', '_group', '__context')
 
     __counter = -1
     _proxy = None
@@ -729,7 +758,7 @@
             name = name.encode('utf-8')
 
         class Spam(Model, metaclass=MetaModelFactory(name, config=config)()):
-            pass
+            __slots__ = ()
         return Spam
 
     @classmethod
@@ -745,8 +774,7 @@
                 del models[name]
 
     def __str__(self):
-        return '<%s(%d)>' % (self.__class__.__name__, self.id)
-    __str__.__doc__ = object.__str__.__doc__
+        return '%s,%d' % (self.__class__.__name__, self.id)
 
     def __repr__(self):
         if self._config == proteus.config.get_config():
@@ -754,12 +782,11 @@
                     self.id)
         return "proteus.Model.get('%s', %s)(%d)" % (self.__class__.__name__,
                 repr(self._config), self.id)
-    __repr__.__doc__ = object.__repr__.__doc__
 
     def __eq__(self, other):
         if isinstance(other, Model):
-            return ((self.__class__.__name__, self.id) ==
-                (other.__class__.__name__, other.id))
+            return ((self.__class__.__name__, self.id)
+                == (other.__class__.__name__, other.id))
         return NotImplemented
 
     def __ne__(self, other):
@@ -1026,36 +1053,44 @@
                 scope = scope[i]
             else:
                 res[arg] = scope
-        res['id'] = self.id
         return res
 
     def _on_change_set(self, field, value):
         if (self._fields[field]['type'] in ('one2many', 'many2many')
                 and not isinstance(value, (list, tuple))):
-            to_remove = []
+            if value and value.get('delete'):
+                for record_id in value['delete']:
+                    for record in getattr(self, field):
+                        if record.id == record_id:
+                            getattr(self, field).remove(record, _changed=False)
             if value and value.get('remove'):
                 for record_id in value['remove']:
-                    for record in getattr(self, field):
+                    for i, record in enumerate(getattr(self, field)):
                         if record.id == record_id:
-                            to_remove.append(record)
-            for record in to_remove:
-                # remove without signal
-                getattr(self, field).remove(record, _changed=False)
+                            getattr(self, field).pop(i, _changed=False)
             if value and (value.get('add') or value.get('update')):
                 for index, vals in value.get('add', []):
                     group = getattr(self, field)
                     Relation = Model.get(
                         self._fields[field]['relation'], self._config)
                     config = Relation._config
+                    id_ = vals.pop('id', None)
                     with config.reset_context(), \
                             config.set_context(self._context):
-                        record = Relation(_group=group, _default=False)
-                    record._set_on_change(vals)
-                    # append without signal
-                    if index == -1:
-                        list.append(group, record)
+                        record = Relation(id=id_, _group=group, _default=False)
+                    try:
+                        idx = group.index(record)
+                    except ValueError:
+                        # append without signal
+                        if index == -1:
+                            list.append(group, record)
+                        else:
+                            list.insert(group, index, record)
                     else:
-                        list.insert(group, index, record)
+                        record = group[idx]
+                        group.record_removed.discard(record)
+                        group.record_deleted.discard(record)
+                    record._set_on_change(vals)
                 for vals in value.get('update', []):
                     if 'id' not in vals:
                         continue
@@ -1146,6 +1181,9 @@
 
 class Wizard(object):
     'Wizard class for Tryton wizards'
+    __slots__ = ('name', 'form', 'form_state', 'actions', '_config',
+        '_context', '_proxy', 'session_id', 'start_state', 'end_state',
+        'states', 'state', 'models', 'action')
 
     def __init__(self, name, models=None, action=None, config=None,
             context=None):
@@ -1224,6 +1262,7 @@
 
 class Report(object):
     'Report class for Tryton reports'
+    __slots__ = ('name', '_config', '_context', '_proxy')
 
     def __init__(self, name, config=None, context=None):
         super(Report, self).__init__()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/proteus/config.py 
new/proteus-6.0.5/proteus/config.py
--- old/proteus-5.0.11/proteus/config.py        2021-09-27 23:49:25.000000000 
+0200
+++ new/proteus-6.0.5/proteus/config.py 2022-03-01 19:23:15.000000000 +0100
@@ -11,8 +11,12 @@
 import xmlrpc.client
 from decimal import Decimal
 
+import defusedxml.xmlrpc
+
 __all__ = ['set_trytond', 'set_xmlrpc', 'get_config']
 
+defusedxml.xmlrpc.monkey_patch()
+
 
 def dump_decimal(self, value, write):
     value = {'__class__': 'Decimal',
@@ -21,13 +25,6 @@
     self.dump_struct(value, write)
 
 
-def dump_bytes(self, value, write):
-    self.write = write
-    value = xmlrpc.client.Binary(value)
-    value.encode(self)
-    del self.write
-
-
 def dump_date(self, value, write):
     value = {'__class__': 'date',
         'year': value.year,
@@ -67,8 +64,6 @@
 xmlrpc.client.Marshaller.dispatch[datetime.date] = dump_date
 xmlrpc.client.Marshaller.dispatch[datetime.time] = dump_time
 xmlrpc.client.Marshaller.dispatch[datetime.timedelta] = dump_timedelta
-if bytes != str:
-    xmlrpc.client.Marshaller.dispatch[bytes] = dump_bytes
 xmlrpc.client.Marshaller.dispatch[int] = dump_long
 
 
@@ -100,6 +95,7 @@
             return self.decoders[dct['__class__']](dct)
         return dct
 
+
 XMLRPCDecoder.register('date',
     lambda dct: datetime.date(dct['year'], dct['month'], dct['day']))
 XMLRPCDecoder.register('time',
@@ -121,6 +117,7 @@
     self._stack[mark:] = [dct]
     self._value = 0
 
+
 xmlrpc.client.Unmarshaller.dispatch['struct'] = end_struct
 
 _CONFIG = threading.local()
@@ -239,6 +236,11 @@
         super(TrytondConfig, self).__init__()
         if not database:
             database = os.environ.get('TRYTOND_DATABASE_URI')
+        elif (os.environ.get('TRYTOND_DATABASE_URI')
+                and not urllib.parse.urlparse(database).scheme):
+            url = urllib.parse.urlparse(os.environ['TRYTOND_DATABASE_URI'])
+            os.environ['TRYTOND_DATABASE_URI'] = urllib.parse.urlunparse(
+                url._replace(path=database))
         else:
             os.environ['TRYTOND_DATABASE_URI'] = database
         if not config_file:
@@ -332,7 +334,7 @@
         super(XmlrpcConfig, self).__init__()
         self.url = url
         self.server = xmlrpc.client.ServerProxy(
-            url, allow_none=1, use_datetime=1, **kwargs)
+            url, allow_none=True, use_builtin_types=True, **kwargs)
         # TODO add user
         self.user = None
         self._context = self.server.model.res.user.get_preferences(True, {})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/proteus/pyson.py 
new/proteus-6.0.5/proteus/pyson.py
--- old/proteus-5.0.11/proteus/pyson.py 2020-10-30 19:56:47.000000000 +0100
+++ new/proteus-6.0.5/proteus/pyson.py  2021-09-27 23:36:47.000000000 +0200
@@ -153,6 +153,12 @@
 
     @staticmethod
     def eval(dct, context):
+        if '.' in dct['v']:
+            base, name = dct['v'].split('.', 1)
+            return Eval.eval({
+                    'v': name,
+                    'd': dct['d'],
+                    }, context.get(base) or {})
         return context.get(dct['v'], dct['d'])
 
 
@@ -296,11 +302,15 @@
         super(Greater, self).__init__()
         for i in (statement1, statement2):
             if isinstance(i, PYSON):
-                assert i.types().issubset({int, float, type(None)}), \
-                    'statement must be an integer or a float'
+                assert i.types().issubset({
+                        int, float, type(None),
+                        datetime.datetime, datetime.date}), \
+                    'statement must be an integer, float, date or datetime'
             else:
-                assert isinstance(i, (int, float, type(None))), \
-                    'statement must be an integer or a float'
+                assert isinstance(i, (
+                        int, float, type(None),
+                        datetime.datetime, datetime.date)), \
+                    'statement must be an integer, float, date or datetime'
         if isinstance(equal, PYSON):
             if equal.types() != {bool}:
                 equal = Bool(equal)
@@ -332,11 +342,19 @@
                 dct[i] = 0.0
             if not isinstance(dct[i], (int, float)):
                 dct = dct.copy()
-                dct[i] = float(dct[i])
+                stmt = dct[i]
+                if isinstance(stmt, datetime.datetime):
+                    stmt = stmt.timestamp()
+                elif isinstance(stmt, datetime.date):
+                    time = datetime.time(0, 0)
+                    stmt = datetime.datetime.combine(stmt, time).timestamp()
+                dct[i] = float(stmt)
         return dct
 
     @staticmethod
     def eval(dct, context):
+        if dct['s1'] is None or dct['s2'] is None:
+            return False
         dct = Greater._convert(dct)
         if dct['e']:
             return dct['s1'] >= dct['s2']
@@ -353,6 +371,8 @@
 
     @staticmethod
     def eval(dct, context):
+        if dct['s1'] is None or dct['s2'] is None:
+            return False
         dct = Less._convert(dct)
         if dct['e']:
             return dct['s1'] <= dct['s2']
@@ -495,7 +515,7 @@
 class Date(PYSON):
 
     def __init__(self, year=None, month=None, day=None,
-            delta_years=0, delta_months=0, delta_days=0, **kwargs):
+            delta_years=0, delta_months=0, delta_days=0, start=None, **kwargs):
         year = kwargs.get('y', year)
         month = kwargs.get('M', month)
         day = kwargs.get('d', day)
@@ -516,11 +536,13 @@
         self._delta_years = delta_years
         self._delta_months = delta_months
         self._delta_days = delta_days
+        self._start = start
 
     @property
     def __repr_params__(self):
         return (self._year, self._month, self._day,
-            self._delta_years, self._delta_months, self._delta_days)
+            self._delta_years, self._delta_months, self._delta_days,
+            self._start)
 
     def pyson(self):
         return {
@@ -531,6 +553,7 @@
             'dy': self._delta_years,
             'dM': self._delta_months,
             'dd': self._delta_days,
+            'start': self._start,
             }
 
     def types(self):
@@ -538,7 +561,12 @@
 
     @staticmethod
     def eval(dct, context):
-        return datetime.date.today() + relativedelta(
+        today = dct.get('start')
+        if isinstance(today, datetime.datetime):
+            today = today.date()
+        if not isinstance(today, datetime.date):
+            today = datetime.date.today()
+        return today + relativedelta(
             year=dct['y'],
             month=dct['M'],
             day=dct['d'],
@@ -554,7 +582,7 @@
             hour=None, minute=None, second=None, microsecond=None,
             delta_years=0, delta_months=0, delta_days=0,
             delta_hours=0, delta_minutes=0, delta_seconds=0,
-            delta_microseconds=0, **kwargs):
+            delta_microseconds=0, start=None, **kwargs):
         hour = kwargs.get('h', hour)
         minute = kwargs.get('m', minute)
         second = kwargs.get('s', second)
@@ -565,7 +593,7 @@
         delta_microseconds = kwargs.get('dms', delta_microseconds)
         super(DateTime, self).__init__(year=year, month=month, day=day,
                 delta_years=delta_years, delta_months=delta_months,
-                delta_days=delta_days, **kwargs)
+                delta_days=delta_days, start=start, **kwargs)
         for i in (hour, minute, second, microsecond,
                 delta_hours, delta_minutes, delta_seconds, delta_microseconds):
             if isinstance(i, PYSON):
@@ -588,9 +616,10 @@
         date_params = super(DateTime, self).__repr_params__
         return (date_params[:3]
             + (self._hour, self._minute, self._second, self._microsecond)
-            + date_params[3:]
+            + date_params[3:-1]
             + (self._delta_hours, self._delta_minutes, self._delta_seconds,
-                self._delta_microseconds))
+                self._delta_microseconds)
+            + date_params[-1:])
 
     def pyson(self):
         res = super(DateTime, self).pyson()
@@ -610,7 +639,13 @@
 
     @staticmethod
     def eval(dct, context):
-        return datetime.datetime.utcnow() + relativedelta(
+        now = dct.get('start')
+        if (isinstance(now, datetime.date)
+                and not isinstance(now, datetime.datetime)):
+            now = datetime.datetime.combine(now, datetime.time())
+        if not isinstance(now, datetime.datetime):
+            now = datetime.datetime.utcnow()
+        return now + relativedelta(
             year=dct['y'],
             month=dct['M'],
             day=dct['d'],
@@ -712,4 +747,6 @@
     'DateTime': DateTime,
     'TimeDelta': TimeDelta,
     'Len': Len,
+    'true': True,
+    'false': False,
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/proteus/tests/__init__.py 
new/proteus-6.0.5/proteus/tests/__init__.py
--- old/proteus-5.0.11/proteus/tests/__init__.py        2018-10-01 
15:51:19.000000000 +0200
+++ new/proteus-6.0.5/proteus/tests/__init__.py 2021-09-27 23:36:47.000000000 
+0200
@@ -10,10 +10,11 @@
 
 os.environ.setdefault('TRYTOND_DATABASE_URI', 'sqlite:///:memory:')
 os.environ.setdefault('DB_NAME', ':memory:')
-from trytond.tests.test_tryton import doctest_setup, doctest_teardown
+from trytond.tests.test_tryton import (  # noqa: E402
+    doctest_setup, doctest_teardown)
 
 here = os.path.dirname(__file__)
-readme = os.path.normpath(os.path.join(here, '..', '..', 'README'))
+readme = os.path.normpath(os.path.join(here, '..', '..', 'README.rst'))
 
 
 def test_suite():
@@ -46,6 +47,7 @@
     runner = unittest.TextTestRunner()
     return runner.run(suite)
 
+
 if __name__ == '__main__':
     sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(
         os.path.abspath(__file__)))))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/proteus/tests/test_model.py 
new/proteus-6.0.5/proteus/tests/test_model.py
--- old/proteus-5.0.11/proteus/tests/test_model.py      2019-11-15 
22:44:58.000000000 +0100
+++ new/proteus-6.0.5/proteus/tests/test_model.py       2021-09-27 
23:36:47.000000000 +0200
@@ -108,6 +108,14 @@
         self.assertEqual(len(User(groups=[x.id for x in groups]).groups),
                 len(groups))
 
+    def test_assign_unknown_field(self):
+        "Test it is not allowed to assign unknown field"
+        User = Model.get('res.user')
+        user = User()
+
+        with self.assertRaises(AttributeError):
+            user.unknown_field = 'foo'
+
     def test_save(self):
         User = Model.get('res.user')
         test = User()
@@ -291,7 +299,6 @@
         Group = Model.get('res.group')
         test = Group()
         test.name = 'Test delete'
-        test.login = 'test delete'
         test.save()
         test.delete()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/proteus.egg-info/PKG-INFO 
new/proteus-6.0.5/proteus.egg-info/PKG-INFO
--- old/proteus-5.0.11/proteus.egg-info/PKG-INFO        2022-01-15 
16:19:09.000000000 +0100
+++ new/proteus-6.0.5/proteus.egg-info/PKG-INFO 2022-03-01 19:23:18.000000000 
+0100
@@ -1,22 +1,22 @@
 Metadata-Version: 2.1
 Name: proteus
-Version: 5.0.11
+Version: 6.0.5
 Summary: Library to access Tryton server as a client
 Home-page: http://www.tryton.org/
 Author: Tryton
-Author-email: issue_trac...@tryton.org
+Author-email: b...@tryton.org
 License: LGPL-3
-Download-URL: http://downloads.tryton.org/5.0/
-Description: proteus
-        =======
+Download-URL: http://downloads.tryton.org/6.0/
+Project-URL: Bug Tracker, https://bugs.tryton.org/
+Project-URL: Documentation, https://docs.tryton.org/
+Project-URL: Forum, https://www.tryton.org/forum
+Project-URL: Source Code, https://hg.tryton.org/proteus
+Description: =======================
+        Tryton Scripting Client
+        =======================
         
         A library to access Tryton's models like a client.
         
-        Installing
-        ----------
-        
-        See INSTALL
-        
         Example of usage
         ----------------
         
@@ -29,7 +29,7 @@
         
             >>> config = config.set_trytond('sqlite:///:memory:')
         
-        Installing a module
+        Activating a module
         ~~~~~~~~~~~~~~~~~~~
         
         Find the module, call the activate button and run the upgrade wizard.
@@ -80,7 +80,7 @@
         Addresses are store on party with a `One2Many` field. So the new 
address just
         needs to be appended to the list `addresses`.
         
-            >>> address = party.addresses.new(zip='42')
+            >>> address = party.addresses.new(postal_code='42')
             >>> party.save()
             >>> party.addresses #doctest: +ELLIPSIS
             [proteus.Model.get('party.address')(...)]
@@ -121,9 +121,9 @@
         Addresses are ordered by sequence which means they can be stored 
following a
         specific order. The `set_sequence` method stores the current order.
         
-            >>> address = party.addresses.new(zip='69')
+            >>> address = party.addresses.new(postal_code='69')
             >>> party.save()
-            >>> address = party.addresses.new(zip='23')
+            >>> address = party.addresses.new(postal_code='23')
             >>> party.save()
         
         Now changing the order.
@@ -137,32 +137,6 @@
             >>> party.addresses == reversed_addresses
             True
         
-        Support
-        -------
-        
-        If you encounter any problems with Tryton, please don't hesitate to ask
-        questions on the Tryton bug tracker, mailing list, wiki or IRC channel:
-        
-          http://bugs.tryton.org/
-          http://groups.tryton.org/
-          http://wiki.tryton.org/
-          irc://irc.freenode.net/tryton
-        
-        License
-        -------
-        
-        See LICENSE
-        
-        Copyright
-        ---------
-        
-        See COPYRIGHT
-        
-        
-        For more information please visit the Tryton web site:
-        
-          http://www.tryton.org/
-        
 Keywords: tryton library cli
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
@@ -173,12 +147,13 @@
 Classifier: Intended Audience :: Legal Industry
 Classifier: License :: OSI Approved :: GNU Library or Lesser General Public 
License (LGPL)
 Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Office/Business
-Requires-Python: >=3.4
+Requires-Python: >=3.6
 Provides-Extra: trytond
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/proteus.egg-info/SOURCES.txt 
new/proteus-6.0.5/proteus.egg-info/SOURCES.txt
--- old/proteus-5.0.11/proteus.egg-info/SOURCES.txt     2022-01-15 
16:19:09.000000000 +0100
+++ new/proteus-6.0.5/proteus.egg-info/SOURCES.txt      2022-03-01 
19:23:19.000000000 +0100
@@ -1,11 +1,11 @@
 .drone.yml
+.flake8
 .hgtags
 CHANGELOG
 COPYRIGHT
-INSTALL
 LICENSE
 MANIFEST.in
-README
+README.rst
 setup.py
 tox.ini
 doc/index.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/proteus.egg-info/requires.txt 
new/proteus-6.0.5/proteus.egg-info/requires.txt
--- old/proteus-5.0.11/proteus.egg-info/requires.txt    2022-01-15 
16:19:09.000000000 +0100
+++ new/proteus-6.0.5/proteus.egg-info/requires.txt     2022-03-01 
19:23:18.000000000 +0100
@@ -1,4 +1,5 @@
+defusedxml
 python-dateutil
 
 [trytond]
-trytond<5.1,>=5.0
+trytond<6.1,>=6.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/setup.py new/proteus-6.0.5/setup.py
--- old/proteus-5.0.11/setup.py 2019-10-23 13:12:22.000000000 +0200
+++ new/proteus-6.0.5/setup.py  2022-03-01 19:23:15.000000000 +0100
@@ -40,19 +40,39 @@
     version = '%s.%s.dev0' % (major_version, minor_version)
     download_url = 'hg+http://hg.tryton.org/%s#egg=%s-%s' % (
         name, name, version)
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+    local_version.append(os.environ['CI_JOB_ID'])
+else:
+    for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+        if os.environ.get(build):
+            local_version.append(os.environ[build])
+        else:
+            local_version = []
+            break
+if local_version:
+    version += '+' + '.'.join(local_version)
 
 dependency_links = []
 if minor_version % 2:
-    dependency_links.append('https://trydevpi.tryton.org/')
+    dependency_links.append(
+        'https://trydevpi.tryton.org/?local_version='
+        + '.'.join(local_version))
 
 setup(name=name,
     version=version,
     description='Library to access Tryton server as a client',
-    long_description=read('README'),
+    long_description=read('README.rst'),
     author='Tryton',
-    author_email='issue_trac...@tryton.org',
+    author_email='b...@tryton.org',
     url='http://www.tryton.org/',
     download_url=download_url,
+    project_urls={
+        "Bug Tracker": 'https://bugs.tryton.org/',
+        "Documentation": 'https://docs.tryton.org/',
+        "Forum": 'https://www.tryton.org/forum',
+        "Source Code": 'https://hg.tryton.org/proteus',
+        },
     keywords='tryton library cli',
     packages=find_packages(),
     classifiers=[
@@ -65,18 +85,20 @@
         'License :: OSI Approved :: '
         'GNU Library or Lesser General Public License (LGPL)',
         'Operating System :: OS Independent',
-        'Programming Language :: Python :: 3.4',
-        'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
+        'Programming Language :: Python :: 3.9',
         'Programming Language :: Python :: Implementation :: CPython',
         'Programming Language :: Python :: Implementation :: PyPy',
         'Topic :: Office/Business',
         ],
     platforms='any',
     license='LGPL-3',
-    python_requires='>=3.4',
+    python_requires='>=3.6',
     install_requires=[
+        'defusedxml',
         "python-dateutil",
         ],
     extras_require={
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/proteus-5.0.11/tox.ini new/proteus-6.0.5/tox.ini
--- old/proteus-5.0.11/tox.ini  2019-10-23 13:12:22.000000000 +0200
+++ new/proteus-6.0.5/tox.ini   2021-09-27 23:36:47.000000000 +0200
@@ -1,5 +1,5 @@
 [tox]
-envlist = py34,py35,py36,py37,pypy3
+envlist = py36,py37,py38,py39,pypy3
 
 [testenv]
 commands = {envpython} setup.py test
@@ -7,4 +7,4 @@
 setenv =
     TRYTOND_DATABASE_URI={env:TRYTOND_DATBASE_URI:sqlite://}
     DB_NAME={env:DB_NAME::memory:}
-install_command = pip install --pre --find-links https://trydevpi.tryton.org/ 
{opts} {packages}
+install_command = pip install --pre --find-links 
https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER}.{env:CI_JOB_NUMBER}}
 {opts} {packages}

Reply via email to