-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit de0fb23
committed
v2.13.0 - DictObject fixes + Added
**New Features**
All new features in this commit, were added in the `privex/helpers/collections.py` module.
- Added previously missing `geoip` extra to setup.py extensions list. While the `geoip.txt` extra file was added a few versions ago,
I forgot to register it in setup.py :)
- Added new collections helper function `copy_class`, which is able to deep copy "normal" non-complex classes / types, including
slotted classes (classes that use `__slots__`). This allows you to duplicate an existing class, severing any object pointers
contained within it's attributes, without having to inherit it or copy and paste it.
- `_q_copy` internal function used to deep copy a given object, and assist with determining whether to use copy.deepcopy,
or just return a reference based on the optional attribute/item key passed to it.
- `_copy_class_dict` internal function - handles deep copying standard classes which use `__dict__`
- `_copy_class_slotted` internal function - handles deep copying slotted classes - i.e. those which use `__slots__` instead
of the standard and default `__dict__`.
- `Dictable` now includes magic methods for getitem and setitem, allowing dataclasses based on `Dictable` to have their attributes
accessed and updated as if they were a dictionary.
- Added instance method `get` to `Dictable`, which works similarly to the standard `dict.get` with a fallback if the key does not exist.
- Brand new `DictDataClass` dataclass base class, based on `Dictable`. This class is designed to massively improve interoperability
between dataclasses and dictionaries - smoothing both conversion from dictionaries, and conversions back into dictionaries.
It includes 4 different dictionary conversion settings for your dataclass, allowing you to choose per-class how you'd like it to
handle converting your dataclass into a `dict` - including the ability to set a list of attribute names which will contain a list
of objects such as `Dictable` / `DictDataClass` based dataclasses - which will be converted into lists of dictionaries
when the instance is casted into a `dict`.
- Added the alias `DictDataclass` for `DictDataClass`, since people (including myself) are bound to get confused about the spelling
many times.
- Added compatibility code to `collections.py` to prevent the lack of dataclasses on Python 3.6 breaking the entire module.
The module displays a warning when it's imported if it detects that dataclasses aren't available, with information on how
rectify the issue.
It uses `Mocker` to generate the dummy classes `dataclass` and `field`, along with the `dataclasses` module. This will allow
classes/methods/functions which use `dataclass` / `field` or the dataclasses module in their type annotations to be interpreted
correctly, without throwing a syntax error due to the missing `dataclass` / `field` / `dataclasses` objects.
This obviously does not mean `Dictable` or `DictDataClass` will actually function on Python 3.6 properly without a shim
library such as the aptly named `dataclasses` PyPi package. The module is just patched with dummy classes/modules so that
otherwise missing references to dataclasses don't break the entire `collections` module.
**Bug Fixes**
- Fixed an issue where if you access or set non-existent items via attributes on a `DictObject` or `OrderedDictObject`, a `KeyError` is raised.
This results in problems with code which expects a non-existent attribute to raise `AttributeError` - not `KeyError`.
The issue has been fixed on both `DictObject` and `OrderedDictObject` by catching `KeyError`'s and re-raising them as `AttributeError`'s,
which would be expected to be raised when accessing an attribute that might not exist.
- Fixed a similar issue to above on `Mocker` - where when accessing an item (dict-like key), it would pass through the `AttributeError`
from `__getattribute__`. It now converts `AttributeError`'s into appropriate `KeyError` exceptions.
- Fixed an issue where `pytest` may refuse to run any tests at all, due to a missing package. This was caused by imports for test module classes
within `__init__.py`. Fixed by moving direct test class imports in `tests/__init__.py` into the `if __name__` block, so that test modules
are only imported if you're running `tests` as a module using the standard Python `unittest` module.
**Unit Testing**
- Added unit tests for the new `privex.helpers.collections.copy_class` helper function within the new unit test class
`tests.test_collections.TestCopyClass`
- Added unit tests for `DictDataClass` in the new unit test class `TestDictDataClass`, with a pytest skipif decorator, ensuring
the tests are safely skipped on older Python versions such as Python 3.6 (unless the `dataclasses` backport shim library is installed).DictDataClass
and copy_class
to collections1 parent 19b0d97 commit de0fb23Copy full SHA for de0fb23
File tree
Expand file treeCollapse file tree
5 files changed
+898
-200
lines changedFilter options
- privex/helpers
- tests
Expand file treeCollapse file tree
5 files changed
+898
-200
lines changedCollapse file: privex/helpers/__init__.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
| |||
143 | 143 |
| |
144 | 144 |
| |
145 | 145 |
| |
146 |
| - | |
| 146 | + | |
147 | 147 |
| |
148 | 148 |
| |
149 | 149 |
|
0 commit comments