def test_empty_signature(self): operation = custom_migration_operations.operations.TestOperation() writer = OperationWriter(operation) writer.indentation = 0 buff, imports = writer.serialize() self.assertEqual(imports, {'import custom_migration_operations.operations'}) self.assertEqual( buff, 'custom_migration_operations.operations.TestOperation(\n' '),' )
def test_kwargs_signature(self): operation = custom_migration_operations.operations.KwargsOperation(kwarg1=1) writer = OperationWriter(operation) writer.indentation = 0 buff, imports = writer.serialize() self.assertEqual(imports, {'import custom_migration_operations.operations'}) self.assertEqual( buff, 'custom_migration_operations.operations.KwargsOperation(\n' ' kwarg1=1,\n' '),' )
def test_expand_args_signature(self): operation = custom_migration_operations.operations.ExpandArgsOperation([1, 2]) writer = OperationWriter(operation) writer.indentation = 0 buff, imports = writer.serialize() self.assertEqual(imports, {'import custom_migration_operations.operations'}) self.assertEqual( buff, 'custom_migration_operations.operations.ExpandArgsOperation(\n' ' arg=[\n' ' 1,\n' ' 2,\n' ' ],\n' '),' )
def test_nested_operation_expand_args_signature(self): operation = custom_migration_operations.operations.ExpandArgsOperation( arg=[ custom_migration_operations.operations.KwargsOperation( kwarg1=1, kwarg2=2, ), ]) buff, imports = OperationWriter(operation, indentation=0).serialize() self.assertEqual(imports, {'import custom_migration_operations.operations'}) self.assertEqual( buff, 'custom_migration_operations.operations.ExpandArgsOperation(\n' ' arg=[\n' ' custom_migration_operations.operations.KwargsOperation(\n' ' kwarg1=1,\n' ' kwarg2=2,\n' ' ),\n' ' ],\n' '),')
def test_nested_args_signature(self): operation = custom_migration_operations.operations.ArgsOperation( custom_migration_operations.operations.ArgsOperation(1, 2), custom_migration_operations.operations.KwargsOperation(kwarg1=3, kwarg2=4), ) buff, imports = OperationWriter(operation, indentation=0).serialize() self.assertEqual(imports, {"import custom_migration_operations.operations"}) self.assertEqual( buff, "custom_migration_operations.operations.ArgsOperation(\n" " arg1=custom_migration_operations.operations.ArgsOperation(\n" " arg1=1,\n" " arg2=2,\n" " ),\n" " arg2=custom_migration_operations.operations.KwargsOperation(\n" " kwarg1=3,\n" " kwarg2=4,\n" " ),\n" "),", )
def serialize(self): from django.db.migrations.writer import OperationWriter string, imports = OperationWriter(self.value, indentation=0).serialize() # Nested operation, trailing comma is handled in upper OperationWriter._write() return string.rstrip(','), imports
def as_string(self): """ Returns a string of the file contents. """ items = { 'replaces_str': '', 'initial_str': '', } imports = set() # Deconstruct operations operations = [] for operation in self.change.operations: operation_string, operation_imports = OperationWriter( operation).serialize() imports.update(operation_imports) operations.append(operation_string) items['operations'] = '\n'.join( operations) + '\n' if operations else '' # Format dependencies and write out swappable dependencies right dependencies = [] for dependency in self.change.dependencies: if dependency[0] == '__setting__': dependencies.append( ' migrations.swappable_dependency(settings.%s),' % dependency[1]) imports.add('from django.conf import settings') else: # No need to output bytestrings for dependencies dependency = tuple(force_text(s) for s in dependency) dependencies.append(' %s,' % self.serialize(dependency)[0]) items['dependencies'] = '\n'.join( dependencies) + '\n' if dependencies else '' # Format imports nicely, swapping imports of functions from migration files # for comments migration_imports = set() for line in list(imports): if re.match(r'^import (.*)\.\d+[^\s]*$', line): migration_imports.add(line.split('import')[1].strip()) imports.remove(line) self.needs_manual_porting = True # django.db.migrations is always used, but models import may not be. imports.add('from exo_changelog import change, operations') # Sort imports by the package / module to be imported (the part after # "from" in "from ... import ..." or after "import" in "import ..."). sorted_imports = sorted(imports, key=lambda i: i.split()[1]) items['imports'] = '\n'.join(sorted_imports) + '\n' if imports else '' if migration_imports: items['imports'] += ( '\n\n# Functions from the following migrations need manual ' 'copying.\n# Move them and any dependencies into this file, ' 'then update the\n# RunPython operations to refer to the local ' 'versions:\n# %s') % '\n# '.join(sorted(migration_imports)) # Hinting that goes into comment items.update( version=get_version(), timestamp=now().strftime('%Y-%m-%d %H:%M'), ) if self.change.initial: items['initial_str'] = '\n initial = True\n' return CHANGE_TEMPLATE % items
def get_kwargs(self): items = { "replaces_str": "", "initial_str": "", } imports = set() # Deconstruct operations operations = [] for operation in self.migration.operations: operation_string, operation_imports = OperationWriter(operation).serialize() imports.update(operation_imports) operations.append(operation_string) items["operations"] = "\n".join(operations) + "\n" if operations else "" # Format dependencies and write out swappable dependencies right dependencies = [] for dependency in self.migration.dependencies: if dependency[0] == "__setting__": dependencies.append(" migrations.swappable_dependency(settings.%s)," % dependency[1]) imports.add("from django.conf import settings") else: dependencies.append(" %s," % self.serialize(dependency)[0]) items["dependencies"] = "\n".join(dependencies) + "\n" if dependencies else "" # Format imports nicely, swapping imports of functions from migration files # for comments migration_imports = set() for line in list(imports): if re.match(r"^import (.*)\.\d+[^\s]*$", line): migration_imports.add(line.split("import")[1].strip()) imports.remove(line) self.needs_manual_porting = True # django.db.migrations is always used, but models import may not be. # If models import exists, merge it with migrations import. if "from django.db import models" in imports: imports.discard("from django.db import models") imports.add("from django.db import migrations, models") else: imports.add("from django.db import migrations") # Sort imports by the package / module to be imported (the part after # "from" in "from ... import ..." or after "import" in "import ..."). sorted_imports = sorted(imports, key=lambda i: i.split()[1]) items["imports"] = "\n".join(sorted_imports) + "\n" if imports else "" if migration_imports: items["imports"] += ( "\n\n# Functions from the following migrations need manual " "copying.\n# Move them and any dependencies into this file, " "then update the\n# RunPython operations to refer to the local " "versions:\n# %s" ) % "\n# ".join(sorted(migration_imports)) # If there's a replaces, make a string for it if self.migration.replaces: items['replaces_str'] = "\n replaces = %s\n" % self.serialize(self.migration.replaces)[0] # Hinting that goes into comment if self.include_header: items['migration_header'] = self.template_class_header % { 'version': get_version(), 'timestamp': now().strftime("%Y-%m-%d %H:%M"), } else: items['migration_header'] = "" if self.migration.initial: items['initial_str'] = "\n initial = True\n" return items