Mu API Reference¶
This API reference is automatically generated from the docstrings found within the source code. It’s meant as an easy to use and easy to share window into the code base.
Take a look around! The code is simple and short.
mu.app
¶
The Mu application is created and configured in this module.
Mu - a “micro” Python editor for beginner programmers.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
Based upon work done for Puppy IDE by Dan Pope, Nicholas Tollervey and Damien George.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.app.
AnimatedSplash
(animation, parent=None)[source]¶ An animated splash screen for gifs. Includes a text area for logging output.
-
draw_log
(text)[source]¶ Draw the log entries onto the splash screen. Will only display the last self.log_lines number of log entries. The logs will be displayed at the bottom of the splash screen, justified left.
-
Simple wrapper around the QSharedMemory object, adding a context handler which uses the built in Semaphore as a locking mechanism and raises an error if the shared memory object is already in use
TODO: The *nix implementation doesn’t release the shared memory if a process attached to it crashes. There is code to attempt to detect this but it doesn’t seem worth implementing for the moment: we’re only talking about a page at most.
-
class
mu.app.
StartupWorker
[source]¶ A worker class for running blocking tasks on a separate thread during application start-up.
The animated splash screen will be shown until this thread is finished.
-
mu.app.
check_only_running_once
()[source]¶ If the application is already running log the error and exit
-
mu.app.
is_linux_wayland
()[source]¶ Checks environmental variables to try to determine if Mu is running on wayland.
-
mu.app.
run
()[source]¶ Creates all the top-level assets for the application, sets things up and then runs the application. Specific tasks include:
- set up logging
- set up global exception handler
- check that another instance of the app isn’t already running (exit if so)
- create an application object
- create an editor window and status bar
- display a splash screen while starting
- close the splash screen after startup timer ends
mu.logic
¶
Most of the fundamental logic for Mu is in this module.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
Based upon work done for Puppy IDE by Dan Pope, Nicholas Tollervey and Damien George.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.logic.
Device
(vid, pid, port, serial_number, manufacturer, long_mode_name, short_mode_name, board_name=None)[source]¶ Device object, containing both information about the connected device, the port it’s connected through and the mode it works with.
-
name
¶ Returns the device name.
-
-
class
mu.logic.
DeviceList
(modes, parent=None)[source]¶ -
add_device
(new_device)[source]¶ Add a new device to the device list, maintains alphabetical ordering
-
check_usb
()[source]¶ Ensure connected USB devices are polled. If there’s a change and a new recognised device is attached, inform the user via a status message. If a single device is found and Mu is in a different mode ask the user if they’d like to change mode.
-
-
class
mu.logic.
Editor
(view)[source]¶ Application logic for the editor itself.
-
ask_to_change_mode
(new_mode, mode_name, heading)[source]¶ Open a dialog asking the user, whether to change mode from mode_name to new_mode. The dialog can be customized by the heading-parameter.
-
change_mode
(mode)[source]¶ Given the name of a mode, will make the necessary changes to put the editor into the new mode.
-
check_code
()[source]¶ Uses PyFlakes and PyCodeStyle to gather information about potential problems with the code in the current tab.
-
check_for_shadow_module
(path)[source]¶ Check if the filename in the path is a shadow of a module already in the Python path. For example, many learners will save their first turtle based script as turtle.py, thus causing Python to never find the built in turtle module because of the name conflict.
If the filename shadows an existing module, return True, otherwise, return False.
-
connect_to_status_bar
(status_bar)[source]¶ Connect the editor with the Window-statusbar. Should be called after Editor.setup(), to ensure modes are initialized
-
debug_toggle_breakpoint
(margin, line, modifiers)[source]¶ How to handle the toggling of a breakpoint.
-
device_changed
(device)[source]¶ Slot for receiving signals that the current device has changed. If the device change requires mode change, the user will be asked through a dialog.
-
find_replace
()[source]¶ Handle find / replace functionality.
If find/replace dialog is dismissed, do nothing.
Otherwise, check there’s something to find, warn if there isn’t.
If there is, find (and, optionally, replace) then confirm outcome with a status message.
-
get_dialog_directory
(default=None)[source]¶ Return the directory folder which a load/save dialog box should open into. In order of precedence this function will return:
- If not None, the value of default.
- The last location used by a load/save dialog.
- The directory containing the current file.
- The mode’s reported workspace directory.
-
get_tab
(path)[source]¶ Given a path, returns either an existing tab for the path or creates / loads a new tab for the path.
-
has_python_extension
(filename)[source]¶ Check whether the given filename matches recognized Python extensions.
-
load
(*args, default_path=None)[source]¶ Loads a Python (or other supported) file from the file system or extracts a Python script from a hex file.
-
load_cli
(paths)[source]¶ Given a set of paths, passed in by the user when Mu starts, this method will attempt to load them and log / report a problem if Mu is unable to open a passed in path.
-
rename_tab
(tab_id=None)[source]¶ How to handle double-clicking a tab in order to rename the file. If activated by the shortcut, activate against the current tab.
-
restore_session
(paths=None)[source]¶ Attempts to recreate the tab state from the last time the editor was run. If paths contains a collection of additional paths specified by the user, they are also “restored” at the same time (duplicates will be ignored).
-
save_tab_to_file
(tab, show_error_messages=True)[source]¶ Given a tab, will attempt to save the script in the tab to the path associated with the tab. If there’s a problem this will be logged and reported and the tab status will continue to show as Modified.
-
show_admin
(event=None)[source]¶ Cause the editor’s admin dialog to be displayed to the user.
Ensure any changes to the envars is updated.
-
show_status_message
(message, duration=5)[source]¶ Displays the referenced message for duration seconds.
-
-
class
mu.logic.
MuFlakeCodeReporter
[source]¶ The class instantiates a reporter that creates structured data about code quality for Mu. Used by the PyFlakes module.
-
syntaxError
(filename, message, line_no, column, source)[source]¶ Records a syntax error in the file called filename.
The message argument contains an explanation of the syntax error, line_no indicates the line where the syntax error occurred, column indicates the column on which the error occurred and source is the source code containing the syntax error.
-
-
mu.logic.
check_flake
(filename, code, builtins=None)[source]¶ Given a filename and some code to be checked, uses the PyFlakesmodule to return a dictionary describing issues of code quality per line. See:
https://github.com/PyCQA/pyflakes
If a list symbols is passed in as “builtins” these are assumed to be additional builtins available when run by Mu.
-
mu.logic.
check_pycodestyle
(code, config_file=False)[source]¶ Given some code, uses the PyCodeStyle module (was PEP8) to return a list of items describing issues of coding style. See:
-
mu.logic.
extract_envars
(raw)[source]¶ Returns a list of environment variables given a string containing NAME=VALUE definitions on separate lines.
-
mu.logic.
save_and_encode
(text, filepath, newline='\n')[source]¶ Detect the presence of an encoding cookie and use that encoding; if none is present, do not add one and use the Mu default encoding. If the codec is invalid, log a warning and fall back to the default.
-
mu.logic.
sniff_encoding
(filepath)[source]¶ Determine the encoding of a file:
- If there is a BOM, return the appropriate encoding
- If there is a PEP 263 encoding cookie, return the appropriate encoding
- Otherwise return None for read_and_decode to attempt several defaults
-
mu.logic.
sniff_newline_convention
(text)[source]¶ Determine which line-ending convention predominates in the text.
Windows usually has U+000D U+000A Posix usually has U+000A But editors can produce either convention from either platform. And a file which has been copied and edited around might even have both!
mu.debugger
¶
The debugger consists of two parts:
- Client - used by Mu to process messages from the process being debugged.
- Runner - created in a new process to run the code to be debugged.
Messages are passed via inter-process communication.
mu.debugger.client
¶
Code used by the Mu application to communicate with the process being debugged.
A debug client for the Mu editor.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.debugger.client.
Breakpoint
(bpnum, filename, line, enabled=True, temporary=False, funcname=None)[source]¶ Represents a breakpoint, identified by a breakpoint number (bpnum). Users set breakpoints to stop the debugger at a certain line (potentially in a named function) in a file.
-
class
mu.debugger.client.
CommandBufferHandler
(debugger)[source]¶ Represents the work to be done on a separate thread for connecting and processing incoming messages.
Emits signals to indicate when messages are receievd or the connection fails at appropriate moments during the lifetime of a debug session.
-
on_command
¶ Signal emitted when a command is received.
-
on_fail
¶ Emitted when there was a connection failure.
-
-
exception
mu.debugger.client.
ConnectionNotBootstrapped
[source]¶ The connection to the runner hasn’t been completed.
-
class
mu.debugger.client.
Debugger
(host, port, proc=None)[source]¶ Represents the networked debugger client.
-
breakpoint
(breakpoint)[source]¶ Given a breakpoint number or (filename, line), return an object representing the referenced breakpoint.
-
create_breakpoint
(filename, line, temporary=False)[source]¶ Create a new, enabled breakpoint at the specified line of the given file.
-
ignore_breakpoint
(breakpoint, count)[source]¶ Ignore an existing breakpoint for “count” iterations.
(N.B. Use a count of 0 to restore the breakpoint.
-
on_breakpoint_disable
(bpnum)[source]¶ The runner has disabled a breakpoint referenced by breakpoint number.
-
on_breakpoint_enable
(bpnum)[source]¶ The runner has enabled the breakpoint referenced by breakpoint number.
-
on_breakpoint_ignore
(bpnum, count)[source]¶ The runner will ignore the referenced breakpoint “count” iterations.
-
mu.debugger.runner
¶
The runner code controls the debug process.
A debug runner for the Mu editor.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
exception
mu.debugger.runner.
ClientClose
[source]¶ Cause the debugger to wait for a new client to connect.
-
class
mu.debugger.runner.
DebugState
[source]¶ Enumerates the three possible states of a debugging session.
-
class
mu.debugger.runner.
Debugger
(socket, host, port, skip=None)[source]¶ Instances of this class represent and drive the debugging process.
-
do_continue
()[source]¶ Stop only at breakpoints or when finished. If there are no breakpoints on script start, do a set_trace to stop at the first available line. However, use the continue_flag to ensure set_continue is always called thereafter.
-
do_ignore
(bpnum, count)[source]¶ Ignore the breakpoint referenced by its breakpoint number (bpnum), count number of times.
-
do_quit
()[source]¶ Set the quitting attribute to True. This raises BdbQuit in the next call to one of the dispatch_*() methods.
-
output_stack
()[source]¶ Dump the current stack.
If this is a normal situation, the top two frames are BDB and the runner executing the program. If there is an exception, there are two further extra frames. All these frames can be ignored.
-
user_call
(frame, argument_list)[source]¶ This method is called from dispatch_call() when there is the possibility that a break might be necessary anywhere inside the called function.
-
user_exception
(frame, exc_info)[source]¶ This method is called from dispatch_exception() when stop_here() yields True.
For when an exception occurs, but only if we are to stop at or just below this level.
-
-
exception
mu.debugger.runner.
Restart
[source]¶ Cause the debugger to restart for the target Python program.
mu.interface
¶
This module contains all the PyQt related code needed to create the user
interface for Mu. All interaction with the user interface is done via the
Window
class in mu.interface.main
.
All the other sub-modules contain different bespoke aspects of the user interface.
mu.interface.main
¶
Contains the core user interface assets used by other parts of the application.
Contains the main Window definition for Mu’s UI.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.interface.main.
ButtonBar
(parent)[source]¶ Represents the bar of buttons across the top of the editor and defines their behaviour.
-
addAction
(name, display_name, tool_text)[source]¶ Creates an action associated with an icon and name and adds it to the widget’s slots.
-
-
class
mu.interface.main.
FileTabs
[source]¶ Extend the base class so we can override the removeTab behaviour.
-
class
mu.interface.main.
StatusBar
(parent=None, mode='python')[source]¶ Defines the look and behaviour of the status bar along the bottom of the UI.
-
connect_logs
(handler, shortcut)[source]¶ Connect the mouse press event and keyboard shortcut for the log widget to the referenced handler function.
-
connect_mode
(handler, shortcut)[source]¶ Connect the mouse press event and keyboard shortcut for the mode widget to the referenced handler function.
-
-
class
mu.interface.main.
Window
(parent=None)[source]¶ Defines the look and characteristics of the application’s main window.
-
add_filesystem
(home, file_manager, board_name='board')[source]¶ Adds the file system pane to the application.
-
add_jupyter_repl
(kernel_manager, kernel_client)[source]¶ Adds a Jupyter based REPL pane to the application.
-
add_micropython_plotter
(name, connection, data_flood_handler)[source]¶ Adds a plotter that reads data from a serial connection.
-
add_micropython_repl
(name, connection)[source]¶ Adds a MicroPython based REPL pane to the application.
-
add_python3_plotter
(mode)[source]¶ Add a plotter that reads from either the REPL or a running script. Since this function will only be called when either the REPL or a running script are running (but not at the same time), it’ll just grab data emitted by the REPL or script via data_received.
-
add_python3_runner
(interpreter, script_name, working_directory, interactive=False, debugger=False, command_args=None, envars=None, python_args=None)[source]¶ Display console output for the interpreter with the referenced pythonpath running the referenced script.
The script will be run within the workspace_path directory.
If interactive is True (default is False) the Python process will run in interactive mode (dropping the user into the REPL when the script completes).
If debugger is True (default is False) the script will be run within a debug runner session. The debugger overrides the interactive flag (you cannot run the debugger in interactive mode).
If there is a list of command_args (the default is None) then these will be passed as further arguments into the command run in the new process.
If envars is given, these will become part of the environment context of the new chlid process.
If python_args is given, these will be passed as arguments to the Python runtime used to launch the child process.
-
add_snek_repl
(name, connection, force_interrupt=True, wait_input=False)[source]¶ Adds a Snek based REPL pane to the application.
-
add_tab
(path, text, api, newline)[source]¶ Adds a tab with the referenced path and text to the editor.
-
annotate_code
(feedback, annotation_type)[source]¶ Given a list of annotations about the code in the current tab, add the annotations to the editor window so the user can make appropriate changes.
-
change_mode
(mode)[source]¶ Given a an object representing a mode, recreates the button bar with the expected functionality.
-
connect_find_again
(handlers, shortcut)[source]¶ Create keyboard shortcuts and associate them with handlers for doing a find again in forward or backward direction. Any given shortcut will be used for forward find again, while Shift+shortcut will find again backwards.
-
connect_find_replace
(handler, shortcut)[source]¶ Create a keyboard shortcut and associate it with a handler for doing a find and replace.
-
connect_tab_rename
(handler, shortcut)[source]¶ Connect the double-click event on a tab and the keyboard shortcut to the referenced handler (causing the Save As dialog).
-
connect_toggle_comments
(handler, shortcut)[source]¶ Create a keyboard shortcut and associate it with a handler for toggling comments on highlighted lines.
-
connect_zoom
(widget)[source]¶ Connects a referenced widget to the zoom related signals and sets the zoom of the widget to the current zoom level.
-
copy_to_repl
()[source]¶ Copies currently selected text in the editor, into the active REPL widget and sets focus to the REPL widget. The final line pasted into the REPL waits for RETURN to be pressed by the user (this appears to be the default behaviour for pasting into the REPL widget).
-
current_tab
¶ Returns the currently focussed tab.
-
get_load_path
(folder, extensions='*', allow_previous=True)[source]¶ Displays a dialog for selecting a file to load. Returns the selected path. Defaults to start in the referenced folder unless a previous folder has been used and the allow_previous flag is True (the default behaviour)
-
get_microbit_path
(folder)[source]¶ Displays a dialog for locating the location of the BBC micro:bit in the host computer’s filesystem. Returns the selected path. Defaults to start in the referenced folder.
-
get_save_path
(folder)[source]¶ Displays a dialog for selecting a file to save. Returns the selected path. Defaults to start in the referenced folder.
-
handle_python_anywhere_complete
(domain)[source]¶ Displays a confirmation that all the API calls completed OK and provides a link to the user’s website.
-
handle_python_anywhere_error
(error_message)[source]¶ Display a friendly message to indicate a problem was encountered when uploading to PythonAnywhere.
-
highlight_text
(target_text, forward=True)[source]¶ Highlight the first match from the current position of the cursor in the current tab for the target_text. Returns True if there’s a match.
-
modified
¶ Returns a boolean indication if there are any modified tabs in the editor.
Called when a user right-clicks on an editor pane.
If the REPL is active AND there is selected text in the current editor pane, modify the default context menu to include a paste to REPL option. Otherwise, just display the default context menu.
-
open_directory_from_os
(path)[source]¶ Given the path to a directory, open the OS’s built in filesystem explorer for that path. Works with Windows, OSX and Linux.
-
replace_text
(target_text, replace, global_replace)[source]¶ Given target_text, replace the first instance after the cursor with “replace”. If global_replace is true, replace all instances of “target”. Returns the number of times replacement has occurred.
-
resizeEvent
(resizeEvent)[source]¶ Respond to window getting too small for the button bar to fit well.
-
set_timer
(duration, callback)[source]¶ Set a repeating timer to call “callback” every “duration” seconds.
-
set_usb_checker
(duration, callback)[source]¶ Sets up a timer that polls for USB changes via the “callback” every “duration” seconds.
-
setup
(breakpoint_toggle, theme)[source]¶ Sets up the window.
Defines the various attributes of the window and defines how the user interface is laid out.
-
show_admin
(log, settings, packages, mode, device_list)[source]¶ Display the administrative dialog with referenced content of the log and settings. Return a dictionary of the settings that may have been changed by the admin dialog.
-
show_confirmation
(message, information=None, icon=None)[source]¶ Displays a modal message to the user to which they need to confirm or cancel.
If information is passed in this will be set as the additional informative text in the modal dialog.
Since this mechanism will be used mainly for warning users that something is awry the default icon is set to “Warning”. It’s possible to override the icon to one of the following settings: NoIcon, Question, Information, Warning or Critical.
-
show_find_replace
(find, replace, global_replace)[source]¶ Display the find/replace dialog. If the dialog’s OK button was clicked return a tuple containing the find term, replace term and global replace flag.
-
show_message
(message, information=None, icon=None)[source]¶ Displays a modal message to the user.
If information is passed in this will be set as the additional informative text in the modal dialog.
Since this mechanism will be used mainly for warning users that something is awry the default icon is set to “Warning”. It’s possible to override the icon to one of the following settings: NoIcon, Question, Information, Warning or Critical.
-
size_window
(x=None, y=None, w=None, h=None)[source]¶ Makes the editor 80% of the width*height of the screen and centres it when none of x, y, w and h is passed in; otherwise uses the passed in values to position and size the editor window.
If the X or Y value will be off the screen, these are reset to None (thus stopping the window being drawn in a hard-to-reach place). See issue #1613 for context.
-
sync_packages
(to_remove, to_add)[source]¶ Display a modal dialog that indicates the status of the add/remove package management operation.
-
tab_count
¶ Returns the number of active tabs.
-
toggle_comments
()[source]¶ Toggle comments on/off for all selected line in the currently active tab.
-
update_debug_inspector
(locals_dict)[source]¶ Given the contents of a dict representation of the locals in the current stack frame, update the debug inspector with the new values.
-
update_title
(filename=None)[source]¶ Updates the title bar of the application. If a filename (representing the name of the file currently the focus of the editor) is supplied, append it to the end of the title.
-
upload_to_python_anywhere
(instance, username, token, app_name, files)[source]¶ Show a progress dialog as the files are uploaded to PythonAnywhere.
-
widgets
¶ Returns a list of references to the widgets representing tabs in the editor.
-
mu.interface.dialogs
¶
Bespoke modal dialogs required by Mu.
UI related code for dialogs used by Mu.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.interface.dialogs.
AdminDialog
(parent=None)[source]¶ Displays administrative related information and settings (logs, environment variables, third party packages etc…).
-
class
mu.interface.dialogs.
ESPFirmwareFlasherWidget
[source]¶ Used for configuring how to interact with the ESP:
- Override MicroPython.
-
class
mu.interface.dialogs.
EnvironmentVariablesWidget
[source]¶ Used for editing and displaying environment variables used with Python 3 mode.
-
class
mu.interface.dialogs.
FindReplaceDialog
(parent=None)[source]¶ Display a dialog for getting:
- A term to find,
- An optional value to replace the search term,
- A flag to indicate if the user wishes to replace all.
-
class
mu.interface.dialogs.
LocaleWidget
[source]¶ Used for manually setting the locale (and thus the language) used by Mu.
-
class
mu.interface.dialogs.
MicrobitSettingsWidget
[source]¶ Used for configuring how to interact with the micro:bit:
- Minification flag.
- Override runtime version to use.
-
class
mu.interface.dialogs.
ModeItem
(name, description, icon, parent=None)[source]¶ Represents an available mode listed for selection.
-
class
mu.interface.dialogs.
ModeSelector
(parent=None)[source]¶ Defines a UI for selecting the mode for Mu.
-
class
mu.interface.dialogs.
PackageDialog
(parent=None)[source]¶ Display the output of the pip commands needed to remove or install packages.
Because the QProcess mechanism we’re using is asynchronous, we have to manage the pip requests via pip_queue. When one request is signalled as finished we start the next.
mu.interface.editor
¶
Contains the customised Scintilla based editor used for textual display and entry.
UI related capabilities for the text editor widget embedded in each tab in Mu.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.interface.editor.
EditorPane
(path, text, newline='n')[source]¶ Represents the text editor.
-
annotate_code
(feedback, annotation_type='error')[source]¶ Given a list of annotations add them to the editor pane so the user can act upon them.
-
connect_margin
(func)[source]¶ Connect clicking the margin to the passed in handler function, via a filtering handler that ignores clicks on margin 4.
-
find_next_match
(text, from_line=-1, from_col=-1, case_sensitive=True, wrap_around=True)[source]¶ Finds the next text match from the current cursor, or the given position, and selects it (the automatic selection is the only available QsciScintilla behaviour). Returns True if match found, False otherwise.
-
highlight_selected_matches
()[source]¶ Checks the current selection, if it is a single word it then searches and highlights all matches.
Since we’re interested in exactly one word: * Ignore an empty selection * Ignore anything which spans more than one line * Ignore more than one word * Ignore anything less than one word
-
label
¶ The label associated with this editor widget (usually the filename of the script we’re editing).
-
range_from_positions
(start_position, end_position)[source]¶ Given a start-end pair, such as are provided by a regex match, return the corresponding Scintilla line-offset pairs which are used for searches, indicators etc.
NOTE: Arguments must be byte offsets into the underlying text bytes.
-
reset_check_indicators
()[source]¶ Clears all the text indicators related to the check code functionality.
-
reset_debugger_highlight
()[source]¶ Reset all the lines so the DEBUG_INDICATOR is no longer displayed.
We need to check each line since there’s no way to tell what the currently highlighted line is. This approach also has the advantage of resetting the whole editor pane.
-
selection_change_listener
()[source]¶ Runs every time the text selection changes. This could get triggered multiple times while the mouse click is down, even if selection has not changed in itself. If there is a new selection is passes control to highlight_selected_matches.
-
set_theme
(theme=<class 'mu.interface.themes.DayTheme'>)[source]¶ Connect the theme to a lexer and return the lexer for the editor to apply to the script text.
-
set_zoom
(size='m')[source]¶ Sets the font zoom to the specified base point size for all fonts given a t-shirt size.
-
title
¶ The title associated with this editor widget (usually the filename of the script we’re editing).
If the script has been modified since it was last saved, the label will end with an asterisk.
-
mu.interface.panes
¶
Contains code used to populate the various panes found in the user interface (REPL, file list, debug inspector etc…).
Contains the UI classes used to populate the various panes used by Mu.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.interface.panes.
DebugInspector
[source]¶ Presents a tree like representation of the current state of the call stack to the user.
-
class
mu.interface.panes.
FileSystemPane
(home)[source]¶ Contains two QListWidgets representing the micro:bit and the user’s code directory. Users transfer files by dragging and dropping. Highlighted files can be selected for deletion.
-
class
mu.interface.panes.
JupyterREPLPane
(theme='day', parent=None)[source]¶ REPL = Read, Evaluate, Print, Loop.
Displays a Jupyter iPython session.
-
class
mu.interface.panes.
LocalFileList
(home)[source]¶ Represents a list of files in the Mu directory on the local machine.
-
class
mu.interface.panes.
MicroPythonDeviceFileList
(home)[source]¶ Represents a list of files on a MicroPython device.
-
class
mu.interface.panes.
MicroPythonREPLPane
(connection, theme='day', parent=None)[source]¶ REPL = Read, Evaluate, Print, Loop.
This widget represents a REPL client connected to a device running MicroPython.
The device MUST be flashed with MicroPython for this to work.
Creates custom context menu with just copy and paste.
-
delete_selection
()[source]¶ Returns true if deletion happened, returns false if there was no selection to delete.
-
keyPressEvent
(data)[source]¶ Called when the user types something in the REPL.
Correctly encodes it and sends it to the connected device.
-
mouseReleaseEvent
(mouseEvent)[source]¶ Called whenever a user have had a mouse button pressed, and releases it. We pass it through to the normal way Qt handles button pressed, but also sends as cursor movement signal to the device (except if a selection is made, for selections we first move the cursor on deselection)
-
move_cursor_to
(new_position)[source]¶ Move the cursor, by sending vt100 left/right signals through serial. The Qt cursor is first returned to the known location of the device cursor. Then the appropriate number of move left or right signals are send. The Qt cursor is not moved to the new_position here, but will be moved once receiving a response (in process_tty_data).
-
process_tty_data
(data)[source]¶ Given some incoming bytes of data, work out how to handle / display them in the REPL widget. If received input is incomplete, stores remainder in self.unprocessed_input.
Updates the self.device_cursor_position to match that of the device for every input received.
-
set_devicecursor_to_qtcursor
()[source]¶ Call this whenever the cursor has been moved by the user, to send the cursor movement to the device.
-
class
mu.interface.panes.
MuFileList
[source]¶ Contains shared methods for the two types of file listing used in Mu.
-
class
mu.interface.panes.
PlotterPane
(parent=None)[source]¶ This plotter widget makes viewing sensor data easy!
This widget represents a chart that will look for tuple data from the MicroPython REPL, Python 3 REPL or Python 3 code runner and will auto-generate a graph.
-
add_data
(values)[source]¶ Given a tuple of values, ensures there are the required number of line series, add the data to the line series, update the range of the chart so the chart displays nicely.
-
-
class
mu.interface.panes.
PythonProcessPane
(parent=None)[source]¶ Handles / displays a Python process’s stdin/out with working command history and simple buffer editing.
Creates custom context menu with just copy and paste.
-
history_back
()[source]¶ Replace the current input line with the next item BACK from the current history position.
-
history_forward
()[source]¶ Replace the current input line with the next item FORWARD from the current history position.
-
on_process_halt
()[source]¶ Called when the the user has manually halted a running process. Ensures that the remaining data from the halted process’s stdout is handled properly.
When the process is halted the user is dropped into the Python prompt and this method ensures the UI is updated in a clean, non-blocking way.
-
parse_input
(key, text, modifiers)[source]¶ Correctly encodes user input and sends it to the connected process.
The key is a Qt.Key_Something value, text is the textual representation of the input, and modifiers are the control keys (shift, CTRL, META, etc) also used.
-
parse_paste
(text)[source]¶ Recursively takes characters from text to be parsed as input. We do this so the event loop has time to respond to output from the process to which the characters are sent (for example, when a newline is sent).
Yes, this is a quick and dirty hack, but ensures the pasted input is also evaluated in an interactive manner rather than as a single-shot splurge of data. Essentially, it’s simulating someone typing in the characters of the pasted text really fast but in such a way that the event loop cycles.
-
set_start_of_current_line
()[source]¶ Set the flag to indicate the start of the current line (used before waiting for input).
This flag is used to discard the preceeding text in the text entry field when Mu parses new input from the user (i.e. any text beyond the self.start_of_current_line).
-
start_process
(interpreter, script_name, working_directory, interactive=True, debugger=False, command_args=None, envars=None, python_args=None)[source]¶ Start the child Python process.
Will use the referenced interpreter to run the Python script_name within the context of the working directory.
If interactive is True (the default) the Python process will run in interactive mode (dropping the user into the REPL when the script completes).
If debugger is True (the default is False) then the script will run within a debug runner session.
If there is a list of command_args (the default is None), then these will be passed as further arguments into the script to be run.
If there is a list of environment variables, these will be part of the context of the new child process.
If python_args is given, these are passed as arguments to the Python interpreter used to launch the child process.
-
class
mu.interface.panes.
SnekREPLPane
(connection, theme='day', parent=None)[source]¶ REPL = Read, Evaluate, Print, Loop.
This widget represents a REPL client connected to a device running Snek.
The device MUST be flashed with Snek for this to work.
-
execute
(commands)[source]¶ Execute a series of commands over a period of time (scheduling remaining commands to be run in the next iteration of the event loop).
-
keyPressEvent
(data)[source]¶ Called when the user types something in the REPL.
Correctly encodes it and sends it to the connected device.
-
mu.interface.themes
¶
Theme related code so Qt changes for each pre-defined theme.
Theme and presentation related code for the Mu editor.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.interface.themes.
ContrastTheme
[source]¶ Defines a Python related theme including the various font colours for syntax highlighting.
This is the high contrast theme.
-
class
mu.interface.themes.
DayTheme
[source]¶ Defines a Python related theme including the various font colours for syntax highlighting.
This is a light theme.
-
class
mu.interface.themes.
Font
(color='#181818', paper='#FEFEF7', bold=False, italic=False)[source]¶ Utility class that makes it easy to set font related values within the editor.
-
classmethod
get_database
()[source]¶ Create a font database and load the MU builtin fonts into it. This is a cached classmethod so the font files aren’t re-loaded every time a font is refereced
-
stylename
¶ Map the bold and italic boolean flags here to a relevant font style name.
-
classmethod
mu.modes
¶
Contains the definitions of the various modes Mu into which Mu can be put. All
the core functionality is in the mu.modes.base
module.
mu.modes.base
¶
Core functionality and base classes for all Mu’s modes. The definitions of
API autocomplete and call tips can be found in the mu.modes.api
namespace.
Contains the base classes for Mu editor modes.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.modes.base.
BaseMode
(editor, view)[source]¶ Represents the common aspects of a mode.
-
actions
()[source]¶ Return an ordered list of actions provided by this module. An action is a name (also used to identify the icon) , description, and handler.
-
add_plotter
()[source]¶ Mode specific implementation of adding and connecting a plotter to incoming streams of data tuples.
-
assets_dir
(asset_type)[source]¶ Determine (and create) the directory for a set of assets
This supports the [Images] and [Sounds] &c. buttons in pygamezero mode and possibly other modes, too.
If a tab is current and has an active file, the assets directory is looked for under that path; otherwise the workspace directory is used.
If the assets directory does not exist it is created
-
builtins
= None¶ Symbols to assume as builtins when checking code style.
-
ensure_state
()[source]¶ Executed when the mode is finished setting up. Used to ensure button / UI state according to current state of settings.
-
on_data_flood
()[source]¶ Handle when the plotter is being flooded by data (which usually causes Mu to become unresponsive). In this case, remove the plotter and display a warning dialog to explain what’s happened and how to fix things (usually, put a time.sleep(x) into the code generating the data).
-
open_file
(path)[source]¶ Some files are not plain text and each mode can attempt to decode them.
When overridden, should return the text and newline convention for the file.
-
remove_plotter
()[source]¶ If there’s an active plotter, hide it.
Save any data captured while the plotter was active into a directory called ‘data_capture’ in the workspace directory. The file contains CSV data and is named with a timestamp for easy identification.
-
return_focus_to_current_tab
()[source]¶ After, eg, stopping the plotter or closing the REPL return the focus to the currently-active tab is there is one.
-
save_timeout
= 5¶ Number of seconds to wait before saving work.
Given the names and boolean settings of buttons associated with actions for the current mode, toggles them into the boolean enabled state.
-
stop
()[source]¶ Called if/when the editor quits when in this mode. Override in child classes to clean up state, stop child processes etc.
-
-
class
mu.modes.base.
FileManager
(port)[source]¶ Used to manage filesystem operations on connected MicroPython devices in a manner such that the UI remains responsive.
Provides an FTP-ish API. Emits signals on success or failure of different operations.
-
delete
(device_filename)[source]¶ Delete the referenced file on the device’s filesystem. Emit the name of the file when complete, or emit a failure signal.
-
get
(device_filename, local_filename)[source]¶ Get the referenced device filename and save it to the local filename. Emit the name of the filename when complete or emit a failure signal.
-
ls
()[source]¶ List the files on the micro:bit. Emit the resulting tuple of filenames or emit a failure signal.
-
-
class
mu.modes.base.
MicroPythonMode
(editor, view)[source]¶ Includes functionality that works with a USB serial based REPL.
-
add_repl
()[source]¶ Detect a connected MicroPython based device and, if found, connect to the REPL and display it to the user.
-
compatible_board
(port)[source]¶ A compatible board must match on vendor ID, but only needs to match on product ID or manufacturer ID, if they are supplied in the list of valid boards (aren’t None).
-
-
class
mu.modes.base.
REPLConnection
(port, baudrate=115200)[source]¶
-
mu.modes.base.
get_default_workspace
()[source]¶ Return the location on the filesystem for opening and closing files.
The default is to use a directory in the users home folder, however in some network systems this in inaccessible. This allows a key in the settings file to be used to set a custom path.
mu.modes.circuitpython
¶
CircuitPython mode for Adafruit boards (and others).
A mode for working with Circuit Python boards.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.modes.circuitpython.
CircuitPythonMode
(editor, view)[source]¶ Represents the functionality required by the CircuitPython mode.
-
actions
()[source]¶ Return an ordered list of actions provided by this module. An action is a name (also used to identify the icon) , description, and handler.
-
compatible_board
(port)[source]¶ Use adafruit_board_toolkit to find out whether a board is running CircuitPython. The toolkit sees if the CDC Interface name is appropriate.
-
connected
= True¶ is the board connected.
-
force_interrupt
= False¶ NO keyboard interrupt on serial connection.
-
save_timeout
= 0¶ No auto-save on CP boards. Will restart.
-
mu.modes.debugger
¶
The Python 3 debugger mode.
The mode Mu is is when it’s debugging a Python 3 script.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.modes.debugger.
DebugMode
(editor, view)[source]¶ Represents the functionality required by the Python 3 visual debugger.
-
actions
()[source]¶ Return an ordered list of actions provided by this module. An action is a name (also used to identify the icon) , description, and handler.
Button clicked to continue running the script.
Button clicked to step into the current block of code.
Button clicked to step out of the current block of code.
Button clicked to step over the current line of code.
Button clicked to stop the current script and return to Python3 mode.
-
debug_on_bootstrap
()[source]¶ Once the debugger is bootstrapped ensure all the current breakpoints are set. Do not set breakpoints (and remove the marker) if:
- The marker is not visible (the line is -1)
- The marker is not a duplicate of an existing line.
- The line with the marker is not a valid breakpoint line.
-
debug_on_breakpoint_clear
(breakpoint)[source]¶ Handle the clearing of the referenced breakpoint. Currently an unimplemented extra feature.
-
debug_on_breakpoint_ignore
(breakpoint, count)[source]¶ Handle when a breakpoint is to be ignored by the debugger. Currently an unimplemented extra feature.
-
debug_on_call
(args)[source]¶ Handle when the debugger has called a function with the referenced args. Make sure the debugger steps into the function.
-
debug_on_exception
(name, value)[source]¶ Handle when the debugger encounters a named exception with an associated value. Clear the highlighted line and allow the script to run until the end so the error message is printed to stdout.
-
debug_on_fail
(message)[source]¶ Called when, for any reason, the debug client was unable to connect to the debug runner. On a Raspberry Pi this is usually because it’s an underpowereed machine and it takes time to start the debug runner process. (However, the debug client waits for 10 seconds for the runner to start.)
-
debug_on_finished
()[source]¶ Called when the runner has completed running the script to be debugged.
-
debug_on_line
(filename, line)[source]¶ Handle when the debugger has moved to the referenced line in the file.
-
debug_on_postmortem
(args, kwargs)[source]¶ Handle when something catastrophic happens to the debugger.
-
debug_on_restart
()[source]¶ Handle when the debugger restarts. Currenty an unimplemented extra feature.
-
debug_on_return
(return_value)[source]¶ Handle when the debugger returns from a function call with the referenced return value. Make sure the debugger steps out of the function to the caller.
Disable all debug control buttons except ‘stop’.
Set a timer to disable all debug control buttons except ‘stop’.
Enable all debug control buttons except ‘stop’: if the timer started in disable_buttons_later is active, stops it and does nothing else.
-
mu.modes.microbit
¶
The original BBC micro:bit mode.
The mode for working with the BBC micro:bit. Contains most of the origial functionality from Mu when it was only a micro:bit related editor.
Copyright (c) 2015-2021 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.modes.microbit.
DeviceFlasher
(path_to_microbit, python_script=None, path_to_runtime=None)[source]¶ Used to flash the micro:bit in a non-blocking manner.
-
class
mu.modes.microbit.
MicrobitMode
(editor, view)[source]¶ Represents the functionality required by the micro:bit mode.
-
actions
()[source]¶ Return an ordered list of actions provided by this module. An action is a name (also used to identify the icon) , description, and handler.
-
copy_main
(script)[source]¶ If script argument contains any code, copy it onto the connected micro:bit as main.py, then restart the board (CTRL-D).
-
flash
()[source]¶ Performs multiple checks to see if it needs to flash MicroPython into the micro:bit and then sends via serial the Python script from the currently active tab. In some error cases it attaches the code directly into the MicroPython hex and flashes that (this method is much slower and deprecated).
WARNING: This method is getting more complex due to several edge cases. Ergo, it’s a target for refactoring.
-
flash_and_send
(script, microbit_path, rt_path=None)[source]¶ Start the MicroPython hex flashing process in a new thread with a custom hex file, or the one provided by uFlash. Then send the user script via serial.
-
flash_attached
(script, microbit_path)[source]¶ Start the MicroPython hex flashing process in a new thread with the hex file provided by uFlash and the script added to the filesystem in the hex.
-
flash_failed
(error)[source]¶ Called when the thread used to flash the micro:bit encounters a problem.
-
fs
= None¶ Reference to filesystem navigator.
-
get_device_micropython_version
()[source]¶ Retrieves the MicroPython version from a micro:bit board. Errors bubble up, so caller must catch them.
-
minify_if_needed
(python_script_bytes)[source]¶ Minify the script if is too large to fit in flash via uFlash appended method. Raises exceptions if minification fails or cannot be performed.
-
on_data_flood
()[source]¶ Ensure the Files button is active before the REPL is killed off when a data flood of the plotter is detected.
-
open_file
(path)[source]¶ Tries to open a MicroPython hex file with an embedded Python script.
Returns the embedded Python script and newline convention.
-
mu.modes.pygamezero
¶
The Pygame Zero / pygame mode.
The Pygame Zero mode for the Mu editor.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.modes.pygamezero.
PyGameZeroMode
(editor, view)[source]¶ Represents the functionality required by the PyGameZero mode.
-
actions
()[source]¶ Return an ordered list of actions provided by this module. An action is a name (also used to identify the icon) , description, and handler.
-
show_fonts
(event)[source]¶ Open the directory containing the font assets used by Pygame Zero.
This should open the host OS’s file system explorer so users can drag new files into the opened folder.
-
show_images
(event)[source]¶ Open the directory containing the image assets used by Pygame Zero.
This should open the host OS’s file system explorer so users can drag new files into the opened folder.
-
show_music
(event)[source]¶ Open the directory containing the music assets used by Pygame Zero.
This should open the host OS’s file system explorer so users can drag new files into the opened folder.
-
mu.modes.python3
¶
The Python 3 editing mode.
The Python3 mode for the Mu editor.
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
-
class
mu.modes.python3.
KernelRunner
(kernel_name, cwd, envars)[source]¶ Used to control the iPython kernel in a non-blocking manner so the UI remains responsive.
-
class
mu.modes.python3.
PythonMode
(editor, view)[source]¶ Represents the functionality required by the Python 3 mode.
-
actions
()[source]¶ Return an ordered list of actions provided by this module. An action is a name (also used to identify the icon) , description, and handler.
-
on_data_flood
()[source]¶ Ensure the process (REPL or runner) causing the data flood is stopped before the base on_data_flood is called to turn off the plotter and tell the user what to fix.
-
on_kernel_start
(kernel_manager, kernel_client)[source]¶ Handles UI update when the kernel runner has started the iPython kernel.
-
mu.resources
¶
Contains utility functions for working with binary assets used by Mu (mainly images).
Copyright (c) 2015-2017 Nicholas H.Tollervey and others (see the AUTHORS file).
Based upon work done for Puppy IDE by Dan Pope, Nicholas Tollervey and Damien George.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.