From f08cfbf0546facfddce8de8ecb5f037a3fc4d465 Mon Sep 17 00:00:00 2001 From: Tom Aldcroft Date: Mon, 4 Feb 2013 22:02:21 -0500 Subject: [PATCH 1/7] Make Column or MaskedColumn name arg be keyword arg name=None --- astropy/table/table.py | 20 +++++++++----------- astropy/table/tests/test_column.py | 6 ++++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/astropy/table/table.py b/astropy/table/table.py index aca0b7403be..886df6a7b17 100644 --- a/astropy/table/table.py +++ b/astropy/table/table.py @@ -158,15 +158,13 @@ def descr(self): return (self.name, self.dtype.str, self.shape[1:]) def __repr__(self): - if self.name: - units = None if self.units is None else str(self.units) - out = "<{0} name={1} units={2} format={3} " \ - "description={4}>\n{5}".format( - self.__class__.__name__, - repr(self.name), repr(units), - repr(self.format), repr(self.description), repr(self.data)) - else: - out = repr(self.data) + units = None if self.units is None else str(self.units) + out = "<{0} name={1} units={2} format={3} " \ + "description={4}>\n{5}".format( + self.__class__.__name__, + repr(self.name), repr(units), + repr(self.format), repr(self.description), repr(self.data)) + return out def iter_str_vals(self): @@ -417,7 +415,7 @@ class Column(BaseColumn, np.ndarray): element. """ - def __new__(cls, name, data=None, + def __new__(cls, name=None, data=None, dtype=None, shape=(), length=0, description=None, units=None, format=None, meta=None): @@ -470,7 +468,7 @@ def copy(self, data=None, copy_data=True): class MaskedColumn(BaseColumn, ma.MaskedArray): - def __new__(cls, name, data=None, mask=None, fill_value=None, + def __new__(cls, name=None, data=None, mask=None, fill_value=None, dtype=None, shape=(), length=0, description=None, units=None, format=None, meta=None): diff --git a/astropy/table/tests/test_column.py b/astropy/table/tests/test_column.py index 31e38a1d6b6..07a4f3eeb68 100644 --- a/astropy/table/tests/test_column.py +++ b/astropy/table/tests/test_column.py @@ -45,11 +45,13 @@ def test_numpy_ops(self, Column): def test_view(self, Column): c = np.array([1, 2, 3]).view(Column) if Column == table.MaskedColumn: - assert repr(c) == ('masked_array(data = [1 2 3],\n' + assert repr(c) == ('\n' + 'masked_array(data = [1 2 3],\n' ' mask = False,\n' ' fill_value = 999999)\n') else: - assert repr(c) == 'array([1, 2, 3])' + assert repr(c) == ('\n' + 'array([1, 2, 3])') def test_format(self, Column): """Show that the formatted output from str() works""" From 2a47e25f54f754682f3e3fe24e5249db1d5b1ebe Mon Sep 17 00:00:00 2001 From: Tom Aldcroft Date: Tue, 5 Feb 2013 22:34:06 -0500 Subject: [PATCH 2/7] Add docstring for MaskedColumn --- astropy/table/table.py | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/astropy/table/table.py b/astropy/table/table.py index 886df6a7b17..6b421152eff 100644 --- a/astropy/table/table.py +++ b/astropy/table/table.py @@ -467,6 +467,89 @@ def copy(self, data=None, copy_data=True): class MaskedColumn(BaseColumn, ma.MaskedArray): + """Define a masked data column for use in a Table object. + + Parameters + ---------- + name : str + Column name and key for reference within Table + data : list, ndarray or None + Column data values + mask : list, ndarray or None + Boolean mask for which True indicates missing or invalid data + fill_value : float, int, str or None + Value used when filling masked column elements + dtype : numpy.dtype compatible value + Data type for column + shape : tuple or () + Dimensions of a single row element in the column data + length : int or 0 + Number of row elements in column data + description : str or None + Full description of column + units : str or None + Physical units + format : str or None + Format string for outputting column values. This can be an + "old-style" (``format % value``) or "new-style" (`str.format`) + format specification string. + meta : dict-like or None + Meta-data associated with the column + + Examples + -------- + A MaskedColumn is similar to a Column except that it includes ``mask`` and + ``fill_value`` attributes. It can be created in two different ways: + + - Provide a ``data`` value but not ``shape`` or ``length`` (which are + inferred from the data). + + Examples:: + + col = MaskedColumn(data=[1, 2], name='name') + col = MaskedColumn(data=[1, 2], name='name', mask=[True, False]) + col = MaskedColumn(data=[1, 2], name='name', dtype=float, fill_value=99) + + The ``mask`` argument will be cast as a boolean array and specifies + which elements are considered to be missing or invalid. + + The ``dtype`` argument can be any value which is an acceptable + fixed-size data-type initializer for the numpy.dtype() method. See + ``_. + Examples include: + + - Python non-string type (float, int, bool) + - Numpy non-string type (e.g. np.float32, np.int64, np.bool) + - Numpy.dtype array-protocol type strings (e.g. 'i4', 'f8', 'S15') + + If no ``dtype`` value is provide then the type is inferred using + ``np.array(data)``. When ``data`` is provided then the ``shape`` + and ``length`` arguments are ignored. + + - Provide ``length`` and optionally ``shape``, but not ``data`` + + Examples:: + + col = MaskedColumn(name='name', length=5) + col = MaskedColumn(name='name', dtype=int, length=10, shape=(3,4)) + + The default ``dtype`` is ``np.float64``. The ``shape`` argument is the + array shape of a single cell in the column. + + .. warning:: + + In the next major release of `astropy` (0.3), the order of function + arguments for creating a |MaskedColumn| will change. Currently the order is + ``MaskedColumn(name, data, ...)``, but in 0.3 and later it will be + ``MaskedColumn(data, name, ...)``. This improves consistency with |Table| + and `numpy`. + + In order to use the same code for Astropy 0.2 and 0.3, column objects + should always be created using named keyword arguments for ``data`` and + ``name``, for instance ``c = MaskedColumn(data=[1, 2], name='col')``. When + Astropy 0.3 is released then the the keyword identifiers can be dropped, + allowing for ``c = MaskedColumn([1, 2], 'c')``. + """ def __new__(cls, name=None, data=None, mask=None, fill_value=None, dtype=None, shape=(), length=0, From 28ea0a9ff576c56992be50b9ec1ec88a6230c58a Mon Sep 17 00:00:00 2001 From: Tom Aldcroft Date: Tue, 5 Feb 2013 22:35:30 -0500 Subject: [PATCH 3/7] Update table docs to used 'data' and 'name' kwargs in Column/MaskedColumn --- astropy/table/table.py | 42 ++++++++++++++++---------- docs/table/access_table.rst | 2 +- docs/table/construct_table.rst | 54 ++++++++++++++++++++++------------ docs/table/index.rst | 2 +- docs/table/masking.rst | 12 ++++---- docs/table/modify_table.rst | 7 ++++- docs/whatsnew/0.2.rst | 2 +- 7 files changed, 77 insertions(+), 44 deletions(-) diff --git a/astropy/table/table.py b/astropy/table/table.py index 6b421152eff..1c72e6d5d9d 100644 --- a/astropy/table/table.py +++ b/astropy/table/table.py @@ -379,15 +379,16 @@ class Column(BaseColumn, np.ndarray): -------- A Column can be created in two different ways: - - Provide a ``data`` value and optionally a ``dtype`` value + - Provide a ``data`` value but not ``shape`` or ``length`` (which are + inferred from the data). Examples:: - col = Column('name', data=[1, 2, 3]) # shape=(3,) - col = Column('name', data=[[1, 2], [3, 4]]) # shape=(2, 2) - col = Column('name', data=[1, 2, 3], dtype=float) - col = Column('name', np.array([1, 2, 3])) - col = Column('name', ['hello', 'world']) + col = Column(data=[1, 2], name='name') # shape=(2,) + col = Column(data=[[1, 2], [3, 4]], name='name') # shape=(2, 2) + col = Column(data=[1, 2], name='name', dtype=float) + col = Column(data=np.array([1, 2]), name='name') + col = Column(data=['hello', 'world'], name='name') The ``dtype`` argument can be any value which is an acceptable fixed-size data-type initializer for the numpy.dtype() method. See @@ -399,20 +400,31 @@ class Column(BaseColumn, np.ndarray): - Numpy.dtype array-protocol type strings (e.g. 'i4', 'f8', 'S15') If no ``dtype`` value is provide then the type is inferred using - ``np.array(data)``. When ``data`` is provided then the ``shape`` - and ``length`` arguments are ignored. + ``np.array(data)``. - - Provide zero or more of ``dtype``, ``shape``, ``length`` + - Provide ``length`` and optionally ``shape``, but not ``data`` Examples:: - col = Column('name') - col = Column('name', dtype=int, length=10, shape=(3,4)) + col = Column(name='name', length=5) + col = Column(name='name', dtype=int, length=10, shape=(3,4)) + + The default ``dtype`` is ``np.float64``. The ``shape`` argument is the + array shape of a single cell in the column. - The default ``dtype`` is ``np.float64`` and the default ``length`` is - zero. The ``shape`` argument is the array shape of a single cell in the - column. The default ``shape`` is () which means a single value in each - element. + .. warning:: + + In the next major release of `astropy` (0.3), the order of function + arguments for creating a |Column| will change. Currently the order is + ``Column(name, data, ...)``, but in 0.3 and later it will be + ``Column(data, name, ...)``. This improves consistency with |Table| and + `numpy`. + + In order to use the same code for Astropy 0.2 and 0.3, column objects + should always be created using named keyword arguments for ``data`` and + ``name``, for instance ``c = Column(data=[1, 2], name='col')``. When + Astropy 0.3 is released then the the keyword identifiers can be dropped, + allowing for ``c = Column([1, 2], 'c')``. """ def __new__(cls, name=None, data=None, diff --git a/docs/table/access_table.rst b/docs/table/access_table.rst index 3a781e96617..00a97e3c4bc 100644 --- a/docs/table/access_table.rst +++ b/docs/table/access_table.rst @@ -377,7 +377,7 @@ column name header:: ... [30, 40]]), ... np.array([[ 5, 6], ... [50, 60]]) ] - >>> t.add_column(Column('a', arr)) + >>> t.add_column(Column(data=arr, name='a')) >>> t['a'].shape (3, 2, 2) >>> t.pprint() diff --git a/docs/table/construct_table.rst b/docs/table/construct_table.rst index 064740a4e48..52d253d9908 100644 --- a/docs/table/construct_table.rst +++ b/docs/table/construct_table.rst @@ -40,9 +40,9 @@ size, columns, or data are not known. :: >>> t = Table() - >>> t.add_column(Column('a', [1, 4])) - >>> t.add_column(Column('b', [2.0, 5.0])) - >>> t.add_column(Column('c', ['x', 'y'])) + >>> t.add_column(Column(data=[1, 4], name='a')) + >>> t.add_column(Column(data=[2.0, 5.0], name='b')) + >>> t.add_column(Column(data=['x', 'y'], name='c')) >>> t = Table(names=('a', 'b', 'c'), dtypes=('f4', 'i4', 'S2')) >>> t.add_row((1, 2.0, 'x')) @@ -98,7 +98,7 @@ of different data types to initialize a table:: >>> a = (1, 4) >>> b = np.array([[2, 3], [5, 6]]) # vector column - >>> c = Column('axis', ['x', 'y']) + >>> c = Column(data=['x', 'y'], name='axis') >>> arr = (a, b, c) >>> Table(arr) # Data column named "c" has a name "axis" that table @@ -134,7 +134,7 @@ The input column data can be any data type that can initialize a |Column| object >>> arr = {'a': (1, 4), 'b': np.array([[2, 3], [5, 6]]), - 'c': Column('axis', ['x', 'y'])} + 'c': Column(data=['x', 'y'], name='axis')} >>> Table(arr, names=('a', 'b', 'c'))
array([(1, [2, 3], 'x'), (4, [5, 6], 'y')], @@ -483,9 +483,13 @@ Column """""" A |Column| object can be created as follows, where in all cases the column -``name`` is required as the first argument and one can optionally provide +``name`` should be provided as a keyword argument and one can optionally provide these values: +``data`` : list, ndarray or None + Column data values +``dtype`` : numpy.dtype compatible value + Data type for column ``description`` : str Full description of column ``units`` : str @@ -500,15 +504,15 @@ Initialization options The column data values, shape, and data type are specified in one of two ways: -**Provide a ``data`` value and optionally a ``dtype`` value** +**Provide a ``data`` value but not a ``length`` or ``shape``** Examples:: - col = Column('a', data=[1, 2, 3]) # shape=(3,) - col = Column('a', data=[[1, 2], [3, 4]]) # shape=(2, 2) - col = Column('a', data=[1, 2, 3], dtype=float) - col = Column('a', np.array([1, 2, 3])) - col = Column('a', ['hello', 'world']) + col = Column(data=[1, 2], name='a') # shape=(2,) + col = Column(data=[[1, 2], [3, 4]], name='a') # shape=(2, 2) + col = Column(data=[1, 2], name='a', dtype=float) + col = Column(data=np.array([1, 2]), name='a') + col = Column(data=['hello', 'world'], name='a') The ``dtype`` argument can be any value which is an acceptable fixed-size data-type initializer for the numpy.dtype() method. See @@ -523,17 +527,29 @@ The column data values, shape, and data type are specified in one of two ways: ``np.array(data)``. When ``data`` is provided then the ``shape`` and ``length`` arguments are ignored. -**Provide zero or more of ``dtype``, ``shape``, ``length``** +**Provide ``length`` and optionally ``shape``, but not ``data``** Examples:: - col = Column('a') - col = Column('a', dtype=int, length=10, shape=(3,4)) + col = Column(name='a', length=5) + col = Column(name='a', dtype=int, length=10, shape=(3,4)) - The default ``dtype`` is ``np.float64`` and the default ``length`` is - zero. The ``shape`` argument is the array shape of a single cell in the - column. The default ``shape`` is () which means a single value in each - element. + The default ``dtype`` is ``np.float64``. The ``shape`` argument is the array shape of a + single cell in the column. The default ``shape`` is () which means a single value in + each element. + +.. warning:: + + In the next major release of `astropy` (0.3), the order of function arguments + for creating a |Column| or |MaskedColumn| will change. Currently the order + is ``Column(name, data, ...)``, but in 0.3 and later it will be + ``Column(data, name, ...)``. This improves consistency with |Table| and `numpy`. + + In order to use the same code for Astropy 0.2 and 0.3, column objects should + always be created using named keyword arguments for ``data`` and ``name``, + as demonstrated in the examples above. When Astropy 0.3 is released then the + the keyword identifiers can be dropped, for instance + ``c = Column([1, 2], 'd')``. .. _table_format_string: diff --git a/docs/table/index.rst b/docs/table/index.rst index 50f382c76dd..f83de321d16 100644 --- a/docs/table/index.rst +++ b/docs/table/index.rst @@ -132,7 +132,7 @@ Modifying table values in place is flexible and works as one would expect:: Add, remove, and rename columns with the following:: - >>> t.add_column(Column('d', [1, 2, 3]))) + >>> t.add_column(Column(data=[1, 2, 3], name='d'))) >>> t.remove_column('c') >>> t.rename_column('a', 'A') >>> t.colnames diff --git a/docs/table/masking.rst b/docs/table/masking.rst index ef7ac58337a..3b181728e97 100644 --- a/docs/table/masking.rst +++ b/docs/table/masking.rst @@ -57,8 +57,8 @@ available for a masked table. **Create a table with one or more columns as a MaskedColumn object** - >>> a = MaskedColumn('a', [1, 2]) - >>> b = Column('b', [3, 4]) + >>> a = MaskedColumn(data=[1, 2], name='a') + >>> b = Column(data=[3, 4], name='b') >>> t = Table([a, b]) The |MaskedColumn| is the masked analog of the |Column| class and @@ -77,8 +77,8 @@ different classes for these two cases. **Add a MaskedColumn object to an existing table** - >>> a = Column('a', [1, 2]) - >>> b = MaskedColumn('b', [3, 4], mask=[True, False]) + >>> a = Column(data=[1, 2], name='a') + >>> b = MaskedColumn(data=[3, 4], name='b', mask=[True, False]) >>> t = Table([a]) >>> t.add_column(b) INFO: Upgrading Table to masked Table [astropy.table.table] @@ -87,8 +87,8 @@ Note the INFO message because the underlying type of the table is modified in th **Add a new row to an existing table and specify a mask argument** - >>> a = Column('a', [1, 2]) - >>> b = Column('b', [3, 4]) + >>> a = Column(data=[1, 2], name='a') + >>> b = Column(data=[3, 4], name='b') >>> t = Table([a, b]) >>> t.add_row([3, 6], mask=[True, False]) INFO: Upgrading Table to masked Table [astropy.table.table] diff --git a/docs/table/modify_table.rst b/docs/table/modify_table.rst index eceabef8900..2f74dd3aee5 100644 --- a/docs/table/modify_table.rst +++ b/docs/table/modify_table.rst @@ -35,9 +35,14 @@ The code below shows the basics of modifying a table and its data. >>> t[0:3]['c'] = 100 # Set column 'c' of rows 0, 1, 2 **Add a column or columns** + +The :func:`~astropy.table.table.add_column` and :func:`~astropy.table.table.add_columns` +functions can be used to add one or multiple columns to a table. In both cases the new +columns must be specified as |Column| or |MaskedColumn| objects. :: - >>> t.add_column(Column('d', np.arange(5))) + >>> c = Column(data=np.arange(5), name='d') + >>> t.add_column(c) # Make a new table with the same number of rows and add columns to original table >>> t2 = Table(np.arange(25).reshape(5, 5), names=('e', 'f', 'g', 'h', 'i')) diff --git a/docs/whatsnew/0.2.rst b/docs/whatsnew/0.2.rst index 7bb350f6249..a596c74d66d 100644 --- a/docs/whatsnew/0.2.rst +++ b/docs/whatsnew/0.2.rst @@ -152,7 +152,7 @@ framework`_ read and write methods. For example, assume you have a table of magnitudes called ``mags`` with columns ``B`` and ``V``. You can add a new column ``B-V`` and write out to an ASCII table with:: - >>> BV = Column('B-V', mags['B'] - mags['V']) + >>> BV = Column(data=mags['B'] - mags['V'], name='B-V') >>> mags.add_column(BV) >>> mags.write('mags_BV.dat', format='ascii') From b999b48a58b0719398e4f9d63bfa7c7d9d3cf4ee Mon Sep 17 00:00:00 2001 From: Tom Aldcroft Date: Wed, 6 Feb 2013 14:06:47 -0500 Subject: [PATCH 4/7] Add tests of behavior when column name is not provided --- astropy/table/tests/test_column.py | 6 ++++++ astropy/table/tests/test_table.py | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/astropy/table/tests/test_column.py b/astropy/table/tests/test_column.py index 07a4f3eeb68..3b59b04af78 100644 --- a/astropy/table/tests/test_column.py +++ b/astropy/table/tests/test_column.py @@ -114,6 +114,12 @@ def test_array_wrap(self): assert np.allclose(c.sum(), 3.) assert isinstance(c.sum(), (np.floating, float)) + def test_name_none(self, Column): + """Can create a column without supplying name, which defaults to None""" + c = Column(data=[1, 2]) + assert c.name is None + assert np.all(c == np.array([1, 2])) + class TestAttrEqual(): """Bunch of tests originally from ATpy that test the attrs_equal method.""" diff --git a/astropy/table/tests/test_table.py b/astropy/table/tests/test_table.py index 0a90eb9386b..8800db2a92f 100644 --- a/astropy/table/tests/test_table.py +++ b/astropy/table/tests/test_table.py @@ -121,6 +121,13 @@ def test_size_mismatch(self): with pytest.raises(ValueError): Table(cols) + def test_name_none(self): + """Column with name=None can init a table IFF names are supplied""" + c = Column(data=[1, 2]) + Table([c], names=('c',)) + with pytest.raises(TypeError): + Table([c]) + @pytest.mark.usefixtures('set_global_Table') class TestReverse(): From 716dde91ec99eb28f1f301bfa36f0281031d0dc8 Mon Sep 17 00:00:00 2001 From: Tom Aldcroft Date: Wed, 6 Feb 2013 21:24:03 -0500 Subject: [PATCH 5/7] Check Column/MaskedColumn __new__ args for compliance with 0.3 ordering This is implemented as a decorate on __new__(cls, name=None, data=None, ..) for Column and MaskedColumn. The warning is: In the next major release of astropy (0.3), the order of function arguments for creating a {class_name} will change. Currently the order is {class_name}(name, data, ...), but in 0.3 and later it will be {class_name}(data, name, ...). This is consistent with Table and NumPy. In order to use the same code for Astropy 0.2 and 0.3, column objects should be created using named keyword arguments for data and name, e.g.: {class_name}(name='a', data=[1, 2]). --- astropy/table/table.py | 53 +++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/astropy/table/table.py b/astropy/table/table.py index 1c72e6d5d9d..435a3a315ea 100644 --- a/astropy/table/table.py +++ b/astropy/table/table.py @@ -2,6 +2,8 @@ import abc import sys from copy import deepcopy +import functools +import warnings import numpy as np from numpy import ma @@ -27,6 +29,36 @@ 'The template that determines the name of a column if it cannot be ' 'determined. Uses new-style (format method) string formatting') +WARN_COLUMN_ARGS = ConfigurationItem("warn_column_args", + True, + "Show a warning when a Column is created " + "in a way that will break in Astropy 0.3") +WARN_COLUMN_ARGS_MESSAGE = \ +"""In the next major release of astropy (0.3), the order of function +arguments for creating a {class_name} will change. Currently the order is +{class_name}(name, data, ...), but in 0.3 and later it will be +{class_name}(data, name, ...). This is consistent with Table and NumPy. + +In order to use the same code for Astropy 0.2 and 0.3, column objects +should be created using named keyword arguments for data and name, e.g.: +{class_name}(name='a', data=[1, 2]).""" + + +def _check_column_new_args(func): + """ + Decorator for Column and MaskedColumn __new__(cls, ...) to check that there + is only one ``args`` value (which is the class). Everything else + should be a keyword argument. Otherwise the calling code will break + when the name and data args are swapped in 0.3. + """ + @functools.wraps(func) + def wrapper(*args, **kwargs): + if len(args) > 1: + cls = args[0] # Column or MaskedColumn class from __new__(cls, ..) + warnings.warn(WARN_COLUMN_ARGS_MESSAGE.format(class_name=cls.__name__)) + return func(*args, **kwargs) + return wrapper + def _auto_names(n_cols): return [AUTO_COLNAME().format(i) for i in range(n_cols)] @@ -58,7 +90,7 @@ def __getitem__(self, item): """Get items from a TableColumns object. :: - tc = TableColumns(cols=[Column('a'), Column('b'), Column('c')]) + tc = TableColumns(cols=[Column(name='a'), Column(name='b'), Column(name='c')]) tc['a'] # Column('a') tc[1] # Column('b') tc['a', 'b'] # @@ -427,6 +459,7 @@ class Column(BaseColumn, np.ndarray): allowing for ``c = Column([1, 2], 'c')``. """ + @_check_column_new_args def __new__(cls, name=None, data=None, dtype=None, shape=(), length=0, description=None, units=None, format=None, meta=None): @@ -474,7 +507,7 @@ def copy(self, data=None, copy_data=True): if copy_data: data = data.copy() - return Column(self.name, data, units=self.units, format=self.format, + return Column(name=self.name, data=data, units=self.units, format=self.format, description=self.description, meta=deepcopy(self.meta)) @@ -563,6 +596,7 @@ class MaskedColumn(BaseColumn, ma.MaskedArray): allowing for ``c = MaskedColumn([1, 2], 'c')``. """ + @_check_column_new_args def __new__(cls, name=None, data=None, mask=None, fill_value=None, dtype=None, shape=(), length=0, description=None, units=None, format=None, meta=None): @@ -681,7 +715,7 @@ def filled(self, fill_value=None): fill_value = self._fix_fill_value(fill_value) data = super(MaskedColumn, self).filled(fill_value) - out = Column(self.name, data, units=self.units, format=self.format, + out = Column(name=self.name, data=data, units=self.units, format=self.format, description=self.description, meta=deepcopy(self.meta)) return out @@ -707,7 +741,7 @@ def copy(self, data=None, copy_data=True): if copy_data: data = data.copy() - return MaskedColumn(self.name, data, units=self.units, format=self.format, + return MaskedColumn(name=self.name, data=data, units=self.units, format=self.format, # Do not include mask=self.mask since `data` has the mask fill_value=self.fill_value, description=self.description, meta=deepcopy(self.meta)) @@ -1004,9 +1038,9 @@ def _init_from_list(self, data, names, dtypes, n_cols, copy): def_names = _auto_names(n_cols) for col, name, def_name, dtype in zip(data, names, def_names, dtypes): if isinstance(col, (Column, MaskedColumn)): - col = self.ColumnClass((name or col.name), col, dtype=dtype) + col = self.ColumnClass(name=(name or col.name), data=col, dtype=dtype) elif isinstance(col, np.ndarray) or isiterable(col): - col = self.ColumnClass((name or def_name), col, dtype=dtype) + col = self.ColumnClass(name=(name or def_name), data=col, dtype=dtype) else: raise ValueError('Elements in list initialization must be ' 'either Column or list-like') @@ -1035,7 +1069,7 @@ def _init_from_ndarray(self, data, names, dtypes, n_cols, copy): columns = TableColumns() for name in names: - columns[name] = self.ColumnClass(name, self._data[name]) + columns[name] = self.ColumnClass(name=name, data=self._data[name]) columns[name].parent_table = self self.columns = columns @@ -1077,7 +1111,7 @@ def _init_from_cols(self, cols): .format(lengths)) self._set_masked_from_cols(cols) - cols = [self.ColumnClass(col.name, col) for col in cols] + cols = [self.ColumnClass(name=col.name, data=col) for col in cols] names = [col.name for col in cols] dtypes = [col.descr for col in cols] @@ -1607,7 +1641,8 @@ def _is_mapping(obj): # Add_row() probably corrupted the Column views of self._data. Rebuild # self.columns. Col.copy() takes an optional data reference that it # uses in the copy. - cols = [self.ColumnClass(c.name, c).copy(self._data[c.name]) for c in self.columns.values()] + cols = [self.ColumnClass(name=c.name, data=c).copy(self._data[c.name]) + for c in self.columns.values()] self.columns = TableColumns(cols) def sort(self, keys): From 69ed30167db16a1f02e0bc160a354794291e7717 Mon Sep 17 00:00:00 2001 From: Tom Aldcroft Date: Wed, 6 Feb 2013 21:27:10 -0500 Subject: [PATCH 6/7] Fix tests so no warnings are generated in Column() calls This is only complete for table and io.ascii. All of these tests run without generating warnings. This was done to be sure that all code in astropy.table and astropy.io.ascii is fully compliant with the new Column args checking, i.e. it will never happen that a call to astropy.Table can generate a warning to the user. --- astropy/io/ascii/tests/test_connect.py | 20 ++++---- astropy/table/tests/test_column.py | 20 ++++---- astropy/table/tests/test_init_table.py | 8 +-- astropy/table/tests/test_item_access.py | 6 +-- astropy/table/tests/test_masked.py | 66 ++++++++++++------------- astropy/table/tests/test_row.py | 4 +- astropy/table/tests/test_table.py | 58 +++++++++++----------- 7 files changed, 91 insertions(+), 91 deletions(-) diff --git a/astropy/io/ascii/tests/test_connect.py b/astropy/io/ascii/tests/test_connect.py index bd63700e456..c6169b3ad77 100644 --- a/astropy/io/ascii/tests/test_connect.py +++ b/astropy/io/ascii/tests/test_connect.py @@ -18,8 +18,8 @@ def test_read_generic(filename): def test_write_generic(tmpdir): t = Table() - t.add_column(Column('a', [1,2,3])) - t.add_column(Column('b', ['a', 'b', 'c'])) + t.add_column(Column(name='a', data=[1,2,3])) + t.add_column(Column(name='b', data=['a', 'b', 'c'])) t.write(str(tmpdir.join("test")), format='ascii') @@ -47,16 +47,16 @@ def test_read_latex_noformat(): def test_write_latex(tmpdir): t = Table() - t.add_column(Column('a', [1,2,3])) - t.add_column(Column('b', ['a', 'b', 'c'])) + t.add_column(Column(name='a', data=[1,2,3])) + t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.tex")) t.write(path, format='latex') def test_write_latex_noformat(tmpdir): t = Table() - t.add_column(Column('a', [1,2,3])) - t.add_column(Column('b', ['a', 'b', 'c'])) + t.add_column(Column(name='a', data=[1,2,3])) + t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.tex")) t.write(path) @@ -71,15 +71,15 @@ def test_read_rdb_noformat(): def test_write_rdb(tmpdir): t = Table() - t.add_column(Column('a', [1,2,3])) - t.add_column(Column('b', ['a', 'b', 'c'])) + t.add_column(Column(name='a', data=[1,2,3])) + t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.rdb")) t.write(path, format='rdb') def test_write_rdb_noformat(tmpdir): t = Table() - t.add_column(Column('a', [1,2,3])) - t.add_column(Column('b', ['a', 'b', 'c'])) + t.add_column(Column(name='a', data=[1,2,3])) + t.add_column(Column(name='b', data=['a', 'b', 'c'])) path = str(tmpdir.join("data.rdb")) t.write(path) diff --git a/astropy/table/tests/test_column.py b/astropy/table/tests/test_column.py index 3b59b04af78..a4fd4ec7449 100644 --- a/astropy/table/tests/test_column.py +++ b/astropy/table/tests/test_column.py @@ -17,10 +17,10 @@ def Column(request): class TestColumn(): def test_1(self, Column): - Column('a') + Column(name='a') def test_subclass(self, Column): - c = Column('a') + c = Column(name='a') assert isinstance(c, np.ndarray) c2 = c * 2 assert isinstance(c2, Column) @@ -30,7 +30,7 @@ def test_numpy_ops(self, Column): """Show that basic numpy operations with Column behave sensibly""" arr = np.array([1, 2, 3]) - c = Column('a', arr) + c = Column(name='a', data=arr) eq = c == arr assert np.all(eq) assert len(eq) == 3 @@ -64,7 +64,7 @@ def test_format(self, Column): table.pprint.MAX_LINES.set(MAX_LINES_val) def test_convert_numpy_array(self, Column): - d = Column('a', [1, 2, 3], dtype='i8') + d = Column(name='a', data=[1, 2, 3], dtype='i8') np_data = np.array(d) assert np.all(np_data == d) @@ -74,7 +74,7 @@ def test_convert_numpy_array(self, Column): assert np.all(np_data == d) def test_convert_units(self, Column): - d = Column('a', [1, 2, 3], dtype="f8", units="m") + d = Column(name='a', data=[1, 2, 3], dtype="f8", units="m") d.convert_units_to("km") assert np.all(d.data == [0.001, 0.002, 0.003]) @@ -83,7 +83,7 @@ def test_array_wrap(self): output that has a different shape into an ndarray view. Without this a method call like c.mean() returns a Column array object with length=1.""" # Mean and sum for a 1-d float column - c = table.Column('a', [1., 2., 3.]) + c = table.Column(name='a', data=[1., 2., 3.]) assert np.allclose(c.mean(), 2.0) assert isinstance(c.mean(), (np.floating, float)) assert np.allclose(c.sum(), 6.) @@ -93,13 +93,13 @@ def test_array_wrap(self): assert isinstance(np.cos(c), table.Column) # Sum for a 1-d int column - c = table.Column('a', [1, 2, 3]) + c = table.Column(name='a', data=[1, 2, 3]) assert np.allclose(c.sum(), 6) assert isinstance(c.sum(), (np.integer, int)) # Sum for a 2-d int column - c = table.Column('a', [[1, 2, 3], - [4, 5, 6]]) + c = table.Column(name='a', data=[[1, 2, 3], + [4, 5, 6]]) assert c.sum() == 21 assert isinstance(c.sum(), (np.integer, int)) assert np.all(c.sum(axis=0) == [5, 7, 9]) @@ -108,7 +108,7 @@ def test_array_wrap(self): if not numpy_lt_1p5: # Sum and mean for a 1-d masked column - c = table.MaskedColumn('a', [1., 2., 3.], mask=[0, 0, 1]) + c = table.MaskedColumn(name='a', data=[1., 2., 3.], mask=[0, 0, 1]) assert np.allclose(c.mean(), 1.5) assert isinstance(c.mean(), (np.floating, float)) assert np.allclose(c.sum(), 3.) diff --git a/astropy/table/tests/test_init_table.py b/astropy/table/tests/test_init_table.py index 116faec7367..3c415d05eef 100644 --- a/astropy/table/tests/test_init_table.py +++ b/astropy/table/tests/test_init_table.py @@ -123,7 +123,7 @@ class TestInitFromListOfLists(BaseInitFromListLike): def setup_method(self, method): self.data = [(np.int32(1), np.int32(3)), - Column('col1', [2, 4], dtype=np.int32), + Column(name='col1', data=[2, 4], dtype=np.int32), np.array([3, 5], dtype=np.int32)] def test_default_names(self): @@ -150,7 +150,7 @@ def test_bad_data(self): class TestInitFromColsList(BaseInitFromListLike): def setup_method(self, method): - self.data = [Column('x', [1, 3], dtype=np.int32), + self.data = [Column(name='x', data=[1, 3], dtype=np.int32), np.array([2, 4], dtype=np.int32), np.array([3, 5], dtype='i8')] @@ -212,7 +212,7 @@ def test_partial_names_ref(self): class TestInitFromDict(BaseInitFromDictLike): def setup_method(self, method): - self.data = dict([('a', Column('x', [1, 3])), + self.data = dict([('a', Column(name='x', data=[1, 3])), ('b', [2, 4]), ('c', np.array([3, 5], dtype='i8'))]) @@ -221,7 +221,7 @@ def setup_method(self, method): class TestInitFromOrderedDict(BaseInitFromDictLike): def setup_method(self, method): - self.data = OrderedDict([('a', Column('x', [1, 3])), + self.data = OrderedDict([('a', Column(name='x', data=[1, 3])), ('b', [2, 4]), ('c', np.array([3, 5], dtype='i8'))]) diff --git a/astropy/table/tests/test_item_access.py b/astropy/table/tests/test_item_access.py index 9d7aad9b1fa..de98b6d1177 100644 --- a/astropy/table/tests/test_item_access.py +++ b/astropy/table/tests/test_item_access.py @@ -31,11 +31,11 @@ def set_global_Table_DATA(request): Table = MaskedTable if request.param else table.Table Column = table.MaskedColumn if request.param else table.Column - COLS = [Column('a', [1, 2, 3], description='da', + COLS = [Column(name='a', data=[1, 2, 3], description='da', format='fa', meta={'ma': 1}, units='ua'), - Column('b', [4, 5, 6], description='db', + Column(name='b', data=[4, 5, 6], description='db', format='fb', meta={'mb': 1}, units='ub'), - Column('c', [7, 8, 9], description='dc', + Column(name='c', data=[7, 8, 9], description='dc', format='fc', meta={'mc': 1}, units='ub')] DATA = Table(COLS) diff --git a/astropy/table/tests/test_masked.py b/astropy/table/tests/test_masked.py index f48790c06a9..d671b71a201 100644 --- a/astropy/table/tests/test_masked.py +++ b/astropy/table/tests/test_masked.py @@ -13,13 +13,13 @@ class SetupData(object): def setup_method(self, method): - self.a = MaskedColumn('a', [1, 2, 3], fill_value=1) - self.b = MaskedColumn('b', [4, 5, 6], mask=True) - self.c = MaskedColumn('c', [7, 8, 9], mask=False) + self.a = MaskedColumn(name='a', data=[1, 2, 3], fill_value=1) + self.b = MaskedColumn(name='b', data=[4, 5, 6], mask=True) + self.c = MaskedColumn(name='c', data=[7, 8, 9], mask=False) self.d_mask = np.array([False, True, False]) - self.d = MaskedColumn('d', [7, 8, 7], mask=self.d_mask) + self.d = MaskedColumn(name='d', data=[7, 8, 7], mask=self.d_mask) self.t = Table([self.a, self.b], masked=True) - self.ca = Column('ca', [1, 2, 3]) + self.ca = Column(name='ca', data=[1, 2, 3]) @pytest.mark.xfail('numpy_lt_1p5') @@ -34,9 +34,9 @@ class TestFilled(object): def setup_method(self, method): mask = [True, False, False] self.meta = {'a': 1, 'b': [2, 3]} - a = self.a = MaskedColumn('a', [1, 2, 3], fill_value=10, mask=mask, meta={'a': 1}) - b = self.b = MaskedColumn('b', [4.0, 5.0, 6.0], fill_value=10.0, mask=mask) - c = self.c = MaskedColumn('c', ['7', '8', '9'], fill_value='1', mask=mask) + a = self.a = MaskedColumn(name='a', data=[1, 2, 3], fill_value=10, mask=mask, meta={'a': 1}) + b = self.b = MaskedColumn(name='b', data=[4.0, 5.0, 6.0], fill_value=10.0, mask=mask) + c = self.c = MaskedColumn(name='c', data=['7', '8', '9'], fill_value='1', mask=mask) def test_filled_column(self): f = self.a.filled() @@ -103,7 +103,7 @@ class TestFillValue(SetupData): def test_init_set_fill_value(self): """Check that setting fill_value in the MaskedColumn init works""" assert self.a.fill_value == 1 - c = MaskedColumn('c', ['xxxx', 'yyyy'], fill_value='none') + c = MaskedColumn(name='c', data=['xxxx', 'yyyy'], fill_value='none') assert c.fill_value == 'none' def test_set_get_fill_value_for_bare_column(self): @@ -113,7 +113,7 @@ def test_set_get_fill_value_for_bare_column(self): assert np.all(self.d.filled() == [7, -999, 7]) def test_set_get_fill_value_for_str_column(self): - c = MaskedColumn('c', ['xxxx', 'yyyy'], mask=[True, False]) + c = MaskedColumn(name='c', data=['xxxx', 'yyyy'], mask=[True, False]) # assert np.all(c.filled() == ['N/A', 'yyyy']) c.fill_value = 'ABCDEF' assert c.fill_value == 'ABCD' # string truncated to dtype length @@ -156,19 +156,19 @@ def test_set_mask_and_not_ref(self): def test_set_mask_from_list(self): """Set mask from a list""" mask_list = [False, True, False] - a = MaskedColumn('a', [1, 2, 3], mask=mask_list) + a = MaskedColumn(name='a', data=[1, 2, 3], mask=mask_list) assert np.all(a.mask == mask_list) def test_override_existing_mask(self): """Override existing mask values""" mask_list = [False, True, False] - b = MaskedColumn('b', self.b, mask=mask_list) + b = MaskedColumn(name='b', data=self.b, mask=mask_list) assert np.all(b.mask == mask_list) def test_incomplete_mask_spec(self): """Incomplete mask specification (mask values cycle through available)""" mask_list = [False, True] - b = MaskedColumn('b', length=4, mask=mask_list) + b = MaskedColumn(name='b', length=4, mask=mask_list) assert np.all(b.mask == mask_list + mask_list) @@ -204,9 +204,9 @@ class TestAddColumn(object): def test_add_masked_column_to_masked_table(self): t = Table(masked=True) assert t.masked - t.add_column(MaskedColumn('a', [1,2,3], mask=[0,1,0])) + t.add_column(MaskedColumn(name='a', data=[1,2,3], mask=[0,1,0])) assert t.masked - t.add_column(MaskedColumn('b', [4,5,6], mask=[1,0,1])) + t.add_column(MaskedColumn(name='b', data=[4,5,6], mask=[1,0,1])) assert t.masked assert np.all(t['a'] == np.array([1,2,3])) assert np.all(t['a'].mask == np.array([0,1,0], bool)) @@ -216,9 +216,9 @@ def test_add_masked_column_to_masked_table(self): def test_add_masked_column_to_non_masked_table(self): t = Table(masked=False) assert not t.masked - t.add_column(Column('a', [1,2,3])) + t.add_column(Column(name='a', data=[1,2,3])) assert not t.masked - t.add_column(MaskedColumn('b', [4,5,6], mask=[1,0,1])) + t.add_column(MaskedColumn(name='b', data=[4,5,6], mask=[1,0,1])) assert t.masked assert np.all(t['a'] == np.array([1,2,3])) assert np.all(t['a'].mask == np.array([0,0,0], bool)) @@ -228,9 +228,9 @@ def test_add_masked_column_to_non_masked_table(self): def test_add_non_masked_column_to_masked_table(self): t = Table(masked=True) assert t.masked - t.add_column(Column('a', [1,2,3])) + t.add_column(Column(name='a', data=[1,2,3])) assert t.masked - t.add_column(MaskedColumn('b', [4,5,6], mask=[1,0,1])) + t.add_column(MaskedColumn(name='b', data=[4,5,6], mask=[1,0,1])) assert t.masked assert np.all(t['a'] == np.array([1,2,3])) assert np.all(t['a'].mask == np.array([0,0,0], bool)) @@ -243,8 +243,8 @@ class TestAddRow(object): def test_add_masked_row_to_masked_table_iterable(self): t = Table(masked=True) - t.add_column(MaskedColumn('a', [1], mask=[0])) - t.add_column(MaskedColumn('b', [4], mask=[1])) + t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) + t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) t.add_row([2,5], mask=[1,0]) t.add_row([3,6], mask=[0,1]) assert t.masked @@ -255,8 +255,8 @@ def test_add_masked_row_to_masked_table_iterable(self): def test_add_masked_row_to_masked_table_mapping1(self): t = Table(masked=True) - t.add_column(MaskedColumn('a', [1], mask=[0])) - t.add_column(MaskedColumn('b', [4], mask=[1])) + t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) + t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) t.add_row({'b':5, 'a':2}, mask={'a':1, 'b':0}) t.add_row({'a':3, 'b':6}, mask={'b':1, 'a':0}) assert t.masked @@ -269,8 +269,8 @@ def test_add_masked_row_to_masked_table_mapping2(self): # When adding values to a masked table, if the mask is specified as a # dict, then values not specified will have mask values set to True t = Table(masked=True) - t.add_column(MaskedColumn('a', [1], mask=[0])) - t.add_column(MaskedColumn('b', [4], mask=[1])) + t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) + t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) t.add_row({'b':5}, mask={'b':0}) t.add_row({'a':3}, mask={'a':0}) assert t.masked @@ -284,8 +284,8 @@ def test_add_masked_row_to_masked_table_mapping3(self): # add_row, then the mask should be set to False if values are present # and True if not. t = Table(masked=True) - t.add_column(MaskedColumn('a', [1], mask=[0])) - t.add_column(MaskedColumn('b', [4], mask=[1])) + t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) + t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) t.add_row({'b':5}) t.add_row({'a':3}) assert t.masked @@ -298,16 +298,16 @@ def test_add_masked_row_to_masked_table_mapping4(self): # When adding values to a masked table, if the mask is specified as a # dict, then keys in values should match keys in mask t = Table(masked=True) - t.add_column(MaskedColumn('a', [1], mask=[0])) - t.add_column(MaskedColumn('b', [4], mask=[1])) + t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) + t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) with pytest.raises(ValueError) as exc: t.add_row({'b':5}, mask={'a':True}) assert exc.value.args[0] == 'keys in mask should match keys in vals' def test_add_masked_row_to_masked_table_mismatch(self): t = Table(masked=True) - t.add_column(MaskedColumn('a', [1], mask=[0])) - t.add_column(MaskedColumn('b', [4], mask=[1])) + t.add_column(MaskedColumn(name='a', data=[1], mask=[0])) + t.add_column(MaskedColumn(name='b', data=[4], mask=[1])) with pytest.raises(TypeError) as exc: t.add_row([2,5], mask={'a':1, 'b':0}) assert exc.value.args[0] == "Mismatch between type of vals and mask" @@ -317,8 +317,8 @@ def test_add_masked_row_to_masked_table_mismatch(self): def test_add_masked_row_to_non_masked_table_iterable(self): t = Table(masked=False) - t.add_column(Column('a', [1])) - t.add_column(Column('b', [4])) + t.add_column(Column(name='a', data=[1])) + t.add_column(Column(name='b', data=[4])) assert not t.masked t.add_row([2,5]) assert not t.masked diff --git a/astropy/table/tests/test_row.py b/astropy/table/tests/test_row.py index 3ef8eb8e465..507e9eb1a56 100644 --- a/astropy/table/tests/test_row.py +++ b/astropy/table/tests/test_row.py @@ -39,8 +39,8 @@ def t(self): if Column is None: return None if not hasattr(self, '_t'): - a = Column('a', [1, 2, 3], dtype='i8') - b = Column('b', [4, 5, 6], dtype='i8') + a = Column(name='a', data=[1, 2, 3], dtype='i8') + b = Column(name='b', data=[4, 5, 6], dtype='i8') self._t = Table([a, b]) return self._t diff --git a/astropy/table/tests/test_table.py b/astropy/table/tests/test_table.py index 8800db2a92f..95259f64886 100644 --- a/astropy/table/tests/test_table.py +++ b/astropy/table/tests/test_table.py @@ -33,28 +33,28 @@ class SetupData(object): def a(self): if Column is not None: if not hasattr(self, '_a'): - self._a = Column('a', [1, 2, 3], meta={'aa': np.arange(5)}) + self._a = Column(name='a', data=[1, 2, 3], meta={'aa': np.arange(5)}) return self._a @property def b(self): if Column is not None: if not hasattr(self, '_b'): - self._b = Column('b', [4, 5, 6]) + self._b = Column(name='b', data=[4, 5, 6]) return self._b @property def c(self): if Column is not None: if not hasattr(self, '_c'): - self._c = Column('c', [7, 8, 9]) + self._c = Column(name='c', data=[7, 8, 9]) return self._c @property def d(self): if Column is not None: if not hasattr(self, '_d'): - self._d = Column('d', [7, 8, 7]) + self._d = Column(name='d', data=[7, 8, 7]) return self._d @property @@ -70,27 +70,27 @@ class TestEmptyData(): def test_1(self): t = Table() - t.add_column(Column('a', dtype=int, length=100)) + t.add_column(Column(name='a', dtype=int, length=100)) assert len(t['a']) == 100 def test_2(self): t = Table() - t.add_column(Column('a', dtype=int, shape=(3, ), length=100)) + t.add_column(Column(name='a', dtype=int, shape=(3, ), length=100)) assert len(t['a']) == 100 def test_3(self): t = Table() # length is not given - t.add_column(Column('a', dtype=int)) + t.add_column(Column(name='a', dtype=int)) assert len(t['a']) == 0 def test_4(self): t = Table() # length is not given - t.add_column(Column('a', dtype=int, shape=(3, 4))) + t.add_column(Column(name='a', dtype=int, shape=(3, 4))) assert len(t['a']) == 0 def test_5(self): t = Table() - t.add_column(Column('a')) # dtype is not specified + t.add_column(Column(name='a')) # dtype is not specified assert len(t['a']) == 0 @@ -98,17 +98,17 @@ def test_5(self): class TestNewFromColumns(): def test_simple(self): - cols = [Column('a', [1, 2, 3]), - Column('b', [4, 5, 6], dtype=np.float32)] + cols = [Column(name='a', data=[1, 2, 3]), + Column(name='b', data=[4, 5, 6], dtype=np.float32)] t = Table(cols) assert np.all(t['a'].data == np.array([1, 2, 3])) assert np.all(t['b'].data == np.array([4, 5, 6], dtype=np.float32)) assert type(t['b'][1]) == np.float32 def test_from_np_array(self): - cols = [Column('a', np.array([1, 2, 3], dtype=np.int64), + cols = [Column(name='a', data=np.array([1, 2, 3], dtype=np.int64), dtype=np.float64), - Column('b', np.array([4, 5, 6], dtype=np.float32))] + Column(name='b', data=np.array([4, 5, 6], dtype=np.float32))] t = Table(cols) assert np.all(t['a'] == np.array([1, 2, 3], dtype=np.float64)) assert np.all(t['b'] == np.array([4, 5, 6], dtype=np.float32)) @@ -116,8 +116,8 @@ def test_from_np_array(self): assert type(t['b'][1]) == np.float32 def test_size_mismatch(self): - cols = [Column('a', [1, 2, 3]), - Column('b', [4, 5, 6, 7])] + cols = [Column(name='a', data=[1, 2, 3]), + Column(name='b', data=[4, 5, 6, 7])] with pytest.raises(ValueError): Table(cols) @@ -162,7 +162,7 @@ def test_1(self): def test_2(self): t = Table() - t.add_column(Column('a', [1, 2, 3])) + t.add_column(Column(name='a', data=[1, 2, 3])) assert np.all(t['a'] == np.array([1, 2, 3])) with pytest.raises(KeyError): t['b'] # column does not exist @@ -178,12 +178,12 @@ def test_right_length(self): def test_too_long(self): t = Table([self.a]) with pytest.raises(ValueError): - t.add_column(Column('b', [4, 5, 6, 7])) # data too long + t.add_column(Column(name='b', data=[4, 5, 6, 7])) # data too long def test_too_short(self): t = Table([self.a]) with pytest.raises(ValueError): - t.add_column(Column('b', [4, 5])) # data too short + t.add_column(Column(name='b', data=[4, 5])) # data too short @pytest.mark.usefixtures('set_global_Table') @@ -306,7 +306,7 @@ def test_add_duplicate_column(self): t = Table() t.add_column(self.a) with pytest.raises(ValueError): - t.add_column(Column('a', [0, 1, 2])) + t.add_column(Column(name='a', data=[0, 1, 2])) t.add_column(self.b) t.add_column(self.c) assert t.colnames == ['a', 'b', 'c'] @@ -314,7 +314,7 @@ def test_add_duplicate_column(self): def test_add_duplicate_columns(self): t = Table([self.a, self.b, self.c]) with pytest.raises(ValueError): - t.add_columns([Column('a', [0, 1, 2]), Column('b', [0, 1, 2])]) + t.add_columns([Column(name='a', data=[0, 1, 2]), Column(name='b', data=[0, 1, 2])]) t.add_column(self.d) assert t.colnames == ['a', 'b', 'c', 'd'] @@ -326,14 +326,14 @@ class TestAddRow(SetupData): def b(self): if Column is not None: if not hasattr(self, '_b'): - self._b = Column('b', [4.0, 5.1, 6.2]) + self._b = Column(name='b', data=[4.0, 5.1, 6.2]) return self._b @property def c(self): if Column is not None: if not hasattr(self, '_c'): - self._c = Column('c', ['7', '8', '9']) + self._c = Column(name='c', data=['7', '8', '9']) return self._c @property @@ -432,14 +432,14 @@ def test_column_view(self): class TestArrayColumns(SetupData): def test_1d(self): - b = Column('b', dtype=int, shape=(2, ), length=3) + b = Column(name='b', dtype=int, shape=(2, ), length=3) t = Table([self.a]) t.add_column(b) assert t['b'].shape == (3, 2) assert t['b'][0].shape == (2, ) def test_2d(self): - b = Column('b', dtype=int, shape=(2, 4), length=3) + b = Column(name='b', dtype=int, shape=(2, 4), length=3) t = Table([self.a]) t.add_column(b) assert t['b'].shape == (3, 2, 4) @@ -447,7 +447,7 @@ def test_2d(self): def test_3d(self): t = Table([self.a]) - b = Column('b', dtype=int, shape=(2, 4, 6), length=3) + b = Column(name='b', dtype=int, shape=(2, 4, 6), length=3) t.add_column(b) assert t['b'].shape == (3, 2, 4, 6) assert t['b'][0].shape == (2, 4, 6) @@ -551,8 +551,8 @@ class TestSort(): def test_single(self): t = Table() - t.add_column(Column('a', [2, 1, 3])) - t.add_column(Column('b', [6, 5, 4])) + t.add_column(Column(name='a', data=[2, 1, 3])) + t.add_column(Column(name='b', data=[6, 5, 4])) assert np.all(t['a'] == np.array([2, 1, 3])) assert np.all(t['b'] == np.array([6, 5, 4])) t.sort('a') @@ -564,8 +564,8 @@ def test_single(self): def test_multiple(self): t = Table() - t.add_column(Column('a', [2, 1, 3, 2, 3, 1])) - t.add_column(Column('b', [6, 5, 4, 3, 5, 4])) + t.add_column(Column(name='a', data=[2, 1, 3, 2, 3, 1])) + t.add_column(Column(name='b', data=[6, 5, 4, 3, 5, 4])) assert np.all(t['a'] == np.array([2, 1, 3, 2, 3, 1])) assert np.all(t['b'] == np.array([6, 5, 4, 3, 5, 4])) t.sort(['a', 'b']) From f91436c1e9eb9be63b36859a4b276bd5eba54bc8 Mon Sep 17 00:00:00 2001 From: Tom Aldcroft Date: Thu, 7 Feb 2013 11:36:07 -0500 Subject: [PATCH 7/7] Pay attention to WARN_COLUMN_ARGS for issuing the args order warning --- astropy/table/__init__.py | 4 ++-- astropy/table/table.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/astropy/table/__init__.py b/astropy/table/__init__.py index 92d7ba677dd..6353a4ff2ed 100644 --- a/astropy/table/__init__.py +++ b/astropy/table/__init__.py @@ -1,7 +1,7 @@ # Licensed under a 3-clause BSD style license - see LICENSE.rst -from .table import Column, Table, TableColumns, Row, MaskedColumn +from .table import Column, Table, TableColumns, Row, MaskedColumn, WARN_COLUMN_ARGS # Import routines that connect readers/writers to astropy.table from ..io.ascii import connect from ..io.misc import connect -from ..io.votable import connect \ No newline at end of file +from ..io.votable import connect diff --git a/astropy/table/table.py b/astropy/table/table.py index 435a3a315ea..06321799b04 100644 --- a/astropy/table/table.py +++ b/astropy/table/table.py @@ -53,7 +53,7 @@ def _check_column_new_args(func): """ @functools.wraps(func) def wrapper(*args, **kwargs): - if len(args) > 1: + if len(args) > 1 and WARN_COLUMN_ARGS(): cls = args[0] # Column or MaskedColumn class from __new__(cls, ..) warnings.warn(WARN_COLUMN_ARGS_MESSAGE.format(class_name=cls.__name__)) return func(*args, **kwargs)