Skip to content

Commit f38c912

Browse files
committed
cqle: refactor container init to common method
PYTHON-306
1 parent 3d66a31 commit f38c912

2 files changed

Lines changed: 37 additions & 71 deletions

File tree

cassandra/cqlengine/columns.py

Lines changed: 35 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from datetime import date, datetime
1717
import logging
1818
import six
19+
from uuid import UUID as _UUID
1920

2021
from cassandra import util
2122
from cassandra.cqltypes import SimpleDateType
@@ -504,7 +505,6 @@ def validate(self, value):
504505
val = super(UUID, self).validate(value)
505506
if val is None:
506507
return
507-
from uuid import UUID as _UUID
508508
if isinstance(val, _UUID):
509509
return val
510510
if isinstance(val, six.string_types):
@@ -523,9 +523,6 @@ def to_database(self, value):
523523
return self.validate(value)
524524

525525

526-
from uuid import UUID as pyUUID, getnode
527-
528-
529526
class TimeUUID(UUID):
530527
"""
531528
UUID containing timestamp
@@ -615,24 +612,22 @@ class BaseContainerColumn(Column):
615612
https://cassandra.apache.org/doc/cql3/CQL.html#collections
616613
"""
617614

618-
def __init__(self, value_type, **kwargs):
615+
def __init__(self, types, **kwargs):
619616
"""
620-
:param value_type: a column class indicating the types of the value
617+
:param types: a sequence of sub types in this collection
621618
"""
622-
inheritance_comparator = issubclass if isinstance(value_type, type) else isinstance
623-
if not inheritance_comparator(value_type, Column):
624-
raise ValidationError('value_type must be a column class')
625-
if inheritance_comparator(value_type, BaseContainerColumn):
626-
raise ValidationError('container types cannot be nested')
627-
if value_type.db_type is None:
628-
raise ValidationError('value_type cannot be an abstract column type')
629-
630-
if isinstance(value_type, type):
631-
self.value_type = value_type
632-
self.value_col = self.value_type()
633-
else:
634-
self.value_col = value_type
635-
self.value_type = self.value_col.__class__
619+
instances = []
620+
for t in types:
621+
inheritance_comparator = issubclass if isinstance(t, type) else isinstance
622+
if not inheritance_comparator(t, Column):
623+
raise ValidationError("%s is not a column class" % (t,))
624+
if inheritance_comparator(t, BaseContainerColumn): # should go away with PYTHON-478
625+
raise ValidationError('container types cannot be nested')
626+
if t.db_type is None:
627+
raise ValidationError("%s is an abstract type" % (t,))
628+
629+
instances.append(t() if isinstance(t, type) else t)
630+
self.types = instances
636631

637632
super(BaseContainerColumn, self).__init__(**kwargs)
638633

@@ -649,7 +644,7 @@ def _val_is_null(self, val):
649644

650645
@property
651646
def sub_types(self):
652-
return [self.value_col]
647+
return self.types
653648

654649

655650
class Set(BaseContainerColumn):
@@ -666,7 +661,10 @@ def __init__(self, value_type, strict=True, default=set, **kwargs):
666661
"""
667662
self.strict = strict
668663
self.db_type = 'set<{0}>'.format(value_type.db_type)
669-
super(Set, self).__init__(value_type, default=default, **kwargs)
664+
665+
super(Set, self).__init__((value_type,), default=default, **kwargs)
666+
667+
self.value_col = self.types[0]
670668

671669
def validate(self, value):
672670
val = super(Set, self).validate(value)
@@ -706,7 +704,10 @@ def __init__(self, value_type, default=list, **kwargs):
706704
:param value_type: a column class indicating the types of the value
707705
"""
708706
self.db_type = 'list<{0}>'.format(value_type.db_type)
709-
return super(List, self).__init__(value_type=value_type, default=default, **kwargs)
707+
708+
super(List, self).__init__((value_type,), default=default, **kwargs)
709+
710+
self.value_col = self.types[0]
710711

711712
def validate(self, value):
712713
val = super(List, self).validate(value)
@@ -743,21 +744,10 @@ def __init__(self, key_type, value_type, default=dict, **kwargs):
743744

744745
self.db_type = 'map<{0}, {1}>'.format(key_type.db_type, value_type.db_type)
745746

746-
inheritance_comparator = issubclass if isinstance(key_type, type) else isinstance
747-
if not inheritance_comparator(key_type, Column):
748-
raise ValidationError('key_type must be a column class')
749-
if inheritance_comparator(key_type, BaseContainerColumn):
750-
raise ValidationError('container types cannot be nested')
751-
if key_type.db_type is None:
752-
raise ValidationError('key_type cannot be an abstract column type')
753-
754-
if isinstance(key_type, type):
755-
self.key_type = key_type
756-
self.key_col = self.key_type()
757-
else:
758-
self.key_col = key_type
759-
self.key_type = self.key_col.__class__
760-
super(Map, self).__init__(value_type, default=default, **kwargs)
747+
super(Map, self).__init__((key_type, value_type), default=default, **kwargs)
748+
749+
self.key_col = self.types[0]
750+
self.value_col = self.types[1]
761751

762752
def validate(self, value):
763753
val = super(Map, self).validate(value)
@@ -780,10 +770,6 @@ def to_database(self, value):
780770
return None
781771
return dict((self.key_col.to_database(k), self.value_col.to_database(v)) for k, v in value.items())
782772

783-
@property
784-
def sub_types(self):
785-
return [self.key_col, self.value_col]
786-
787773

788774
class UDTValueManager(BaseValueManager):
789775
@property
@@ -796,7 +782,7 @@ def reset_previous_value(self):
796782
self.previous_value = copy(self.value)
797783

798784

799-
class Tuple(Column):
785+
class Tuple(BaseContainerColumn):
800786
"""
801787
Stores a fixed-length set of positional values
802788
@@ -812,46 +798,26 @@ def __init__(self, *args, **kwargs):
812798
if not args:
813799
raise ValueError("Tuple must specify at least one inner type")
814800

815-
types = []
816-
for arg in args:
817-
inheritance_comparator = issubclass if isinstance(arg, type) else isinstance
818-
if not inheritance_comparator(arg, Column):
819-
raise ValidationError("%s is not a column class" % (arg,))
820-
if arg.db_type is None:
821-
raise ValidationError("%s is an abstract type" % (arg,))
822-
823-
types.append(arg() if isinstance(arg, type) else arg)
824-
self.types = types
825-
826-
super(Tuple, self).__init__(**kwargs)
801+
super(Tuple, self).__init__(args, **kwargs)
827802

828803
def validate(self, value):
829804
val = super(Tuple, self).validate(value)
830805
if val is None:
831806
return
832-
if len(val) > self.sub_types:
807+
if len(val) > len(self.types):
833808
raise ValidationError("Value %r has more fields than tuple definition (%s)" %
834-
(val, ', '.join(t for t in self.sub_types)))
835-
return tuple(t.validate(v) for t, v in zip(self.sub_types, val))
809+
(val, ', '.join(t for t in self.types)))
810+
return tuple(t.validate(v) for t, v in zip(self.types, val))
836811

837812
def to_python(self, value):
838813
if value is None:
839814
return tuple()
840-
return tuple(t.to_python(v) for t, v in zip(self.sub_types, value))
815+
return tuple(t.to_python(v) for t, v in zip(self.types, value))
841816

842817
def to_database(self, value):
843818
if value is None:
844819
return
845-
return tuple(t.to_database(v) for t, v in zip(self.sub_types, value))
846-
847-
@property
848-
def sub_types(self):
849-
return self.types
850-
851-
# TODO:
852-
# test UDTs in tuples, vice versa
853-
# refactor init validation to common base
854-
# cqlsh None in tuple should display as null
820+
return tuple(t.to_database(v) for t, v in zip(self.types, value))
855821

856822

857823
class UserDefinedType(Column):

cassandra/cqlengine/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,8 +814,8 @@ def _get_polymorphic_base(bases):
814814
raise ModelDefinitionException("column '{0}' conflicts with built-in attribute/method".format(k))
815815

816816
# counter column primary keys are not allowed
817-
if (v.primary_key or v.partition_key) and isinstance(v, (columns.Counter, columns.BaseContainerColumn)):
818-
raise ModelDefinitionException('counter columns and container columns cannot be used as primary keys')
817+
if (v.primary_key or v.partition_key) and isinstance(v, columns.Counter):
818+
raise ModelDefinitionException('counter columns cannot be used as primary keys')
819819

820820
# this will mark the first primary key column as a partition
821821
# key, if one hasn't been set already

0 commit comments

Comments
 (0)