Hello community,

here is the log from the commit of package python-atom for openSUSE:Factory 
checked in at 2020-08-29 20:38:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-atom (Old)
 and      /work/SRC/openSUSE:Factory/.python-atom.new.3399 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-atom"

Sat Aug 29 20:38:29 2020 rev:4 rq:829857 version:0.5.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-atom/python-atom.changes  2020-05-07 
14:55:54.578446479 +0200
+++ /work/SRC/openSUSE:Factory/.python-atom.new.3399/python-atom.changes        
2020-08-29 20:38:39.973372377 +0200
@@ -1,0 +2,8 @@
+Thu Aug 27 05:05:29 UTC 2020 - Steve Kowalik <[email protected]>
+
+- Update to 0.5.2:
+  * make comparison used in C safe (fix bug introduced in 0.5.0) PR #107
+  * fix bug in using atomlist from C PR #102
+  * clarify Unicode deprecation warning PR #102 
+
+-------------------------------------------------------------------

Old:
----
  0.5.0.tar.gz

New:
----
  0.5.2.tar.gz

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

Other differences:
------------------
++++++ python-atom.spec ++++++
--- /var/tmp/diff_new_pack.5bSZD7/_old  2020-08-29 20:38:42.349373378 +0200
+++ /var/tmp/diff_new_pack.5bSZD7/_new  2020-08-29 20:38:42.353373381 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-atom
-Version:        0.5.0
+Version:        0.5.2
 Release:        0
 Summary:        Memory efficient Python objects
 License:        BSD-3-Clause

++++++ 0.5.0.tar.gz -> 0.5.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/.github/workflows/ci.yml 
new/atom-0.5.2/.github/workflows/ci.yml
--- old/atom-0.5.0/.github/workflows/ci.yml     2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/.github/workflows/ci.yml     2020-07-05 21:38:25.000000000 
+0200
@@ -25,7 +25,7 @@
     steps:
       - uses: actions/checkout@v2
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v1
+        uses: actions/setup-python@v2
         with:
           python-version: ${{ matrix.python-version }}
       - name: Install dependencies
@@ -38,9 +38,15 @@
         run: |
           python setup.py develop
       - name: Test with pytest
+        if: matrix.python-version == '3.6'
         run: |
           pip install pytest-cov
-          pytest tests --cov atom --cov-report xml
+          python -m pytest tests --cov atom --cov-report xml
+      - name: Test with pytest
+        if: matrix.python-version != '3.6'
+        run: |
+          pip install pytest-cov
+          python -X dev -m pytest tests --cov atom --cov-report xml
       - name: Upload coverage to Codecov
         uses: codecov/codecov-action@v1
         if: matrix.os == 'windows-latest'
@@ -49,7 +55,6 @@
           file: ./coverage.xml
           flags: unittests
           name: codecov-umbrella
-          yml: ./codecov.yml
           fail_ci_if_error: true
       - name: Upload coverage to Codecov
         uses: codecov/codecov-action@v1
@@ -58,5 +63,4 @@
           token: ${{ secrets.CODECOV_TOKEN }}
           flags: unittests
           name: codecov-umbrella
-          yml: ./codecov.yml
           fail_ci_if_error: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/scalars.py 
new/atom-0.5.2/atom/scalars.py
--- old/atom-0.5.0/atom/scalars.py      2020-03-27 03:22:43.000000000 +0100
+++ new/atom-0.5.2/atom/scalars.py      2020-07-05 21:38:25.000000000 +0200
@@ -223,7 +223,8 @@
     __slots__ = ()
 
     def __init__(self, default=u'', factory=None, strict=False):
-        msg = 'Unicode is deprecated and will be removed in atom 0.6.0'
+        msg = ('Unicode is deprecated and will be removed in atom 0.6.0, '
+               'use Str instead.')
         warnings.warn(FutureWarning(msg))
         super(Unicode, self).__init__(default, factory)
         if strict:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/src/atomlist.cpp 
new/atom-0.5.2/atom/src/atomlist.cpp
--- old/atom-0.5.0/atom/src/atomlist.cpp        2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/atom/src/atomlist.cpp        2020-07-05 21:38:25.000000000 
+0200
@@ -794,7 +794,7 @@
         bool obs = observer_check();
         if( obs )
         {
-            olditem = PyList_GetItem( m_list.get(), index );
+            olditem = cppy::xincref(PyList_GetItem( m_list.get(), index ));
             if( !olditem )
                 return -1;
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/src/member.cpp 
new/atom-0.5.2/atom/src/member.cpp
--- old/atom-0.5.0/atom/src/member.cpp  2020-03-27 03:22:43.000000000 +0100
+++ new/atom-0.5.2/atom/src/member.cpp  2020-07-05 21:38:25.000000000 +0200
@@ -967,7 +967,7 @@
     std::vector<cppy::ptr>::iterator end = static_observers->end();
     for( it = static_observers->begin(); it != end; ++it )
     {
-        if( *it == obptr || it->richcmp( obptr, Py_EQ ) )
+        if( *it == obptr || utils::safe_richcompare( it->get(), obptr, Py_EQ ) 
)
             return;
     }
     static_observers->push_back( obptr );
@@ -991,7 +991,7 @@
         std::vector<cppy::ptr>::iterator end = static_observers->end();
         for( it = static_observers->begin(); it != end; ++it )
         {
-            if( *it == obptr || it->richcmp( obptr, Py_EQ ) )
+            if( *it == obptr || utils::safe_richcompare( it->get(), obptr, 
Py_EQ ) )
             {
                 static_observers->erase( it );
                 if( static_observers->size() == 0 )
@@ -1016,7 +1016,7 @@
     std::vector<cppy::ptr>::iterator end = static_observers->end();
     for( it = static_observers->begin(); it != end; ++it )
     {
-        if( *it == obptr || it->richcmp( obptr, Py_EQ ) )
+        if( *it == obptr || utils::safe_richcompare( it->get(), obptr, Py_EQ ) 
)
             return true;
     }
     return false;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/src/observerpool.cpp 
new/atom-0.5.2/atom/src/observerpool.cpp
--- old/atom-0.5.0/atom/src/observerpool.cpp    2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/atom/src/observerpool.cpp    2020-07-05 21:38:25.000000000 
+0200
@@ -6,6 +6,7 @@
 | The full license is in the file LICENSE, distributed with this software.
 |----------------------------------------------------------------------------*/
 #include "observerpool.h"
+#include "utils.h"
 
 
 namespace atom
@@ -82,7 +83,7 @@
             obs_end = obs_it + topic_it->m_count;
             for( ; obs_it != obs_end; ++obs_it )
             {
-                if( *obs_it == observer || obs_it->richcmp( observer, Py_EQ ) )
+                if( *obs_it == observer || utils::safe_richcompare( 
obs_it->get(), observer, Py_EQ ) )
                     return true;
             }
             return false;
@@ -117,7 +118,7 @@
             obs_free = obs_end;
             for( ; obs_it != obs_end; ++obs_it )
             {
-                if( *obs_it == observer || obs_it->richcmp( observer, Py_EQ ) )
+                if( *obs_it == observer || utils::safe_richcompare( 
obs_it->get(), observer, Py_EQ ) )
                     return;
                 if( !obs_it->is_truthy() )
                     obs_free = obs_it;
@@ -160,7 +161,7 @@
             obs_end = obs_it + topic_it->m_count;
             for( ; obs_it != obs_end; ++obs_it )
             {
-                if( *obs_it == observer || obs_it->richcmp( observer, Py_EQ ) )
+                if( *obs_it == observer || utils::safe_richcompare( 
obs_it->get(), observer, Py_EQ ) )
                 {
                     m_observers.erase( obs_it );
                     if( ( --topic_it->m_count ) == 0 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/src/observerpool.h 
new/atom-0.5.2/atom/src/observerpool.h
--- old/atom-0.5.0/atom/src/observerpool.h      2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/atom/src/observerpool.h      2020-07-05 21:38:25.000000000 
+0200
@@ -11,6 +11,8 @@
 #include <cppy/cppy.h>
 #include "platstdint.h"
 #include "modifyguard.h"
+#include "utils.h"
+
 
 namespace atom
 {
@@ -26,7 +28,7 @@
         ~Topic() {}
         bool match( cppy::ptr& topic )
         {
-            return m_topic == topic || m_topic.richcmp( topic, Py_EQ );
+            return m_topic == topic || utils::safe_richcompare( m_topic, 
topic, Py_EQ );
         }
         cppy::ptr m_topic;
         uint32_t m_count;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/src/propertyhelper.cpp 
new/atom-0.5.2/atom/src/propertyhelper.cpp
--- old/atom-0.5.0/atom/src/propertyhelper.cpp  2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/atom/src/propertyhelper.cpp  2020-07-05 21:38:25.000000000 
+0200
@@ -10,6 +10,7 @@
 #include "catom.h"
 #include "member.h"
 #include "memberchange.h"
+#include "utils.h"
 
 
 namespace atom
@@ -80,7 +81,7 @@
             return 0;
         }
         bool cached = member->get_getattr_mode() == GetAttr::CachedProperty;
-        if( !cached || !oldptr.richcmp( newptr, Py_EQ ) )
+        if( !cached || !utils::safe_richcompare( oldptr, newptr, Py_EQ ) )
         {
             cppy::ptr argsptr( property_args( atom, member, oldptr.get(), 
newptr.get() ) );
             if( !argsptr )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/src/setattrbehavior.cpp 
new/atom-0.5.2/atom/src/setattrbehavior.cpp
--- old/atom-0.5.0/atom/src/setattrbehavior.cpp 2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/atom/src/setattrbehavior.cpp 2020-07-05 21:38:25.000000000 
+0200
@@ -8,6 +8,7 @@
 #include <cppy/cppy.h>
 #include "member.h"
 #include "memberchange.h"
+#include "utils.h"
 
 
 namespace atom
@@ -130,7 +131,7 @@
         cppy::ptr argsptr;
         if( member->has_observers() )
         {
-            if( valid_old && oldptr.richcmp( newptr, Py_EQ ) )
+            if( valid_old && utils::safe_richcompare( oldptr, newptr, Py_EQ ) )
                 return 0;
             if( valid_old )
                 argsptr = updated_args( atom, member, oldptr.get(), 
newptr.get() );
@@ -145,7 +146,7 @@
         {
             if( !argsptr )
             {
-                if( valid_old && oldptr.richcmp( newptr, Py_EQ ) )
+                if( valid_old && utils::safe_richcompare( oldptr, newptr, 
Py_EQ ) )
                     return 0;
                 if( valid_old )
                     argsptr = updated_args( atom, member, oldptr.get(), 
newptr.get() );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/src/sortedmap.cpp 
new/atom-0.5.2/atom/src/sortedmap.cpp
--- old/atom-0.5.0/atom/src/sortedmap.cpp       2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/atom/src/sortedmap.cpp       2020-07-05 21:38:25.000000000 
+0200
@@ -11,6 +11,7 @@
 #include <iostream>
 #include <sstream>
 #include "packagenaming.h"
+#include "utils.h"
 
 #ifdef __clang__
 #pragma clang diagnostic ignored "-Wdeprecated-writable-strings"
@@ -24,80 +25,6 @@
 namespace
 {
 
-/**
- * A fallback 3way comparison function for when PyObject_RichCompareBool
- * fails to compare "unorderable types" on Python 3.
- *
- * This is based on Python 2's `default_3way_compare`.
- *
- * This function will not change the Python exception state.
- */
-inline int
-fallback_3way_compare( PyObject* first, PyObject* second )
-{
-    // Compare pointer values if the types are the same.
-    if( first->ob_type == second->ob_type ) {
-        Py_uintptr_t fp = reinterpret_cast<Py_uintptr_t>( first );
-        Py_uintptr_t sp = reinterpret_cast<Py_uintptr_t>( second );
-        return (fp < sp) ? -1 : (fp > sp) ? 1 : 0;
-    }
-
-    // None is smaller than anything.
-    if( first == Py_None )
-        return -1;
-    if( second == Py_None )
-        return 1;
-
-    // Compare based on type names, numbers are smaller.
-    const char* fn = PyNumber_Check( first ) ? "" : first->ob_type->tp_name;
-    const char* sn = PyNumber_Check( second ) ? "" : second->ob_type->tp_name;
-    int c = strcmp( fn, sn );
-    if( c < 0 )
-        return -1;
-    if( c > 0 )
-        return 1;
-
-    // Finally, fall back to comparing type pointers.
-    Py_uintptr_t ftp = reinterpret_cast<Py_uintptr_t>( first->ob_type );
-    Py_uintptr_t stp = reinterpret_cast<Py_uintptr_t>( second->ob_type );
-    return ftp < stp ? -1 : 1;
-}
-
-
-bool richcompare( PyObject* first, PyObject* second, int opid )
-{
-    // Start with Python's rich compare.
-    int r = PyObject_RichCompareBool( first, second, opid );
-
-    // Handle a successful comparison.
-    if( r == 1 )
-        return true;
-    if( r == 0 )
-        return false;
-
-    // Clear the error if one happened because we attempted an invalid
-    // comparison.
-    if( PyErr_Occurred() )
-        PyErr_Clear();
-
-    // Fallback to the Python 2 default 3 way compare.
-    int c = fallback_3way_compare( first, second );
-
-    // Convert the 3way comparison result based on the `opid`.
-    switch (opid) {
-    case Py_EQ: return c == 0;
-    case Py_NE: return c != 0;
-    case Py_LE: return c <= 0;
-    case Py_GE: return c >= 0;
-    case Py_LT: return c < 0;
-    case Py_GT: return c > 0;
-    }
-
-    // Return `false` if the `opid` is not handled.
-    return false;
-}
-
-
 class MapItem
 {
 
@@ -142,21 +69,21 @@
         {
             if( first.m_key == second.m_key )
                 return false;
-            return richcompare( first.m_key.get(), second.m_key.get(), Py_LT );
+            return atom::utils::safe_richcompare( first.m_key.get(), 
second.m_key.get(), Py_LT );
         }
 
         bool operator()( MapItem& first, PyObject* second )
         {
             if( first.m_key == second )
                 return false;
-            return richcompare( first.m_key.get(), second, Py_LT );
+            return atom::utils::safe_richcompare( first.m_key.get(), second, 
Py_LT );
         }
 
         bool operator()( PyObject* first, MapItem& second )
         {
             if( first == second.m_key )
                 return false;
-            return richcompare( first, second.m_key.get(), Py_LT );
+            return atom::utils::safe_richcompare( first, second.m_key.get(), 
Py_LT );
         }
     };
 
@@ -166,21 +93,21 @@
         {
             if( first.m_key == second.m_key )
                 return true;
-            return richcompare( first.m_key.get(), second.m_key.get(), Py_EQ );
+            return atom::utils::safe_richcompare( first.m_key.get(), 
second.m_key.get(), Py_EQ );
         }
 
         bool operator()( MapItem& first, PyObject* second )
         {
             if( first.m_key == second )
                 return true;
-            return richcompare( first.m_key.get(),  second, Py_EQ );
+            return atom::utils::safe_richcompare( first.m_key.get(),  second, 
Py_EQ );
         }
 
         bool operator()( PyObject* first, MapItem& second )
         {
             if( first == second.m_key )
                 return true;
-            return richcompare( first, second.m_key.get(), Py_EQ );
+            return atom::utils::safe_richcompare( first, second.m_key.get(), 
Py_EQ );
         }
     };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/src/utils.h 
new/atom-0.5.2/atom/src/utils.h
--- old/atom-0.5.0/atom/src/utils.h     2020-03-27 03:22:43.000000000 +0100
+++ new/atom-0.5.2/atom/src/utils.h     2020-07-05 21:38:25.000000000 +0200
@@ -92,6 +92,61 @@
 }
 
 
+/**
+ * A safe richcomparison that will never fail and fallback to 3way compare
+ * if the conventional rich compare fails.
+ */
+inline bool safe_richcompare( PyObject* first, PyObject* second, int opid )
+{
+    // Start with Python's rich compare.
+    int r = PyObject_RichCompareBool( first, second, opid );
+
+    // Handle a successful comparison.
+    if( r == 1 )
+        return true;
+    if( r == 0 )
+        return false;
+
+    // Clear the error if one happened because we attempted an invalid
+    // comparison.
+    if( PyErr_Occurred() )
+        PyErr_Clear();
+
+    // Fallback to the Python 2 default 3 way compare.
+    int c = fallback_3way_compare( first, second );
+
+    // Convert the 3way comparison result based on the `opid`.
+    switch (opid) {
+    case Py_EQ: return c == 0;
+    case Py_NE: return c != 0;
+    case Py_LE: return c <= 0;
+    case Py_GE: return c >= 0;
+    case Py_LT: return c < 0;
+    case Py_GT: return c > 0;
+    }
+
+    // Return `false` if the `opid` is not handled.
+    return false;
+}
+
+inline bool safe_richcompare( cppy::ptr first, PyObject* second, int opid )
+{
+    return safe_richcompare( first.get(), second, opid );
+}
+
+
+inline bool safe_richcompare( PyObject* first, cppy::ptr second, int opid )
+{
+    return safe_richcompare( first, second.get(), opid );
+}
+
+
+inline bool safe_richcompare( cppy::ptr first, cppy::ptr second, int opid )
+{
+    return safe_richcompare( first.get(), second.get(), opid );
+}
+
+
 } // namespace utils
 
 } // namespace atom
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/atom/version.py 
new/atom-0.5.2/atom/version.py
--- old/atom-0.5.0/atom/version.py      2020-03-27 03:22:43.000000000 +0100
+++ new/atom-0.5.2/atom/version.py      2020-07-05 21:38:25.000000000 +0200
@@ -22,7 +22,7 @@
 
 # The micro release number. The micro release number is incremented
 # for bug fix releases and small feature additions.
-MICRO = 0
+MICRO = 2
 
 # The status indicate if this is a development or pre-release version
 STATUS = ''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/codecov.yml new/atom-0.5.2/codecov.yml
--- old/atom-0.5.0/codecov.yml  2020-03-27 03:22:43.000000000 +0100
+++ new/atom-0.5.2/codecov.yml  2020-07-05 21:38:25.000000000 +0200
@@ -8,7 +8,7 @@
   status:
     project: yes
     patch: yes
-    changes: no
+    changes: yes
 
 parsers:
   gcov:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/releasenotes.rst 
new/atom-0.5.2/releasenotes.rst
--- old/atom-0.5.0/releasenotes.rst     2020-03-27 03:22:43.000000000 +0100
+++ new/atom-0.5.2/releasenotes.rst     2020-07-05 21:38:25.000000000 +0200
@@ -1,7 +1,17 @@
 Atom Release Notes
 ==================
 
-0.5.0 - unreleased
+0.5.2 - 04/07/2020
+------------------
+- make comparison used in C safe (fix bug introduced in 0.5.0) PR #107
+
+0.5.1 - 03/06/2020
+------------------
+- fix bug in using atomlist from C PR #102
+- clarify Unicode deprecation warning PR #102
+
+
+0.5.0 - 26/03/2020
 ------------------
 - drop Python 2 support PR #83
 - use cppy to write the c++ extension PR #83
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/tests/datastructure/test_sortedmap.py 
new/atom-0.5.2/tests/datastructure/test_sortedmap.py
--- old/atom-0.5.0/tests/datastructure/test_sortedmap.py        2020-03-27 
03:22:43.000000000 +0100
+++ new/atom-0.5.2/tests/datastructure/test_sortedmap.py        2020-07-05 
21:38:25.000000000 +0200
@@ -161,6 +161,33 @@
     smap[1] = 4
     assert [k for k in smap.keys()] == [1, '0', 'a', 'b', 'c', 'd']
 
+    # Test ordering None, which is smaller than anything
+    s = sortedmap()
+    s[1] = 1
+    s[None] = 1
+    assert [k for k in s.keys()] == [None, 1]
+
+    s = sortedmap()
+    s[None] = 1
+    s[1] = 1
+    assert [k for k in s.keys()] == [None, 1]
+
+    # Test ordering class that cannot be ordered through the usual mean
+    class T:
+        pass
+    t1 = T()
+    t2 = T()
+    oT = T
+    class T:
+        pass
+    u = T()
+    s = sortedmap()
+    s[t1] = 1
+    s[t2] = 1
+    assert [k for k in s.keys()] == [t1, t2] if id(t1) < id(t2) else [t2, t1]
+    s[u] = 1
+    assert [k for k in s.keys()][0] is u if id(T) < id(oT) else [k for k in 
s.keys()][-1] is u
+
 
 def test_deleting_keys(smap):
     """Test deleting items.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/tests/test_observe.py 
new/atom-0.5.2/tests/test_observe.py
--- old/atom-0.5.0/tests/test_observe.py        2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/tests/test_observe.py        2020-07-05 21:38:25.000000000 
+0200
@@ -11,6 +11,13 @@
 import pytest
 from atom.api import Atom, Int, List, Value, Event, Signal, observe
 
+
+class NonComparableObject:
+
+    def __eq__(self, other):
+        raise ValueError()
+
+
 # --- Static observer manipulations
 
 @pytest.fixture
@@ -66,8 +73,15 @@
     """Test manually managing static observers.
 
     """
-    def react(change):
-        change['object'].changes.append(change['name'])
+    # Force the use of safe comparison (error cleaning and fallback)
+    class Observer:
+        def __eq__(self, other):
+            raise ValueError()
+
+        def __call__(self, change):
+            change['object'].changes.append(change['name'])
+
+    react = Observer()
 
     # We have 2 static observers hence 2 removals
     member = static_atom.get_member('val2')
@@ -236,6 +250,11 @@
     def react(self, change):
         self.count += 1
 
+    # Force the use of safe equality comparison (ie clean error and fallback
+    # on pointer comparison)
+    def __eq__(self, other):
+        raise ValueError()
+
 
 class DynamicAtom(Atom):
     """Atom used to test dynamic observers.
@@ -559,11 +578,12 @@
             self.count = 0
 
         def react(self, change):
+            print(change)
             self.count += 1
 
     class NotifTest(Atom):
 
-        val = Int()
+        val = Value()
 
         count = Int()
 
@@ -575,6 +595,7 @@
             self.observe('val', self.observer.react)
 
         def _observe_val(self, change):
+            print(change)
             self.count += 1
 
     return NotifTest()
@@ -617,8 +638,43 @@
     assert sd_observed_atom.observer.count == 2
 
 
+def test_notification_on_setting_non_comparable_value(sd_observed_atom):
+    """Test that notifiers are called when setting a value.
+
+    """
+    o1 = NonComparableObject()
+    sd_observed_atom.val = 0
+
+    assert sd_observed_atom.count == 1
+    assert sd_observed_atom.observer.count == 1
+
+    # And also test update of values
+    sd_observed_atom.val = 1
+
+    assert sd_observed_atom.count == 2
+    assert sd_observed_atom.observer.count == 2
+
+    # No notification on equal assignment
+    sd_observed_atom.val = 1
+
+    assert sd_observed_atom.count == 2
+    assert sd_observed_atom.observer.count == 2
+
+    # Check notification on invalid comparison
+    sd_observed_atom.val = o1
+
+    assert sd_observed_atom.count == 3
+    assert sd_observed_atom.observer.count == 3
+
+     # Check no notification on equal value assignment
+    sd_observed_atom.val = o1
+
+    assert sd_observed_atom.count == 3
+    assert sd_observed_atom.observer.count == 3
+
+
 def test_enabling_disabling_notifications(sd_observed_atom):
-    """Test enabling/disabling motification on an atom.
+    """Test enabling/disabling notification on an atom.
 
     """
     assert sd_observed_atom.notifications_enabled()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.5.0/tests/test_property.py 
new/atom-0.5.2/tests/test_property.py
--- old/atom-0.5.0/tests/test_property.py       2020-03-27 03:22:43.000000000 
+0100
+++ new/atom-0.5.2/tests/test_property.py       2020-07-05 21:38:25.000000000 
+0200
@@ -9,8 +9,8 @@
 
 """
 import pytest
-from atom.api import (Atom, Int, Property, GetAttr, SetAttr,
-                      observe, cached_property)
+from atom.api import (Atom, GetAttr, Int, Property, SetAttr, Value,
+                      cached_property, observe)
 from atom.catom import DelAttr, reset_property
 
 
@@ -167,9 +167,17 @@
     """Test observing a property.
 
     """
+    class NonComparableObject:
+
+        def __eq__(self, other):
+            raise ValueError()
+
+        def __add__(self, other):
+            return other + 5
+
     class PropertyTest(Atom):
 
-        i = Int()
+        i = Value(0)
 
         counter = Int()
 
@@ -188,9 +196,11 @@
     assert pt.prop == 1
     assert pt.prop == 2
 
+    pt.i = NonComparableObject()
     pt.observe('prop', pt.observe_cp)
     pt.get_member('prop').reset(pt)
     assert pt.counter == 2
+    assert pt.prop == 7
 
 
 def test_wrong_reset_arguments():


Reply via email to