55import pandas as pd
66import pandas .io .formats .format as fmt
77
8- import itables .options as opt
8+ try :
9+ import polars as pl
10+ except ImportError :
11+ pl = None
12+
13+
14+ JS_MAX_SAFE_INTEGER = 2 ** 53 - 1
15+ JS_MIN_SAFE_INTEGER = - (2 ** 53 - 1 )
916
1017
1118def _format_column (x ):
@@ -48,7 +55,7 @@ def default(self, obj):
4855 warnings .warn (
4956 "Unexpected type '{}' for '{}'.\n "
5057 "You can report this warning at https://github.com/mwouts/itables/issues\n "
51- "To ignore the warning, please run:\n "
58+ "To silence this warning, please run:\n "
5259 " import itables.options as opt\n "
5360 " opt.warn_on_unexpected_types = False" .format (type (obj ), obj ),
5461 category = RuntimeWarning ,
@@ -58,8 +65,48 @@ def default(self, obj):
5865 return TableValuesEncoder
5966
6067
61- def datatables_rows (df , count = None ):
68+ def convert_bigints_to_str (df , warn_on_int_to_str_conversion ):
69+ """In Javascript, integers have to remain between JS_MIN_SAFE_INTEGER and JS_MAX_SAFE_INTEGER."""
70+ converted = []
71+ for i , col in enumerate (df .columns ):
72+ try :
73+ x = df .iloc [:, i ]
74+ if (
75+ x .dtype .kind == "i"
76+ and (
77+ ~ x .isnull ()
78+ & ((x < JS_MIN_SAFE_INTEGER ) | (x > JS_MAX_SAFE_INTEGER ))
79+ ).any ()
80+ ):
81+ df .iloc [:, i ] = x .astype (str )
82+ converted .append (col )
83+ except AttributeError :
84+ x = df [col ]
85+ if (
86+ x .dtype in pl .INTEGER_DTYPES
87+ and ((x < JS_MIN_SAFE_INTEGER ) | (x > JS_MAX_SAFE_INTEGER )).any ()
88+ ):
89+ df = df .with_columns (pl .col (col ).cast (pl .Utf8 ))
90+ converted .append (col )
91+
92+ if converted and warn_on_int_to_str_conversion :
93+ warnings .warn (
94+ "The columns {} contains integers that are too large for Javascript.\n "
95+ "They have been converted to str.\n "
96+ "To silence this warning, please run:\n "
97+ " import itables.options as opt\n "
98+ " opt.warn_on_int_to_str_conversion = False" .format (converted )
99+ )
100+
101+ return df
102+
103+
104+ def datatables_rows (
105+ df , count = None , warn_on_unexpected_types = False , warn_on_int_to_str_conversion = False
106+ ):
62107 """Format the values in the table and return the data, row by row, as requested by DataTables"""
108+ df = convert_bigints_to_str (df , warn_on_int_to_str_conversion )
109+
63110 # We iterate over columns using an index rather than the column name
64111 # to avoid an issue in case of duplicated column names #89
65112 if count is None or len (df .columns ) == count :
@@ -73,7 +120,7 @@ def datatables_rows(df, count=None):
73120 try :
74121 # Pandas DataFrame
75122 data = list (zip (* (empty_columns + [_format_column (x ) for _ , x in df .items ()])))
76- return json .dumps (data , cls = generate_encoder (opt . warn_on_unexpected_types ))
123+ return json .dumps (data , cls = generate_encoder (warn_on_unexpected_types ))
77124 except AttributeError :
78125 # Polars DataFrame
79126 data = list (df .iter_rows ())
0 commit comments