Releases: hearsaycorp/normalize
More diffing fixes
Diffing fixes with yield
Merge pull request #67 from bluemoon/bradford-fix-fix Fix return issue with chain/yield
Diffing improvements
Merge pull request #65 from bluemoon/bradford-recurse-poc Recursion as an option PoC
normalize 0.8
0.8.0 6th March 2015
bool(record)
was reverted to pre-0.7.x behavior: always True,
unless a Collection in which case Falsy depending on the number of
members in the collection.- Empty psuedo-attributes now return
normalize.empty.EmptyVal
objects, which are alwaysFalse
and perform a limited amount of
sanity checking/type inference, so that misspellings of sub-properties
can sometimes be caught.
0.7.x series release notes
0.7.4 5th March 2015
- A regression which introduced subtle bugs in 0.7.0, which became more
significant with the new feature delivered in 0.7.3 was fixed. - An exception with some forms of dereferencing MultiFieldSelectors was
fixed.
0.7.3 4th March 2015
- Added a new option to diff to suppress diffs found when comparing
lists of objects for which all populated fields are filtered.
0.7.2 27th February 2015
- Fixed a regression with the new 'json_out' behavior I decided was big
enough to pull 0.7.1 from PyPI for.
0.7.1 27th February 2015
-
VisitorPattern.visit with visit_filter would not visit everything in
the filter due to the changes in 0.7.0 -
MultiFieldSelector subscripting, where the result is now a "complete"
MultiFieldSelector (ie, matches all fields/values) is now more
efficient by using a singleton -
the return of 'json_out' is no longer unconditionally passed to
to_json
: call it explicitly if you desire this behavior:::
class Foo(Record): bar = Property(isa=Record, json_out=lambda x: {"bar": x})
If you are using
json_out
like this, and expectingRecord
values or anything with ajson_data
method to have that called,
then you can wrap the whole thing into_json
:::
from normalize.record.json import to_json class Foo(Record): bar = Property(isa=Record, json_out=lambda x: to_json({"bar": x}))
Normalize 0.7.0 release, the name0 release
This release brings lots of long awaited and behavior-changing features:
-
empty pseudo-attributes are now available which return (usually falsy)
values when the attribute is not set, instead of throwing
AttributeError like the regular getters.The default is to call this the same as the regular attribute, but
with a '0' appended;class Foo(Record): bar = Property() foo = Foo() foo.bar # raises AttributeError foo.bar0 # None
The default 'empty' value depends on the passed
isa=
type
constraint, and can be set toNone
or the empty string, as
desired, usingempty=
:class Dated(Record): date = Property(isa=MyType, empty=None)
It's also possible to disable this functionality for particular
attributes usingempty_attr=None
.Property uses which are not safe will see a new warning raised which
includes instructions on the changes recommended. -
accordingly, bool(record) now also returns false if the record has no
attributes defined; this allows you to use '0' in a chain with
properties that are record types:if some_record.sub_prop0.foobar0: pass
Instead of the previous:
if hasattr(some_record, "sub_prop") and \ getattr(some_record.sub_prop, "foobar", False): pass
This currently involves creating a new (empty) instance of the object
for each of the intermediate properties; but this may in the future be
replaced by a proxy object for performance.The main side effect of this change is that this kind of code is no
longer safe:try: foo = FooJsonRecord(json_data) except: foo = None if foo: #... doesn't imply an exception happened
-
The mechanism by which
empty=
delivers psuedo-attributes is
available via theaux_props
sub-class API on Property. -
Various ambiguities around the way MultiFieldSelectors and their
__getattr__
and__contains__
operators (ie,multi_field_selector[X]
andX in multi_field_selector
) are defined have been updated based on
findings from using them in real applications. See the function
definitions for more.
Normalize 0.6.0, the "fuzzy diff" release
Diff will now attempt to do fuzzy matching when comparing
collections. This should result in more fine-grained differences
when comparing data where the values have to be matched by content.
This implementation in this version can be slow (O(N²)), if comparing
very large sets with few identical items.
normalize 0.5.0, the "VisitorPattern class grows up" release!
normalize.visitor overhaul. Visitor got split into a sub-class API, VisitorPattern, which is all class methods, and Visitor, the instance which travels with the operation to provide context. Hugely backwards incompatible, but the old API was undocumented and sucked anyway.
The new visitor API supports visiting instances, creating instances, and reflection using the same infrastructure; a convergence of implementation I'm pretty happy with!
The normalize 0.4.x series: the highlights
-
added support for comparing filtered objects;
__pk__()
object
method no longer honored. Seetests/test_mfs_diff.py
for
examples -
MultiFieldSelector can now be traversed by indexing, and supports
thein
operator, with individual indices or FieldSelector
objects as the member. Seetests/test_selector.py
for examples. -
extraneous
diff option now customizable via theDiffOptions
sub-class API. -
Diff
,JsonDiff
andMultiFieldSelector
now have more
useful default stringification. -
The 'ignore_empty_slots' diff option is now capable of ignoring empty
records as well as None-y values. This even works if the records
are not actually None but all of the fields that have values are
filtered by the DiffOptions compare_filter parameter. -
added Diffas property trait, so you can easily add
'compare_as=lambda x: scrub(x)' for field-specific clean-ups specific
to comparison. -
errors thrown from property coerce functions are now wrapped in
another exception to supply the extra context. For instance, the
example in the intro will now print an error like:CoerceError: coerce to datetime for Comment.edited failed with value '2001-09-09T01:47:22': datetime constructor raised: an integer is required
Fix tuple protocol
Merge pull request #28 from samv/fix-visitor-lists Fix visitor lists