Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xlsxwriter, Py27 and Linux Failure on to_excel with Timedelta #19911

Closed
WillAyd opened this issue Feb 26, 2018 · 2 comments · Fixed by #19921
Closed

Xlsxwriter, Py27 and Linux Failure on to_excel with Timedelta #19911

WillAyd opened this issue Feb 26, 2018 · 2 comments · Fixed by #19921
Labels
IO Excel read_excel, to_excel Timedelta Timedelta data type
Milestone

Comments

@WillAyd
Copy link
Member

WillAyd commented Feb 26, 2018

See this comment in #19829. The test to write Timedelta data to an excel file is failing only with the combination of xlsxwriter as the engine using Py27 and on Linux. All other engines (save openpyxl which has an issue referenced in #19900), Python versions and OSes appear to work, but this particular combination kept failing on Travis.

Need help from someone running Linux to debug further. Right now the test cases are imperatively skipping this combination:

if engine == 'xlsxwriter' and (sys.version_info[0] == 2 and

Here's the Travis build that was failing and I've provided the traceback of the test below for reference

=================================== FAILURES ===================================
�[31m�[1m________ TestExcelWriter.test_to_excel_timedelta[xlsxwriter-.xlsx-True] ________�[0m
[gw0] linux2 -- Python 2.7.14 /home/travis/miniconda3/envs/pandas/bin/python

self = <pandas.tests.io.test_excel.TestExcelWriter object at 0x7f44821a0b50>
merge_cells = True, engine = 'xlsxwriter', ext = '.xlsx'

�[1m    def test_to_excel_timedelta(self, merge_cells, engine, ext):�[0m
�[1m        # GH 19242, GH9155 - test writing timedelta to xls�[0m
�[1m        if engine == 'openpyxl':�[0m
�[1m            pytest.xfail('Timedelta roundtrip broken with openpyxl')�[0m
�[1m        frame = DataFrame(np.random.randint(-10, 10, size=(20, 1)),�[0m
�[1m                          columns=['A'],�[0m
�[1m                          dtype=np.int64�[0m
�[1m                          )�[0m
�[1m        expected = frame.copy()�[0m
�[1m        frame['new'] = frame['A'].apply(lambda x: timedelta(seconds=x))�[0m
�[1m        expected['new'] = expected['A'].apply(�[0m
�[1m            lambda x: timedelta(seconds=x).total_seconds() / float(86400))�[0m
�[1m>       frame.to_excel(self.path, 'test1')�[0m

�[31m�[1mpandas/tests/io/test_excel.py�[0m:1384: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
�[31m�[1mpandas/core/frame.py�[0m:1599: in to_excel
�[1m    engine=engine)�[0m
�[31m�[1mpandas/io/formats/excel.py�[0m:652: in write
�[1m    freeze_panes=freeze_panes)�[0m
�[31m�[1mpandas/io/excel.py�[0m:1772: in write_cells
�[1m    val, style)�[0m
�[31m�[1m../../../miniconda3/envs/pandas/lib/python2.7/site-packages/xlsxwriter/worksheet.py�[0m:57: in cell_wrapper
�[1m    return method(self, *args, **kwargs)�[0m
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <xlsxwriter.worksheet.Worksheet object at 0x7f44821a04d0>, row = 1
col = 2, args = (Timedelta('-1 days +23:59:52'), None)
token = Timedelta('-1 days +23:59:52')
num_types = (<type 'float'>, <type 'int'>, <type 'long'>, <class 'decimal.Decimal'>, <class 'fractions.Fraction'>)
str_types = <type 'basestring'>

�[1m    @convert_cell_args�[0m
�[1m    def write(self, row, col, *args):�[0m
�[1m        """�[0m
�[1m            Write data to a worksheet cell by calling the appropriate write_*()�[0m
�[1m            method based on the type of data being passed.�[0m
�[1m    �[0m
�[1m            Args:�[0m
�[1m                row:   The cell row (zero indexed).�[0m
�[1m                col:   The cell column (zero indexed).�[0m
�[1m                *args: Args to pass to sub functions.�[0m
�[1m    �[0m
�[1m            Returns:�[0m
�[1m                 0:    Success.�[0m
�[1m                -1:    Row or column is out of worksheet bounds.�[0m
�[1m                other: Return value of called method.�[0m
�[1m    �[0m
�[1m            """�[0m
�[1m        # Check the number of args passed.�[0m
�[1m        if not len(args):�[0m
�[1m            raise TypeError("write() takes at least 4 arguments (3 given)")�[0m
�[1m    �[0m
�[1m        # The first arg should be the token for all write calls.�[0m
�[1m        token = args[0]�[0m
�[1m    �[0m
�[1m        # Types to check in Python 2/3.�[0m
�[1m        if sys.version_info[0] == 2:�[0m
�[1m            num_types = (float, int, long, Decimal, Fraction)�[0m
�[1m            str_types = basestring�[0m
�[1m            date_types = (datetime.datetime, datetime.date, datetime.time)�[0m
�[1m        else:�[0m
�[1m            num_types = (float, int, Decimal, Fraction)�[0m
�[1m            str_types = str�[0m
�[1m            date_types = (datetime.datetime, datetime.date, datetime.time)�[0m
�[1m    �[0m
�[1m        # Write None as a blank cell.�[0m
�[1m        if token is None:�[0m
�[1m            return self.write_blank(row, col, *args)�[0m
�[1m    �[0m
�[1m        # Write boolean types.�[0m
�[1m        if isinstance(token, bool):�[0m
�[1m            return self.write_boolean(row, col, *args)�[0m
�[1m    �[0m
�[1m        # Write datetime objects.�[0m
�[1m        if isinstance(token, date_types):�[0m
�[1m            return self.write_datetime(row, col, *args)�[0m
�[1m    �[0m
�[1m        # Write number types.�[0m
�[1m        if isinstance(token, num_types):�[0m
�[1m            return self.write_number(row, col, *args)�[0m
�[1m    �[0m
�[1m        # Write string types.�[0m
�[1m        if isinstance(token, str_types):�[0m
�[1m            # Map the data to the appropriate write_*() method.�[0m
�[1m            if token == '':�[0m
�[1m                return self.write_blank(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_formulas and token.startswith('='):�[0m
�[1m                return self.write_formula(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_urls and re.match('(ftp|http)s?://', token):�[0m
�[1m                return self.write_url(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_urls and re.match('mailto:', token):�[0m
�[1m                return self.write_url(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_urls and re.match('(in|ex)ternal:', token):�[0m
�[1m                return self.write_url(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_numbers:�[0m
�[1m                try:�[0m
�[1m                    f = float(token)�[0m
�[1m                    if not self._isnan(f) and not self._isinf(f):�[0m
�[1m                        return self.write_number(row, col, f, *args[1:])�[0m
�[1m                except ValueError:�[0m
�[1m                    # Not a number, write as a string.�[0m
�[1m                    pass�[0m
�[1m    �[0m
�[1m                return self.write_string(row, col, *args)�[0m
�[1m    �[0m
�[1m            else:�[0m
�[1m                # We have a plain string.�[0m
�[1m                return self.write_string(row, col, *args)�[0m
�[1m    �[0m
�[1m        # We haven't matched a supported type. Try float.�[0m
�[1m        try:�[0m
�[1m>           f = float(token)�[0m
�[31m�[1mE           TypeError: float() argument must be a string or a number�[0m

�[31m�[1m../../../miniconda3/envs/pandas/lib/python2.7/site-packages/xlsxwriter/worksheet.py�[0m:417: TypeError
�[31m�[1m_______ TestExcelWriter.test_to_excel_timedelta[xlsxwriter-.xlsx-False] ________�[0m
[gw0] linux2 -- Python 2.7.14 /home/travis/miniconda3/envs/pandas/bin/python

self = <pandas.tests.io.test_excel.TestExcelWriter object at 0x7f4481b83750>
merge_cells = False, engine = 'xlsxwriter', ext = '.xlsx'

�[1m    def test_to_excel_timedelta(self, merge_cells, engine, ext):�[0m
�[1m        # GH 19242, GH9155 - test writing timedelta to xls�[0m
�[1m        if engine == 'openpyxl':�[0m
�[1m            pytest.xfail('Timedelta roundtrip broken with openpyxl')�[0m
�[1m        frame = DataFrame(np.random.randint(-10, 10, size=(20, 1)),�[0m
�[1m                          columns=['A'],�[0m
�[1m                          dtype=np.int64�[0m
�[1m                          )�[0m
�[1m        expected = frame.copy()�[0m
�[1m        frame['new'] = frame['A'].apply(lambda x: timedelta(seconds=x))�[0m
�[1m        expected['new'] = expected['A'].apply(�[0m
�[1m            lambda x: timedelta(seconds=x).total_seconds() / float(86400))�[0m
�[1m>       frame.to_excel(self.path, 'test1')�[0m

�[31m�[1mpandas/tests/io/test_excel.py�[0m:1384: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
�[31m�[1mpandas/core/frame.py�[0m:1599: in to_excel
�[1m    engine=engine)�[0m
�[31m�[1mpandas/io/formats/excel.py�[0m:652: in write
�[1m    freeze_panes=freeze_panes)�[0m
�[31m�[1mpandas/io/excel.py�[0m:1772: in write_cells
�[1m    val, style)�[0m
�[31m�[1m../../../miniconda3/envs/pandas/lib/python2.7/site-packages/xlsxwriter/worksheet.py�[0m:57: in cell_wrapper
�[1m    return method(self, *args, **kwargs)�[0m
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <xlsxwriter.worksheet.Worksheet object at 0x7f4481a754d0>, row = 1
col = 2, args = (Timedelta('-1 days +23:59:54'), None)
token = Timedelta('-1 days +23:59:54')
num_types = (<type 'float'>, <type 'int'>, <type 'long'>, <class 'decimal.Decimal'>, <class 'fractions.Fraction'>)
str_types = <type 'basestring'>

�[1m    @convert_cell_args�[0m
�[1m    def write(self, row, col, *args):�[0m
�[1m        """�[0m
�[1m            Write data to a worksheet cell by calling the appropriate write_*()�[0m
�[1m            method based on the type of data being passed.�[0m
�[1m    �[0m
�[1m            Args:�[0m
�[1m                row:   The cell row (zero indexed).�[0m
�[1m                col:   The cell column (zero indexed).�[0m
�[1m                *args: Args to pass to sub functions.�[0m
�[1m    �[0m
�[1m            Returns:�[0m
�[1m                 0:    Success.�[0m
�[1m                -1:    Row or column is out of worksheet bounds.�[0m
�[1m                other: Return value of called method.�[0m
�[1m    �[0m
�[1m            """�[0m
�[1m        # Check the number of args passed.�[0m
�[1m        if not len(args):�[0m
�[1m            raise TypeError("write() takes at least 4 arguments (3 given)")�[0m
�[1m    �[0m
�[1m        # The first arg should be the token for all write calls.�[0m
�[1m        token = args[0]�[0m
�[1m    �[0m
�[1m        # Types to check in Python 2/3.�[0m
�[1m        if sys.version_info[0] == 2:�[0m
�[1m            num_types = (float, int, long, Decimal, Fraction)�[0m
�[1m            str_types = basestring�[0m
�[1m            date_types = (datetime.datetime, datetime.date, datetime.time)�[0m
�[1m        else:�[0m
�[1m            num_types = (float, int, Decimal, Fraction)�[0m
�[1m            str_types = str�[0m
�[1m            date_types = (datetime.datetime, datetime.date, datetime.time)�[0m
�[1m    �[0m
�[1m        # Write None as a blank cell.�[0m
�[1m        if token is None:�[0m
�[1m            return self.write_blank(row, col, *args)�[0m
�[1m    �[0m
�[1m        # Write boolean types.�[0m
�[1m        if isinstance(token, bool):�[0m
�[1m            return self.write_boolean(row, col, *args)�[0m
�[1m    �[0m
�[1m        # Write datetime objects.�[0m
�[1m        if isinstance(token, date_types):�[0m
�[1m            return self.write_datetime(row, col, *args)�[0m
�[1m    �[0m
�[1m        # Write number types.�[0m
�[1m        if isinstance(token, num_types):�[0m
�[1m            return self.write_number(row, col, *args)�[0m
�[1m    �[0m
�[1m        # Write string types.�[0m
�[1m        if isinstance(token, str_types):�[0m
�[1m            # Map the data to the appropriate write_*() method.�[0m
�[1m            if token == '':�[0m
�[1m                return self.write_blank(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_formulas and token.startswith('='):�[0m
�[1m                return self.write_formula(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_urls and re.match('(ftp|http)s?://', token):�[0m
�[1m                return self.write_url(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_urls and re.match('mailto:', token):�[0m
�[1m                return self.write_url(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_urls and re.match('(in|ex)ternal:', token):�[0m
�[1m                return self.write_url(row, col, *args)�[0m
�[1m    �[0m
�[1m            elif self.strings_to_numbers:�[0m
�[1m                try:�[0m
�[1m                    f = float(token)�[0m
�[1m                    if not self._isnan(f) and not self._isinf(f):�[0m
�[1m                        return self.write_number(row, col, f, *args[1:])�[0m
�[1m                except ValueError:�[0m
�[1m                    # Not a number, write as a string.�[0m
�[1m                    pass�[0m
�[1m    �[0m
�[1m                return self.write_string(row, col, *args)�[0m
�[1m    �[0m
�[1m            else:�[0m
�[1m                # We have a plain string.�[0m
�[1m                return self.write_string(row, col, *args)�[0m
�[1m    �[0m
�[1m        # We haven't matched a supported type. Try float.�[0m
�[1m        try:�[0m
�[1m>           f = float(token)�[0m
�[31m�[1mE           TypeError: float() argument must be a string or a number�[0m

�[31m�[1m../../../miniconda3/envs/pandas/lib/python2.7/site-packages/xlsxwriter/worksheet.py�[0m:417: TypeError
@jreback jreback added IO Excel read_excel, to_excel Timedelta Timedelta data type labels Feb 28, 2018
@jreback jreback added this to the 0.23.0 milestone Feb 28, 2018
@jreback
Copy link
Contributor

jreback commented Feb 28, 2018

I closed this, but lmk if fixed

@WillAyd
Copy link
Member Author

WillAyd commented Feb 28, 2018

Yep should be fixed. Could never reproduce this locally anyway but I'm assuming the explicitness of the Timdelta -> float conversion prevented the failure from happening on Travis for all versions / platforms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
IO Excel read_excel, to_excel Timedelta Timedelta data type
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants