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

AttributeError: 'function' object has no attribute 'isatty' (progress.py, line 163) #17

Closed
jonturneratduke opened this issue Nov 13, 2019 · 11 comments

Comments

@jonturneratduke
Copy link

jonturneratduke commented Nov 13, 2019

The library is throwing the following exception w. MacOS High Sierra 10.13.6 (17G8030):

  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/alive_progress/progress.py", line 163, in alive_bar
    if sys.stdout.isatty() or config.force_tty:
AttributeError: 'function' object has no attribute 'isatty'
```. Need to first check if sys.stdout is not null in case output is being supressed?
@rogerio-geru
Copy link

rogerio-geru commented Nov 13, 2019

Hello @jonturneratduke

That's weird, it does work on Python 3.7:

 ~ $ ipython
Python 3.7.4 (default, Sep 29 2019, 03:13:35) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.8.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import sys                                                                                                                                                                       

In [2]: sys.stdout                                                                                                                                                                       
Out[2]: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>

In [3]: from alive_progress import alive_bar 
   ...: import time                                                                                                                                                                      

In [4]: with alive_bar(1000) as bar: 
   ...:     for i in range(1000): 
   ...:         time.sleep(.01) 
   ...:         bar() 
   ...:                                                                                                                                                                                  
|████████████████████████████████████████| 1000/1000 [100%] in 10.2s (98.47/s) 

In [5]: sys.stdout.isatty()                                                                                                                                                              
Out[5]: True

@rogerio-geru
Copy link

Ohh I see, you are using the Python provided by the system? Python.framework

I'll try to find out if the MacOS one have something different.
But in the meantime, you could install Python via pyenv (the best one, which I totally recommend), or via homebrew.

@jonturneratduke
Copy link
Author

running Python v3.7.5. I saw this behavior with v1.1 and the latest v1.3 of alive-progress. I'll see if I can use pyenv, it gets complicated with our build system and packaging(using pyinstaller) on a remote gitlab runner...

@jonturneratduke
Copy link
Author

jonturneratduke commented Nov 13, 2019

Although I'm not sure of the reason for the sys.stdout.isatty() being null, this at least safely checks the condition without throwing an exception. progress.py @ line 163

-     if sys.stdout.isatty() or config.force_tty:
+    isatty_op = getattr(sys.stdout, "isatty", None)
+    if callable(isatty_op):
+        isatty = isatty_op()
+    else:
+        isatty = False
+    if isatty or config.force_tty:

edit: refer to isatty() method. And in the code, call it if it's available.

@rogerio-geru
Copy link

rogerio-geru commented Nov 13, 2019

But the error does not say null anywhere, it says the attribute isatty was not found in function.
So, the sys.stdout must have returned a function, which did not have the said attribute.

I do install a hook in stdout at some point, but this line should have already ran...

Could you please post the complete stacktrace? Maybe there's something more there.

@jonturneratduke
Copy link
Author

jonturneratduke commented Nov 14, 2019

So, the sys.stdout must have returned a function, which did not have the said attribute.

You're correct. Sorry for my lack of precision. The isatty method/attribute reference is null, not the parent object.

Exception ignored in: <function AzureProgressBarCallback.__del__ at 0x10dd5e8c0> cli/build/capsule/PKG-00.pkg
Traceback (most recent call last):
  File "cli/src/capsule/utils/azureUtils.py", line 674, in __del__
    self._pb.__exit__(None, None, None)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/contextlib.py", line 119, in __exit__
    next(self.gen)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/alive_progress/progress.py", line 164, in alive_bar
    if sys.stdout.isatty() or config.force_tty:
AttributeError: 'function' object has no attribute 'isatty'

So to explain what's going on, azureUtils.py is calling Azure's download method ane passing a reference to a callback. Azure's library thread calls that callback, which creates your progressbar, and the callback periodically updates the bar's status.

@jonturneratduke
Copy link
Author

@rogerio-geru any thoughts on whether the code above (#17 (comment)) would be a suitable patch?

@rogerio-geru
Copy link

rogerio-geru commented Nov 21, 2019

Hello @jonturneratduke

I did understand what did happen, it should not be needed.
Your code is trying to create another alive-bar, while there is already one in place.
Note the complete exception shows that it ocurred in __del__ and was actually ignored:
Exception ignored in: <function AzureProgressBarCallback.__del__ at 0x10dd5e8c0> cli/build/capsule/PKG-00.pkg

So, after being used, your AzureProgressBarCallback was being destroyed, while there was another already created.

I can simulate by doing manually this:

In [1]: from alive_progress import alive_bar                                                                                                                                             

In [2]: pb = alive_bar()                                                                                                                                                                 

In [3]: pb.__enter__()                                                                                                                                                                   
on 0: <function alive_progress.progress.alive_bar.<locals>.bar(text=None, incr=1)>
on 0: 
In [4]:                                                                                                                                                                                  
on 0: 
In [4]: pb2 = alive_bar()                                                                                                                                                                
on 0: 
In [5]: pb2.__enter__()                                                                                                                                                                  
on 0: ---------------------------------------------------------------------------
      AttributeError                            Traceback (most recent call last)
      <ipython-input-5-11d9d01a04a1> in <module>
      ----> 1 pb2.__enter__()
      
      ~/.pyenv/versions/3.7.4/lib/python3.7/contextlib.py in __enter__(self)
          110         del self.args, self.kwds, self.func
          111         try:
      --> 112             return next(self.gen)
          113         except StopIteration:
          114             raise RuntimeError("generator didn't yield") from None
      
      ~/.pyenv/versions/3.7.4/envs/segregation/lib/python3.7/site-packages/alive_progress/progress.py in alive_bar(total, title, calibrate, **options)
          161 
          162     event = threading.Event()
      --> 163     if sys.stdout.isatty() or config.force_tty:
          164         @contextmanager
          165         def pause_monitoring():
      
      AttributeError: 'function' object has no attribute 'isatty'
on 0: 
|                          ▶▶▶▶▶▶▶▶▶▶▶▶▶ | ▃▁▃ 0 in 40s (0.0/s) (0.0/s)                                                                                                                  

@rogerio-geru
Copy link

Well, I think I can proxy the isatty method inside my print hook, no problem.
But do note the best solution would be your code not create two bars at the same time, this is a very non standard way of use.

@rsalmei
Copy link
Owner

rsalmei commented Jan 26, 2020

Related to #20

@rsalmei
Copy link
Owner

rsalmei commented Jan 26, 2020

Fixed in 1.3.3, please let me know if that's ok.

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

3 participants