1

I want to print in Python 3.6 using colored if that package is available, like so:

print('{}Hello, world!{}'.format(colored.fg(1), colored.attr(0)))

However, I want to make colored optional if possible, while still printing any text that would optionally be stylized. Simply creating a wrapper function for printing seems inadequate, due to the multiple ways you can use colored, such as colored.stylize() and adding colors together:

cheerful = colored.fg('cyan') + colored.attr('bold')
print(colored.stylize("Hello, world!", cheerful, colored.attr("underlined"))

Although mocking is usually used for testing, is it acceptable practice to create a mock library to use if the optional library isn't available? Something like so, in a module called colored_mock (mocking as described in this question):

from unittest.mock import Mock
import sys
import types

module_name = 'mock_colored'
mock_colored = types.ModuleType(module_name)
sys.modules[module_name] = mock_colored

# following the original definition
def stylize(string, styles, reset=True):
    # return the original string so it can be used
    return string

mock_colored.stylize = Mock(name=module_name+'.stylize', side_effect=stylize)

# and so on until most of the module attributes and functions are covered

This way I can do:

try:
   import colored
except ImportError:
    from .mock_colored import mock_colored as colored
eijen
  • 409
  • 1
  • 4
  • 12
  • Why do you want to make this module optional? – sanyassh May 19 '19 at 13:39
  • Because the color formatting is purely to make certain words stand out when printed, but I'd rather them print without formatting than not print at all. – eijen May 19 '19 at 13:42
  • I mean why can't you just install it? – sanyassh May 19 '19 at 13:43
  • Because I'm thinking of distributing this code, and might add an option to print with and without styling. – eijen May 19 '19 at 13:45
  • When distributing your code, you can specify what modules and packages are required for successfull installation of your code. This is a common approach. Like when you run `pip install matplotlib` it installs `numpy` with it. – sanyassh May 19 '19 at 13:47
  • Yes, I know this. But this would not be a distribution through PyPi, and again, I want to make `colored` _optional_. If the user doesn't feel they need it, then everything should print without being stylized. – eijen May 19 '19 at 13:50

1 Answers1

0

Using a Mock suggests you are testing. If this is your own code, it might be better to have a wrapper for stylized plus any other colored methods you are importing:

colored_imported = False
try:
    import colored
    colored_imported = True
except ImportError: 
    pass

def stylized(string, styles, reset=True):
    if colored_imported:
        return colored.stylized(string, styles, reset=reset)
    else:
        return string

This will help spot problems caused by misspelt methods (e.g., stylised) or having too few parameters. This approach should also make your code easier to understand and debug.

James Brusey
  • 355
  • 3
  • 11