HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

ANSI colors cross platform

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
ansicolorscrossplatform

Problem

I am trying to write for both NT and POSIX (my two usual platforms) and have come up with the code below. The clrs code I refer to is apparently from blender build scripts, I discovered it on this SO post. They called the class bcolors but I wanted to reduce clutter so I renamed it.

But the main class is what I've written that determines the os before printing. Prints are called, for example, via PRN.cyan("some string").

For this to work I import colorama:

from colorama import init, Fore, Back, Style
init()


The PRN class that handles the print calls:

class PRN:
    @staticmethod
    def cyan(p_str):
        """print some text with cyan foreground"""
        if os.name == 'nt':
            # we'll try the Colorama option but if it fails we can
            # change the global variable for colours.
            if coloursOn:
                sys.stdout.write(Fore.CYAN + p_str + Fore.RESET)
            else:
                sys.stdout.write(p_str)
        else:
            # try Deez1.clrs for posix environment
            sys.stdout.write(clrs.cyan + p_str + clrs.ENDC)


If colorama doesn't work on a Windows system for some reason I can change the global boolean coloursOn.

Is this an incredibly klutzy/dumb implementation? From what I've read, so far, cross platform capability for ANSI color printing has only gotten shakier, not simpler.

Solution

First off, "cross platform capability for ANSI color printing" doesn't quite make sense (if I understand correctly). ANSI color printing is only going to work on terminals that are ANSI compatible.

Therefore, it doesn't really matter what OS it is: if it's an ANSI terminal, you can use ANSI colored output.

Therefore, you can remove the checking of the operating system.

Note: according to this answer,


"All modern terminal emulators use ANSI escape codes to show colours
and other things."

Judging by the name of the method your presented and the context of the code, you have created a separate method for each color.

-
This sounds like you are repeating yourself a lot.

-
It's not very flexible for the code that is using your library.

I recommend that you create a single method print_color_string that takes a string and the color to print.

def print_color_string(str, color):
    ansi_color = getattr(Fore, color)
    if ansi_color:
        sys.stdout.write(ansi_color + p_str + Fore.RESET)
    else:
        # throw error because color is not a valid color

Code Snippets

def print_color_string(str, color):
    ansi_color = getattr(Fore, color)
    if ansi_color:
        sys.stdout.write(ansi_color + p_str + Fore.RESET)
    else:
        # throw error because color is not a valid color

Context

StackExchange Code Review Q#101454, answer score: 2

Revisions (0)

No revisions yet.