After digging a little more and gaining an understanding of how things are supposed to work, the OpenGL and SDL renderers are both fine, it's the GLSL renderer that's broken. GLSL just happens to be the default. Change your lt.console_init_root call to this and your test program should work:
lt.console_init_root(80, 50, "test", False, renderer = lt.RENDERER_OPENGL)
I used this to test rendering the whole font:
import libtcodpy as lt
lt.console_set_custom_font("testfont.png", lt.FONT_TYPE_GREYSCALE | lt.FONT_LAYOUT_ASCII_INROW, 16, 32)
lt.console_init_root(80, 50, "test", False, renderer=lt.RENDERER_OPENGL)
lt.console_set_default_foreground(0, lt.white)
while not lt.console_is_window_closed():
for y in xrange(32):
for x in xrange(16):
lt.console_put_char(0, x, y, y * 16 + x)
lt.console_flush()
key = lt.console_wait_for_keypress(True)
if key.vk == lt.KEY_ESCAPE:
break
It also works with your remapping in place: it renders the extended characters twice, except for 0, which I think is getting treated specially somewhere. And also 255, but that's because your remapping call should have 256 in it, not 255, to get the whole set. It's number of characters, not the maximum character. Both behaviors are consistent across all three renderers.
I also submitted a pull request for the GLSL renderer, it wasn't too hard to fix once I understood it all. (Scratch that, it didn't work at all, it was just falling back to SDL and making me think it did, back to the drawing board on that one

)