summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2017-11-02 16:13:31 +0200
committerLars Wirzenius <liw@liw.fi>2017-11-02 16:57:51 +0200
commitba16a904e153fc71f1537b588793659800c78b4c (patch)
treedc7076bc11804b242910a7710305874b06d96e5a
parent4fed1867dcd5343f5c7d53592a43b8595bfb777f (diff)
downloadqvisqve-ba16a904e153fc71f1537b588793659800c78b4c.tar.gz
Fix: flatten objects with same name, unorderable fields
Bug reported by Mantas. If a resource (or its prototype) has two fields with the same name, but unorderable value types (such as string and integer), the flatten_object function used to crash. This is now fixed.
-rw-r--r--NEWS5
-rw-r--r--qvarn/objstore.py13
-rw-r--r--qvarn/resource_type_tests.py1
-rw-r--r--resource_type/files.yaml7
4 files changed, 24 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 8153469..9b7d8fe 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,11 @@ Bug fixes:
resources, not just `foo`. This has been fixed. Bug reported by
Kaius, fixed by Lars.
+* Mantas reported that if a resource type or resource had two fields
+ with the same type but values that were not possible to compare,
+ such as a string and an integer, Qvarn would crash. This is now
+ fixed.
+
Version 0.86, released 2017-10-10
----------------------------------
diff --git a/qvarn/objstore.py b/qvarn/objstore.py
index 90d4e84..d88774e 100644
--- a/qvarn/objstore.py
+++ b/qvarn/objstore.py
@@ -386,7 +386,18 @@ class NoSuchObject(Exception):
def flatten_object(obj):
- return list(sorted(set(_flatten(obj))))
+ # We sort only by the name, not the object in each pair in the
+ # list. Otherwise, if there are two fields with the same name but
+ # incompatible value types this will break. However, to guarantee
+ # that objects always result in the same flattened representation,
+ # we also compare the second field. For this, we convert the
+ # second value to a string with repr. This allows the second
+ # fields to be compared regardless of type.
+
+ pairs = _flatten(obj)
+ unique_pairs = set(pairs)
+ sorted_pairs = sorted(unique_pairs, key=repr)
+ return list(sorted_pairs)
def _flatten(obj, obj_key=None):
diff --git a/qvarn/resource_type_tests.py b/qvarn/resource_type_tests.py
index a1fd09a..36c775b 100644
--- a/qvarn/resource_type_tests.py
+++ b/qvarn/resource_type_tests.py
@@ -59,6 +59,7 @@ class ResourceTypeTests(unittest.TestCase):
'prototype': {
'foo': '',
'bar': '',
+ 'version': 0, # test for bug
},
'subpaths': {
'subfoo': {
diff --git a/resource_type/files.yaml b/resource_type/files.yaml
index 947b7f6..ef74217 100644
--- a/resource_type/files.yaml
+++ b/resource_type/files.yaml
@@ -4,7 +4,12 @@ versions:
- prototype: {id: '', revision: '', type: ''}
version: v0
- files: [file]
- prototype: {filename: '', id: '', revision: '', type: ''}
+ prototype:
+ filename: ''
+ id: ''
+ revision: ''
+ type: ''
+ version: 0
subpaths:
file:
prototype: {body: blob, content_type: ''}