Indian numbering system formatting
I don't think I'd get so fancy with the grouper; the data is small, a constant table will do:

comma_after_digit = set(3, 5, 7, 9, 11, 13, 15, 17)

result = '.' + ''.join(map(str, fractional_part))
for i, d in enumerate(integer_part_digits):
    if i in comma_after_digit:
        result = ',' + result
    result = d + result
result = {0:pos, 1:neg}[sign] + result
return result


Also:


Try and be a bit more consistent: you use reversed() to reverse a string on one line, and then the next you use [::-1].  You also use map(str, digits) in one place and [str(x) for x in digits] another! They do the same thing, but it's nice to the reader to pick one idiom and stick with it.
thousand = ''.join(islice(integer_part_digits, 3))[::-1] can be simplified into thousand = integer_part_digits[-4::-1]
Using .format() is overkill for concatenating strings.  + works just fine.  If you want to use it, you should 1) factor out constant strings (like the decimal point) and 2) use the args as your temporary variables, like:

return '{sign}{curr}{hundreds}{sep}{thousand}.{fractional_part}'.format(
    sign=neg if sign else pos,
    curr=curr,
    thousand=integer_part_digits[-4::-1],
    sep=',' if exponent &gt; 3 else '',
    hundreds=','.join(map(''.join, grouper(integer_part_digits, 2, fillvalue='')))[::-1],
    fractional_part=''.join(map(str,fractional_part)) if fractional_part else ''
)

According to the wikipedia page you cite, there's no comma after the 1 in 10**19, so your code is wrong :) ... which leads inevitably to:
Needs tests!