Skip to content

vivify issue links in RELEASE.rst #2505

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

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,670 changes: 1,799 additions & 871 deletions RELEASE.rst

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/source/missing_data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ arise and we wish to also consider that "missing" or "null".

Until recently, for legacy reasons ``inf`` and ``-inf`` were also
considered to be "null" in computations. This is no longer the case by
default; use the :func: `~pandas.core.common.use_inf_as_null` function to recover it.
default; use the ``mode.use_inf_as_null`` option to recover it.

.. _missing.isnull:

Expand Down
7 changes: 4 additions & 3 deletions pandas/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ def isnull_old(obj):
else:
return obj is None

def use_inf_as_null(flag):
'''
def _use_inf_as_null(key):
'''Option change callback for null/inf behaviour
Choose which replacement for numpy.isnan / -numpy.isfinite is used.

Parameters
Expand All @@ -113,6 +113,7 @@ def use_inf_as_null(flag):
* http://stackoverflow.com/questions/4859217/
programmatically-creating-variables-in-python/4859312#4859312
'''
flag = get_option(key)
if flag == True:
globals()['isnull'] = isnull_old
else:
Expand Down Expand Up @@ -1179,7 +1180,7 @@ def in_interactive_session():
returns True if running under python/ipython interactive shell
"""
import __main__ as main
return not hasattr(main, '__file__') or get_option('test.interactive')
return not hasattr(main, '__file__') or get_option('mode.sim_interactive')

def in_qtconsole():
"""
Expand Down
16 changes: 12 additions & 4 deletions pandas/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
- all options in a certain sub - namespace can be reset at once.
- the user can set / get / reset or ask for the description of an option.
- a developer can register and mark an option as deprecated.

- you can register a callback to be invoked when the the option value
is set or reset. Changing the stored value is considered misuse, but
is not verboten.

Implementation
==============
Expand Down Expand Up @@ -54,7 +56,7 @@
import warnings

DeprecatedOption = namedtuple('DeprecatedOption', 'key msg rkey removal_ver')
RegisteredOption = namedtuple('RegisteredOption', 'key defval doc validator')
RegisteredOption = namedtuple('RegisteredOption', 'key defval doc validator cb')

_deprecated_options = {} # holds deprecated option metdata
_registered_options = {} # holds registered option metdata
Expand Down Expand Up @@ -105,6 +107,9 @@ def _set_option(pat, value):
root, k = _get_root(key)
root[k] = value

if o and o.cb:
o.cb(key)


def _describe_option(pat='', _print_desc=True):

Expand Down Expand Up @@ -270,7 +275,7 @@ def __doc__(self):
######################################################
# Functions for use by pandas developers, in addition to User - api

def register_option(key, defval, doc='', validator=None):
def register_option(key, defval, doc='', validator=None, cb=None):
"""Register an option in the package-wide pandas config object

Parameters
Expand All @@ -280,6 +285,9 @@ def register_option(key, defval, doc='', validator=None):
doc - a string description of the option
validator - a function of a single argument, should raise `ValueError` if
called with a value which is not a legal value for the option.
cb - a function of a single argument "key", which is called
immediately after an option value is set/reset. key is
the full name of the option.

Returns
-------
Expand Down Expand Up @@ -321,7 +329,7 @@ def register_option(key, defval, doc='', validator=None):

# save the option metadata
_registered_options[key] = RegisteredOption(key=key, defval=defval,
doc=doc, validator=validator)
doc=doc, validator=validator,cb=cb)


def deprecate_option(key, msg=None, rkey=None, removal_ver=None):
Expand Down
23 changes: 20 additions & 3 deletions pandas/core/config_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,27 @@
cf.register_option('expand_frame_repr', True, pc_expand_repr_doc)
cf.register_option('line_width', 80, pc_line_width_doc)

tc_interactive_doc="""
tc_sim_interactive_doc="""
: boolean
Default False
Whether to simulate interactive mode for purposes of testing
"""
with cf.config_prefix('test'):
cf.register_option('interactive', False, tc_interactive_doc)
with cf.config_prefix('mode'):
cf.register_option('sim_interactive', False, tc_sim_interactive_doc)

use_inf_as_null_doc="""
: boolean
True means treat None, NaN, INF, -INF as null (old way),
False means None and NaN are null, but INF, -INF are not null
(new way).
"""

# we don't want to start importing evrything at the global context level
# or we'll hit circular deps.
def use_inf_as_null_cb(key):
from pandas.core.common import _use_inf_as_null
_use_inf_as_null(key)

with cf.config_prefix('mode'):
cf.register_option('use_inf_as_null', False, use_inf_as_null_doc,
cb=use_inf_as_null_cb)
9 changes: 5 additions & 4 deletions pandas/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import unittest

from pandas import Series, DataFrame, date_range, DatetimeIndex
from pandas.core.common import notnull, isnull, use_inf_as_null
from pandas.core.common import notnull, isnull
import pandas.core.common as com
import pandas.util.testing as tm
import pandas.core.config as cf

import numpy as np

Expand All @@ -29,15 +30,15 @@ def test_notnull():
assert not notnull(None)
assert not notnull(np.NaN)

use_inf_as_null(False)
cf.set_option("mode.use_inf_as_null",False)
assert notnull(np.inf)
assert notnull(-np.inf)

use_inf_as_null(True)
cf.set_option("mode.use_inf_as_null",True)
assert not notnull(np.inf)
assert not notnull(-np.inf)

use_inf_as_null(False)
cf.set_option("mode.use_inf_as_null",False)

float_series = Series(np.random.randn(5))
obj_series = Series(np.random.randn(5), dtype=object)
Expand Down
25 changes: 25 additions & 0 deletions pandas/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,31 @@ def test_config_prefix(self):
self.assertEqual(self.cf.get_option('a'), 1)
self.assertEqual(self.cf.get_option('b'), 2)

def test_callback(self):
k=[None]
v=[None]
def callback(key):
k.append(key)
v.append(self.cf.get_option(key))

self.cf.register_option('d.a', 'foo',cb=callback)
self.cf.register_option('d.b', 'foo',cb=callback)

del k[-1],v[-1]
self.cf.set_option("d.a","fooz")
self.assertEqual(k[-1],"d.a")
self.assertEqual(v[-1],"fooz")

del k[-1],v[-1]
self.cf.set_option("d.b","boo")
self.assertEqual(k[-1],"d.b")
self.assertEqual(v[-1],"boo")

del k[-1],v[-1]
self.cf.reset_option("d.b")
self.assertEqual(k[-1],"d.b")



# fmt.reset_printoptions and fmt.set_printoptions were altered
# to use core.config, test_format exercises those paths.
28 changes: 14 additions & 14 deletions pandas/tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ def test_repr_should_return_str (self):
self.assertTrue(type(df.__repr__() == str)) # both py2 / 3

def test_repr_no_backslash(self):
pd.set_option('test.interactive', True)
pd.set_option('mode.sim_interactive', True)
df = DataFrame(np.random.randn(10, 4))

self.assertTrue('\\' not in repr(df))
pd.reset_option('test.interactive')
pd.reset_option('mode.sim_interactive')

def test_to_string_repr_unicode(self):
buf = StringIO()
Expand Down Expand Up @@ -409,7 +409,7 @@ def test_frame_info_encoding(self):
fmt.set_printoptions(max_rows=200)

def test_wide_repr(self):
set_option('test.interactive', True)
set_option('mode.sim_interactive', True)
col = lambda l, k: [tm.rands(k) for _ in xrange(l)]
df = DataFrame([col(20, 25) for _ in range(10)])
set_option('print.expand_frame_repr', False)
Expand All @@ -423,11 +423,11 @@ def test_wide_repr(self):
self.assert_(len(wider_repr) < len(wide_repr))

reset_option('print.expand_frame_repr')
set_option('test.interactive', False)
set_option('mode.sim_interactive', False)
set_option('print.line_width', 80)

def test_wide_repr_named(self):
set_option('test.interactive', True)
set_option('mode.sim_interactive', True)
col = lambda l, k: [tm.rands(k) for _ in xrange(l)]
df = DataFrame([col(20, 25) for _ in range(10)])
df.index.name = 'DataFrame Index'
Expand All @@ -446,11 +446,11 @@ def test_wide_repr_named(self):
self.assert_('DataFrame Index' in line)

reset_option('print.expand_frame_repr')
set_option('test.interactive', False)
set_option('mode.sim_interactive', False)
set_option('print.line_width', 80)

def test_wide_repr_multiindex(self):
set_option('test.interactive', True)
set_option('mode.sim_interactive', True)
col = lambda l, k: [tm.rands(k) for _ in xrange(l)]
midx = pandas.MultiIndex.from_arrays([np.array(col(10, 5)),
np.array(col(10, 5))])
Expand All @@ -471,11 +471,11 @@ def test_wide_repr_multiindex(self):
self.assert_('Level 0 Level 1' in line)

reset_option('print.expand_frame_repr')
set_option('test.interactive', False)
set_option('mode.sim_interactive', False)
set_option('print.line_width', 80)

def test_wide_repr_multiindex_cols(self):
set_option('test.interactive', True)
set_option('mode.sim_interactive', True)
col = lambda l, k: [tm.rands(k) for _ in xrange(l)]
midx = pandas.MultiIndex.from_arrays([np.array(col(10, 5)),
np.array(col(10, 5))])
Expand All @@ -497,11 +497,11 @@ def test_wide_repr_multiindex_cols(self):
self.assert_(len(wide_repr.splitlines()) == 14 * 10 - 1)

reset_option('print.expand_frame_repr')
set_option('test.interactive', False)
set_option('mode.sim_interactive', False)
set_option('print.line_width', 80)

def test_wide_repr_unicode(self):
set_option('test.interactive', True)
set_option('mode.sim_interactive', True)
col = lambda l, k: [tm.randu(k) for _ in xrange(l)]
df = DataFrame([col(20, 25) for _ in range(10)])
set_option('print.expand_frame_repr', False)
Expand All @@ -515,18 +515,18 @@ def test_wide_repr_unicode(self):
self.assert_(len(wider_repr) < len(wide_repr))

reset_option('print.expand_frame_repr')
set_option('test.interactive', False)
set_option('mode.sim_interactive', False)
set_option('print.line_width', 80)

def test_wide_repr_wide_long_columns(self):
set_option('test.interactive', True)
set_option('mode.sim_interactive', True)

df = DataFrame({'a': ['a'*30, 'b'*30], 'b': ['c'*70, 'd'*80]})

result = repr(df)
self.assertTrue('ccccc' in result)
self.assertTrue('ddddd' in result)
set_option('test.interactive', False)
set_option('mode.sim_interactive', False)

def test_to_string(self):
from pandas import read_table
Expand Down
42 changes: 42 additions & 0 deletions scripts/touchup_gh_issues.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
from collections import OrderedDict
import sys
import re

"""
Reads in stdin, replace all occurences of '#num' or 'GH #num' with
links to github issue. dumps the issue anchors before the next
section header
"""

pat = "((?:\s*GH\s*)?)#(\d{3,4})([^_]|$)?"
rep_pat = r"\1GH\2_\3"
anchor_pat =".. _GH{id}: https://github.com/pydata/pandas/issues/{id}"
section_pat = "^pandas\s[\d\.]+\s*$"
def main():
issues = OrderedDict()
while True:

line = sys.stdin.readline()
if not line:
break

if re.search(section_pat,line):
for id in issues:
print(anchor_pat.format(id=id).rstrip())
if issues:
print("\n")
issues = OrderedDict()

for m in re.finditer(pat,line):
id = m.group(2)
if id not in issues:
issues[id] = True
print(re.sub(pat, rep_pat,line).rstrip())
pass

if __name__ == "__main__":
main()