Completed
Pull Request — master (#21)
by
unknown
01:17
created

main()   F

Complexity

Conditions 11

Size

Total Lines 65

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 11
c 3
b 0
f 0
dl 0
loc 65
rs 3.8571

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like main() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"""CLI for accessing the gtk/tickit UIs implemented by this package."""
2
import os
3
import resource
4
import sys
5
import shlex
6
7
import click
0 ignored issues
show
Configuration introduced by
The import click could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
8
import yaml
0 ignored issues
show
Configuration introduced by
The import yaml could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
9
10
from .ui_bridge import UIBridge
11
from neovim import attach
0 ignored issues
show
Configuration introduced by
The import neovim could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
12
from neovim.compat import IS_PYTHON3
0 ignored issues
show
Configuration introduced by
The import neovim.compat could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
Unused Code introduced by
Unused IS_PYTHON3 imported from neovim.compat
Loading history...
13
14
15
CONFIG_FILES = (
16
    '.pynvim.yaml',
17
    '~/.pynvim.yaml',
18
    '~/.config/pynvim/config.yaml'
19
)
20
21
22
def load_config(config_file):
23
    """Load config values from yaml."""
24
25
    if config_file:
26
        with open(config_file) as f:
27
            return yaml.load(f)
28
29
    else:
30
        for config_file in CONFIG_FILES:
31
            try:
32
                with open(os.path.expanduser(config_file)) as f:
33
                    return yaml.load(f)
34
35
            except IOError:
0 ignored issues
show
Unused Code introduced by
This except handler seems to be unused and could be removed.

Except handlers which only contain pass and do not have an else clause can usually simply be removed:

try:
    raises_exception()
except:  # Could be removed
    pass
Loading history...
36
                pass
37
38
    return {}
39
40
41
# http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/
42
def detach_proc(workdir='.', umask=0):
43
    """Detach a process from the controlling terminal and run it in the
44
    background as a daemon.
45
    """
46
47
    # Default maximum for the number of available file descriptors.
48
    MAXFD = 1024
49
50
    # The standard I/O file descriptors are redirected to /dev/null by default.
51
    if (hasattr(os, "devnull")):
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after if.
Loading history...
52
        REDIRECT_TO = os.devnull
53
    else:
54
        REDIRECT_TO = "/dev/null"
55
56
    pid = os.fork()
57
    if (pid == 0):
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after if.
Loading history...
58
        os.setsid()
59
60
        pid = os.fork()
61
        if (pid == 0):
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after if.
Loading history...
62
            os.chdir(workdir)
63
            os.umask(umask)
64
        else:
65
            os._exit(0)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _exit was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
66
    else:
67
        os._exit(0)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _exit was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
68
69
        maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
70
        if (maxfd == resource.RLIM_INFINITY):
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after if.
Loading history...
71
            maxfd = MAXFD
72
73
            # Iterate through and close all file descriptors.
74
            for fd in range(0, maxfd):
75
                try:
76
                    os.close(fd)
77
                except OSError:
0 ignored issues
show
Unused Code introduced by
This except handler seems to be unused and could be removed.

Except handlers which only contain pass and do not have an else clause can usually simply be removed:

try:
    raises_exception()
except:  # Could be removed
    pass
Loading history...
78
                    pass
79
80
    os.open(REDIRECT_TO, os.O_RDWR)
81
82
    os.dup2(0, 1)
83
    os.dup2(0, 2)
84
85
    return(0)
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after return.
Loading history...
86
87
88
@click.command(context_settings=dict(allow_extra_args=True))
89
@click.option('--prog')
90
@click.option('--notify', '-n', default=False, is_flag=True)
91
@click.option('--listen', '-l')
92
@click.option('--connect', '-c')
93
@click.option('--profile',
94
              default='disable',
95
              type=click.Choice(['ncalls', 'tottime', 'percall', 'cumtime',
96
                                 'name', 'disable']))
97
@click.option('config_file', '--config', type=click.Path(exists=True))
98
@click.option('--detach/--no-detach', default=True, is_flag=True)
99
@click.pass_context
100
def main(ctx, prog, notify, listen, connect, profile, config_file, detach):
101
    """Entry point."""
102
103
    if detach:
104
        exit_code = detach_proc()
105
106
    address = connect or listen
107
108
    if address:
109
        import re
110
        p = re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:\:\d{1,5})?$')
111
112
        if p.match(address):
113
            args = ('tcp',)
114
            kwargs = {'address': address}
115
        else:
116
            args = ('socket',)
117
            kwargs = {'path': address}
118
119
    if connect:
120
        # connect to existing instance listening on address
121
        nvim = attach(*args, **kwargs)
122
    elif listen:
123
        # spawn detached instance listening on address and connect to it
124
        import os
0 ignored issues
show
Comprehensibility Bug introduced by
os is re-defining a name which is already available in the outer-scope (previously defined on line 2).

It is generally a bad practice to shadow variables from the outer-scope. In most cases, this is done unintentionally and might lead to unexpected behavior:

param = 5

class Foo:
    def __init__(self, param):   # "param" would be flagged here
        self.param = param
Loading history...
Unused Code introduced by
The import os was already done on line 2. You should be able to
remove this line.
Loading history...
125
        import time
126
        from subprocess import Popen
127
        os.environ['NVIM_LISTEN_ADDRESS'] = address
128
        nvim_argv = shlex.split(prog or 'nvim --headless') + ctx.args
129
        # spawn the nvim with stdio redirected to /dev/null.
130
        dnull = open(os.devnull)
131
        p = Popen(nvim_argv, stdin=dnull, stdout=dnull, stderr=dnull)
132
        dnull.close()
133
        while p.poll() or p.returncode is None:
134
            try:
135
                nvim = attach(*args, **kwargs)
136
                break
137
            except IOError:
138
                # socket not ready yet
139
                time.sleep(0.050)
140
    else:
141
        # spawn embedded instance
142
        nvim_argv = shlex.split(prog or 'nvim --embed') + ctx.args
143
        nvim = attach('child', argv=nvim_argv)
144
145
    from .gtk_ui import GtkUI
146
    config = load_config(config_file)
147
    ui = GtkUI(config)
148
    bridge = UIBridge()
149
    bridge.connect(nvim, ui, profile if profile != 'disable' else None, notify)
150
151
    if detach:
152
        sys.exit(exit_code)
153
154
155
if __name__ == '__main__':
156
    main()
0 ignored issues
show
Bug introduced by
It seems like a value for argument ctx is missing in the function call.
Loading history...
Bug introduced by
It seems like a value for argument prog is missing in the function call.
Loading history...
Bug introduced by
It seems like a value for argument notify is missing in the function call.
Loading history...
Bug introduced by
It seems like a value for argument listen is missing in the function call.
Loading history...
Bug introduced by
It seems like a value for argument connect is missing in the function call.
Loading history...
Bug introduced by
It seems like a value for argument profile is missing in the function call.
Loading history...
Bug introduced by
It seems like a value for argument config_file is missing in the function call.
Loading history...
Bug introduced by
It seems like a value for argument detach is missing in the function call.
Loading history...
157