In Python3, classes no longer need to explicitly inherit from object

This commit is contained in:
Arjan Molenaar 2019-05-04 20:51:15 +02:00
parent d6f01f9fe0
commit d3db2205e1
55 changed files with 111 additions and 110 deletions

View File

@ -16,7 +16,7 @@ First you need to describe event types you want to use in your application,
``generic.event`` dispatches events to corresponding handlers by inspecting
events' types, so it's natural to model those as classes::
class CommentAdded(object):
class CommentAdded:
def __init__(self, post_id, comment):
self.post_id = post_id
self.comment = comment

View File

@ -12,7 +12,7 @@ and managing data objects. Items can be queried using this element factory.
It's registered in the application as `element_factory`. When writing a service
or plugin the element factory can be injected into the service like this::
class MyThing(object):
class MyThing:
element_factory = inject('element_factory')

View File

@ -57,19 +57,19 @@ For methods, it should be possible to create a decorator (@reversible) that
schedules a method with the same signature as the calling operation, but with
the inverse effect (e.g. the gaphas.tree module)::
class Tree(object):
class Tree:
@reversable(lambda s, n, p: s.remove(n))
def add(self, node, parent=None):
... add
... add
@reversable(add, self='self', node='node', parent='self.get_parent(node)')
def remove(self, node):
... remove
Okay, so the second case is tougher...
So what we did:
Add a StateManager to gaphas. All changes are sent to the statemanager.
Gaphor should implement its own state manager.
@ -82,18 +82,18 @@ Gaphor should implement its own state manager.
Transactions
------------
Gaphor's Undo manager works transactionally. Typically, methods can be
Gaphor's Undo manager works transactionally. Typically, methods can be
decorated with @transactional and undo data is stored in the current
transaction. A new tx is created when none exists.
Although undo functionality is at the core of Gaphor (diagram items and
model elements have been adapted to provide proper undo information), the
model elements have been adapted to provide proper undo information), the
UndoManager itself is just a service.
Transaction support though is a real core functionality. By letting elements
and items emit event notifications on important changed other (yet to be
defined) services can take benefit of those events. The UML module already
works this way. Gaphas (the Gaphor canvas) also emits state changes.
works this way. Gaphas (the Gaphor canvas) also emits state changes.
When state changes happen in model elements and diagram items an event is
emitted. Those events are handled by special handlers that produce
@ -113,7 +113,7 @@ Now, that should be done when a model element or diagram item sends a state
change:
1. The event is handled by the "reverse-handler"
2. Reverse handler generates a IUndoEvent signal
2. Reverse handler generates a IUndoEvent signal
3. The signal is received and stored as part of the undo-transaction.
(Maybe step 2 and 3 can be merged, since only one function is not of any
@ -127,7 +127,7 @@ When the topmost Transaction is committed:
2. This triggers the UndoManager to close and store the transaction.
When a transaction is rolled back:
1. The main transaction is marked for rollback
2. When the toplevel tx is rolled back or committed a
TransactionRollback event is emitted

View File

@ -46,7 +46,7 @@ class collectionlist(recursemixin, querymixin, list):
"""
class collection(object):
class collection:
"""
Collection (set-like) for model elements' 1:n and n:m relationships.
"""

View File

@ -10,7 +10,7 @@ import uuid
from gaphor.UML.properties import umlproperty
class Element(object):
class Element:
"""
Base class for UML data classes.
"""

View File

@ -20,7 +20,7 @@ from gaphor.interfaces import IService
from gaphor.misc import odict
class ElementFactory(object):
class ElementFactory:
"""
The ElementFactory is used to create elements and do lookups to
elements.

View File

@ -3,7 +3,7 @@
from gaphor.event import ServiceEvent
class ElementEvent(object):
class ElementEvent:
"""Generic event fired when element state changes.
"""

View File

@ -13,14 +13,14 @@ See the documentation on the mixins.
__all__ = ["querymixin", "recursemixin"]
class Matcher(object):
class Matcher:
"""
Returns True if the expression returns True.
The context for the expression is the element.
Given a class:
>>> class A(object):
>>> class A:
... def __init__(self, name): self.name = name
We can create a path for each object:
@ -57,13 +57,13 @@ class Matcher(object):
return False
class querymixin(object):
class querymixin:
"""
Implementation of the matcher as a mixin for lists.
Given a class:
>>> class A(object):
>>> class A:
... def __init__(self, name): self.name = name
We can do nice things with this list:
@ -123,7 +123,7 @@ def issafeiterable(obj):
return False
class recurseproxy(object):
class recurseproxy:
"""
Proxy object (helper) for the recusemixin.
@ -167,14 +167,14 @@ class recurseproxy(object):
return type(self)(type(self.__sequence)(mygetattr()))
class recursemixin(object):
class recursemixin:
"""
Mixin class for lists, sets, etc. If data is requested using ``[:]``,
a ``recurseproxy`` instance is created.
The basic idea is to have a class that can contain children:
>>> class A(object):
>>> class A:
... def __init__(self, name, *children):
... self.name = name
... self.children = list(children)
@ -208,7 +208,7 @@ class recursemixin(object):
>>> class rlist(recursemixin, list):
... pass
>>> class A(object):
>>> class A:
... def __init__(self, name, *children):
... self.name = name
... self.children = rlist(children)

View File

@ -49,7 +49,7 @@ from gaphor.UML.event import (
log = logging.getLogger(__name__)
class umlproperty(object):
class umlproperty:
"""
Superclass for attribute, enumeration and association.
@ -502,7 +502,7 @@ class associationstub(umlproperty):
c.discard(value)
class unioncache(object):
class unioncache:
"""
Small cache helper object for derivedunions.
"""

View File

@ -6,12 +6,12 @@ See also gaphor/service/actionmanager.py for the management module.
from gaphor.application import Application
class action(object):
class action:
"""
Decorator. Turns a regular function (/method) into a full blown
Action class.
>>> class A(object):
>>> class A:
... @action(name="my_action", label="my action")
... def myaction(self):
... print('action called')
@ -90,7 +90,7 @@ def build_action_group(obj, name=None):
Build actions and a Gtk.ActionGroup for each Action instance found in obj()
(that's why Action is a class ;) ). This function requires GTK+.
>>> class A(object):
>>> class A:
... @action(name='bar')
... def bar(self): print('Say bar')
... @toggle_action(name='foo')

View File

@ -280,7 +280,7 @@ class FlowItemActionTestCase(TestCase):
self.assertEqual("tguard", flow.subject.guard)
class FlowItemDesisionAndForkNodes(object):
class FlowItemDesisionAndForkNodes:
"""
Base class for flow connecting to decision and fork nodes.

View File

@ -29,7 +29,7 @@ class ComponentLookupError(LookupError):
_ESSENTIAL_SERVICES = ["component_registry", "element_dispatcher"]
class _Application(object):
class _Application:
"""
The Gaphor application is started from the Application instance. It behaves
like a singleton in many ways.
@ -197,14 +197,14 @@ class _Application(object):
Application = _Application()
class inject(object):
class inject:
"""
Simple descriptor for dependency injection.
This is technically a wrapper around Application.get_service().
Usage::
>>> class A(object):
>>> class A:
... element_factory = inject('element_factory')
"""

View File

@ -60,7 +60,7 @@ class FlowItem(NamedLine):
# class ACItem(TextElement):
class ACItem(object):
class ACItem:
"""
Activity edge connector. It is a circle with name inside.
"""

View File

@ -18,7 +18,7 @@ from gaphor.diagram.textelement import text_extents, text_align
log = logging.getLogger(__name__)
class FeatureItem(object):
class FeatureItem:
"""
FeatureItems are model elements who reside inside a ClassifierItem, such
as methods and attributes. Those items can have comments attached, but only

View File

@ -16,7 +16,7 @@ from gaphor.diagram.style import ALIGN_CENTER, ALIGN_TOP
logger = logging.getLogger(__name__)
class StereotypeSupport(object):
class StereotypeSupport:
"""
Support for stereotypes for every diagram item.
"""

View File

@ -19,19 +19,19 @@ def Editor(obj):
@multidispatch(object, object)
class Group(object):
class Group:
def __init__(self, parent, item):
pass
@multidispatch(object, object)
class Group(object):
class Group:
def __init__(self, parent, item):
pass
@multidispatch(object, object)
class IConnect(object):
class IConnect:
"""
This function is used by the HandleTool to allow connecting
lines to element items. For each specific case (Element, Line) an

View File

@ -60,7 +60,7 @@ class LifetimePort(LinePort):
return LineAlignConstraint(line, point, align, delta)
class LifetimeItem(object):
class LifetimeItem:
"""
Lifeline's lifetime object.
@ -204,7 +204,7 @@ class LifelineItem(NamedItem):
def draw(self, context):
"""
Draw lifeline.
Lifeline's head is always drawn.
Lifeline's lifetime is drawn when lifetime is visible.

View File

@ -19,7 +19,7 @@ PADDING_HINT = (1, 1, -1) # padding hint tuple
EPSILON = 1e-6
class Style(object):
class Style:
"""
Item style information. Style information is provided through object's
attributes, i.e.::

View File

@ -108,7 +108,7 @@ def text_multiline(cr, x, y, text, font, width=-1, height=-1):
)
class EditableTextSupport(object):
class EditableTextSupport:
"""
Editable text support to allow display and edit text parts of a diagram
item.
@ -377,7 +377,7 @@ class EditableTextSupport(object):
cr.restore()
class TextElement(object):
class TextElement:
"""
Representation of an editable text, which is part of a diagram item.

View File

@ -5,7 +5,7 @@ Application wide events are managed here.
from gaphor.interfaces import *
class ServiceEvent(object):
class ServiceEvent:
"""
An event emitted by a service.
"""
@ -34,7 +34,7 @@ class ServiceShutdownEvent(ServiceEvent):
self.service = service
class TransactionBegin(object):
class TransactionBegin:
"""
This event denotes the beginning of a transaction.
Nested (sub-) transactions should not emit this signal.
@ -43,7 +43,7 @@ class TransactionBegin(object):
pass
class TransactionCommit(object):
class TransactionCommit:
"""
This event is emitted when a transaction (toplevel) is successfully
committed.
@ -52,7 +52,7 @@ class TransactionCommit(object):
pass
class TransactionRollback(object):
class TransactionRollback:
"""
If a set of operations fail (e.i. due to an exception) the transaction
should be marked for rollback. This event is emitted to tell the operation
@ -62,7 +62,7 @@ class TransactionRollback(object):
pass
class ActionExecuted(object):
class ActionExecuted:
"""
Once an operation has successfully been executed this event is raised.
"""

View File

@ -31,7 +31,7 @@ Type "help" for more information.
)
class Help(object):
class Help:
def __call__(self, obj=None):
if obj:
pydoc.help(obj)
@ -45,7 +45,7 @@ class Help(object):
return str(self)
class TextViewWriter(object):
class TextViewWriter:
"""
A Multiplexing output stream.
It can replace another stream, and tee output to the original stream and too

View File

@ -50,7 +50,7 @@ class HandlerSet(namedtuple("HandlerSet", ["parents", "handlers"])):
yield handler
class Manager(object):
class Manager:
""" Event manager
Provides API for subscribing for and firing events. There's also global

View File

@ -44,7 +44,7 @@ def multidispatch(*argtypes):
return _replace_with_dispatcher
class FunctionDispatcher(object):
class FunctionDispatcher:
""" Multidispatcher for functions
This object dispatch calls to function by its argument types. Usually it is

View File

@ -8,7 +8,7 @@ This implementation was borrowed from happy[1] project by Chris Rossi.
__all__ = ("Registry", "SimpleAxis", "TypeAxis")
class Registry(object):
class Registry:
""" Registry implementation."""
def __init__(self, *axes):
@ -113,7 +113,7 @@ class _TreeNode(dict):
return "<TreeNode %s %s>" % (self.target, dict.__str__(self))
class SimpleAxis(object):
class SimpleAxis:
""" A simple axis where the key into the axis is the same as the object to
be matched (aka the identity axis). This axis behaves just like a
dictionary. You might use this axis if you are interested in registering

View File

@ -131,7 +131,7 @@ class ManagerTests(unittest.TestCase):
self.assertTrue("handler2" in eb.effects)
class Event(object):
class Event:
def __init__(self):
self.effects = []

View File

@ -62,7 +62,7 @@ class DispatcherTests(unittest.TestCase):
self.assertEqual(dispatcher((1,)), (1,))
def test_subtype_evaluation(self):
class Super(object):
class Super:
pass
class Sub(Super):

View File

@ -7,7 +7,7 @@ from gaphor.misc.generic.registry import Registry, SimpleAxis, TypeAxis
__all__ = ("RegistryTests",)
class DummyA(object):
class DummyA:
pass

View File

@ -18,7 +18,7 @@ from gi.repository import GLib
import time
class GIdleThread(object):
class GIdleThread:
"""This is a pseudo-"thread" for use with the GTK+ main loop.
This class does act a bit like a thread, all code is executed in
@ -148,7 +148,7 @@ class QueueFull(Exception):
pass
class Queue(object):
class Queue:
"""A FIFO queue. If the queue has a max size, the oldest item on the
queue is dropped if that size id exceeded.
"""

View File

@ -9,7 +9,7 @@ def rgetattr(obj, attr):
- obj: object
- attr: attribute name(s)
>>> class A(object): pass
>>> class A: pass
>>> a = A()
>>> a.a = A()
>>> a.a.a = 1
@ -36,7 +36,7 @@ def rsetattr(obj, attr, val):
- attr: attribute name(s)
- val: attribute value
>>> class A(object): pass
>>> class A: pass
>>> a = A()
>>> a.a = A()
>>> a.a.a = 1

View File

@ -3,7 +3,7 @@ import unittest
from gaphor.misc.xmlwriter import XMLWriter
class Writer(object):
class Writer:
def __init__(self):
self.s = ""

View File

@ -15,7 +15,7 @@ Given an object, this tool throws up a gtk tree widget that maps all the referen
from gi.repository import Gtk
class Browser(object):
class Browser:
def make_row(self, piter, name, value):
info = repr(value)
if not hasattr(value, "__dict__"):
@ -111,7 +111,7 @@ def dump(name, value):
def test():
class Nil(object):
class Nil:
pass
a = Nil()

View File

@ -12,7 +12,7 @@ from gaphor.plugins.pynsource.pynsource import PySourceAsText
BASE_CLASSES = ("object", "type", "dict", "list", "tuple", "int", "float")
class Engineer(object):
class Engineer:
"""
The Engineer class will create a Gaphor model based on a list of Python
files.

View File

@ -81,7 +81,7 @@ from gaphor.plugins.pynsource.keywords import (
DEBUG_DUMPTOKENS = False
class AndyBasicParseEngine(object):
class AndyBasicParseEngine:
def __init__(self):
self.meat = 0
self.tokens = None
@ -175,7 +175,7 @@ class AndyBasicParseEngine(object):
return 0
class ClassEntry(object):
class ClassEntry:
def __init__(self):
self.defs = []
self.attrs = []
@ -213,7 +213,7 @@ class ClassEntry(object):
# self.attrs.append(Attribute(attrname, attrtype))
class Attribute(object):
class Attribute:
def __init__(self, attrname, attrtype="normal"):
self.attrname = attrname
self.attrtype = attrtype
@ -1106,7 +1106,7 @@ class PySourceAsDelphi(PySourceAsText):
pass
class PythonToJava(object):
class PythonToJava:
def __init__(self, directories, treatmoduleasclass=0, verbose=0):
self.directories = directories
self.optionModuleAsClass = treatmoduleasclass

View File

@ -5,7 +5,7 @@ from gaphor.misc.xmlwriter import XMLWriter
logger = logging.getLogger(__name__)
class XMIExport(object):
class XMIExport:
XMI_VERSION = "2.1"
XMI_NAMESPACE = "http://schema.omg.org/spec/XMI/2.1"

View File

@ -18,7 +18,7 @@ from gaphor.UML.event import (
)
class EventWatcher(object):
class EventWatcher:
"""
A helper for easy registering and unregistering event handlers.
"""

View File

@ -14,7 +14,7 @@ from gaphor.abc import Service
from gaphor.interfaces import IService
class PropertyChangeEvent(object):
class PropertyChangeEvent:
"""This event is triggered any time a property is changed. This event
holds the property name, the current value, and the new value."""
@ -111,7 +111,7 @@ class Properties(Service):
self._backend.update(resources, key, value)
class FileBackend(object):
class FileBackend:
"""Resource backend that stores data to a resource file
($HOME/.gaphor/resource)."""

View File

@ -2,7 +2,7 @@ from unittest import TestCase
from gaphor.services.properties import Properties, FileBackend
import tempfile
# class MockApplication(object):
# class MockApplication:
#
# def __init__(self):
# self.events = []

View File

@ -43,7 +43,7 @@ from gaphor.transaction import Transaction, transactional
logger = logging.getLogger(__name__)
class ActionStack(object):
class ActionStack:
"""
A transaction. Every action that is added between a begin_transaction()
and a commit_transaction() call is recorded in a transaction, so it can

View File

@ -39,7 +39,7 @@ from xml.sax import handler
from gaphor.misc.odict import odict
class base(object):
class base:
"""Simple base class for element, canvas and canvasitem.
"""
@ -289,7 +289,7 @@ def parse_generator(filename, loader):
yield percentage
class ProgressGenerator(object):
class ProgressGenerator:
"""A generator that yields the progress of taking from a file input object
and feeding it into an output object. The supplied file object is neither
opened not closed by this generator. The file object is assumed to

View File

@ -17,7 +17,7 @@ from gaphor.storage import storage
from gaphor.tests.testcase import TestCase
class PseudoFile(object):
class PseudoFile:
def __init__(self):
self.data = ""

View File

@ -23,7 +23,7 @@ log = logging.getLogger("Gaphor")
log.setLevel(logging.WARNING)
class TestCaseExtras(object):
class TestCaseExtras:
"""
Mixin for some extra tests.
"""

View File

@ -49,7 +49,7 @@ class TransactionError(Exception):
pass
class Transaction(object):
class Transaction:
"""
The transaction. On start and end of a transaction an event is emitted.

View File

@ -167,7 +167,7 @@ def itemiter(toolbox_actions):
yield e
class DiagramToolbox(object):
class DiagramToolbox:
"""
Composite class for DiagramPage (diagrampage.py).
"""

View File

@ -97,7 +97,7 @@ class DiagramItemConnector(Connector.default):
super(DiagramItemConnector, self).disconnect()
class DisconnectHandle(object):
class DisconnectHandle:
"""
Callback for items disconnection using the adapters.

View File

@ -3,18 +3,18 @@ UI related events.
"""
class DiagramShow(object):
class DiagramShow:
def __init__(self, diagram):
self.diagram = diagram
class DiagramPageChange(object):
class DiagramPageChange:
def __init__(self, item):
self.item = item
self.diagram_page = item.diagram_page
class DiagramSelectionChange(object):
class DiagramSelectionChange:
def __init__(self, diagram_view, focused_item, selected_items):
self.diagram_view = diagram_view
self.focused_item = focused_item

View File

@ -4,7 +4,7 @@ or save files."""
from gi.repository import Gtk
class FileDialog(object):
class FileDialog:
"""This is a file dialog that is used to open or save a file."""
def __init__(

View File

@ -4,7 +4,7 @@
from gi.repository import Gtk
class QuestionDialog(object):
class QuestionDialog:
"""A dialog that displays a GTK MessageDialog to get a yes or no answer
from the user."""

View File

@ -6,9 +6,9 @@ from gi.repository import GLib, Gdk, Gtk, Pango
from gaphor.misc.gidlethread import QueueEmpty
class StatusWindow(object):
"""Create a borderless window on the parent, usually the main window,
with a label and a progress bar. The progress bar is updated as the
class StatusWindow:
"""Create a borderless window on the parent, usually the main window,
with a label and a progress bar. The progress bar is updated as the
queue is updated."""
def __init__(self, title, message, parent=None, queue=None, display=True):

View File

@ -5,7 +5,7 @@ from gaphor.ui.diagrampage import DiagramPage
from gaphor.ui.diagramtoolbox import TOOLBOX_ACTIONS
class WindowOwner(object):
class WindowOwner:
"""
Placeholder object for a MainWindow. Should provide just enough
methods to make the tests work.

View File

@ -9,7 +9,7 @@ import unittest
from utils.command.gen_uml import generate
class PseudoFile(object):
class PseudoFile:
def __init__(self):
self.data = ""
@ -36,9 +36,9 @@ GENERATED = """# This file is generated by build_uml.py. DO NOT EDIT!
from gaphor.UML.properties import association, attribute, enumeration, derived, derivedunion, redefine
# class 'ValSpec' has been stereotyped as 'SimpleAttribute'
# class 'ShouldNotShowUp' has been stereotyped as 'SimpleAttribute' too
class Element(object): pass
class Element: pass
class SubClass(Element): pass
class C(object): pass
class C: pass
class D(C): pass
C.attr = attribute('attr', str)
C.name1 = association('name1', SubClass, opposite='name2')

View File

@ -12,7 +12,7 @@ from utils.command import pygettext
# from pygettext.main():
class Options(object):
class Options:
# constants
GNU = 1
SOLARIS = 2

View File

@ -65,7 +65,7 @@ def msg(s):
sys.stderr.flush()
class Writer(object):
class Writer:
def __init__(self, filename, overrides=None):
self.overrides = overrides
if filename:
@ -93,10 +93,11 @@ class Writer(object):
if s:
s += ", "
s = s + g["name"]
if not s:
s = "object"
if not self.overrides.write_override(self, clazz["name"]):
self.write("class %s(%s): pass\n" % (clazz["name"], s))
self.write("class %s" % (clazz["name"],))
if s:
self.write("(%s)" % (s,))
self.write(": pass\n")
clazz.written = True
def write_property(self, full_name, value):

View File

@ -7,7 +7,7 @@ This is a simple rip-off of the override script used in PyGTK.
"""
class Overrides(object):
class Overrides:
def __init__(self, filename=None):
self.overrides = {}
if filename:

View File

@ -5,7 +5,7 @@
# Minimally patched to make it even more xgettext compatible
# by Peter Funk <pf@artcom-gmbh.de>
#
# 2002-11-22 Jürgen Hermann <jh@web.de>
# 2002-11-22 J<EFBFBD>rgen Hermann <jh@web.de>
# Added checks that _() only contains string literals, and
# command line args are resolved to module lists, i.e. you
# can now pass a filename, a module or package name, or a
@ -27,17 +27,17 @@ __doc__ = _(
Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
internationalization of C programs. Most of these tools are independent of
the programming language and can be used from within Python programs.
Martin von Loewis' work[1] helps considerably in this regard.
Martin von Loewis' work[1] helps considerably in this regard.
There's one problem though; xgettext is the program that scans source code
looking for message strings, but it groks only C (or C++). Python
introduces a few wrinkles, such as dual quoting characters, triple quoted
strings, and raw strings. xgettext understands none of this.
strings, and raw strings. xgettext understands none of this.
Enter pygettext, which uses Python's standard tokenize module to scan
Python source code, generating .pot files identical to what GNU xgettext[2]
generates for C and C++ code. From there, the standard GNU tools can be
used.
used.
A word about marking Python strings as candidates for translation. GNU
xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
@ -45,7 +45,7 @@ and gettext_noop. But those can be a lot of text to include all over your
code. C and C++ have a trick: they use the C preprocessor. Most
internationalized C source includes a #define for gettext() to _() so that
what has to be written in the source is much less. Thus these are both
translatable strings:
translatable strings:
gettext("Translatable String")
_("Translatable String")
@ -61,7 +61,7 @@ NOTE: pygettext attempts to be option and feature compatible with GNU
xgettext where ever possible. However some options are still missing or are
not fully implemented. Also, xgettext's use of command line switches with
option arguments is broken, and in these cases, pygettext just defines
additional switches.
additional switches.
Usage: pygettext [options] inputfile ...
@ -213,7 +213,7 @@ def make_escapes(pass_iso8859):
global escapes
if pass_iso8859:
# Allow iso-8859 characters to pass through so that e.g. 'msgid
# "Höhe"' would result not result in 'msgid "H\366he"'. Otherwise we
# "H<EFBFBD>he"' would result not result in 'msgid "H\366he"'. Otherwise we
# escape any character outside the 32..126 range.
mod = 128
else:
@ -367,7 +367,7 @@ def getFilesForName(name):
return []
class TokenEater(object):
class TokenEater:
def __init__(self, options):
self.__options = options
self.__messages = {}
@ -542,7 +542,7 @@ def main():
usage(1, msg)
# for holding option values
class Options(object):
class Options:
# constants
GNU = 1
SOLARIS = 2

View File

@ -15,7 +15,7 @@ import gaphor.storage.parser
import gaphor.UML
class Compare(object):
class Compare:
"""This class makes it possible to compare two files.
By default reports are printed to stdout in a diff-like syntax.
"""