Skip to content

Commit 2c2d4e7

Browse files
DEPR/TST: correct stacklevels (GH9584)
Only check stacklevel for FutureWarnings/DeprecationWarnings for now
1 parent 1dc619a commit 2c2d4e7

28 files changed

+91
-80
lines changed

pandas/computation/align.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ def _align_core(terms):
101101
'than an order of magnitude on term {1!r}, '
102102
'by more than {2:.4g}; performance may '
103103
'suffer'.format(axis, terms[i].name, ordm),
104-
category=pd.io.common.PerformanceWarning)
104+
category=pd.io.common.PerformanceWarning,
105+
stacklevel=6)
105106

106107
if transpose:
107108
f = partial(ti.reindex, index=reindexer, copy=False)

pandas/computation/pytables.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ def parse_back_compat(self, w, op=None, value=None):
535535
w, op, value = w
536536
warnings.warn("passing a tuple into Expr is deprecated, "
537537
"pass the where as a single string",
538-
DeprecationWarning)
538+
DeprecationWarning, stacklevel=10)
539539

540540
if op is not None:
541541
if not isinstance(w, string_types):

pandas/core/categorical.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ def _get_labels(self):
414414
415415
Deprecated, use .codes!
416416
"""
417-
warn("'labels' is deprecated. Use 'codes' instead", FutureWarning, stacklevel=3)
417+
warn("'labels' is deprecated. Use 'codes' instead", FutureWarning, stacklevel=2)
418418
return self.codes
419419

420420
labels = property(fget=_get_labels, fset=_set_codes)
@@ -456,7 +456,7 @@ def _validate_categories(cls, categories, fastpath=False):
456456
# NaNs in cats deprecated in 0.17, remove in 0.18 or 0.19 GH 10748
457457
msg = ('\nSetting NaNs in `categories` is deprecated and '
458458
'will be removed in a future version of pandas.')
459-
warn(msg, FutureWarning, stacklevel=5)
459+
warn(msg, FutureWarning, stacklevel=3)
460460

461461
# categories must be unique
462462

@@ -491,12 +491,12 @@ def _get_categories(self):
491491

492492
def _set_levels(self, levels):
493493
""" set new levels (deprecated, use "categories") """
494-
warn("Assigning to 'levels' is deprecated, use 'categories'", FutureWarning, stacklevel=3)
494+
warn("Assigning to 'levels' is deprecated, use 'categories'", FutureWarning, stacklevel=2)
495495
self.categories = levels
496496

497497
def _get_levels(self):
498498
""" Gets the levels (deprecated, use "categories") """
499-
warn("Accessing 'levels' is deprecated, use 'categories'", FutureWarning, stacklevel=3)
499+
warn("Accessing 'levels' is deprecated, use 'categories'", FutureWarning, stacklevel=2)
500500
return self.categories
501501

502502
# TODO: Remove after deprecation period in 2017/ after 0.18
@@ -507,7 +507,7 @@ def _get_levels(self):
507507
def _set_ordered(self, value):
508508
""" Sets the ordered attribute to the boolean value """
509509
warn("Setting 'ordered' directly is deprecated, use 'set_ordered'", FutureWarning,
510-
stacklevel=3)
510+
stacklevel=2)
511511
self.set_ordered(value, inplace=True)
512512

513513
def set_ordered(self, value, inplace=False):
@@ -1200,7 +1200,7 @@ def order(self, inplace=False, ascending=True, na_position='last'):
12001200
Category.sort
12011201
"""
12021202
warn("order is deprecated, use sort_values(...)",
1203-
FutureWarning, stacklevel=3)
1203+
FutureWarning, stacklevel=2)
12041204
return self.sort_values(inplace=inplace, ascending=ascending, na_position=na_position)
12051205

12061206
def sort(self, inplace=True, ascending=True, na_position='last'):

pandas/core/frame.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2919,7 +2919,7 @@ def dropna(self, axis=0, how='any', thresh=None, subset=None,
29192919
return result
29202920

29212921
@deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'})
2922-
@deprecate_kwarg(old_arg_name='cols', new_arg_name='subset')
2922+
@deprecate_kwarg(old_arg_name='cols', new_arg_name='subset', stacklevel=3)
29232923
def drop_duplicates(self, subset=None, keep='first', inplace=False):
29242924
"""
29252925
Return DataFrame with duplicate rows removed, optionally only
@@ -2953,7 +2953,7 @@ def drop_duplicates(self, subset=None, keep='first', inplace=False):
29532953
return self[-duplicated]
29542954

29552955
@deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'})
2956-
@deprecate_kwarg(old_arg_name='cols', new_arg_name='subset')
2956+
@deprecate_kwarg(old_arg_name='cols', new_arg_name='subset', stacklevel=3)
29572957
def duplicated(self, subset=None, keep='first'):
29582958
"""
29592959
Return boolean Series denoting duplicate rows, optionally only

pandas/core/generic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ def iterkv(self, *args, **kwargs):
706706
"iteritems alias used to get around 2to3. Deprecated"
707707
warnings.warn("iterkv is deprecated and will be removed in a future "
708708
"release, use ``iteritems`` instead.",
709-
FutureWarning)
709+
FutureWarning, stacklevel=2)
710710
return self.iteritems(*args, **kwargs)
711711

712712
def __len__(self):

pandas/core/index.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -842,14 +842,14 @@ def to_int():
842842
elif is_float(key):
843843
key = to_int()
844844
warnings.warn("scalar indexers for index type {0} should be integers and not floating point".format(
845-
type(self).__name__),FutureWarning, stacklevel=2)
845+
type(self).__name__), FutureWarning, stacklevel=5)
846846
return key
847847
return self._invalid_indexer('label', key)
848848

849849
if is_float(key):
850850
if not self.is_floating():
851851
warnings.warn("scalar indexers for index type {0} should be integers and not floating point".format(
852-
type(self).__name__),FutureWarning, stacklevel=2)
852+
type(self).__name__), FutureWarning, stacklevel=3)
853853
return to_int()
854854

855855
return key
@@ -887,7 +887,7 @@ def f(c):
887887
# warn if it's a convertible float
888888
if v == int(v):
889889
warnings.warn("slice indexers when using iloc should be integers "
890-
"and not floating point",FutureWarning, stacklevel=2)
890+
"and not floating point", FutureWarning, stacklevel=7)
891891
return int(v)
892892

893893
self._invalid_indexer('slice {0} value'.format(c), v)

pandas/core/strings.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def str_contains(arr, pat, case=True, flags=0, na=np.nan, regex=True):
204204

205205
if regex.groups > 0:
206206
warnings.warn("This pattern has match groups. To actually get the"
207-
" groups, use str.extract.", UserWarning)
207+
" groups, use str.extract.", UserWarning, stacklevel=3)
208208

209209
f = lambda x: bool(regex.search(x))
210210
else:
@@ -377,11 +377,12 @@ def str_match(arr, pat, case=True, flags=0, na=np.nan, as_indexer=False):
377377
# Do this first, to make sure it happens even if the re.compile
378378
# raises below.
379379
warnings.warn("In future versions of pandas, match will change to"
380-
" always return a bool indexer.", UserWarning)
380+
" always return a bool indexer.", FutureWarning,
381+
stacklevel=3)
381382

382383
if as_indexer and regex.groups > 0:
383384
warnings.warn("This pattern has match groups. To actually get the"
384-
" groups, use str.extract.", UserWarning)
385+
" groups, use str.extract.", UserWarning, stacklevel=3)
385386

386387
# If not as_indexer and regex.groups == 0, this returns empty lists
387388
# and is basically useless, so we will not warn.

pandas/io/parsers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ def _clean_options(self, options, engine):
647647
warnings.warn(("Falling back to the 'python' engine because"
648648
" {0}; you can avoid this warning by specifying"
649649
" engine='python'.").format(fallback_reason),
650-
ParserWarning)
650+
ParserWarning, stacklevel=5)
651651

652652
index_col = options['index_col']
653653
names = options['names']

pandas/io/pytables.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1596,7 +1596,7 @@ def update_info(self, info):
15961596
# frequency/name just warn
15971597
if key in ['freq', 'index_name']:
15981598
ws = attribute_conflict_doc % (key, existing_value, value)
1599-
warnings.warn(ws, AttributeConflictWarning)
1599+
warnings.warn(ws, AttributeConflictWarning, stacklevel=6)
16001600

16011601
# reset
16021602
idx[key] = None
@@ -2581,7 +2581,7 @@ def write_array(self, key, value, items=None):
25812581
except:
25822582
pass
25832583
ws = performance_doc % (inferred_type, key, items)
2584-
warnings.warn(ws, PerformanceWarning)
2584+
warnings.warn(ws, PerformanceWarning, stacklevel=7)
25852585

25862586
vlarr = self._handle.create_vlarray(self.group, key,
25872587
_tables().ObjectAtom())
@@ -3716,7 +3716,7 @@ def read(self, where=None, columns=None, **kwargs):
37163716
objs.append(obj)
37173717

37183718
else:
3719-
warnings.warn(duplicate_doc, DuplicateWarning)
3719+
warnings.warn(duplicate_doc, DuplicateWarning, stacklevel=5)
37203720

37213721
# reconstruct
37223722
long_index = MultiIndex.from_arrays(

pandas/io/sql.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ def read_sql_table(table_name, con, schema=None, index_col=None,
328328
read_sql
329329
330330
"""
331-
331+
332332
con = _engine_builder(con)
333333
if not _is_sqlalchemy_connectable(con):
334334
raise NotImplementedError("read_sql_table only supported for "
@@ -364,7 +364,7 @@ def read_sql_query(sql, con, index_col=None, coerce_float=True, params=None,
364364
----------
365365
sql : string
366366
SQL query to be executed
367-
con : SQLAlchemy connectable(engine/connection) or database string URI
367+
con : SQLAlchemy connectable(engine/connection) or database string URI
368368
or sqlite3 DBAPI2 connection
369369
Using SQLAlchemy makes it possible to use any DB supported by that
370370
library.
@@ -618,7 +618,7 @@ def pandasSQL_builder(con, flavor=None, schema=None, meta=None,
618618
return SQLDatabase(con, schema=schema, meta=meta)
619619
else:
620620
if flavor == 'mysql':
621-
warnings.warn(_MYSQL_WARNING, FutureWarning, stacklevel=2)
621+
warnings.warn(_MYSQL_WARNING, FutureWarning, stacklevel=3)
622622
return SQLiteDatabase(con, flavor, is_cursor=is_cursor)
623623

624624

@@ -957,7 +957,7 @@ def _sqlalchemy_type(self, col):
957957
if col_type == 'timedelta64':
958958
warnings.warn("the 'timedelta' type is not supported, and will be "
959959
"written as integer values (ns frequency) to the "
960-
"database.", UserWarning)
960+
"database.", UserWarning, stacklevel=8)
961961
return BigInteger
962962
elif col_type == 'floating':
963963
if col.dtype == 'float32':
@@ -1409,7 +1409,7 @@ def _create_table_setup(self):
14091409
pat = re.compile('\s+')
14101410
column_names = [col_name for col_name, _, _ in column_names_and_types]
14111411
if any(map(pat.search, column_names)):
1412-
warnings.warn(_SAFE_NAMES_WARNING)
1412+
warnings.warn(_SAFE_NAMES_WARNING, stacklevel=6)
14131413

14141414
flv = self.pd_sql.flavor
14151415
escape = _SQL_GET_IDENTIFIER[flv]
@@ -1450,7 +1450,7 @@ def _sql_type_name(self, col):
14501450
if col_type == 'timedelta64':
14511451
warnings.warn("the 'timedelta' type is not supported, and will be "
14521452
"written as integer values (ns frequency) to the "
1453-
"database.", UserWarning)
1453+
"database.", UserWarning, stacklevel=8)
14541454
col_type = "integer"
14551455

14561456
elif col_type == "datetime64":

pandas/io/tests/test_pytables.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def _maybe_remove(store, key):
122122
pass
123123

124124

125-
def compat_assert_produces_warning(w,f):
125+
def compat_assert_produces_warning(w, f):
126126
""" don't produce a warning under PY3 """
127127
if compat.PY3:
128128
f()
@@ -2516,7 +2516,8 @@ def test_terms(self):
25162516
[ "minor_axis=['A','B']", dict(field='major_axis', op='>', value='20121114') ]
25172517
]
25182518
for t in terms:
2519-
with tm.assert_produces_warning(expected_warning=DeprecationWarning):
2519+
with tm.assert_produces_warning(expected_warning=DeprecationWarning,
2520+
check_stacklevel=False):
25202521
Term(t)
25212522

25222523
# valid terms
@@ -2609,7 +2610,8 @@ def test_backwards_compat_without_term_object(self):
26092610
major_axis=date_range('1/1/2000', periods=5),
26102611
minor_axis=['A', 'B', 'C', 'D'])
26112612
store.append('wp',wp)
2612-
with tm.assert_produces_warning(expected_warning=DeprecationWarning):
2613+
with tm.assert_produces_warning(expected_warning=DeprecationWarning,
2614+
check_stacklevel=not compat.PY3):
26132615
result = store.select('wp', [('major_axis>20000102'),
26142616
('minor_axis', '=', ['A','B']) ])
26152617
expected = wp.loc[:,wp.major_axis>Timestamp('20000102'),['A','B']]
@@ -2628,20 +2630,24 @@ def test_backwards_compat_without_term_object(self):
26282630
store.append('wp',wp)
26292631

26302632
# stringified datetimes
2631-
with tm.assert_produces_warning(expected_warning=DeprecationWarning):
2633+
with tm.assert_produces_warning(expected_warning=DeprecationWarning,
2634+
check_stacklevel=not compat.PY3):
26322635
result = store.select('wp', [('major_axis','>',datetime.datetime(2000,1,2))])
26332636
expected = wp.loc[:,wp.major_axis>Timestamp('20000102')]
26342637
assert_panel_equal(result, expected)
2635-
with tm.assert_produces_warning(expected_warning=DeprecationWarning):
2638+
with tm.assert_produces_warning(expected_warning=DeprecationWarning,
2639+
check_stacklevel=not compat.PY3):
26362640
result = store.select('wp', [('major_axis','>',datetime.datetime(2000,1,2,0,0))])
26372641
expected = wp.loc[:,wp.major_axis>Timestamp('20000102')]
26382642
assert_panel_equal(result, expected)
2639-
with tm.assert_produces_warning(expected_warning=DeprecationWarning):
2643+
with tm.assert_produces_warning(expected_warning=DeprecationWarning,
2644+
check_stacklevel=not compat.PY3):
26402645
result = store.select('wp', [('major_axis','=',[datetime.datetime(2000,1,2,0,0),
26412646
datetime.datetime(2000,1,3,0,0)])])
26422647
expected = wp.loc[:,[Timestamp('20000102'),Timestamp('20000103')]]
26432648
assert_panel_equal(result, expected)
2644-
with tm.assert_produces_warning(expected_warning=DeprecationWarning):
2649+
with tm.assert_produces_warning(expected_warning=DeprecationWarning,
2650+
check_stacklevel=not compat.PY3):
26452651
result = store.select('wp', [('minor_axis','=',['A','B'])])
26462652
expected = wp.loc[:,:,['A','B']]
26472653
assert_panel_equal(result, expected)
@@ -4528,7 +4534,7 @@ def f():
45284534
s = Series(np.random.randn(len(unicode_values)), unicode_values)
45294535
self._check_roundtrip(s, tm.assert_series_equal)
45304536

4531-
compat_assert_produces_warning(PerformanceWarning,f)
4537+
compat_assert_produces_warning(PerformanceWarning, f)
45324538

45334539
def test_store_datetime_mixed(self):
45344540

pandas/parser.pyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,7 @@ def _concatenate_chunks(list chunks):
18381838
warning_message = " ".join(["Columns (%s) have mixed types." % warning_names,
18391839
"Specify dtype option on import or set low_memory=False."
18401840
])
1841-
warnings.warn(warning_message, DtypeWarning)
1841+
warnings.warn(warning_message, DtypeWarning, stacklevel=8)
18421842
return result
18431843

18441844
#----------------------------------------------------------------------

pandas/tests/test_categorical.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,7 @@ def test_nan_handling(self):
15901590

15911591
# Changing categories should also make the replaced category np.nan
15921592
s3 = Series(Categorical(["a","b","c","a"]))
1593-
with tm.assert_produces_warning(FutureWarning):
1593+
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
15941594
s3.cat.categories = ["a","b",np.nan]
15951595
self.assert_numpy_array_equal(s3.cat.categories,
15961596
np.array(["a","b",np.nan], dtype=np.object_))

pandas/tests/test_expressions.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -382,32 +382,32 @@ def test_bool_ops_warn_on_arithmetic(self):
382382
fe = getattr(operator, sub_funcs[subs[op]])
383383

384384
with tm.use_numexpr(True, min_elements=5):
385-
with tm.assert_produces_warning():
385+
with tm.assert_produces_warning(check_stacklevel=False):
386386
r = f(df, df)
387387
e = fe(df, df)
388388
tm.assert_frame_equal(r, e)
389389

390-
with tm.assert_produces_warning():
390+
with tm.assert_produces_warning(check_stacklevel=False):
391391
r = f(df.a, df.b)
392392
e = fe(df.a, df.b)
393393
tm.assert_series_equal(r, e)
394394

395-
with tm.assert_produces_warning():
395+
with tm.assert_produces_warning(check_stacklevel=False):
396396
r = f(df.a, True)
397397
e = fe(df.a, True)
398398
tm.assert_series_equal(r, e)
399399

400-
with tm.assert_produces_warning():
400+
with tm.assert_produces_warning(check_stacklevel=False):
401401
r = f(False, df.a)
402402
e = fe(False, df.a)
403403
tm.assert_series_equal(r, e)
404404

405-
with tm.assert_produces_warning():
405+
with tm.assert_produces_warning(check_stacklevel=False):
406406
r = f(False, df)
407407
e = fe(False, df)
408408
tm.assert_frame_equal(r, e)
409409

410-
with tm.assert_produces_warning():
410+
with tm.assert_produces_warning(check_stacklevel=False):
411411
r = f(df, True)
412412
e = fe(df, True)
413413
tm.assert_frame_equal(r, e)

pandas/tests/test_format.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2734,7 +2734,7 @@ def test_round_dataframe(self):
27342734
non_int_round_dict = {'col1': 1, 'col2': 0.5}
27352735
if sys.version < LooseVersion('2.7'):
27362736
# np.round([1.123, 2.123], 0.5) is only a warning in Python 2.6
2737-
with self.assert_produces_warning(DeprecationWarning):
2737+
with self.assert_produces_warning(DeprecationWarning, check_stacklevel=False):
27382738
df.round(non_int_round_dict)
27392739
else:
27402740
with self.assertRaises(TypeError):

pandas/tests/test_frame.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1440,7 +1440,8 @@ def test_getitem_setitem_float_labels(self):
14401440
df = DataFrame(np.random.randn(5, 5), index=index)
14411441

14421442
# positional slicing only via iloc!
1443-
with tm.assert_produces_warning(FutureWarning):
1443+
# stacklevel=False -> needed stacklevel depends on index type
1444+
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
14441445
result = df.iloc[1.0:5]
14451446

14461447
expected = df.reindex([2.5, 3.5, 4.5, 5.0])

pandas/tests/test_graphics_others.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ def test_grouped_box_return_type(self):
677677
expected_keys=['height', 'weight', 'category'])
678678

679679
# now for groupby
680-
with tm.assert_produces_warning(FutureWarning):
680+
with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
681681
result = df.groupby('gender').boxplot()
682682
self._check_box_return_type(result, 'dict', expected_keys=['Male', 'Female'])
683683

0 commit comments

Comments
 (0)