Black Mamba documentation

Welcome stranger. Use one of the following links to continue.

About Black Mamba

Black Mamba is Python™ package for Pythonista application.

Pythonista is great tool, seriously, but it lacks some features like keyboard shortcuts for specific actions. I’m slow without them. So I decided to write set of scripts to fix all these issues. To speed up my iteration cycle. To make it as fast as possible. And which snake is the speediest one on the planet? Black Mamba. And now you know why it’s called Black Mamba.

For learning how to use Black Mamba, see the Black Mamba User Guide.

For detailed reference documentation of the functions and classes contained in the package, see the Black Mamba Reference.

Author

Written in spare time by Robert Vojta. You can find me at:

Blog is highly irregular and it’s almost one year from my last post. I’m not good at blogging. I always think that I have nothing to say and I blog about things I’m unable to find elsewhere only. Better stick with Twitter or GitHub.

Black Mamba User Guide

Release:1.4.3
Date:Jan 11, 2018

This guide is intended as an introductory overview of Black Mamba and explains how to install and make use of the most important features of Black Mamba. For detailed reference documentation of the functions and classes contained in the package, see the Black Mamba Reference.

Requirements

System

  • iOS >= 10
  • iPad w/ external keyboard

External keyboard “is a must”. You can use Scripts as action items (wrench menu icon), but it’s not as great as with Keyboard shortcuts.

Note

Black Mamba should work on iPhone, but the UI is not optimized for this device at all. You can try it, but it’s not officially supported and never will be.

Continue to Installation.

Installation

Install

import requests as r; exec(r.get('http://bit.ly/get-blackmamba').text)

Copy the above line, paste it into Pythonista interactive prompt and execute it. Black Mamba will be installed under the site-packages-3 folder.

Update

Black Mamba checks for updates automatically. You can disable check for updates entirely or you can configure time interval. See Configuration section.

Updates are not installed automatically. Black Mamba just informs you about available update. Copy & paste the installation line into Pythonista interactive prompt and execute it. Latest version will be downloaded and installed.

PIP

Black Mamba no longer supports installation via pip. Latest available release is 1.0.2.

Startup

Black Mamba requires from you to put following lines to the ~/Documents/site-packages-3/pythonista_startup.py file:

#!python3
import blackmamba

blackmamba.main()

This is bare minimum. Continue to Configuration section to learn how to tweak Black Mamba.

Configuration

I strongly suggests to check config.py:_DEFAULTS from time to time. Just to check if this documentation isn’t outdated.

Sections

General

Defaults:

'general': {
    'jedi': False,
    'register_key_commands': True,
    'page_line_count': 40
}

jedi: bool - JEDI is used as a backend for Find usages, Jump to definition and Show documentation Scripts. But because JEDI is also used by the Pythonista, JEDI is not thread safe and I don’t know when and how it is used, it’s disabled by default. You have to set it to True to enable mentioned scripts.

register_key_commands: bool - set to False to disable default Keyboard shortcuts.

page_line_count: int - number of lines to scroll up / down for page up / down.

Updates

Defaults:

'update': {
    'enabled': True,
    'interval': 3600
}

enabled: bool - set to False to disable check for updates.

interval: int - check for updates time interval (in seconds).

File picker

Defaults:

'file_picker': {
    'ignore_folders': {
        '': ['.git'],
        '.': ['.Trash', 'Examples',
              'site-packages', 'site-packages-2', 'site-packages-3']
    }
}

ignore_folders: dict - key is a parent directory (not full path, just name) and value is a list of folders to ignore. You can use two special values as keys:

  • '' - any parent directory,
  • '.' - parent directory is ~/Documents.

Default value says that .git folder inside any folder is ignored. .Trash, Examples, … folders inside ~/Documents folder are ignored as well.

Affects Open quickly and Run quickly scripts, see Scripts.

Analyzer

Defaults (since 1.1.0):

  • ignore_codes option is removed /ignored
  • max_line_length option is removed / ignored
'analyzer': {
    'hud_alert_delay': 1.0,
    'remove_whitespaces': True,
    'flake8': [
        # 1st pass
        ['--select=E901,E999,F821,F822,F823'],
        # 2nd pass
        ['--max-complexity=10', '--max-line-length=127']
    ]
}

If flake8 is provided, ignore_codes and max_line_length options are ignored. flake8 must contain list of passes and every pass contains list of flake8 arguments. You can run flake8 several times with different options in this way.

Defaults (pre 1.1.0):

'analyzer': {
    'hud_alert_delay': 1.0,
    'ignore_codes': None,
    'max_line_length': 127,
    'remove_whitespaces': True
}

Affects Analyze script, see Scripts.

Tester

Defaults:

'tester': {
    'hud_alert_delay': 1.0,
    'hide_console': True
}

Affects Run unit tests script, see Scripts.

Drag and Drop

Defaults:

'drag_and_drop': {
    'ignore_folders': {
        '': ['.git'],
        '.': ['.Trash', 'Examples',
              'site-packages', 'site-packages-2', 'site-packages-3', 'stash_extensions']
    }
}

Affects Drag & Drop script, see Scripts.

Documentation

Defaults:

'documentation': {
    'reuse': True,
    'frame': (630, 110, 730, 350)
}

reuse: bool - same overlay view is reused for consequent show documentation calls if set to True. Otherwise multiple overlays appear in consequent show documentation calls, but if a symbol’s fully qualified name matches existing overlay, this particular overlay is expanded and activated.

frame: tuple(float, float, float, float) - initial overlay frame in the key window coordinates.

Affects Show documentation script, see Scripts.

Sample

See pythonista_startup.py for more examples.

Keyboard shortcuts

General

Cmd 0 toggles file navigator / library.

Dialogs

You can close all dialogs with Esc key. Use Cmd . if you have a keyboard without Esc key.

Dialogs with tables support arrow keys to change selection and Enter key to select item.

Some of these dialogs support Shift Enter for an alternate action. Example is the Open Quickly script where you can open file in a new tab (Enter) or in the current tab (Shift Enter).

Tabs

Cmd 1 .. Cmd 9 quickly switches between tabs.

Ctrl Tab or Cmd Shift ] selects next tab and Ctrl Shift Tab or Cmd Shift [ selects previous tab.

Cmd W closes current tab and Cmd Shift W closes all tabs except current one.

Cmd T creates new empty tab and Cmd N shows Pythonista new file dialog.

Note

Shortcuts Cmd W, Ctrl Tab and Ctrl Shift Tab are no longer registered if you’re using Pythonista (> 311013). These three are natively supported. They still do work if you’re using older Pythonista version.

Editor

Ctrl Up for page up, Ctrl Down for page down. Page line count is configurable, see Configuration.

Scripts

Scripts keyboard shortcuts binding:

Shortcut Function
Cmd E Drag & Drop
Cmd / Toggle comments
Cmd Shift O Open quickly
Cmd Shift 0 Search Dash
Cmd Shift R Run quickly
Cmd Shift A Action quickly
Ctrl Shift B Analyze
Cmd Shift K Clear annotations
Cmd U Run unit tests
Cmd Shift L Outline quickly
Ctrl L Jump to line
Ctrl Cmd J Jump to definition
Ctrl Cmd U Find usages
Ctrl Cmd ? Show documentation
Ctrl W Close active overlay [1]
Cmd Option O Refactor - Organize imports
Cmd Option E Refactor - Expand star imports
Cmd Option R Refactor - Rename
[1]Show documentation script does use overlays.

Just hold Cmd key and iOS will show you all available shortcuts if you can’t remember them.

Custom shortcuts

See blackmamba.uikit.keyboard to learn how to register custom keyboard shortcuts.

Scripts

Following scripts are usable as Pythonista action items (wrench menu icon). In other words, you can use them even without external keyboard.

Note

Scripts still requires you to call blackmamba.main(), see Startup section.

Action quickly

Script name action_quickly.py.

Shows dialog with user defined action items (wrench icon). You can filter them by title, use arrow keys to change selection and run any of them with Enter key.

Only user defined action items are listed.

Analyze

Script name analyze.py.

Source code analysis with flake8. Results are displayed as Pythonista annotations. If there’s no error / warning, HUD informs you about that.

This script is configurable, see Analyzer configuration.

Clear annotations

Script name clear_annotations.py.

Clears all Pythonista annotations.

Close all tabs except current one

Script name close_all_tabs_except_current_one.py.

Closes all tabs except current one.

Drag & Drop

Script name drag_and_drop.py. iOS >= 11.0 required.

Shows dialog with opened files and folders tree. You can drag a file / folder to any other iOS application. Works well with Working Copy and Kaleidoscope for example.

You can drag a file / folder from any other iOS application as well. But there’s one limitation, you can drop them at the folder only.

This script is configurable, see Drag and Drop configuration.

Find usages

Script name find_usages.py.

Finds usages of a symbol. If there’re no usage, HUD informs you. Otherwise dialog appears where you can select location and scroll to it.

Note

JEDI must be enabled, see General configuration.

Jump to definition

Script name jump_to_definition.py.

Jumps to symbol definition. If definition can’t be found, HUD informs you. Otherwise it jumps to definition location or shows dialog where you can choose location if more than one definition was found.

Note

JEDI must be enabled, see General configuration.

Jump to line

Script name jump_to_line.py.

Shows dialog where you can enter line number to scroll to.

New file

Script name new_file.py.

If there’s no opened file in the Pythonista, new tab is created and New File… button tap is emulated.

Otherwise dialog appears where you can enter new file name. File will be created in the current folder. If it already exists, file will be opened instead of creating new one.

New tab

Script name new_tab.py.

Creates new empty tab.

Open quickly

Script name open_quickly.py.

Shows dialog with all your files. You can filter these files by directories, file name, etc. Use arrow keys to change selection and then hit Enter to open selected file.

If file is already opened, Black Mamba changes selected tab only.

This script is configurable, see File picker configuration.

Outline quickly

Script name outline_quickly.py.

Shows source code outline. You can filter functions, … by name. Use arrows key to change selection and then hit Enter to scroll to the symbol.

Run quickly

Script name run_quickly.py.

Shows dialog with all your Python files. You can filter these files by directories, file name, etc. Use arrows keys to change selection and then hit Enter to run selected file.

This script is configurable, see File picker configuration.

Run unit tests

Script name run_unit_tests.py.

Runs unit tests and show results as Pythonista annotations.

This script is configurable, see Tester configuration.

Search Dash

Script name search_dash.py.

Opens Dash application with selected text or a symbol around cursor position.

Show documentation

Script name show_documentation.py.

Shows documentation for the symbol around cursor. If definition can’t be found, HUD informs you. If there’re more than one definitions, dialog appears where you can select which one to show.

Documentation is displayed as an overlay, which can be closed by the Ctrl W shortcut or by tapping on the X button.

This script is configurable, see Documentation configuration.

Note

JEDI must be enabled, see General configuration.

Toggle comments

Script name toggle_comments.py.

Toggles current line / selected lines comments.

Refactoring

All refactoring scripts are limited to open single file only.

Note

It’s an experiment. You should use version control system to avoid loosing data.

Rename

Script name rename.py.

Rename identifier.

Expand star imports

Script name expand_star_imports.py.

Expand star imports.

Organize imports

Script name organize_imports.py.

Organize imports.

Futurize

Script name futurize.py.

Runs stage 1 of the futurizer.

Black Mamba Reference

Release:1.4.3
Date:Jan 11, 2018

Versioning

Black Mamba does use semantic versioning since version 1.0.0. Given a version number MAJOR.MINOR.PATCH:

  • MAJOR version is incremented if there’re incompatible API changes,
  • MINOR version is incremented if there’s a new functionality in a backwards-compatible manner,
  • PATCH version is incremented if there’re backwards-compatible bug fixes.

Black Mamba does not use additional labels for pre-release and build metadata as extensions to the MAJOR.MINOR.PATCH format.

Modules

Following modules are considered to be the API for Black Mamba from the versioning point of view. Black Mamba includes lot of other modules, but it’s not recommended to use them, because they can break even if MAJOR is not incremented.

blackmamba

Black Mamba initialization module.

Module is Python 3 compatible only.

The only requirement is to call blackmamba.main(). Example:

import blackmamba
blackmamba.main()

Warning

Do not add top level imports which depends on Pythonista modules. Module must be importable on any other platform. Add these imports to specific functions decorated with blackmamba.system.Pythonista and / or blackmamba.system.iOS.

Reference
blackmamba.main(config=None)[source]

Black Mamba initialization.

Call this function from pythonista_startup.py (site-packages-3) file.

Parameters:config – Optional dictionary, see Configuration

Example:

import blackmamba

config = {
    'general': {
        'jedi': True
    }
}

blackmamba.main(config)

See pythonista_startup.py for more examples.

blackmamba.log

Logging module.

Why custom module instead of logging? Several reasons:

  • not to interfere with Pythonista logging settings,
  • unable to convince Pythonista to use my colors,
  • etc.

Default log level is INFO. You can use blackmamba.log.set_level() to change effective log level. Available log levels are:

  • ERROR
  • WARNING
  • INFO
  • DEBUG
  • NOTSET

If you’d like to silent Black Mamba messages, it’s recommended to set log level to ERROR.

import blackmamba.log as log

log.set_level(log.ERROR)

Warning

This module must not introduce dependency on any other Black Mamba modules and must be importable on any other platform.

Reference
blackmamba.log.get_level()[source]

Return effective log level.

Returns:Effective log level
blackmamba.log.set_level(level)[source]

Set effective log level.

Parameters:level – Level to set
blackmamba.log.debug(*args, **kwargs)[source]

Log message with DEBUG level.

Parameters:
blackmamba.log.info(*args, **kwargs)[source]

Log message with INFO level.

Parameters:
blackmamba.log.warn(*args, **kwargs)[source]

Log message with WARNING level.

Parameters:
blackmamba.log.error(*args, **kwargs)[source]

Log message with ERROR level.

Parameters:

blackmamba.system

System info and decorators.

Warning

This module must not introduce dependency on any other Black Mamba modules and must be importable on any other platform as well.

Reference
blackmamba.system.PYTHONISTA = False

bool: True if we’re running within Pythonista or False.

blackmamba.system.IOS = False

bool: True if we’re running within iOS or False.

blackmamba.system.PYTHONISTA_VERSION = None

str: Pythonista version or None if we’re not within Pythonista.

blackmamba.system.PYTHONISTA_BUNDLE_VERSION = None

int: Pythonista bundle version or None if we’re not within Pythonista.

blackmamba.system.PYTHONISTA_VERSION_TUPLE = None

tuple(int): Pythonista version tuple (3, 1, 1) or None if we’re not within Pythonista.

blackmamba.system.IOS_VERSION = None

str: iOS version or None if we’re not within iOS.

blackmamba.system.IOS_VERSION_TUPLE = None

tuple(int): iOS version tuple (11, 0) or None if we’re not within iOS.

class blackmamba.system.iOS(from_version=None, to_version=None)[source]

Decorator to execute function under specific iOS versions.

Return value is return value of decorated function or None if iOS condition isn’t met.

Examples:

Run function only within any iOS version:

@iOS()
def run_me():
    pass

Run function only within iOS >= 11.0:

@iOS('11.0')  # or @iOS(from_version='11.0')
def run_me():
    pass

Run function only within iOS <= 11.0:

@iOS(None, '11.0')  # or @iOS(to_version='11.0')
def run_me():
    pass
class blackmamba.system.Pythonista(from_version=None, to_version=None, appex=None)[source]

Decorator to execute function under specific Pythonista versions.

By default, function is not executed under application extension. You have to pass appex=True if you’d like to run some function under appex as well.

Return value is return value of decorated function or None if Pythonista condition isn’t met.

Examples:

Run function only within any Pythonista version:

@Pythonista()
def run_me():
    pass

Run function only within any Pythonista version and allow appex:

@Pythonista(appex=True)
def run_me():
    pass

Run function only within any Pythonista version and disallow appex:

@Pythonista(appex=False)
def run_me():
    pass

Run function only within Pythonista >= 3.1.1:

@Pythonista('3.1.1')  # or @Pythonista(from_version='3.1.1')
def run_me():
    pass

Run function only within Pythonista <= 3.2:

@Pythonista(None, '3.2')  # or @Pythonista(to_version='3.2')
def run_me():
    pass
blackmamba.system.catch_exceptions(func)[source]

Decorator catching all Exception exceptions and writing info to console.

Use this decorator for functions handling keyboard shortcuts, keyboard events, … to avoid Pythonista crash.

Parameters:func – Function to decorate
Returns:Return value of func

blackmamba.uikit.keyboard

Keyboard shortcuts.

Key commands

Key command is kind of global shortcut in Pythonista. They’re visible if you hold down Cmd key for example. Black Mamba does use key commands for shortcuts like toggle comments, etc.

Related functions:

Following example shows how to print Hallo with Cmd H keyboard shortcut.

from blackmamba.uikit.keyboard import (
    register_key_command, UIKeyModifier
)

def hallo():
    print('Hallo')

register_key_command(
    'h',
    UIKeyModifier.command,
    hallo,
    'Print Hallo'  # Optional discoverability title (hold down Cmd)
)
Key event handlers

Key event handler is kind of local keyboard shortcut. They’re not visible if you hold down Cmd key. Designed to be used in custom dialogs.

Related functions:

Following example shows how to close dialog with Cmd . keyboard shortcut.

from blackmamba.uikit.keyboard import (
    register_key_event_handler, UIEventKeyCode, UIKeyModifier,
    unregister_key_event_handlers
)

class MyView(ui.View):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        def close_me():
            self.close()

        self._handlers = [
            register_key_event_handler(UIEventKeyCode.dot, close_me, modifier=UIKeyModifier.command)
        ]

    def will_close(self):
        unregister_key_event_handlers(self._handlers)
Reference
blackmamba.uikit.keyboard.is_in_hardware_keyboard_mode()[source]

Check if HW keyboard is connected.

Returns:True if HW keyboard is connected otherwise False
class blackmamba.uikit.keyboard.UIKeyModifier[source]

Key modifiers enumeration.

Modifiers can be combined like:

UIKeyModifier.command | UIKeyModifier.shift

See also:

none = 0

No modifier key

alphaShift = 65536

Caps Lock key

shift = 131072

Shift key

control = 262144

Control key

alternate = 524288

Option key

command = 1048576

Command key

numericPad = 2097152

Key is on numberic pad

class blackmamba.uikit.keyboard.UIEventKeyCode[source]

Event key codes.

Not all key codes are listed / included here. Feel free to create pull request with more key codes if you’d like to use them.

See also:

right = 79

Right arrow key

left = 80

Left arrow key

down = 81

Down arrow key

up = 82

Up arrow key

enter = 40

Enter key

space = 44

Space key

backspace = 42

Backspace key

escape = 41

Escape key

dot = 55

Dot key

class blackmamba.uikit.keyboard.UIKeyInput[source]

Enumeration of special key input values.

See also:

leftArrow = 'UIKeyInputLeftArrow'

Left arrow

rightArrow = 'UIKeyInputRightArrow'

Right arrow

upArrow = 'UIKeyInputUpArrow'

Up arrow

downArrow = 'UIKeyInputDownArrow'

Down arrow

blackmamba.uikit.keyboard.register_key_command(input, modifier_flags, function, title=None)[source]

Register key command.

Note

There’s no function to unregister key commands.

Parameters:
  • inputstr or UIKeyInput
  • modifier_flagsUIKeyModifier or int
  • function – Function to call
  • title – Optional discoverability title
Returns:

True if key command was registered otherwise False

blackmamba.uikit.keyboard.register_key_event_handler(key_code, func, *, modifier=<UIKeyModifier.none: 0>)[source]

Register key event handler.

Usable in dialogs for example. Do not forget to unregister key event handler in will_close function of your ui.View.

Parameters:
Returns:

Handler to use in unregister_key_event_handler()

blackmamba.uikit.keyboard.unregister_key_event_handler(handler)[source]

Unregister key event handler.

It is safe to call this function multiple times with the same handler. Handler is silently ignored if it’s not registered.

Parameters:handler – Handler from register_key_event_handler()
blackmamba.uikit.keyboard.unregister_key_event_handlers(handlers)[source]

Unregister list of key event handlers.

Convenience function, it just calls unregister_key_event_handler() for every handler.

Parameters:handlers – List of handlers

Contribution

There are several areas where you can help.

Documentation

I’m not native English speaker and some of my sentences sound weird. Fork blackmamba repository, update documentation and open pull request. Will happily merge it.

Documentation does use reStructuredText. Here’s quick start guide.

Why not Markdown? reStructuredText is more powerful and allows me to use links, references and other stuff.

Testing

If you find a bug, please do not hesitate to file an issue. I’m unable to test everything.

Development

Black Mamba is developed in my spare time. I have a full time job, love it and I don’t have much time to enhance it. If you’d like to help, see Development.

Questions

Do you have a question? File an issue, I’ll add question tag and will answer it. Or you can send me direct message on Twitter.

Development

Style

There’s no defined style for development. Just stick with the same style you see in other blackmamba modules.

Pull requests

Pull requests must pass flake8 checks:

flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
flake8 . --count --max-complexity=10 --max-line-length=127 --statistics

Pull requests must pass tests:

PYTHONPATH=. pytest tests

Consult .travis.yml for more details.

Existing issues

Let me know if you’d like to work on something. To avoid situation where I already started working on it.

New ideas

I’m open to new ideas as well. Please, file an issue first, we can discuss it and then you can implement it.

FAQ

General

Are you affiliated with Pythonista?

No. It’s a completely separate project. Although I discuss some of my ideas with Ole (Pythonista author) from time to time.

What if some feature will be added to Pythonista?

I’m perfectly okay with this and will be happy if something from Black Mamba will be natively supported by the Pythonista. That’s also the reason why I filled so many issues.

These features will be removed from Black Mamba after some period if this happens.

Bundled packages

Black Mamba has several bundled packages. Why?

  • Not fully working pip in Pythonista.
  • Pythonista contains some of these packages, but they’re outdated (longer release cycle).
  • Installation must be as easy as possible (no pip, pip3, no dependencies).

Packages

List of bundled packages.

docutils

Project homepage.

License

See COPYING for more details.

flake8

Project homepage.

License

Copyright (C) 2011-2013 Tarek Ziade <tarek@ziade.org> Copyright (C) 2012-2016 Ian Cordasco <graffatcolmingov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

future

Project homepage.

License

Copyright (c) 2013-2016 Python Charmers Pty Ltd, Australia

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

mccabe

Project homepage.

License

Copyright © <year> Ned Batchelder Copyright © 2011-2013 Tarek Ziade <tarek@ziade.org> Copyright © 2013 Florent Xicluna <florent.xicluna@gmail.com>

Licensed under the terms of the Expat License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pycodestyle

Project homepage.

License

Copyright © 2006-2009 Johann C. Rocholl <johann@rocholl.net> Copyright © 2009-2014 Florent Xicluna <florent.xicluna@gmail.com> Copyright © 2014-2016 Ian Lee <IanLee1521@gmail.com>

Licensed under the terms of the Expat License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pyflakes

Project homepage.

License

Copyright 2005-2011 Divmod, Inc. Copyright 2013-2014 Florent Xicluna

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

rope

Project homepage.

License

Copyright (C) 2015-2016 Nicholas Smith Copyright (C) 2014-2015 Matej Cepl Copyright (C) 2006-2012 Ali Gholami Rudi Copyright (C) 2009-2012 Anton Gritsay

This program is free software; you can redistribute it and/or modify it under the terms of GNU General Public License as published by the Free Software Foundation; either version 2 of the license, or (at your opinion) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.