Repository: mahmoud/boltons

Issue:
python 3.9 test failure version 20.2.1
=================================== FAILURES ===================================
_____________________________ test_frozendict_api ______________________________

    def test_frozendict_api():
        # all the read-only methods that are fine
        through_methods = ['__class__',
                           '__cmp__',
                           '__contains__',
                           '__delattr__',
                           '__dir__',
                           '__eq__',
                           '__format__',
                           '__ge__',
                           '__getattribute__',
                           '__getitem__',
                           '__gt__',
                           '__init__',
                           '__iter__',
                           '__le__',
                           '__len__',
                           '__lt__',
                           '__ne__',
                           '__new__',
                           '__reduce__',
                           '__reversed__',
                           '__setattr__',
                           '__sizeof__',
                           '__str__',
                           'copy',
                           'get',
                           'has_key',
                           'items',
                           'iteritems',
                           'iterkeys',
                           'itervalues',
                           'keys',
                           'values',
                           'viewitems',
                           'viewkeys',
                           'viewvalues']
    
        fd = FrozenDict()
        ret = []
        for attrname in dir(fd):
            if attrname == '_hash':  # in the dir, even before it's set
                continue
            attr = getattr(fd, attrname)
            if not callable(attr):
                continue
    
            if getattr(FrozenDict, attrname) == getattr(dict, attrname, None) and attrname not in through_methods:
>               assert attrname == False
E               AssertionError: assert '__ior__' == False

tests/test_dictutils.py:483: AssertionError
=========================== short test summary info ============================
FAILED tests/test_dictutils.py::test_frozendict_api - AssertionError: assert .

Comments:

Patch:
diff --git a/boltons/dictutils.py b/boltons/dictutils.py
index ce5884c..8d1a4e7 100644
--- a/boltons/dictutils.py
+++ b/boltons/dictutils.py
@@ -1076,7 +1076,7 @@ class FrozenDict(dict):
         "raises a TypeError, because FrozenDicts are immutable"
         raise TypeError('%s object is immutable' % self.__class__.__name__)
 
-    __setitem__ = __delitem__ = update = _raise_frozen_typeerror
+    __ior__ = __setitem__ = __delitem__ = update = _raise_frozen_typeerror
     setdefault = pop = popitem = clear = _raise_frozen_typeerror
 
     del _raise_frozen_typeerror


Test patch:
diff --git a/tests/test_dictutils.py b/tests/test_dictutils.py
index b6873a8..6eac812 100644
--- a/tests/test_dictutils.py
+++ b/tests/test_dictutils.py
@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 
+import sys
 import pytest
 
 from boltons.dictutils import OMD, OneToOne, ManyToMany, FrozenDict, subdict, FrozenHashError
@@ -432,6 +433,15 @@ def test_frozendict():
     return
 
 
+@pytest.mark.skipif(sys.version_info < (3, 9), reason="requires python3.9 or higher")
+def test_frozendict_ior():
+    data = {'a': 'A', 'b': 'B'}
+    fd = FrozenDict(data)
+
+    with pytest.raises(TypeError, match=".*FrozenDicts are immutable.*"):
+        fd |= fd
+
+
 def test_frozendict_api():
     # all the read-only methods that are fine
     through_methods = ['__class__',
@@ -452,8 +462,10 @@ def test_frozendict_api():
                        '__lt__',
                        '__ne__',
                        '__new__',
+                       '__or__',
                        '__reduce__',
                        '__reversed__',
+                       '__ror__',
                        '__setattr__',
                        '__sizeof__',
                        '__str__',