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

DummyTqdmFile.write cannot handle bytes type #1563

Open
5 of 6 tasks
marinelay opened this issue Apr 7, 2024 · 0 comments
Open
5 of 6 tasks

DummyTqdmFile.write cannot handle bytes type #1563

marinelay opened this issue Apr 7, 2024 · 0 comments

Comments

@marinelay
Copy link

marinelay commented Apr 7, 2024

  • I have marked all applicable categories:
    • exception-raising bug
    • visual output bug
  • I have visited the source website, and in particular
    read the known issues
  • I have searched through the issue tracker for duplicates
  • I have mentioned version numbers, operating system and
    environment, where applicable:
    import tqdm, sys
    print(tqdm.__version__, sys.version, sys.platform)

tqdm: 4.66
Python: 3.9.18
[GCC 9.4.0] linux

import contextlib
import sys
from tqdm import tqdm
from tqdm.contrib import DummyTqdmFile


@contextlib.contextmanager
def std_out_err_redirect_tqdm():
    orig_out_err = sys.stdout, sys.stderr
    try:
        sys.stdout, sys.stderr = map(DummyTqdmFile, orig_out_err)
        yield orig_out_err[0]
    # Relay exceptions
    except Exception as exc:
        raise exc
    # Always restore sys.stdout/err if necessary
    finally:
        sys.stdout, sys.stderr = orig_out_err

def some_fun(i):
    print("Fee, fi, fo,".split()[i])

# Redirect stdout to tqdm.write() (don't forget the `as save_stdout`)
with std_out_err_redirect_tqdm() as orig_stdout:
    sys.stdout.write(b"I'm being redirected to `tqdm.write()`\n")

Output :

Traceback (most recent call last):
  File "./tqdm/my_test.py", line 42, in <module>
    sys.stdout.write(b"I'm being redirected to `tqdm.write()`\n")
  File "./tqdm/tqdm/contrib/__init__.py", line 28, in write
    tqdm.write(blank.join(self._buf + [pre, sep]),
  File "./tqdm/tqdm/std.py", line 722, in write
    fp.write(s)
TypeError: write() argument must be str, not bytes

When redirecting sys.stdout to DummyTqdmFile.write, I believed that DummyTqdmFile.write could handle bytes type, but it raises TypeError: write() argument must be str, not bytes.

In the tqdm.contrib.__init__ source code,

def write(self, x, nolock=False):
nl = b"\n" if isinstance(x, bytes) else "\n"
pre, sep, post = x.rpartition(nl)
if sep:
blank = type(nl)()
tqdm.write(blank.join(self._buf + [pre, sep]),
end=blank, file=self._wrapped, nolock=nolock)
self._buf = [post]
else:
self._buf.append(x)

DummyTqdmFile.write handles bytes type obviously at line 24, so it is the reason why I think such that.
However, it raises TypeError because fp.write(s) ("./tqdm/tqdm/std.py", line 722) only accepts string type.

I think this bug can be fixed in two ways:
(1) Disallow bytes type in DummyTqdmFile.write
(2) Casting bytes to string before calling fp.write(s)

Thank you!

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

1 participant