Fixed #23433 -- Deprecated django-admin.py entry point in favor of django-admin.

Unify on the entry point created by setuptools entry_points feature.
This commit is contained in:
Jon Dufresne 2019-11-01 21:08:23 -07:00 committed by Mariusz Felisiak
parent 8eb0f73eed
commit 5708327c37
10 changed files with 79 additions and 32 deletions

View File

@ -1,5 +1,21 @@
#!/usr/bin/env python
# When the django-admin.py deprecation ends, remove this script.
import warnings
from django.core import management
try:
from django.utils.deprecation import RemovedInDjango40Warning
except ImportError:
raise ImportError(
'django-admin.py was deprecated in Django 3.1 and removed in Django '
'4.0. Please manually remove this script from your virtual environment '
'and use django-admin instead.'
)
if __name__ == "__main__":
warnings.warn(
'django-admin.py is deprecated in favor of django-admin.',
RemovedInDjango40Warning,
)
management.execute_from_command_line()

View File

@ -14,15 +14,9 @@ Problems running ``django-admin``
-----------------------------------
:doc:`django-admin </ref/django-admin>` should be on your system path if you
installed Django via ``pip``. If it's not on your path, you can find it in
``site-packages/django/bin``, where ``site-packages`` is a directory within
your Python installation. Consider symlinking to :doc:`django-admin
</ref/django-admin>` from some place on your path, such as
:file:`/usr/local/bin`.
If ``django-admin`` doesn't work but ``django-admin.py`` does, you're probably
using a version of Django that doesn't match the version of this documentation.
``django-admin`` is new in Django 1.7.
installed Django via ``pip``. If it's not in your path, ensure you have your
virtual environment activated and you can try running the equivalent command
``python -m django``.
macOS permissions
-----------------

View File

@ -287,7 +287,7 @@ define some extra description units:
:ticket:`12345`
Django's documentation uses a custom ``console`` directive for documenting
command-line examples involving ``django-admin.py``, ``manage.py``, ``python``,
command-line examples involving ``django-admin``, ``manage.py``, ``python``,
etc.). In the HTML documentation, it renders a two-tab UI, with one tab showing
a Unix-style command prompt and a second tab showing a Windows prompt.

View File

@ -42,6 +42,8 @@ details on these changes.
* The ``django.db.models.query_utils.InvalidQuery`` exception class will be
removed.
* The ``django-admin.py`` entry point will be removed.
See the :ref:`Django 3.1 release notes <deprecated-features-3.1>` for more
details on these changes.

View File

@ -11,14 +11,8 @@ does the same thing as ``django-admin`` but also sets the
project's ``settings.py`` file.
The ``django-admin`` script should be on your system path if you installed
Django via ``pip``. If it's not on your path, you can find it in
``site-packages/django/bin`` within your Python installation. Consider
symlinking it from some place on your path, such as ``/usr/local/bin``.
For Windows users, who do not have symlinking functionality available, you can
copy ``django-admin.exe`` to a location on your existing path or edit the
``PATH`` settings (under ``Settings - Control Panel - System - Advanced -
Environment...``) to point to its installed location.
Django via ``pip``. If it's not in your path, ensure you have your virtual
environment activated.
Generally, when working on a single Django project, it's easier to use
``manage.py`` than ``django-admin``. If you need to switch between multiple

View File

@ -384,6 +384,9 @@ Miscellaneous
:class:`~django.core.exceptions.FieldDoesNotExist` and
:class:`~django.core.exceptions.FieldError`.
* The ``django-admin.py`` entry point is deprecated in favor of
``django-admin``.
.. _removed-features-3.1:
Features removed in 3.1

View File

@ -1,6 +1,5 @@
# #########################################################################
# This bash script adds tab-completion feature to django-admin.py and
# manage.py.
# #############################################################################
# This bash script adds tab-completion feature to django-admin and manage.py.
#
# Testing it out without installing
# =================================
@ -37,6 +36,7 @@ _django_completion()
COMP_CWORD=$COMP_CWORD \
DJANGO_AUTO_COMPLETE=1 $1 ) )
}
# When the django-admin.py deprecation ends, remove django-admin.py.
complete -F _django_completion -o default django-admin.py manage.py django-admin
_python_django_completion()

View File

@ -34,6 +34,7 @@ project_urls =
[options]
python_requires = >=3.6
packages = find:
# When the django-admin.py deprecation ends, remove "scripts".
scripts = django/bin/django-admin.py
include_package_data = true
zip_safe = false

View File

@ -0,0 +1,37 @@
import subprocess
import sys
from pathlib import Path
import django
from django.test import SimpleTestCase
class DeprecationTests(SimpleTestCase):
DEPRECATION_MESSAGE = (
b'RemovedInDjango40Warning: django-admin.py is deprecated in favor of '
b'django-admin.'
)
def _run_test(self, args):
p = subprocess.run(
[sys.executable, *args],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
)
return p.stdout, p.stderr
def test_django_admin_py_deprecated(self):
django_admin_py = Path(django.__file__).parent / 'bin' / 'django-admin.py'
_, err = self._run_test(['-Wd', django_admin_py, '--version'])
self.assertIn(self.DEPRECATION_MESSAGE, err)
def test_main_not_deprecated(self):
_, err = self._run_test(['-Wd', '-m', 'django', '--version'])
self.assertNotIn(self.DEPRECATION_MESSAGE, err)
def test_django_admin_py_equivalent_main(self):
django_admin_py = Path(django.__file__).parent / 'bin' / 'django-admin.py'
django_admin_py_out, _ = self._run_test([django_admin_py, '--version'])
django_out, _ = self._run_test(['-m', 'django', '--version'])
self.assertEqual(django_admin_py_out, django_out)

View File

@ -14,7 +14,6 @@ import unittest
from io import StringIO
from unittest import mock
import django
from django import conf, get_version
from django.conf import settings
from django.core.management import (
@ -125,8 +124,7 @@ class AdminScriptTestCase(SimpleTestCase):
return p.stdout, p.stderr
def run_django_admin(self, args, settings_file=None):
script_dir = os.path.abspath(os.path.join(os.path.dirname(django.__file__), 'bin'))
return self.run_test([os.path.join(script_dir, 'django-admin.py'), *args], settings_file)
return self.run_test(['-m', 'django', *args], settings_file)
def run_manage(self, args, settings_file=None, manage_py=None):
template_manage_py = (
@ -1898,7 +1896,12 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
# running again..
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "already exists")
self.assertOutput(
err,
"CommandError: 'testproject' conflicts with the name of an "
"existing Python module and cannot be used as a project name. "
"Please try another name.",
)
def test_invalid_project_name(self):
"Make sure the startproject management command validates a project name"
@ -2160,8 +2163,10 @@ class StartApp(AdminScriptTestCase):
)
def test_overlaying_app(self):
self.run_django_admin(['startapp', 'app1'])
out, err = self.run_django_admin(['startapp', 'app2', 'app1'])
# Use a subdirectory so it is outside the PYTHONPATH.
os.makedirs(os.path.join(self.test_dir, 'apps/app1'))
self.run_django_admin(['startapp', 'app1', 'apps/app1'])
out, err = self.run_django_admin(['startapp', 'app2', 'apps/app1'])
self.assertOutput(
err,
"already exists. Overlaying an app into an existing directory "
@ -2261,11 +2266,6 @@ class Dumpdata(AdminScriptTestCase):
class MainModule(AdminScriptTestCase):
"""python -m django works like django-admin."""
def test_runs_django_admin(self):
cmd_out, _ = self.run_django_admin(['--version'])
mod_out, _ = self.run_test(['-m', 'django', '--version'])
self.assertEqual(mod_out, cmd_out)
def test_program_name_in_help(self):
out, err = self.run_test(['-m', 'django', 'help'])
self.assertOutput(out, "Type 'python -m django help <subcommand>' for help on a specific subcommand.")