@@ -1710,29 +1710,37 @@ class IndexCol:
1710
1710
is_data_indexable = True
1711
1711
_info_fields = ["freq" , "tz" , "index_name" ]
1712
1712
1713
+ name : str
1714
+ cname : str
1715
+ kind_attr : str
1716
+
1713
1717
def __init__ (
1714
1718
self ,
1719
+ name : str ,
1715
1720
values = None ,
1716
1721
kind = None ,
1717
1722
typ = None ,
1718
- cname = None ,
1723
+ cname : Optional [ str ] = None ,
1719
1724
itemsize = None ,
1720
- name = None ,
1721
1725
axis = None ,
1722
- kind_attr = None ,
1726
+ kind_attr : Optional [ str ] = None ,
1723
1727
pos = None ,
1724
1728
freq = None ,
1725
1729
tz = None ,
1726
1730
index_name = None ,
1727
1731
** kwargs ,
1728
1732
):
1733
+
1734
+ if not isinstance (name , str ):
1735
+ raise ValueError ("`name` must be a str." )
1736
+
1729
1737
self .values = values
1730
1738
self .kind = kind
1731
1739
self .typ = typ
1732
1740
self .itemsize = itemsize
1733
1741
self .name = name
1734
- self .cname = cname
1735
- self .kind_attr = kind_attr
1742
+ self .cname = cname or name
1743
+ self .kind_attr = kind_attr or f" { name } _kind"
1736
1744
self .axis = axis
1737
1745
self .pos = pos
1738
1746
self .freq = freq
@@ -1742,19 +1750,14 @@ def __init__(
1742
1750
self .meta = None
1743
1751
self .metadata = None
1744
1752
1745
- if name is not None :
1746
- self .set_name (name , kind_attr )
1747
1753
if pos is not None :
1748
1754
self .set_pos (pos )
1749
1755
1750
- def set_name (self , name , kind_attr = None ):
1751
- """ set the name of this indexer """
1752
- self .name = name
1753
- self .kind_attr = kind_attr or "{name}_kind" .format (name = name )
1754
- if self .cname is None :
1755
- self .cname = name
1756
-
1757
- return self
1756
+ # These are ensured as long as the passed arguments match the
1757
+ # constructor annotations.
1758
+ assert isinstance (self .name , str )
1759
+ assert isinstance (self .cname , str )
1760
+ assert isinstance (self .kind_attr , str )
1758
1761
1759
1762
def set_axis (self , axis : int ):
1760
1763
""" set the axis over which I index """
@@ -1771,7 +1774,6 @@ def set_pos(self, pos: int):
1771
1774
1772
1775
def set_table (self , table ):
1773
1776
self .table = table
1774
- return self
1775
1777
1776
1778
def __repr__ (self ) -> str :
1777
1779
temp = tuple (
@@ -1797,10 +1799,13 @@ def __ne__(self, other) -> bool:
1797
1799
@property
1798
1800
def is_indexed (self ) -> bool :
1799
1801
""" return whether I am an indexed column """
1800
- try :
1801
- return getattr ( self . table . cols , self .cname ). is_indexed
1802
- except AttributeError :
1802
+ if not hasattr ( self . table , "cols" ) :
1803
+ # e.g. if self.set_table hasn't been called yet , self.table
1804
+ # will be None.
1803
1805
return False
1806
+ # GH#29692 mypy doesn't recognize self.table as having a "cols" attribute
1807
+ # 'error: "None" has no attribute "cols"'
1808
+ return getattr (self .table .cols , self .cname ).is_indexed # type: ignore
1804
1809
1805
1810
def copy (self ):
1806
1811
new_self = copy .copy (self )
@@ -2508,6 +2513,7 @@ class DataIndexableCol(DataCol):
2508
2513
2509
2514
def validate_names (self ):
2510
2515
if not Index (self .values ).is_object ():
2516
+ # TODO: should the message here be more specifically non-str?
2511
2517
raise ValueError ("cannot have non-object label DataIndexableCol" )
2512
2518
2513
2519
def get_atom_string (self , block , itemsize ):
@@ -2842,8 +2848,8 @@ def write_index(self, key, index):
2842
2848
else :
2843
2849
setattr (self .attrs , "{key}_variety" .format (key = key ), "regular" )
2844
2850
converted = _convert_index (
2845
- index , self .encoding , self .errors , self .format_type
2846
- ). set_name ( "index" )
2851
+ "index" , index , self .encoding , self .errors , self .format_type
2852
+ )
2847
2853
2848
2854
self .write_array (key , converted .values )
2849
2855
@@ -2893,8 +2899,8 @@ def write_multi_index(self, key, index):
2893
2899
)
2894
2900
level_key = "{key}_level{idx}" .format (key = key , idx = i )
2895
2901
conv_level = _convert_index (
2896
- lev , self .encoding , self .errors , self .format_type
2897
- ). set_name ( level_key )
2902
+ level_key , lev , self .encoding , self .errors , self .format_type
2903
+ )
2898
2904
self .write_array (level_key , conv_level .values )
2899
2905
node = getattr (self .group , level_key )
2900
2906
node ._v_attrs .kind = conv_level .kind
@@ -3436,9 +3442,10 @@ def queryables(self):
3436
3442
3437
3443
def index_cols (self ):
3438
3444
""" return a list of my index cols """
3445
+ # Note: each `i.cname` below is assured to be a str.
3439
3446
return [(i .axis , i .cname ) for i in self .index_axes ]
3440
3447
3441
- def values_cols (self ):
3448
+ def values_cols (self ) -> List [ str ] :
3442
3449
""" return a list of my values cols """
3443
3450
return [i .cname for i in self .values_axes ]
3444
3451
@@ -3540,6 +3547,8 @@ def indexables(self):
3540
3547
3541
3548
self ._indexables = []
3542
3549
3550
+ # Note: each of the `name` kwargs below are str, ensured
3551
+ # by the definition in index_cols.
3543
3552
# index columns
3544
3553
self ._indexables .extend (
3545
3554
[
@@ -3553,13 +3562,16 @@ def indexables(self):
3553
3562
base_pos = len (self ._indexables )
3554
3563
3555
3564
def f (i , c ):
3565
+ assert isinstance (c , str )
3556
3566
klass = DataCol
3557
3567
if c in dc :
3558
3568
klass = DataIndexableCol
3559
3569
return klass .create_for_block (
3560
3570
i = i , name = c , pos = base_pos + i , version = self .version
3561
3571
)
3562
3572
3573
+ # Note: the definition of `values_cols` ensures that each
3574
+ # `c` below is a str.
3563
3575
self ._indexables .extend (
3564
3576
[f (i , c ) for i , c in enumerate (self .attrs .values_cols )]
3565
3577
)
@@ -3797,11 +3809,9 @@ def create_axes(
3797
3809
3798
3810
if i in axes :
3799
3811
name = obj ._AXIS_NAMES [i ]
3800
- index_axes_map [i ] = (
3801
- _convert_index (a , self .encoding , self .errors , self .format_type )
3802
- .set_name (name )
3803
- .set_axis (i )
3804
- )
3812
+ index_axes_map [i ] = _convert_index (
3813
+ name , a , self .encoding , self .errors , self .format_type
3814
+ ).set_axis (i )
3805
3815
else :
3806
3816
3807
3817
# we might be able to change the axes on the appending data if
@@ -3900,6 +3910,9 @@ def get_blk_items(mgr, blocks):
3900
3910
if data_columns and len (b_items ) == 1 and b_items [0 ] in data_columns :
3901
3911
klass = DataIndexableCol
3902
3912
name = b_items [0 ]
3913
+ if not (name is None or isinstance (name , str )):
3914
+ # TODO: should the message here be more specifically non-str?
3915
+ raise ValueError ("cannot have non-object label DataIndexableCol" )
3903
3916
self .data_columns .append (name )
3904
3917
3905
3918
# make sure that we match up the existing columns
@@ -4582,6 +4595,7 @@ def indexables(self):
4582
4595
self ._indexables = [GenericIndexCol (name = "index" , axis = 0 )]
4583
4596
4584
4597
for i , n in enumerate (d ._v_names ):
4598
+ assert isinstance (n , str )
4585
4599
4586
4600
dc = GenericDataIndexableCol (
4587
4601
name = n , pos = i , values = [n ], version = self .version
@@ -4700,12 +4714,15 @@ def _set_tz(values, tz, preserve_UTC: bool = False, coerce: bool = False):
4700
4714
return values
4701
4715
4702
4716
4703
- def _convert_index (index , encoding = None , errors = "strict" , format_type = None ):
4717
+ def _convert_index (name : str , index , encoding = None , errors = "strict" , format_type = None ):
4718
+ assert isinstance (name , str )
4719
+
4704
4720
index_name = getattr (index , "name" , None )
4705
4721
4706
4722
if isinstance (index , DatetimeIndex ):
4707
4723
converted = index .asi8
4708
4724
return IndexCol (
4725
+ name ,
4709
4726
converted ,
4710
4727
"datetime64" ,
4711
4728
_tables ().Int64Col (),
@@ -4716,6 +4733,7 @@ def _convert_index(index, encoding=None, errors="strict", format_type=None):
4716
4733
elif isinstance (index , TimedeltaIndex ):
4717
4734
converted = index .asi8
4718
4735
return IndexCol (
4736
+ name ,
4719
4737
converted ,
4720
4738
"timedelta64" ,
4721
4739
_tables ().Int64Col (),
@@ -4726,6 +4744,7 @@ def _convert_index(index, encoding=None, errors="strict", format_type=None):
4726
4744
atom = _tables ().Int64Col ()
4727
4745
# avoid to store ndarray of Period objects
4728
4746
return IndexCol (
4747
+ name ,
4729
4748
index ._ndarray_values ,
4730
4749
"integer" ,
4731
4750
atom ,
@@ -4743,6 +4762,7 @@ def _convert_index(index, encoding=None, errors="strict", format_type=None):
4743
4762
if inferred_type == "datetime64" :
4744
4763
converted = values .view ("i8" )
4745
4764
return IndexCol (
4765
+ name ,
4746
4766
converted ,
4747
4767
"datetime64" ,
4748
4768
_tables ().Int64Col (),
@@ -4753,6 +4773,7 @@ def _convert_index(index, encoding=None, errors="strict", format_type=None):
4753
4773
elif inferred_type == "timedelta64" :
4754
4774
converted = values .view ("i8" )
4755
4775
return IndexCol (
4776
+ name ,
4756
4777
converted ,
4757
4778
"timedelta64" ,
4758
4779
_tables ().Int64Col (),
@@ -4765,18 +4786,21 @@ def _convert_index(index, encoding=None, errors="strict", format_type=None):
4765
4786
dtype = np .float64 ,
4766
4787
)
4767
4788
return IndexCol (
4768
- converted , "datetime" , _tables ().Time64Col (), index_name = index_name
4789
+ name , converted , "datetime" , _tables ().Time64Col (), index_name = index_name
4769
4790
)
4770
4791
elif inferred_type == "date" :
4771
4792
converted = np .asarray ([v .toordinal () for v in values ], dtype = np .int32 )
4772
- return IndexCol (converted , "date" , _tables ().Time32Col (), index_name = index_name )
4793
+ return IndexCol (
4794
+ name , converted , "date" , _tables ().Time32Col (), index_name = index_name ,
4795
+ )
4773
4796
elif inferred_type == "string" :
4774
4797
# atom = _tables().ObjectAtom()
4775
4798
# return np.asarray(values, dtype='O'), 'object', atom
4776
4799
4777
4800
converted = _convert_string_array (values , encoding , errors )
4778
4801
itemsize = converted .dtype .itemsize
4779
4802
return IndexCol (
4803
+ name ,
4780
4804
converted ,
4781
4805
"string" ,
4782
4806
_tables ().StringCol (itemsize ),
@@ -4787,7 +4811,11 @@ def _convert_index(index, encoding=None, errors="strict", format_type=None):
4787
4811
if format_type == "fixed" :
4788
4812
atom = _tables ().ObjectAtom ()
4789
4813
return IndexCol (
4790
- np .asarray (values , dtype = "O" ), "object" , atom , index_name = index_name
4814
+ name ,
4815
+ np .asarray (values , dtype = "O" ),
4816
+ "object" ,
4817
+ atom ,
4818
+ index_name = index_name ,
4791
4819
)
4792
4820
raise TypeError (
4793
4821
"[unicode] is not supported as a in index type for [{0}] formats" .format (
@@ -4799,17 +4827,25 @@ def _convert_index(index, encoding=None, errors="strict", format_type=None):
4799
4827
# take a guess for now, hope the values fit
4800
4828
atom = _tables ().Int64Col ()
4801
4829
return IndexCol (
4802
- np .asarray (values , dtype = np .int64 ), "integer" , atom , index_name = index_name
4830
+ name ,
4831
+ np .asarray (values , dtype = np .int64 ),
4832
+ "integer" ,
4833
+ atom ,
4834
+ index_name = index_name ,
4803
4835
)
4804
4836
elif inferred_type == "floating" :
4805
4837
atom = _tables ().Float64Col ()
4806
4838
return IndexCol (
4807
- np .asarray (values , dtype = np .float64 ), "float" , atom , index_name = index_name
4839
+ name ,
4840
+ np .asarray (values , dtype = np .float64 ),
4841
+ "float" ,
4842
+ atom ,
4843
+ index_name = index_name ,
4808
4844
)
4809
4845
else : # pragma: no cover
4810
4846
atom = _tables ().ObjectAtom ()
4811
4847
return IndexCol (
4812
- np .asarray (values , dtype = "O" ), "object" , atom , index_name = index_name
4848
+ name , np .asarray (values , dtype = "O" ), "object" , atom , index_name = index_name ,
4813
4849
)
4814
4850
4815
4851
0 commit comments