colorama: deinit() doesn't work if init() was called twice.

>>> import colorama
>>> import sys
>>> id(sys.stdout)
2198406407512
>>> colorama.init()
>>> id(sys.stdout)
2198419631912
>>> colorama.deinit()
>>> id(sys.stdout)  # back to the original, as expected
2198406407512
>>> colorama.init()
>>> colorama.init()
>>> colorama.deinit()
>>> id(sys.stdout)  # What?
2198419494224

I think init() should probably either raise an error, or no-op if colorama was already initialized. But in any case, it should not break deinit by losing the original stdout/stderr.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 16 (7 by maintainers)

Commits related to this issue

Most upvoted comments

@AlkisPis Play nice, m’kay? Glitch and everyone else are doing their best, giving time and effort for free, we should all be grateful, not demanding.

Why am I not playing nice? Anyway, this is an opportunity for me to thank you for your nice package! 😃

I oringinally thought that this problem could be solved by just running deinit() again (as init() was called twice therefore to go back would require two deinit() calls) to get back to the original stdout.

However this does not seem to be the case when I started investigating, I found out that the second deinit() does not have any affect on the output of stdout, however the first deinit() seems to have some effect and lets you go back to the stdout output after the first init() was called.

>>> import colorama
>>> import sys
>>> id(sys.stdout)  # The original stdout output
56145200
>>> colorama.init()
>>> id(sys.stdout)  # The stdout output after init()
94884112
>>> colorama.deinit()
>>> id(sys.stdout)  # Should be back to the original stdout output
56145200  # stdout goes back

>>> colorama.init()
>>> id(sys.stdout)  # The stdout output after init()
95230320
>>> colorama.init()  # init() for the second time
>>> id(sys.stdout)  # The stdout output after the second init()
95230544
>>> colorama.deinit()  # deinit() once
>>> id(sys.stdout)  # stdout output after first deinit()
95230320  # stdout goes back to stdout after first deinit()
>>> colorama.deinit() # deinit() again (second time), should go back to original stdout ouput
>>> id(sys.stdout)  # stdout output after second deinit()
95230320  # stdout output is the same after the second deinit() as after the first deinit()

For the curious, the same effect occurs when more calls to init() are made without calling deinit(). Calling init() 3 times in a row and then calling deinit() 3 times makes stdout print out the same result as after the first init() this implies that multiple init() calls have an effect on stderr while multiple deinit() calls have no effect on stderr after the first deinit() call was made.

I hope this helps, I think an error needs to be raised when init() is called again before deinit() is called to prevent this problem happening.

I used colorama to pretty log and was very cool to have multi-platform support. Hope to use it more times in the future.

I liked the idea of init became no-op, the user interface would be very clean, @tartley.

Another option would be to wrap stdout and keep a reference on stdout.__colorama_original_stdout. Init and deinit would call hasattr(stdout, '__colorama_original_stdout') it being lazy initialized or explicitly. Seems that it would avoid recursion errors.

I’m thinking of fixing this by making ‘init()’ a no-op if it has already wrapped stdout. This has some precedence, because ‘init()’ is already a no-op in other situations, such as on non-windows platforms. So we’ll only need a single ‘deinit()’ to fix multiple ‘init()’ calls.

@AlkisPis Play nice, m’kay? Glitch and everyone else are doing their best, giving time and effort for free, we should all be grateful, not demanding.

I’ll see if I can figure this out in the next few days. Hugs, all