| Conditions | 14 | 
| Total Lines | 82 | 
| Lines | 0 | 
| Ratio | 0 % | 
| Changes | 2 | ||
| Bugs | 1 | Features | 0 | 
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:
If many parameters/temporary variables are present:
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 | """Entry point and related functionality""" | ||
| 239 | def main(): # type: () -> None | ||
| 240 | """setuptools entry point""" | ||
| 241 | # TODO: Switch to argparse | ||
| 242 | from optparse import OptionParser, OptionGroup | ||
| 243 | parser = OptionParser(usage="%prog [options] [action] ...", | ||
| 244 | version="%%prog v%s" % __version__) | ||
| 245 |     parser.add_option('-d', '--daemonize', action="store_true", | ||
| 246 | dest="daemonize", default=False, help="Attempt to set up global " | ||
| 247 | "keybindings using python-xlib and a D-Bus service using dbus-python. " | ||
| 248 | "Exit if neither succeeds") | ||
| 249 |     parser.add_option('-b', '--bindkeys', action="store_true", | ||
| 250 | dest="daemonize", default=False, | ||
| 251 | help="Deprecated alias for --daemonize") | ||
| 252 |     parser.add_option('--debug', action="store_true", dest="debug", | ||
| 253 | default=False, help="Display debug messages") | ||
| 254 |     parser.add_option('--no-workarea', action="store_true", dest="no_workarea", | ||
| 255 | default=False, help="Overlap panels but work better with " | ||
| 256 | "non-rectangular desktops") | ||
| 257 | |||
| 258 | help_group = OptionGroup(parser, "Additional Help") | ||
| 259 |     help_group.add_option('--show-bindings', action="store_true", | ||
| 260 | dest="show_binds", default=False, help="List all configured keybinds") | ||
| 261 |     help_group.add_option('--show-actions', action="store_true", | ||
| 262 | dest="show_args", default=False, help="List valid arguments for use " | ||
| 263 | "without --daemonize") | ||
| 264 | parser.add_option_group(help_group) | ||
| 265 | |||
| 266 | opts, args = parser.parse_args() | ||
| 267 | |||
| 268 | if not opts.debug: | ||
| 269 | attach_glib_log_filter() | ||
| 270 | |||
| 271 | # Set up the output verbosity | ||
| 272 | logging.basicConfig(level=logging.DEBUG if opts.debug else logging.INFO, | ||
| 273 | format='%(levelname)s: %(message)s') | ||
| 274 | |||
| 275 | cfg_path = os.path.join(XDG_CONFIG_DIR, 'quicktile.cfg') | ||
| 276 | first_run = not os.path.exists(cfg_path) | ||
| 277 | config = load_config(cfg_path) | ||
| 278 | |||
| 279 |     ignore_workarea = ((not config.getboolean('general', 'UseWorkarea')) or | ||
| 280 | opts.no_workarea) | ||
| 281 | |||
| 282 | # TODO: Rearchitect so this hack isn't needed | ||
| 283 | commands.cycle_dimensions = commands.commands.add_many( | ||
| 284 |         layout.make_winsplit_positions(config.getint('general', 'ColumnCount')) | ||
| 285 | )(commands.cycle_dimensions) | ||
| 286 |     commands.commands.extra_state = {'config': config} | ||
| 287 | |||
| 288 | try: | ||
| 289 | winman = WindowManager(ignore_workarea=ignore_workarea) | ||
| 290 | except XInitError as err: | ||
| 291 |         logging.critical("%s", err) | ||
| 292 | sys.exit(1) | ||
| 293 | app = QuickTileApp(winman, | ||
| 294 | commands.commands, | ||
| 295 |                        keys=dict(config.items('keys')), | ||
| 296 |                        modmask=config.get('general', 'ModMask')) | ||
| 297 | |||
| 298 | if opts.show_binds: | ||
| 299 | app.show_binds() | ||
| 300 | if opts.show_args: | ||
| 301 | print(commands.commands) | ||
| 302 | |||
| 303 | if opts.daemonize: | ||
| 304 | if not app.run(): | ||
| 305 |             logging.critical("Neither the Xlib nor the D-Bus backends were " | ||
| 306 | "available") | ||
| 307 | sys.exit(errno.ENOENT) | ||
| 308 | # FIXME: What's the proper exit code for "library not found"? | ||
| 309 | elif not first_run: | ||
| 310 | if args: | ||
| 311 | winman.screen.force_update() | ||
| 312 | |||
| 313 | for arg in args: | ||
| 314 | commands.commands.call(arg, winman) | ||
| 315 | while gtk.events_pending(): # pylint: disable=no-member | ||
| 316 | gtk.main_iteration() # pylint: disable=no-member | ||
| 317 | elif not opts.show_args and not opts.show_binds: | ||
| 318 | print(commands.commands) | ||
| 319 |             print("\nUse --help for a list of valid options.") | ||
| 320 | sys.exit(errno.ENOENT) | ||
| 321 | |||
| 326 | 
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: