diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py index 6eb402109f..0b39536f5b 100644 --- a/django/core/management/commands/makemigrations.py +++ b/django/core/management/commands/makemigrations.py @@ -208,7 +208,10 @@ class Command(BaseCommand): if self.verbosity >= 1: # Display a relative path if it's below the current working # directory, or an absolute path otherwise. - migration_string = os.path.relpath(writer.path) + try: + migration_string = os.path.relpath(writer.path) + except ValueError: + migration_string = writer.path if migration_string.startswith('..'): migration_string = writer.path self.stdout.write(" %s:\n" % (self.style.MIGRATE_LABEL(migration_string),)) diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index 6681ceecbc..fb2b0fb877 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -1152,6 +1152,19 @@ class MakeMigrationsTests(MigrationTestBase): call_command("makemigrations", "migrations", stdout=out) self.assertIn(os.path.join(migration_dir, '0001_initial.py'), out.getvalue()) + def test_makemigrations_migration_path_output_valueerror(self): + """ + makemigrations prints the absolute path if os.path.relpath() raises a + ValueError when it's impossible to obtain a relative path, e.g. on + Windows if Django is installed on a different drive than where the + migration files are created. + """ + out = six.StringIO() + with self.temporary_migration_module() as migration_dir: + with mock.patch('os.path.relpath', side_effect=ValueError): + call_command('makemigrations', 'migrations', stdout=out) + self.assertIn(os.path.join(migration_dir, '0001_initial.py'), out.getvalue()) + def test_makemigrations_inconsistent_history(self): """ makemigrations should raise InconsistentMigrationHistory exception if