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

Problem with os.get_terminal_size() and argcomplete #476

Closed
rabuchaim opened this issue Mar 11, 2024 · 2 comments
Closed

Problem with os.get_terminal_size() and argcomplete #476

rabuchaim opened this issue Mar 11, 2024 · 2 comments

Comments

@rabuchaim
Copy link

rabuchaim commented Mar 11, 2024

Hi there!

I rewrote my code twice... the third time (this weekend) I decided to add class by class, and I found the problem. A pretty stupid problem.

If you add the class below in your code with argcomplete, the argcomplete will stop working. This class just draw a line in your terminal. You don't even need to call the class, the code will stop working.

class line:
    middot = "\xb7" * (os.get_terminal_size().columns - 1)
    single = "─" * (os.get_terminal_size().columns - 1)
    double = "═" * (os.get_terminal_size().columns - 1)

If you want to call to see the result:

print(line.middot)

This is the expected result:
····················································································································

The problem is the function os.get_terminal_size().columns. If you change this text by a number like '120', the argcomplete will work without problem. But the terminal size can change, the user can change the window size, this is why to get the current columns size every time I call the class "line".

So my code is like this:

class terminal:
    def __init__(self):
        self.width = os.get_terminal_size().columns - 1
class line:
    middot = "\xb7" * terminal().width
    single = "─" * terminal().width
    double = "═" * terminal().width

If you put a __init__(self) function in this class "line", the argcomplete works with no problems, but I don´t want to call the function line with parentheses (kkkk).

class line:
    def __init__(self):
        self.middot = "\xb7" * os.get_terminal_size().columns
        self.single = "─" * os.get_terminal_size().columns
        self.double = "═" * os.get_terminal_size().columns

print(line().middot)

If you set the environment variable _ARC_DEBUG=1 you will see an error exception <class 'SystemExit'> 2 while parsing args without any useful information. BUT AT THE END YOU WILL SEE THE COMPLETION WORKING!!

word ./argc.py split, lexer state: ' '
In trailing whitespace
LINE: './argc.py '
POINT: 10
PREQUOTE: ''
PREFIX: ''
SUFFIX: ''
WORDS: ['./argc.py']
Active parsers: [MonkeyPatchedIntrospectiveArgumentParser(prog='argc.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=False)]
Visited positionals: [MonkeyPatchedIntrospectiveArgumentParser(prog='argc.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=False)]
invoking parser with []

exception <class 'SystemExit'> 2 while parsing args
all active parsers: [MonkeyPatchedIntrospectiveArgumentParser(prog='argc.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=False)]
active_parser: MonkeyPatchedIntrospectiveArgumentParser(prog='argc.py', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=False)
optional options: ['-c', '-r', '--raw', '-nc', '--no-color']
(.....)
display completions: {'-c': 'Supply a configuration file. (Default: /opt/relogwatch/argc.conf).', '-r': 'Displays output to stdout without colors and with linear summary sections', '--raw': 'Displays output to stdout without colors and with linear summary sections', '-nc': 'Displays output to stdout without colors. Note: the output for syslog is already without colors.', '--no-color': 'Displays output to stdout without colors. Note: the output for syslog is already without colors.', 'block': 'Manage the IP/CIDR list currently blocked.'}

Returning completions: ['--raw', '--no-color', 'block']

If you remove the environment variable, It will stop working.

Why does it happen? I didn't understand... (I gave up and my code is calling the line() function with parentheses)

I appreciate your time reading this, I spent a lot of time to discover this, I think the debug function could show more specific errors.

Thanks

Ricardo Abuchaim - ricardoabuchaim@gmail.com

@kislyuk
Copy link
Owner

kislyuk commented Mar 11, 2024

Hello,

When argcomplete runs your program to collect completions, there is no terminal that the program is connected to. So if you run os.get_terminal_size() (which raises OSError in this situation) at startup time, you will have to catch and deal with the error.

You can reproduce this issue more easily by redirecting the output of your program to a file or device: ./argc.py > /dev/null

@kislyuk kislyuk closed this as completed Mar 11, 2024
@rabuchaim
Copy link
Author

Thanks!!

I just changed the code and put a try: except and argcomplete is working as I expected!

##──── GET THE TERMINAL WIDTH 
class terminal:
    def __init__(self):
        try:
            self.width = os.get_terminal_size().columns - 1
        except:
            self.width = 120
##──── RETURNS A LINE FILLED WITH A CHAR 
class line:
    middot = "\xb7" * terminal().width
    single = "─" * terminal().width
    double = "═" * terminal().width
    

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