pager2 module

Rewrite the module that creates the %pycat magic.

In it’s current implementation, the pager gives Windows a dumb terminal and never checks for whether less is on the PATH or if the user has a pager they would like to implement!

Revisions

%pycat

Still considering different ways of designing a new Windows specific pager on IPython. It’s a bit difficult as the default implementation is over 10 years old, and it seems to mirror a similar setup from pydoc where a Windows user who doesn’t have PAGER set will use a home-brewed more lite type pager.

However, I haven’t found anywhere in the docs where this is mentioned which is frustrating.

Original Pydoc Implementation and Errors

Running pydoc with PAGER set on Windows doesn’t catch the KeyboardInterrupt. …

$ pydoc FRAMEOBJECTS
Traceback (most recent call last):
File "C:/tools/miniconda3/lib/runpy.py", line 193, in _run_module_as_main
   "__main__", mod_spec)
File "C:/tools/miniconda3/lib/runpy.py", line 85, in _run_code
   exec(code, run_globals)
   elif request in self.topics: self.showtopic(request)
File "C:/tools/miniconda3/lib/pydoc.py", line 2021, in showtopic
   return self.showtopic(target, more_xrefs)
File "C:/tools/miniconda3/lib/pydoc.py", line 2037, in showtopic
   pager(doc)
File "C:/tools/miniconda3/lib/pydoc.py", line 1449, in pager
   pager(text)
File "C:/tools/miniconda3/lib/pydoc.py", line 1462, in <lambda>
   return lambda text: tempfilepager(plain(text), use_pager)
File "C:/tools/miniconda3/lib/pydoc.py", line 1519, in tempfilepager
   os.system(cmd + ' "' + filename + '"')
KeyboardInterrupt

Outside of the stupid traceback, that command worked perfectly for me.

I have PAGER set on Windows {which I realize isn’t typical}, however we should re-use this implementation entirely and cut IPython.core.page.page out.

Also worth noting IPython.core.payloadpage.page.:

pydoc.pipepager(inspect.getdoc(arg), os.environ.get('PAGER'))

Despite the source code of the std lib stating that pipes are completely broken on windows, this worked just fine for me.

Define ‘arg’ as an object like if you pass a string it’ll give you the help message for a str.

inspect has a million more methods and pydoc does too so possibly change the inspect.getdoc() part, but honestly that one line is 80% of the way to what I’ve been trying to do.

Autogenerated Pager Docs

get_docs_and_page()[source][source]

Resourceful way to parse sys.argv and then expand a *args.

were_in_ipython()[source][source]

Call ipython to make sure we’re really in it.

provided_or_last(s=None, shell=None)[source][source]

Either run a provided code_cell from a user or rerun their last input.

Parameters
  • s (str, optional) – str to page

  • shell (IPython instance, optional) –

Returns

Found user code.

Return type

code_to_page

Notes

We should consider using something else to find user code.

class PagerMagics(**kwargs)[source][source]

Bases: IPython.core.magic.Magics

A pager if you’re outside of IPython.

shell = None[source]
__init__(use_pager=True, cmd=None, **kwargs)[source][source]

Initializes the class.

This occurs by binding an optional text to the instance and determining whether to use a pager or output by printing to the shell.

Parameters
  • text (str, optional) – Text to page

  • use_pager (bool, optional) – Whether to print to the shell or pipe to a pager.

blocking_pager(text, cmd=None)[source][source]

A pipe pager that works on Windows. Doesn’t colorize anything.

It’s better that way though as we can send the contents elsewhere to be highlighted.

Better to keep things separated.

factory(text=None, func=None, cmd=None, *args, **kwargs)[source][source]
c(s=None)[source][source]

Intentionally abbreviated function call to %pycat.

This implementation has the added benefit of wrapping everything in a try/except that catches KeyboardInterrupts and EOFErrors because pycat doesn’t.

Note

The internal variable namespace, or an instance of the magic NameSpaceMagics can display the magics through the attribute …magics.

Parameters

s (str) – String to page.

page(s)[source][source]

Pretty print the object and display it through a pager.

If no object is given, use _ (last output).:

%page [options] OBJECT
magics = {'cell': {}, 'line': {'c': 'c', 'page': 'page'}}[source]
registered = True[source]