Set populated on first use.
| 119 | |
| 120 | |
| 121 | class LazySet(set): |
| 122 | """Set populated on first use.""" |
| 123 | |
| 124 | _props = ( |
| 125 | '__str__', '__repr__', '__unicode__', |
| 126 | '__hash__', '__sizeof__', '__cmp__', |
| 127 | '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', |
| 128 | '__contains__', '__len__', '__nonzero__', |
| 129 | '__getitem__', '__setitem__', '__delitem__', '__iter__', |
| 130 | '__sub__', '__and__', '__xor__', '__or__', |
| 131 | '__rsub__', '__rand__', '__rxor__', '__ror__', |
| 132 | '__isub__', '__iand__', '__ixor__', '__ior__', |
| 133 | 'add', 'clear', 'copy', 'difference', 'difference_update', |
| 134 | 'discard', 'intersection', 'intersection_update', 'isdisjoint', |
| 135 | 'issubset', 'issuperset', 'pop', 'remove', |
| 136 | 'symmetric_difference', 'symmetric_difference_update', |
| 137 | 'union', 'update') |
| 138 | |
| 139 | def __new__(cls, fill_iter=None): |
| 140 | |
| 141 | if fill_iter is None: |
| 142 | return set() |
| 143 | |
| 144 | class LazySet(set): |
| 145 | pass |
| 146 | |
| 147 | fill_iter = [fill_iter] |
| 148 | |
| 149 | def lazy(name): |
| 150 | def _lazy(self, *args, **kw): |
| 151 | _fill_lock.acquire() |
| 152 | try: |
| 153 | if len(fill_iter) > 0: |
| 154 | for i in fill_iter.pop(): |
| 155 | set.add(self, i) |
| 156 | for method_name in cls._props: |
| 157 | delattr(LazySet, method_name) |
| 158 | finally: |
| 159 | _fill_lock.release() |
| 160 | return getattr(set, name)(self, *args, **kw) |
| 161 | return _lazy |
| 162 | |
| 163 | for name in cls._props: |
| 164 | setattr(LazySet, name, lazy(name)) |
| 165 | |
| 166 | new_set = LazySet() |
| 167 | return new_set |
| 168 | |
| 169 | # Not all versions of Python declare the same magic methods. |
| 170 | # Filter out properties that don't exist in this version of Python |