2

Disclaimer: I'm a super noob in Python so please be patient.

I'm not even sure if this is possible at all, but we are using Schematics for data validation in Python and we have a list of dictionaries that can have values of multiple types (e.g. List of strings, List of numbers, List of Dictionaries etc.) So my first attempt was to use Union Type.

Now, the model looks like this:

class Filter(Model):
    _id = ObjectIdType(default=ObjectId)
    name = StringType()
    filters = ListType(DictType(UnionType([ListType(StringType()),
              ListType(NumberType()),BooleanType(), StringType()])))
    created_at = DateTimeType(default=datetime.datetime.now)
    updated_at = DateTimeType(default=datetime.datetime.now)

But for some unknown reason, isinstance() is giving me the error that arg 2 must be a type or tuple of types (which I have a feeling means that only 2 types can be unified). So I'm a bit out of ideas. I tried to write a custom model and use ModelType, but that didn't fly too far either.

Thank you in advance!

Iulia Mihet
  • 650
  • 1
  • 10
  • 34

1 Answers1

0

You say you have a dictionary with multiple key types. In python, it doesn;t matter what type the keys are as long as they are hashable. Meaning the following is perfectly acceptable:

my_dict={}    
my_dict[1]=[1,2,3]    
my_dict['s']='hello'    
my_dict[(0,2)]={'a':1,2:'b'}
print(my_dict)
{1: [1, 2, 3], 
's': 'hello', 
(0, 2): {'a': 1, 2: 'b'}
}

However, you state that your keys are lists of other values. Because a list is mutable, it can't be used as a key in a dict:

my_dict[[1,2]]='coords'
TypeError: unhashable type: 'list'

The solution would be to convert your list keys into tuple keys, as in my 3rd example above, which are similarly structured but immutable

G. Anderson
  • 5,815
  • 2
  • 14
  • 21
  • My bad, I am super tired. I wanted to mean "values" of multiple types, not keys. – Iulia Mihet Oct 04 '18 at 19:28
  • That makes more sense. However, the main point still stands. Python doesn't care about the types of values in a dict. Is there a reason you HAVE to union the types? – G. Anderson Oct 04 '18 at 19:32
  • To be honest, reading your comments and also the question you linked above, I am beginning to doubt the practical value of the whole validation. – Iulia Mihet Oct 05 '18 at 04:49
  • Apologies if this isn't feasible for your situation, but rather than trying to union all of the types then pass a single filter, would it be better code practice/more readable/more maintainable, to define validation for each input type individually then pass it through some if/elif logic? It might be less efficient depending on how much data you have to throughput, though. – G. Anderson Oct 05 '18 at 15:09
  • 1
    Yes, in the end we came to the same conclusion: either we define a very specific, custom model that contains the type for each field or we leave a very general type with the possibility to add whatever subtypes. – Iulia Mihet Oct 09 '18 at 05:10