Skip to content

cmd2 2.5.0 changed the method chain for output #1390

@kotfu

Description

@kotfu

To describe this issue, I need to define what I mean by "method chain for output". If you are a developer of a cmd2 based app, you would typically call one of the cmd2 methods to produce output, i.e, one of poutput(), perror(), pwarning(), pfeedback(), or ppaged(). The cmd2.py implementation of these methods appropriately called each other. For example, ppaged() makes a determination whether output is going to a terminal, if so, it opens a pipe and sends the output to your operating system pager (like less), but if output is not going to a terminal, ppaged() just calls poutput(). Similarly pwarning() applies a different style and then calls perror(). This is what I mean by the "method chain for output".

In cmd2 version 2.4.3 and prior, the method chain for output was:

  • poutput() -> style_aware_write()
  • perror() -> style_aware_write()
  • pwarning() -> perror()
  • pexcept() -> perror()
  • pfeedback() -> poutput() or perror()
  • ppaged() -> poutput() if not on a functional terminal

cmd2 version 2.5.0 made some material changes to this method chain. It introduces a new method print_to()

  • print_to() -> ppaged() or style_aware_write()
  • poutput() -> print_to()
  • perror() -> print_to()
  • pwarning() -> print_to()
  • pexcept() -> perror()
  • pfeedback() -> print_to()
  • ppaged() -> style_aware_write()

What is the rationale for this new design? I have some specific questions:

  • what's the purpose of the print_to() method and what guidance is there for developers for the use/overriding of that method?
  • why does print_to() call ppaged()?
  • why doesn't pexcept() call print_to()?
  • why doesn't ppaged() call poutput() any more?
  • why does pexcept() still call perror() but pwarning() doesn't?

Besides the philosophical questions to help me understand this better, this change broke my test suite because I had reimplemented poutput() to use rich.console. In v2.4.3 when you called ppaged() the call chain went to poutput() if there was no terminal present. In 2.5.0, ppaged() no longer calls poutput() so I couldn't intercept the output in the way I was previously doing. There is a relatively simple workaround for me in my app, I can just reimplement ppaged().

One other note, the method signatures for print_to() and style_aware_write() use a fundamentally different design than rich.console. Meaning, if I as a developer of a cmd2 based app wanted to use rich.console for my output, I need to not use any of the cmd2 output methods or I need to reimplement them all. Even more discouraging, if you are using rich.console, there is now no method you can reimplement and get all of the cmd2 generated output to go to rich.console

The cmd2 approach is based on file descriptors passed a parameters to the methods: you set the file descriptors to be where you want the output to go and then pass the file descriptor around to the various methods which write to that file descriptor. In rich.console you create a console object give it the file descriptor to use, but to generate output you must call methods on the console object.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions