Fixed #20841 -- Added messages to NotImplementedErrors

Thanks joseph at vertstudios.com for the suggestion.
This commit is contained in:
Gregor MacGregor 2013-09-06 13:24:52 -05:00 committed by Tim Graham
parent d59f1993f1
commit b2b763448f
26 changed files with 96 additions and 95 deletions

View File

@ -33,26 +33,26 @@ class ListFilter(object):
"""
Returns True if some choices would be output for this filter.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of ListFilter must provide a has_output() method')
def choices(self, cl):
"""
Returns choices ready to be output in the template.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of ListFilter must provide a choices() method')
def queryset(self, request, queryset):
"""
Returns the filtered queryset.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of ListFilter must provide a queryset() method')
def expected_parameters(self):
"""
Returns the list of parameter names that are expected from the
request's query string and that will be used by this filter.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of ListFilter must provide an expected_parameters() method')
class SimpleListFilter(ListFilter):
@ -89,7 +89,9 @@ class SimpleListFilter(ListFilter):
"""
Must be overridden to return a list of tuples (value, verbose value)
"""
raise NotImplementedError
raise NotImplementedError(
'The SimpleListFilter.lookups() method must be overridden to '
'return a list of tuples (value, verbose value)')
def expected_parameters(self):
return [self.parameter_name]

View File

@ -192,7 +192,7 @@ class BasePasswordHasher(object):
"""
Checks if the given password is correct
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BasePasswordHasher must provide a verify() method')
def encode(self, password, salt):
"""
@ -201,7 +201,7 @@ class BasePasswordHasher(object):
The result is normally formatted as "algorithm$salt$hash" and
must be fewer than 128 characters.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BasePasswordHasher must provide an encode() method')
def safe_summary(self, encoded):
"""
@ -210,7 +210,7 @@ class BasePasswordHasher(object):
The result is a dictionary and will be used where the password field
must be displayed to construct a safe representation of the password.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BasePasswordHasher must provide a safe_summary() method')
class PBKDF2PasswordHasher(BasePasswordHasher):

View File

@ -245,10 +245,10 @@ class AbstractBaseUser(models.Model):
return is_password_usable(self.password)
def get_full_name(self):
raise NotImplementedError()
raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_full_name() method')
def get_short_name(self):
raise NotImplementedError()
raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_short_name() method.')
# A few helper functions for common logic between User and AnonymousUser.
@ -441,16 +441,16 @@ class AnonymousUser(object):
return 1 # instances always return the same hash value
def save(self):
raise NotImplementedError
raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
def delete(self):
raise NotImplementedError
raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
def set_password(self, raw_password):
raise NotImplementedError
raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
def check_password(self, raw_password):
raise NotImplementedError
raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.")
def _get_groups(self):
return self._groups

View File

@ -112,7 +112,7 @@ class BaseCommentNode(six.with_metaclass(RenameBaseCommentNodeMethods, template.
def get_context_value_from_queryset(self, context, qs):
"""Subclasses should override this."""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseCommentNode must provide a get_context_value_from_queryset() method')
class CommentListNode(BaseCommentNode):
"""Insert a list of comments into the context."""
@ -338,4 +338,3 @@ def get_comment_permalink(comment, anchor_pattern=None):
if anchor_pattern:
return comment.get_absolute_url(anchor_pattern)
return comment.get_absolute_url()

View File

@ -101,7 +101,7 @@ class BaseSpatialOperations(object):
Returns the database column type for the geometry field on
the spatial backend.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseSpatialOperations must provide a geo_db_type() method')
def get_distance(self, f, value, lookup_type):
"""
@ -117,7 +117,7 @@ class BaseSpatialOperations(object):
stored procedure call to the transformation function of the spatial
backend.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseSpatialOperations must provide a geo_db_placeholder() method')
def get_expression_column(self, evaluator):
"""
@ -134,14 +134,14 @@ class BaseSpatialOperations(object):
raise NotImplementedError('Aggregate support not implemented for this spatial backend.')
def spatial_lookup_sql(self, lvalue, lookup_type, value, field):
raise NotImplementedError
raise NotImplementedError('subclasses of BaseSpatialOperations must a provide spatial_lookup_sql() method')
# Routines for getting the OGC-compliant models.
def geometry_columns(self):
raise NotImplementedError
raise NotImplementedError('subclasses of BaseSpatialOperations must a provide geometry_columns() method')
def spatial_ref_sys(self):
raise NotImplementedError
raise NotImplementedError('subclasses of BaseSpatialOperations must a provide spatial_ref_sys() method')
@python_2_unicode_compatible
class SpatialRefSysMixin(object):

View File

@ -105,7 +105,7 @@ class BaseStorage(object):
just containing no messages) then ``None`` should be returned in
place of ``messages``.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseStorage must provide a _get() method')
def _store(self, messages, response, *args, **kwargs):
"""
@ -116,7 +116,7 @@ class BaseStorage(object):
**This method must be implemented by a subclass.**
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseStorage must provide a _store() method')
def _prepare_messages(self, messages):
"""

View File

@ -284,7 +284,7 @@ class SessionBase(object):
"""
Returns True if the given session_key already exists.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of SessionBase must provide an exists() method')
def create(self):
"""
@ -292,7 +292,7 @@ class SessionBase(object):
a unique key and will have saved the result once (with empty data)
before the method returns.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of SessionBase must provide a create() method')
def save(self, must_create=False):
"""
@ -300,20 +300,20 @@ class SessionBase(object):
is created (otherwise a CreateError exception is raised). Otherwise,
save() can update an existing object with the same key.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of SessionBase must provide a save() method')
def delete(self, session_key=None):
"""
Deletes the session data under this key. If the key is None, the
current session key value is used.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of SessionBase must provide a delete() method')
def load(self):
"""
Loads the session data and returns a dictionary.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of SessionBase must provide a load() method')
@classmethod
def clear_expired(cls):
@ -324,4 +324,4 @@ class SessionBase(object):
NotImplementedError. If it isn't necessary, because the backend has
a built-in expiration mechanism, it should be a no-op.
"""
raise NotImplementedError
raise NotImplementedError('This backend does not support clear_expired().')

View File

@ -28,7 +28,7 @@ class BaseFinder(object):
the first found file path will be returned; if set
to ``True`` a list of all found files paths is returned.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseFinder must provide a find() method')
def list(self, ignore_patterns):
"""
@ -36,7 +36,7 @@ class BaseFinder(object):
a two item iterable consisting of the relative path and storage
instance.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseFinder must provide a list() method')
class FileSystemFinder(BaseFinder):

View File

@ -96,27 +96,27 @@ class BaseCache(object):
Returns True if the value was stored, False otherwise.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseCache must provide an add() method')
def get(self, key, default=None, version=None):
"""
Fetch a given key from the cache. If the key does not exist, return
default, which itself defaults to None.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseCache must provide a get() method')
def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
"""
Set a value in the cache. If timeout is given, that timeout will be
used for the key; otherwise the default cache timeout will be used.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseCache must provide a set() method')
def delete(self, key, version=None):
"""
Delete a key from the cache, failing silently.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseCache must provide a delete() method')
def get_many(self, keys, version=None):
"""
@ -190,7 +190,7 @@ class BaseCache(object):
def clear(self):
"""Remove *all* values from the cache at once."""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseCache must provide a clear() method')
def validate_key(self, key):
"""

View File

@ -92,55 +92,55 @@ class Storage(object):
"""
Deletes the specified file from the storage system.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Storage must provide a delete() method')
def exists(self, name):
"""
Returns True if a file referened by the given name already exists in the
storage system, or False if the name is available for a new file.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Storage must provide a exists() method')
def listdir(self, path):
"""
Lists the contents of the specified path, returning a 2-tuple of lists;
the first item being directories, the second item being files.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Storage must provide a listdir() method')
def size(self, name):
"""
Returns the total size, in bytes, of the file specified by name.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Storage must provide a size() method')
def url(self, name):
"""
Returns an absolute URL where the file's contents can be accessed
directly by a Web browser.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Storage must provide a url() method')
def accessed_time(self, name):
"""
Returns the last accessed time (as datetime object) of the file
specified by name.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Storage must provide an accessed_time() method')
def created_time(self, name):
"""
Returns the creation time (as datetime object) of the file
specified by name.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Storage must provide a created_time() method')
def modified_time(self, name):
"""
Returns the last modified time (as datetime object) of the file
specified by name.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Storage must provide a modified_time() method')
class FileSystemStorage(Storage):
"""

View File

@ -104,7 +104,7 @@ class FileUploadHandler(object):
Receive data from the streamed upload parser. ``start`` is the position
in the file of the chunk.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of FileUploadHandler must provide a recieve_data_chunk() method')
def file_complete(self, file_size):
"""
@ -113,7 +113,7 @@ class FileUploadHandler(object):
Subclasses should return a valid ``UploadedFile`` object.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of FileUploadHandler must provide a file_complete() method')
def upload_complete(self):
"""

View File

@ -36,4 +36,4 @@ class BaseEmailBackend(object):
Sends one or more EmailMessage objects and returns the number of email
messages sent.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseEmailBackend must override send_messages() method')

View File

@ -325,7 +325,7 @@ class BaseCommand(object):
this method.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseCommand must provide a handle() method')
class AppCommand(BaseCommand):
@ -361,7 +361,7 @@ class AppCommand(BaseCommand):
the command line.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of AppCommand must provide a handle_app() method')
class LabelCommand(BaseCommand):
@ -397,7 +397,7 @@ class LabelCommand(BaseCommand):
string as given on the command line.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of LabelCommand must provide a handle_label() method')
class NoArgsCommand(BaseCommand):
@ -423,4 +423,4 @@ class NoArgsCommand(BaseCommand):
Perform this command's actions.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of NoArgsCommand must provide a handle_noargs() method')

View File

@ -65,7 +65,7 @@ class Serializer(object):
"""
Called when serializing of the queryset starts.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of Serializer must provide a start_serialization() method')
def end_serialization(self):
"""
@ -77,7 +77,7 @@ class Serializer(object):
"""
Called when serializing of an object starts.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of Serializer must provide a start_object() method')
def end_object(self, obj):
"""
@ -89,19 +89,19 @@ class Serializer(object):
"""
Called to handle each individual (non-relational) field on an object.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of Serializer must provide an handle_field() method')
def handle_fk_field(self, obj, field):
"""
Called to handle a ForeignKey field.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of Serializer must provide an handle_fk_field() method')
def handle_m2m_field(self, obj, field):
"""
Called to handle a ManyToManyField.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of Serializer must provide an handle_m2m_field() method')
def getvalue(self):
"""
@ -135,7 +135,7 @@ class Deserializer(six.Iterator):
def __next__(self):
"""Iteration iterface -- return the next item in the stream"""
raise NotImplementedError
raise NotImplementedError('subclasses of Deserializer must provide a __next__() method')
class DeserializedObject(object):
"""

View File

@ -84,19 +84,19 @@ class BaseDatabaseWrapper(object):
def get_connection_params(self):
"""Returns a dict of parameters suitable for get_new_connection."""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseWrapper may require a get_connection_params() method')
def get_new_connection(self, conn_params):
"""Opens a connection to the database."""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseWrapper may require a get_new_connection() method')
def init_connection_state(self):
"""Initializes the database connection settings."""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseWrapper may require an init_connection_state() method')
def create_cursor(self):
"""Creates a cursor. Assumes that a connection is established."""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseWrapper may require a create_cursor() method')
##### Backend-specific methods for creating connections #####
@ -262,7 +262,7 @@ class BaseDatabaseWrapper(object):
"""
Backend-specific implementation to enable or disable autocommit.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseWrapper may require a _set_autocommit() method')
##### Generic transaction management methods #####
@ -440,7 +440,7 @@ class BaseDatabaseWrapper(object):
Tests if the database connection is usable.
This function may assume that self.connection is not None.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseWrapper may require an is_usable() method')
def close_if_unusable_or_obsolete(self):
"""
@ -519,11 +519,11 @@ class BaseDatabaseWrapper(object):
"""
Only required when autocommits_when_autocommit_is_off = True.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseWrapper may require a _start_transaction_under_autocommit() method')
def schema_editor(self, *args, **kwargs):
"Returns a new instance of this backend's SchemaEditor"
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseWrapper may require a schema_editor() method')
class BaseDatabaseFeatures(object):
@ -741,13 +741,13 @@ class BaseDatabaseOperations(object):
Given a lookup_type of 'year', 'month' or 'day', returns the SQL that
extracts a value from the given date field field_name.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseOperations may require a date_extract_sql() method')
def date_interval_sql(self, sql, connector, timedelta):
"""
Implements the date interval functionality for expressions
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseOperations may require a date_interval_sql() method')
def date_trunc_sql(self, lookup_type, field_name):
"""
@ -755,7 +755,7 @@ class BaseDatabaseOperations(object):
truncates the given date field field_name to a date object with only
the given specificity.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseOperations may require a datetrunc_sql() method')
def datetime_cast_sql(self):
"""
@ -772,7 +772,7 @@ class BaseDatabaseOperations(object):
'second', returns the SQL that extracts a value from the given
datetime field field_name, and a tuple of parameters.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseOperations may require a datetime_extract_sql() method')
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
"""
@ -781,7 +781,7 @@ class BaseDatabaseOperations(object):
field_name to a datetime object with only the given specificity, and
a tuple of parameters.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseOperations may require a datetime_trunk_sql() method')
def deferrable_sql(self):
"""
@ -916,7 +916,7 @@ class BaseDatabaseOperations(object):
Returns the value to use for the LIMIT when we are wanting "LIMIT
infinity". Returns None if the limit clause can be omitted in this case.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseOperations may require a no_limit_value() method')
def pk_default_value(self):
"""
@ -956,7 +956,7 @@ class BaseDatabaseOperations(object):
Returns a quoted version of the given table, index or column name. Does
not quote the given name if it's already been quoted.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseOperations may require a quote_name() method')
def quote_parameter(self, value):
"""
@ -982,7 +982,7 @@ class BaseDatabaseOperations(object):
If the feature is not supported (or part of it is not supported), a
NotImplementedError exception can be raised.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseOperations may require a regex_lookup() method')
def savepoint_create_sql(self, sid):
"""
@ -1028,7 +1028,7 @@ class BaseDatabaseOperations(object):
to tables with foreign keys pointing the tables being truncated.
PostgreSQL requires a cascade even if these tables are empty.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseOperations must provide a sql_flush() method')
def sequence_reset_by_name_sql(self, style, sequences):
"""
@ -1245,7 +1245,7 @@ class BaseDatabaseIntrospection(object):
Returns an unsorted list of names of all tables that exist in the
database.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseIntrospection may require a get_table_list() method')
def django_table_names(self, only_existing=False):
"""
@ -1322,7 +1322,7 @@ class BaseDatabaseIntrospection(object):
Backends can override this to return a list of (column_name, referenced_table_name,
referenced_column_name) for all key columns in given table.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseIntrospection may require a get_key_columns() method')
def get_primary_key_column(self, cursor, table_name):
"""
@ -1342,7 +1342,7 @@ class BaseDatabaseIntrospection(object):
Only single-column indexes are introspected.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseIntrospection may require a get_indexes() method')
def get_constraints(self, cursor, table_name):
"""
@ -1361,7 +1361,7 @@ class BaseDatabaseIntrospection(object):
Some backends may return special constraint names that don't exist
if they don't name constraints of a certain type (e.g. SQLite)
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseDatabaseIntrospection may require a get_constraints() method')
class BaseDatabaseClient(object):
@ -1378,7 +1378,7 @@ class BaseDatabaseClient(object):
self.connection = connection
def runshell(self):
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseClient must provide a runshell() method')
class BaseDatabaseValidation(object):

View File

@ -148,7 +148,7 @@ class BaseDatabaseSchemaEditor(object):
"""
Only used for backends which have requires_literal_defaults feature
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of BaseDatabaseSchemaEditor for backends which have requires_literal_defaults must provide a prepare_default() method')
def effective_default(self, field):
"""

View File

@ -38,14 +38,14 @@ class Operation(object):
Takes the state from the previous migration, and mutates it
so that it matches what this migration would perform.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Operation must provide a state_forwards() method')
def database_forwards(self, app_label, schema_editor, from_state, to_state):
"""
Performs the mutation on the database schema in the normal
(forwards) direction.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Operation must provide a database_forwards() method')
def database_backwards(self, app_label, schema_editor, from_state, to_state):
"""
@ -53,7 +53,7 @@ class Operation(object):
direction - e.g. if this were CreateModel, it would in fact
drop the model's table.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Operation must provide a database_backwards() method')
def describe(self):
"""

View File

@ -190,7 +190,7 @@ class Widget(six.with_metaclass(MediaDefiningClass)):
The 'value' given is not guaranteed to be valid input, so subclass
implementations should program defensively.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of Widget must provide a render() method')
def build_attrs(self, extra_attrs=None, **kwargs):
"Helper function for building an attribute dictionary."

View File

@ -99,7 +99,7 @@ class Origin(object):
self.name = name
def reload(self):
raise NotImplementedError
raise NotImplementedError('subclasses of Origin must provide a reload() method')
def __str__(self):
return self.name
@ -385,7 +385,7 @@ class TokenParser(object):
"""
Overload this method to do the actual parsing and return the result.
"""
raise NotImplementedError()
raise NotImplementedError('subclasses of Tokenparser must provide a top() method')
def more(self):
"""

View File

@ -61,7 +61,7 @@ class BaseLoader(object):
name.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of BaseLoader must provide a load_template_source() method')
def reset(self):
"""

View File

@ -126,10 +126,10 @@ class BaseArchive(object):
return True
def extract(self):
raise NotImplementedError
raise NotImplementedError('subclasses of BaseArchive must provide an extract() method')
def list(self):
raise NotImplementedError
raise NotImplementedError('subclasses of BaseArchive must provide a list() method')
class TarArchive(BaseArchive):

View File

@ -65,7 +65,7 @@ class TimeFormat(Formatter):
def B(self):
"Swatch Internet time"
raise NotImplementedError
raise NotImplementedError('may be implemented in a future release')
def e(self):
"""

View File

@ -177,7 +177,7 @@ class SyndicationFeed(object):
Outputs the feed in the given encoding to outfile, which is a file-like
object. Subclasses should override this.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of SyndicationFeed must provide a write() method')
def writeString(self, encoding):
"""

View File

@ -257,7 +257,7 @@ class LazyObject(object):
"""
Must be implemented by subclasses to initialise the wrapped object.
"""
raise NotImplementedError
raise NotImplementedError('subclasses of LazyObject must provide a _setup() method')
# Introspection support
__dir__ = new_method_proxy(dir)

View File

@ -92,7 +92,7 @@ def normalize(pattern):
result.append(".")
elif ch == '|':
# FIXME: One day we'll should do this, but not in 1.0.
raise NotImplementedError
raise NotImplementedError('Awaiting Implementation')
elif ch == "^":
pass
elif ch == '$':

View File

@ -443,10 +443,10 @@ class BaseEmailBackendTests(HeadersCheckMixin, object):
self.assertEqual(first[:len(second)], second, "First string doesn't start with the second.")
def get_mailbox_content(self):
raise NotImplementedError
raise NotImplementedError('subclasses of BaseEmailBackendTests must provide a get_mailbox_content() method')
def flush_mailbox(self):
raise NotImplementedError
raise NotImplementedError('subclasses of BaseEmailBackendTests may require a flush_mailbox() method')
def get_the_message(self):
mailbox = self.get_mailbox_content()