1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

Refs #27656 -- Updated django.db docstring verbs according to PEP 257.

This commit is contained in:
Anton Samarchyan
2017-01-24 18:04:12 -05:00
committed by Tim Graham
parent d6e26e5b7c
commit 60e52a047e
63 changed files with 934 additions and 1266 deletions

View File

@@ -18,9 +18,9 @@ from .topological_sort import stable_topological_sort
class MigrationAutodetector:
"""
Takes a pair of ProjectStates, and compares them to see what the
first would need doing to make it match the second (the second
usually being the project's current state).
Take a pair of ProjectStates and compare them to see what the first would
need doing to make it match the second (the second usually being the
project's current state).
Note that this naturally operates on entire projects at a time,
as it's likely that changes interact (for example, you can't
@@ -38,7 +38,7 @@ class MigrationAutodetector:
def changes(self, graph, trim_to_apps=None, convert_apps=None, migration_name=None):
"""
Main entry point to produce a list of applicable changes.
Takes a graph to base names on and an optional set of apps
Take a graph to base names on and an optional set of apps
to try and restrict to (restriction is not guaranteed)
"""
changes = self._detect_changes(convert_apps, graph)
@@ -90,9 +90,8 @@ class MigrationAutodetector:
def only_relation_agnostic_fields(self, fields):
"""
Return a definition of the fields that ignores field names and
what related fields actually relate to.
Used for detecting renames (as, of course, the related fields
change during renames)
what related fields actually relate to. Used for detecting renames (as,
of course, the related fields change during renames).
"""
fields_def = []
for name, field in sorted(fields):
@@ -104,7 +103,7 @@ class MigrationAutodetector:
def _detect_changes(self, convert_apps=None, graph=None):
"""
Returns a dict of migration plans which will achieve the
Return a dict of migration plans which will achieve the
change from from_state to to_state. The dict has app labels
as keys and a list of migrations as values.
@@ -117,11 +116,10 @@ class MigrationAutodetector:
graph is an optional argument that, if provided, can help improve
dependency generation and avoid potential circular dependencies.
"""
# The first phase is generating all the operations for each app
# and gathering them into a big per-app list.
# We'll then go through that list later and order it and split
# into migrations to resolve dependencies caused by M2Ms and FKs.
# Then go through that list, order it, and split into migrations to
# resolve dependencies caused by M2Ms and FKs.
self.generated_operations = {}
self.altered_indexes = {}
@@ -198,9 +196,9 @@ class MigrationAutodetector:
def _prepare_field_lists(self):
"""
Prepare field lists, and prepare a list of the fields that used
through models in the old state so we can make dependencies
from the through model deletion to the field that uses it.
Prepare field lists and a list of the fields that used through models
in the old state so dependencies can be made from the through model
deletion to the field that uses it.
"""
self.kept_model_keys = set(self.old_model_keys).intersection(self.new_model_keys)
self.kept_proxy_keys = set(self.old_proxy_keys).intersection(self.new_proxy_keys)
@@ -216,9 +214,7 @@ class MigrationAutodetector:
self.new_field_keys.update((app_label, model_name, x) for x, y in new_model_state.fields)
def _generate_through_model_map(self):
"""
Through model map generation
"""
"""Through model map generation."""
for app_label, model_name in sorted(self.old_model_keys):
old_model_name = self.renamed_models.get((app_label, model_name), model_name)
old_model_state = self.from_state.models[app_label, old_model_name]
@@ -234,13 +230,13 @@ class MigrationAutodetector:
def _build_migration_list(self, graph=None):
"""
We need to chop the lists of operations up into migrations with
dependencies on each other. We do this by stepping up an app's list of
operations until we find one that has an outgoing dependency that isn't
in another app's migration yet (hasn't been chopped off its list). We
then chop off the operations before it into a migration and move onto
the next app. If we loop back around without doing anything, there's a
circular dependency (which _should_ be impossible as the operations are
Chop the lists of operations up into migrations with dependencies on
each other. Do this by going through an app's list of operations until
one is found that has an outgoing dependency that isn't in another
app's migration yet (hasn't been chopped off its list). Then chop off
the operations before it into a migration and move onto the next app.
If the loops completes without doing anything, there's a circular
dependency (which _should_ be impossible as the operations are
all split at this point so they can't depend and be depended on).
"""
self.migrations = {}
@@ -325,9 +321,8 @@ class MigrationAutodetector:
def _sort_migrations(self):
"""
Reorder to make things possible. The order we have already isn't bad,
but we need to pull a few things around so FKs work nicely inside the
same app
Reorder to make things possible. Reordering may be needed so FKs work
nicely inside the same app.
"""
for app_label, ops in sorted(self.generated_operations.items()):
# construct a dependency graph for intra-app dependencies
@@ -360,8 +355,8 @@ class MigrationAutodetector:
def check_dependency(self, operation, dependency):
"""
Returns ``True`` if the given operation depends on the given dependency,
``False`` otherwise.
Return True if the given operation depends on the given dependency,
False otherwise.
"""
# Created model
if dependency[2] is None and dependency[3] is True:
@@ -431,8 +426,8 @@ class MigrationAutodetector:
def swappable_first_key(self, item):
"""
Sorting key function that places potential swappable models first in
lists of created models (only real way to solve #22783)
Place potential swappable models first in lists of created models (only
real way to solve #22783).
"""
try:
model = self.new_apps.get_model(item[0], item[1])
@@ -451,9 +446,9 @@ class MigrationAutodetector:
def generate_renamed_models(self):
"""
Finds any renamed models, and generates the operations for them,
and removes the old entry from the model lists.
Must be run before other model-level generation.
Find any renamed models, generate the operations for them, and remove
the old entry from the model lists. Must be run before other
model-level generation.
"""
self.renamed_models = {}
self.renamed_models_rel = {}
@@ -490,11 +485,11 @@ class MigrationAutodetector:
"""
Find all new models (both managed and unmanaged) and make create
operations for them as well as separate operations to create any
foreign key or M2M relationships (we'll optimize these back in later
if we can).
foreign key or M2M relationships (these are optimized later, if
possible).
We also defer any model options that refer to collections of fields
that might be deferred (e.g. unique_together, index_together).
Defer any model options that refer to collections of fields that might
be deferred (e.g. unique_together, index_together).
"""
old_keys = set(self.old_model_keys).union(self.old_unmanaged_keys)
added_models = set(self.new_model_keys) - old_keys
@@ -643,10 +638,10 @@ class MigrationAutodetector:
def generate_created_proxies(self):
"""
Makes CreateModel statements for proxy models.
We use the same statements as that way there's less code duplication,
but of course for proxy models we can skip all that pointless field
stuff and just chuck out an operation.
Make CreateModel statements for proxy models. Use the same statements
as that way there's less code duplication, but of course for proxy
models it's safe to skip all the pointless field stuff and just chuck
out an operation.
"""
added = set(self.new_proxy_keys) - set(self.old_proxy_keys)
for app_label, model_name in sorted(added):
@@ -679,10 +674,10 @@ class MigrationAutodetector:
"""
Find all deleted models (managed and unmanaged) and make delete
operations for them as well as separate operations to delete any
foreign key or M2M relationships (we'll optimize these back in later
if we can).
foreign key or M2M relationships (these are optimized later, if
possible).
We also bring forward removal of any model options that refer to
Also bring forward removal of any model options that refer to
collections of fields - the inverse of generate_created_models().
"""
new_keys = set(self.new_model_keys).union(self.new_unmanaged_keys)
@@ -769,9 +764,7 @@ class MigrationAutodetector:
)
def generate_deleted_proxies(self):
"""
Makes DeleteModel statements for proxy models.
"""
"""Make DeleteModel options for proxy models."""
deleted = set(self.old_proxy_keys) - set(self.new_proxy_keys)
for app_label, model_name in sorted(deleted):
model_state = self.from_state.models[app_label, model_name]
@@ -784,9 +777,7 @@ class MigrationAutodetector:
)
def generate_renamed_fields(self):
"""
Works out renamed fields
"""
"""Work out renamed fields."""
self.renamed_fields = {}
for app_label, model_name, field_name in sorted(self.new_field_keys - self.old_field_keys):
old_model_name = self.renamed_models.get((app_label, model_name), model_name)
@@ -817,9 +808,7 @@ class MigrationAutodetector:
break
def generate_added_fields(self):
"""
Fields that have been added
"""
"""Make AddField operations."""
for app_label, model_name, field_name in sorted(self.new_field_keys - self.old_field_keys):
self._generate_added_field(app_label, model_name, field_name)
@@ -855,9 +844,7 @@ class MigrationAutodetector:
)
def generate_removed_fields(self):
"""
Fields that have been removed.
"""
"""Make RemoveField operations."""
for app_label, model_name, field_name in sorted(self.old_field_keys - self.new_field_keys):
self._generate_removed_field(app_label, model_name, field_name)
@@ -879,7 +866,8 @@ class MigrationAutodetector:
def generate_altered_fields(self):
"""
Fields that have been altered.
Make AlterField operations, or possibly RemovedField/AddField if alter
isn's possible.
"""
for app_label, model_name, field_name in sorted(self.old_field_keys.intersection(self.new_field_keys)):
# Did the field change?
@@ -1057,9 +1045,9 @@ class MigrationAutodetector:
def generate_altered_options(self):
"""
Works out if any non-schema-affecting options have changed and
makes an operation to represent them in state changes (in case Python
code in migrations needs them)
Work out if any non-schema-affecting options have changed and make an
operation to represent them in state changes (in case Python code in
migrations needs them).
"""
models_to_check = self.kept_model_keys.union(
self.kept_proxy_keys
@@ -1137,9 +1125,9 @@ class MigrationAutodetector:
def arrange_for_graph(self, changes, graph, migration_name=None):
"""
Takes in a result from changes() and a MigrationGraph,
and fixes the names and dependencies of the changes so they
extend the graph from the leaf nodes for each app.
Take a result from changes() and a MigrationGraph, and fix the names
and dependencies of the changes so they extend the graph from the leaf
nodes for each app.
"""
leaves = graph.leaf_nodes()
name_map = {}
@@ -1186,11 +1174,10 @@ class MigrationAutodetector:
def _trim_to_apps(self, changes, app_labels):
"""
Takes changes from arrange_for_graph and set of app labels and
returns a modified set of changes which trims out as many migrations
that are not in app_labels as possible.
Note that some other migrations may still be present, as they may be
required dependencies.
Take changes from arrange_for_graph() and set of app labels, and return
a modified set of changes which trims out as many migrations that are
not in app_labels as possible. Note that some other migrations may
still be present as they may be required dependencies.
"""
# Gather other app dependencies in a first pass
app_dependencies = {}
@@ -1214,10 +1201,9 @@ class MigrationAutodetector:
@classmethod
def suggest_name(cls, ops):
"""
Given a set of operations, suggests a name for the migration
they might represent. Names are not guaranteed to be unique,
but we put some effort in to the fallback name to avoid VCS conflicts
if we can.
Given a set of operations, suggest a name for the migration they might
represent. Names are not guaranteed to be unique, but put some effort
into the fallback name to avoid VCS conflicts if possible.
"""
if len(ops) == 1:
if isinstance(ops[0], operations.CreateModel):
@@ -1236,8 +1222,8 @@ class MigrationAutodetector:
@classmethod
def parse_number(cls, name):
"""
Given a migration name, tries to extract a number from the
beginning of it. If no number found, returns None.
Given a migration name, try to extract a number from the beginning of
it. If no number is found, return None.
"""
match = re.match(r'^\d+', name)
if match:

View File

@@ -2,51 +2,37 @@ from django.db.utils import DatabaseError
class AmbiguityError(Exception):
"""
Raised when more than one migration matches a name prefix.
"""
"""More than one migration matches a name prefix."""
pass
class BadMigrationError(Exception):
"""
Raised when there's a bad migration (unreadable/bad format/etc.).
"""
"""There's a bad migration (unreadable/bad format/etc.)."""
pass
class CircularDependencyError(Exception):
"""
Raised when there's an impossible-to-resolve circular dependency.
"""
"""There's an impossible-to-resolve circular dependency."""
pass
class InconsistentMigrationHistory(Exception):
"""
Raised when an applied migration has some of its dependencies not applied.
"""
"""An applied migration has some of its dependencies not applied."""
pass
class InvalidBasesError(ValueError):
"""
Raised when a model's base classes can't be resolved.
"""
"""A model's base classes can't be resolved."""
pass
class IrreversibleError(RuntimeError):
"""
Raised when a irreversible migration is about to be reversed.
"""
"""An irreversible migration is about to be reversed."""
pass
class NodeNotFoundError(LookupError):
"""
Raised when an attempt on a node is made that is not available in the graph.
"""
"""An attempt on a node is made that is not available in the graph."""
def __init__(self, message, node, origin=None):
self.message = message

View File

@@ -9,8 +9,8 @@ from .state import ProjectState
class MigrationExecutor:
"""
End-to-end migration execution - loads migrations, and runs them
up or down to a specified set of targets.
End-to-end migration execution - load migrations and run them up or down
to a specified set of targets.
"""
def __init__(self, connection, progress_callback=None):
@@ -21,7 +21,7 @@ class MigrationExecutor:
def migration_plan(self, targets, clean_start=False):
"""
Given a set of targets, returns a list of (Migration instance, backwards?).
Given a set of targets, return a list of (Migration instance, backwards?).
"""
plan = []
if clean_start:
@@ -81,7 +81,7 @@ class MigrationExecutor:
def migrate(self, targets, plan=None, state=None, fake=False, fake_initial=False):
"""
Migrates the database up to the given targets.
Migrate the database up to the given targets.
Django first needs to create all project states before a migration is
(un)applied and in a second step run all the database operations.
@@ -208,8 +208,8 @@ class MigrationExecutor:
def collect_sql(self, plan):
"""
Takes a migration plan and returns a list of collected SQL
statements that represent the best-efforts version of that plan.
Take a migration plan and return a list of collected SQL statements
that represent the best-efforts version of that plan.
"""
statements = []
state = None
@@ -225,9 +225,7 @@ class MigrationExecutor:
return statements
def apply_migration(self, state, migration, fake=False, fake_initial=False):
"""
Runs a migration forwards.
"""
"""Run a migration forwards."""
if self.progress_callback:
self.progress_callback("apply_start", migration, fake)
if not fake:
@@ -252,9 +250,7 @@ class MigrationExecutor:
return state
def unapply_migration(self, state, migration, fake=False):
"""
Runs a migration backwards.
"""
"""Run a migration backwards."""
if self.progress_callback:
self.progress_callback("unapply_start", migration, fake)
if not fake:
@@ -275,12 +271,12 @@ class MigrationExecutor:
"""
Mark replacement migrations applied if their replaced set all are.
We do this unconditionally on every migrate, rather than just when
migrations are applied or unapplied, so as to correctly handle the case
Do this unconditionally on every migrate, rather than just when
migrations are applied or unapplied, to correctly handle the case
when a new squash migration is pushed to a deployment that already had
all its replaced migrations applied. In this case no new migration will
be applied, but we still want to correctly maintain the applied state
of the squash migration.
be applied, but the applied state of the squashed migration must be
maintained.
"""
applied = self.recorder.applied_migrations()
for key, migration in self.loader.replacements.items():
@@ -290,7 +286,7 @@ class MigrationExecutor:
def detect_soft_applied(self, project_state, migration):
"""
Tests whether a migration has been implicitly applied - that the
Test whether a migration has been implicitly applied - that the
tables or columns it would create exist. This is intended only for use
on initial migrations (as it only looks for CreateModel and AddField).
"""

View File

@@ -97,7 +97,7 @@ class DummyNode(Node):
class MigrationGraph:
"""
Represents the digraph of all migrations in a project.
Represent the digraph of all migrations in a project.
Each migration is a node, and each dependency is an edge. There are
no implicit dependencies between numbered migrations - the numbering is
@@ -142,8 +142,9 @@ class MigrationGraph:
def add_dependency(self, migration, child, parent, skip_validation=False):
"""
This may create dummy nodes if they don't yet exist.
If `skip_validation` is set, validate_consistency should be called afterwards.
This may create dummy nodes if they don't yet exist. If
`skip_validation=True`, validate_consistency() should be called
afterwards.
"""
if child not in self.nodes:
error_message = (
@@ -165,7 +166,7 @@ class MigrationGraph:
def remove_replaced_nodes(self, replacement, replaced):
"""
Removes each of the `replaced` nodes (when they exist). Any
Remove each of the `replaced` nodes (when they exist). Any
dependencies that were referencing them are changed to reference the
`replacement` node instead.
"""
@@ -201,10 +202,10 @@ class MigrationGraph:
def remove_replacement_node(self, replacement, replaced):
"""
The inverse operation to `remove_replaced_nodes`. Almost. Removes the
replacement node `replacement` and remaps its child nodes to
`replaced` - the list of nodes it would have replaced. Its parent
nodes are not remapped as they are expected to be correct already.
The inverse operation to `remove_replaced_nodes`. Almost. Remove the
replacement node `replacement` and remap its child nodes to `replaced`
- the list of nodes it would have replaced. Don't remap its parent
nodes as they are expected to be correct already.
"""
self.nodes.pop(replacement, None)
try:
@@ -237,9 +238,7 @@ class MigrationGraph:
self.clear_cache()
def validate_consistency(self):
"""
Ensure there are no dummy nodes remaining in the graph.
"""
"""Ensure there are no dummy nodes remaining in the graph."""
[n.raise_error() for n in self.node_map.values() if isinstance(n, DummyNode)]
def clear_cache(self):
@@ -251,10 +250,9 @@ class MigrationGraph:
def forwards_plan(self, target):
"""
Given a node, returns a list of which previous nodes (dependencies)
must be applied, ending with the node itself.
This is the list you would follow if applying the migrations to
a database.
Given a node, return a list of which previous nodes (dependencies) must
be applied, ending with the node itself. This is the list you would
follow if applying the migrations to a database.
"""
if target not in self.nodes:
raise NodeNotFoundError("Node %r not a valid node" % (target, ), target)
@@ -271,10 +269,9 @@ class MigrationGraph:
def backwards_plan(self, target):
"""
Given a node, returns a list of which dependent nodes (dependencies)
must be unapplied, ending with the node itself.
This is the list you would follow if removing the migrations from
a database.
Given a node, return a list of which dependent nodes (dependencies)
must be unapplied, ending with the node itself. This is the list you
would follow if removing the migrations from a database.
"""
if target not in self.nodes:
raise NodeNotFoundError("Node %r not a valid node" % (target, ), target)
@@ -290,9 +287,7 @@ class MigrationGraph:
return self.iterative_dfs(node, forwards=False)
def iterative_dfs(self, start, forwards=True):
"""
Iterative depth first search, for finding dependencies.
"""
"""Iterative depth-first search for finding dependencies."""
visited = deque()
visited.append(start)
if forwards:
@@ -314,7 +309,7 @@ class MigrationGraph:
def root_nodes(self, app=None):
"""
Returns all root nodes - that is, nodes with no dependencies inside
Return all root nodes - that is, nodes with no dependencies inside
their app. These are the starting point for an app.
"""
roots = set()
@@ -325,7 +320,7 @@ class MigrationGraph:
def leaf_nodes(self, app=None):
"""
Returns all leaf nodes - that is, nodes with no dependents in their app.
Return all leaf nodes - that is, nodes with no dependents in their app.
These are the "most current" version of an app's schema.
Having more than one per app is technically an error, but one that
gets handled further up, in the interactive command - it's usually the
@@ -369,9 +364,9 @@ class MigrationGraph:
def make_state(self, nodes=None, at_end=True, real_apps=None):
"""
Given a migration node or nodes, returns a complete ProjectState for it.
If at_end is False, returns the state before the migration has run.
If nodes is not provided, returns the overall most current project state.
Given a migration node or nodes, return a complete ProjectState for it.
If at_end is False, return the state before the migration has run.
If nodes is not provided, return the overall most current project state.
"""
if nodes is None:
nodes = list(self.leaf_nodes())

View File

@@ -17,7 +17,7 @@ MIGRATIONS_MODULE_NAME = 'migrations'
class MigrationLoader:
"""
Loads migration files from disk, and their status from the database.
Load migration files from disk and their status from the database.
Migration files are expected to live in the "migrations" directory of
an app. Their names are entirely unimportant from a code perspective,
@@ -62,9 +62,7 @@ class MigrationLoader:
return '%s.%s' % (app_package_name, MIGRATIONS_MODULE_NAME), False
def load_disk(self):
"""
Loads the migrations from all INSTALLED_APPS from disk.
"""
"""Load the migrations from all INSTALLED_APPS from disk."""
self.disk_migrations = {}
self.unmigrated_apps = set()
self.migrated_apps = set()
@@ -119,11 +117,13 @@ class MigrationLoader:
)
def get_migration(self, app_label, name_prefix):
"Gets the migration exactly named, or raises `graph.NodeNotFoundError`"
"""Return the named migration or raise NodeNotFoundError."""
return self.graph.nodes[app_label, name_prefix]
def get_migration_by_prefix(self, app_label, name_prefix):
"Returns the migration(s) which match the given app label and name _prefix_"
"""
Return the migration(s) which match the given app label and name_prefix.
"""
# Do the search
results = []
for migration_app_label, migration_name in self.disk_migrations:
@@ -192,7 +192,7 @@ class MigrationLoader:
def build_graph(self):
"""
Builds a migration dependency graph using both the disk and database.
Build a migration dependency graph using both the disk and database.
You'll need to rebuild the graph if you apply migrations. This isn't
usually a problem as generally migration stuff runs in a one-shot process.
"""
@@ -294,8 +294,8 @@ class MigrationLoader:
def detect_conflicts(self):
"""
Looks through the loaded graph and detects any conflicts - apps
with more than one leaf migration. Returns a dict of the app labels
Look through the loaded graph and detect any conflicts - apps
with more than one leaf migration. Return a dict of the app labels
that conflict with the migration names that conflict.
"""
seen_apps = {}
@@ -308,9 +308,9 @@ class MigrationLoader:
def project_state(self, nodes=None, at_end=True):
"""
Returns a ProjectState object representing the most recent state
that the migrations we loaded represent.
Return a ProjectState object representing the most recent state
that the loaded migrations represent.
See graph.make_state for the meaning of "nodes" and "at_end"
See graph.make_state() for the meaning of "nodes" and "at_end".
"""
return self.graph.make_state(nodes=nodes, at_end=at_end, real_apps=list(self.unmigrated_apps))

View File

@@ -73,9 +73,9 @@ class Migration:
def mutate_state(self, project_state, preserve=True):
"""
Takes a ProjectState and returns a new one with the migration's
operations applied to it. Preserves the original object state by
default and will return a mutated state from a copy.
Take a ProjectState and return a new one with the migration's
operations applied to it. Preserve the original object state by
default and return a mutated state from a copy.
"""
new_state = project_state
if preserve:
@@ -87,11 +87,11 @@ class Migration:
def apply(self, project_state, schema_editor, collect_sql=False):
"""
Takes a project_state representing all migrations prior to this one
and a schema_editor for a live database and applies the migration
Take a project_state representing all migrations prior to this one
and a schema_editor for a live database and apply the migration
in a forwards order.
Returns the resulting project state for efficient re-use by following
Return the resulting project state for efficient reuse by following
Migrations.
"""
for operation in self.operations:
@@ -124,8 +124,8 @@ class Migration:
def unapply(self, project_state, schema_editor, collect_sql=False):
"""
Takes a project_state representing all migrations prior to this one
and a schema_editor for a live database and applies the migration
Take a project_state representing all migrations prior to this one
and a schema_editor for a live database and apply the migration
in a reverse order.
The backwards migration process consists of two phases:
@@ -185,7 +185,5 @@ class SwappableTuple(tuple):
def swappable_dependency(value):
"""
Turns a setting value into a dependency.
"""
"""Turn a setting value into a dependency."""
return SwappableTuple((value.split(".", 1)[0], "__first__"), value)

View File

@@ -41,7 +41,7 @@ class Operation:
def deconstruct(self):
"""
Returns a 3-tuple of class import path (or just name if it lives
Return a 3-tuple of class import path (or just name if it lives
under django.db.migrations), positional arguments, and keyword
arguments.
"""
@@ -53,21 +53,21 @@ class Operation:
def state_forwards(self, app_label, state):
"""
Takes the state from the previous migration, and mutates it
Take the state from the previous migration, and mutate it
so that it matches what this migration would perform.
"""
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
Perform the mutation on the database schema in the normal
(forwards) direction.
"""
raise NotImplementedError('subclasses of Operation must provide a database_forwards() method')
def database_backwards(self, app_label, schema_editor, from_state, to_state):
"""
Performs the mutation on the database schema in the reverse
Perform the mutation on the database schema in the reverse
direction - e.g. if this were CreateModel, it would in fact
drop the model's table.
"""
@@ -75,13 +75,13 @@ class Operation:
def describe(self):
"""
Outputs a brief summary of what the action does.
Output a brief summary of what the action does.
"""
return "%s: %s" % (self.__class__.__name__, self._constructor_args)
def references_model(self, name, app_label=None):
"""
Returns True if there is a chance this operation references the given
Return True if there is a chance this operation references the given
model name (as a string), with an optional app label for accuracy.
Used for optimization. If in doubt, return True;
@@ -93,7 +93,7 @@ class Operation:
def references_field(self, model_name, name, app_label=None):
"""
Returns True if there is a chance this operation references the given
Return True if there is a chance this operation references the given
field name, with an optional app label for accuracy.
Used for optimization. If in doubt, return True.
@@ -102,7 +102,7 @@ class Operation:
def allow_migrate_model(self, connection_alias, model):
"""
Returns if we're allowed to migrate the model.
Return wether or not a model may be migrated.
This is a thin wrapper around router.allow_migrate_model() that
preemptively rejects any proxy, swapped out, or unmanaged model.

View File

@@ -37,9 +37,7 @@ class FieldOperation(Operation):
class AddField(FieldOperation):
"""
Adds a field to a model.
"""
"""Add a field to a model."""
def __init__(self, model_name, name, field, preserve_default=True):
self.field = field
@@ -118,9 +116,7 @@ class AddField(FieldOperation):
class RemoveField(FieldOperation):
"""
Removes a field from a model.
"""
"""Remove a field from a model."""
def deconstruct(self):
kwargs = {
@@ -163,7 +159,8 @@ class RemoveField(FieldOperation):
class AlterField(FieldOperation):
"""
Alters a field's database column (e.g. null, max_length) to the provided new field
Alter a field's database column (e.g. null, max_length) to the provided
new field.
"""
def __init__(self, model_name, name, field, preserve_default=True):
@@ -236,9 +233,7 @@ class AlterField(FieldOperation):
class RenameField(FieldOperation):
"""
Renames a field on the model. Might affect db_column too.
"""
"""Rename a field on the model. Might affect db_column too."""
def __init__(self, model_name, old_name, new_name):
self.old_name = old_name

View File

@@ -39,9 +39,7 @@ class ModelOperation(Operation):
class CreateModel(ModelOperation):
"""
Create a model's table.
"""
"""Create a model's table."""
serialization_expand_args = ['fields', 'options', 'managers']
@@ -227,9 +225,7 @@ class CreateModel(ModelOperation):
class DeleteModel(ModelOperation):
"""
Drops a model's table.
"""
"""Drop a model's table."""
def deconstruct(self):
kwargs = {
@@ -259,9 +255,7 @@ class DeleteModel(ModelOperation):
class RenameModel(ModelOperation):
"""
Renames a model.
"""
"""Rename a model."""
def __init__(self, old_name, new_name):
self.old_name = old_name
@@ -423,9 +417,7 @@ class RenameModel(ModelOperation):
class AlterModelTable(ModelOperation):
"""
Renames a model's table
"""
"""Rename a model's table."""
def __init__(self, name, table):
self.table = table
@@ -497,7 +489,7 @@ class FieldRelatedOptionOperation(ModelOptionOperation):
class AlterUniqueTogether(FieldRelatedOptionOperation):
"""
Changes the value of unique_together to the target one.
Change the value of unique_together to the target one.
Input value of unique_together must be a set of tuples.
"""
option_name = "unique_together"
@@ -551,7 +543,7 @@ class AlterUniqueTogether(FieldRelatedOptionOperation):
class AlterIndexTogether(FieldRelatedOptionOperation):
"""
Changes the value of index_together to the target one.
Change the value of index_together to the target one.
Input value of index_together must be a set of tuples.
"""
option_name = "index_together"
@@ -604,9 +596,7 @@ class AlterIndexTogether(FieldRelatedOptionOperation):
class AlterOrderWithRespectTo(FieldRelatedOptionOperation):
"""
Represents a change with the order_with_respect_to option.
"""
"""Represent a change with the order_with_respect_to option."""
def __init__(self, name, order_with_respect_to):
self.order_with_respect_to = order_with_respect_to
@@ -664,7 +654,7 @@ class AlterOrderWithRespectTo(FieldRelatedOptionOperation):
class AlterModelOptions(ModelOptionOperation):
"""
Sets new model options that don't directly affect the database schema
Set new model options that don't directly affect the database schema
(like verbose_name, permissions, ordering). Python code in migrations
may still need them.
"""
@@ -718,9 +708,7 @@ class AlterModelOptions(ModelOptionOperation):
class AlterModelManagers(ModelOptionOperation):
"""
Alters the model's managers
"""
"""Alter the model's managers."""
serialization_expand_args = ['managers']
@@ -759,9 +747,7 @@ class IndexOperation(Operation):
class AddIndex(IndexOperation):
"""
Add an index on a model.
"""
"""Add an index on a model."""
def __init__(self, model_name, index):
self.model_name = model_name
@@ -806,9 +792,7 @@ class AddIndex(IndexOperation):
class RemoveIndex(IndexOperation):
"""
Remove an index from a model.
"""
"""Remove an index from a model."""
def __init__(self, model_name, name):
self.model_name = model_name

View File

@@ -5,7 +5,7 @@ from .base import Operation
class SeparateDatabaseAndState(Operation):
"""
Takes two lists of operations - ones that will be used for the database,
Take two lists of operations - ones that will be used for the database,
and ones that will be used for the state change. This allows operations
that don't support state change to have it applied, or have operations
that affect the state or not the database, or so on.
@@ -62,9 +62,9 @@ class SeparateDatabaseAndState(Operation):
class RunSQL(Operation):
"""
Runs some raw SQL. A reverse SQL statement may be provided.
Run some raw SQL. A reverse SQL statement may be provided.
Also accepts a list of operations that represent the state change effected
Also accept a list of operations that represent the state change effected
by this SQL change, in case it's custom column/table creation/deletion.
"""
noop = ''
@@ -132,7 +132,7 @@ class RunSQL(Operation):
class RunPython(Operation):
"""
Runs Python code in a context suitable for doing versioned ORM operations.
Run Python code in a context suitable for doing versioned ORM operations.
"""
reduces_to_sql = False

View File

@@ -1,6 +1,6 @@
class MigrationOptimizer:
"""
Powers the optimization process, where you provide a list of Operations
Power the optimization process, where you provide a list of Operations
and you are returned a list of equal or shorter length - operations
are merged into one if possible.
@@ -39,9 +39,7 @@ class MigrationOptimizer:
operations = result
def optimize_inner(self, operations, app_label=None):
"""
Inner optimization loop.
"""
"""Inner optimization loop."""
new_operations = []
for i, operation in enumerate(operations):
# Compare it to each operation after it

View File

@@ -11,7 +11,7 @@ from .loader import MigrationLoader
class MigrationQuestioner:
"""
Gives the autodetector responses to questions it might have.
Give the autodetector responses to questions it might have.
This base class has a built-in noninteractive mode, but the
interactive subclass is what the command-line arguments will use.
"""
@@ -22,7 +22,7 @@ class MigrationQuestioner:
self.dry_run = dry_run
def ask_initial(self, app_label):
"Should we create an initial migration for the app?"
"""Should we create an initial migration for the app?"""
# If it was specified on the command line, definitely true
if app_label in self.specified_apps:
return True
@@ -52,29 +52,29 @@ class MigrationQuestioner:
return not any(x.endswith(".py") for x in filenames if x != "__init__.py")
def ask_not_null_addition(self, field_name, model_name):
"Adding a NOT NULL field to a model"
"""Adding a NOT NULL field to a model."""
# None means quit
return None
def ask_not_null_alteration(self, field_name, model_name):
"Changing a NULL field to NOT NULL"
"""Changing a NULL field to NOT NULL."""
# None means quit
return None
def ask_rename(self, model_name, old_name, new_name, field_instance):
"Was this field really renamed?"
"""Was this field really renamed?"""
return self.defaults.get("ask_rename", False)
def ask_rename_model(self, old_model_state, new_model_state):
"Was this model really renamed?"
"""Was this model really renamed?"""
return self.defaults.get("ask_rename_model", False)
def ask_merge(self, app_label):
"Do you really want to merge these migrations?"
"""Do you really want to merge these migrations?"""
return self.defaults.get("ask_merge", False)
def ask_auto_now_add_addition(self, field_name, model_name):
"Adding an auto_now_add field to a model"
"""Adding an auto_now_add field to a model."""
# None means quit
return None
@@ -138,7 +138,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
print("Invalid input: %s" % e)
def ask_not_null_addition(self, field_name, model_name):
"Adding a NOT NULL field to a model"
"""Adding a NOT NULL field to a model."""
if not self.dry_run:
choice = self._choice_input(
"You are trying to add a non-nullable field '%s' to %s without a default; "
@@ -157,7 +157,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
return None
def ask_not_null_alteration(self, field_name, model_name):
"Changing a NULL field to NOT NULL"
"""Changing a NULL field to NOT NULL."""
if not self.dry_run:
choice = self._choice_input(
"You are trying to change the nullable field '%s' on %s to non-nullable "
@@ -182,13 +182,13 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
return None
def ask_rename(self, model_name, old_name, new_name, field_instance):
"Was this field really renamed?"
"""Was this field really renamed?"""
msg = "Did you rename %s.%s to %s.%s (a %s)? [y/N]"
return self._boolean_input(msg % (model_name, old_name, model_name, new_name,
field_instance.__class__.__name__), False)
def ask_rename_model(self, old_model_state, new_model_state):
"Was this model really renamed?"
"""Was this model really renamed?"""
msg = "Did you rename the %s.%s model to %s? [y/N]"
return self._boolean_input(msg % (old_model_state.app_label, old_model_state.name,
new_model_state.name), False)
@@ -202,7 +202,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
)
def ask_auto_now_add_addition(self, field_name, model_name):
"Adding an auto_now_add field to a model"
"""Adding an auto_now_add field to a model."""
if not self.dry_run:
choice = self._choice_input(
"You are trying to add the field '{}' with 'auto_now_add=True' "

View File

@@ -8,7 +8,7 @@ from .exceptions import MigrationSchemaMissing
class MigrationRecorder:
"""
Deals with storing migration records in the database.
Deal with storing migration records in the database.
Because this table is actually itself used for dealing with model
creation, it's the one thing we can't do normally via migrations.
@@ -40,9 +40,7 @@ class MigrationRecorder:
return self.Migration.objects.using(self.connection.alias)
def ensure_schema(self):
"""
Ensures the table exists and has the correct schema.
"""
"""Ensure the table exists and has the correct schema."""
# If the table's there, that's fine - we've never changed its schema
# in the codebase.
if self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor()):
@@ -55,28 +53,20 @@ class MigrationRecorder:
raise MigrationSchemaMissing("Unable to create the django_migrations table (%s)" % exc)
def applied_migrations(self):
"""
Returns a set of (app, name) of applied migrations.
"""
"""Return a set of (app, name) of applied migrations."""
self.ensure_schema()
return set(tuple(x) for x in self.migration_qs.values_list("app", "name"))
def record_applied(self, app, name):
"""
Records that a migration was applied.
"""
"""Record that a migration was applied."""
self.ensure_schema()
self.migration_qs.create(app=app, name=name)
def record_unapplied(self, app, name):
"""
Records that a migration was unapplied.
"""
"""Record that a migration was unapplied."""
self.ensure_schema()
self.migration_qs.filter(app=app, name=name).delete()
def flush(self):
"""
Deletes all migration records. Useful if you're testing migrations.
"""
"""Delete all migration records. Useful for testing migrations."""
self.migration_qs.all().delete()

View File

@@ -27,9 +27,7 @@ def _get_app_label_and_model_name(model, app_label=''):
def _get_related_models(m):
"""
Return all models that have a direct relationship to the given model.
"""
"""Return all models that have a direct relationship to the given model."""
related_models = [
subclass for subclass in m.__subclasses__()
if issubclass(subclass, models.Model)
@@ -82,9 +80,9 @@ def get_related_models_recursive(model):
class ProjectState:
"""
Represents the entire project's overall state.
This is the item that is passed around - we do it here rather than at the
app level so that cross-app FKs/etc. resolve properly.
Represent the entire project's overall state. This is the item that is
passed around - do it here rather than at the app level so that cross-app
FKs/etc. resolve properly.
"""
def __init__(self, models=None, real_apps=None):
@@ -194,7 +192,7 @@ class ProjectState:
self.apps.render_multiple(states_to_be_rendered)
def clone(self):
"Returns an exact copy of this ProjectState"
"""Return an exact copy of this ProjectState."""
new_state = ProjectState(
models={k: v.clone() for k, v in self.models.items()},
real_apps=self.real_apps,
@@ -219,7 +217,7 @@ class ProjectState:
@classmethod
def from_apps(cls, apps):
"Takes in an Apps and returns a ProjectState matching it"
"""Take an Apps and return a ProjectState matching it."""
app_models = {}
for model in apps.get_models(include_swapped=True):
model_state = ModelState.from_model(model)
@@ -235,9 +233,7 @@ class ProjectState:
class AppConfigStub(AppConfig):
"""
Stubs a Django AppConfig. Only provides a label, and a dict of models.
"""
"""Stub of an AppConfig. Only provides a label and a dict of models."""
# Not used, but required by AppConfig.__init__
path = ''
@@ -325,9 +321,7 @@ class StateApps(Apps):
unrendered_models = new_unrendered_models
def clone(self):
"""
Return a clone of this registry, mainly used by the migration framework.
"""
"""Return a clone of this registry."""
clone = StateApps([], {})
clone.all_models = copy.deepcopy(self.all_models)
clone.app_configs = copy.deepcopy(self.app_configs)
@@ -358,9 +352,9 @@ class StateApps(Apps):
class ModelState:
"""
Represents a Django Model. We don't use the actual Model class
as it's not designed to have its options changed - instead, we
mutate this one and then render it into a Model as required.
Represent a Django Model. Don't use the actual Model class as it's not
designed to have its options changed - instead, mutate this one and then
render it into a Model as required.
Note that while you are allowed to mutate .fields, you are not allowed
to mutate the Field instances inside there themselves - you must instead
@@ -409,9 +403,7 @@ class ModelState:
@classmethod
def from_model(cls, model, exclude_rels=False):
"""
Feed me a model, get a ModelState representing it out.
"""
"""Given a model, return a ModelState representing it."""
# Deconstruct the fields
fields = []
for field in model._meta.local_fields:
@@ -532,7 +524,7 @@ class ModelState:
)
def construct_managers(self):
"Deep-clone the managers using deconstruction"
"""Deep-clone the managers using deconstruction."""
# Sort all managers by their creation counter
sorted_managers = sorted(self.managers, key=lambda v: v[1].creation_counter)
for mgr_name, manager in sorted_managers:
@@ -546,7 +538,7 @@ class ModelState:
yield mgr_name, manager_class(*args, **kwargs)
def clone(self):
"Returns an exact copy of this ModelState"
"""Return an exact copy of this ModelState."""
return self.__class__(
app_label=self.app_label,
name=self.name,
@@ -557,7 +549,7 @@ class ModelState:
)
def render(self, apps):
"Creates a Model object from our current state into the given apps"
"""Create a Model object from our current state into the given apps."""
# First, make a Meta object
meta_contents = {'app_label': self.app_label, "apps": apps}
meta_contents.update(self.options)

View File

@@ -1,9 +1,10 @@
def topological_sort_as_sets(dependency_graph):
"""Variation of Kahn's algorithm (1962) that returns sets.
"""
Variation of Kahn's algorithm (1962) that returns sets.
Takes a dependency graph as a dictionary of node => dependencies.
Take a dependency graph as a dictionary of node => dependencies.
Yields sets of items in topological order, where the first set contains
Yield sets of items in topological order, where the first set contains
all nodes without dependencies, and each following set contains all
nodes that may depend on the nodes only in the previously yielded sets.
"""

View File

@@ -129,7 +129,7 @@ class OperationWriter:
class MigrationWriter:
"""
Takes a Migration instance and is able to produce the contents
Take a Migration instance and is able to produce the contents
of the migration file from it.
"""
@@ -138,9 +138,7 @@ class MigrationWriter:
self.needs_manual_porting = False
def as_string(self):
"""
Returns a string of the file contents.
"""
"""Return a string of the file contents."""
items = {
"replaces_str": "",
"initial_str": "",