Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

colorama is not working with Travis CI under specific circumstance #165

Closed
funilrys opened this issue May 26, 2018 · 4 comments
Closed

colorama is not working with Travis CI under specific circumstance #165

funilrys opened this issue May 26, 2018 · 4 comments

Comments

@funilrys
Copy link

Hello there!

This issue is more likely a help wanted than anything.
I'm writing PyFunceble (in this issue I'm referencing to the dev branch) and since more than 2 months, I'm trying to find why colorama is not working under a specific circumstance.

So back to our issue:

Case that it is working

As PyFunceble is running for more than 6 months every day under Travis CI, server and sometimes PC, I consider the following as safe to mention.

Locally

If I run PyFunceble (the executable) locally it's working.

Same if I create a script like the following, it's working.

#!/usr/bin/bash

PyFunceble -d github.com

Travis CI

Under Travis CI if I run PyFunceble directly for testing, it is working as you can see in the following link.

Case that it is not working

Locally

No case found after months of testing and using.

Travis CI

If we create a .py file or a bash script, and run PyFunceble from inside the script, it is not working.

Examples:


Maybe I forgot to configure something, but I'm still not understanding this issue...

So, does anyone know what am I missing and why it is not working?

Thanks in advance for taking the time to read this issue and for the time you may take to answer this issue.

Have a nice day/night.

Cheers,
Nissar

@wiggin15
Copy link
Collaborator

This is probably because the users of PyFunceble run it in a subprocess, where "stdout" is not a tty, so colorama does not recognize stdout as a wrap-able stream and therefore strips the ANSI color codes.

Consider this simple script (let's put it in a file named "a.py"):

import colorama
colorama.init()
print(colorama.Fore.RED + 'hello' + colorama.Fore.RESET)

And this script that executes "a.py" in a subprocess (let's call it "b.py")

import subprocess
proc = subprocess.Popen("python a.py", stdout=subprocess.PIPE, shell=True)
output, error = proc.communicate()
print(output)

If you run the first script directly (python a.py) you will get a red "hello". If you run b.py, which runs a.py, you will get a "regular" non-red "hello". The stdout of the subprocess is a pipe, i.e. not a "terminal stream" (tty), so the colors will be stripped.
I can't think of a good work around for you. Technically this is the intended behavior.

@funilrys
Copy link
Author

funilrys commented Oct 10, 2018

Hi @wiggin15,
I tried to find a workaround based on your example and I finally found one. I hope that this may help improve colorama or help others who are in the same situation.

a.py

import colorama

print(colorama.Fore.RED + "hello" + colorama.Fore.RESET)

b.py

import sys
from subprocess import PIPE, Popen


def run_command(command, encoding="utf-8"):
    """
    Run a command and return each line one by one.

    :param command: The command to run
    :type command: str|list

    :param encoding: The encoding to use to decode the output of the command.
    :type encoding: str

    :return: A line of the command.
    :rtype: str
    """

    if isinstance(command, list):
        # The given command is a list.

        # We convert it to string.
        command = " ".join(command)

    # We launch the command.
    process = Popen(command, stdout=PIPE, shell=True)

    while True:
        # We loop infinity because we want to get the output
        # until there is not output anymore.

        # We get the current line from the process stdout.
        #
        # Note: we use rstrip because we may have spaces after the output.
        current_line = process.stdout.readline().rstrip()

        if not current_line:
            # The current line is empty or equal to None.

            # We break the loop.
            break

        # We decode and return the current line to upstream.
        yield current_line.decode(encoding)


if __name__ == "__main__":
    # The script is executed directory.

    for line in run_command("python a.py"):
        # We loop through each line from the commands output.

        # We print to stdout.
        sys.stdout.write(line + "\n")

Proof:

2018-10-10-203529_1600x900_scrot

"Concept"

Because proc.communicate() return the output after the execution of the command as stated in the Documentation:

Wait for process to terminate.

I used Popen.stdout instead which allow us to get line "correctly".

Strangely if we use colorama.init() the coloration does not show up can you explain that @wiggin15 ?

Cheers,
Nissar

@wiggin15
Copy link
Collaborator

Reading directly from stdout attribute or using communicate method makes no difference. The stdout "PIPE" is still not a tty and will be stripped from colorama. What happens in your case is that you don't actually use colorama, since you don't call colorama.init so the streams are not wrapped. This will not work on Windows.

@funilrys
Copy link
Author

funilrys commented Nov 2, 2022

Closing as this is old enough but people can alternatively just set the PYCHARM_HOSTED environment variable.

Stay safe and healthy.

@funilrys funilrys closed this as completed Nov 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants