Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer setuptools imports to distutils imports #843

Merged
merged 1 commit into from Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
94 changes: 54 additions & 40 deletions babel/messages/frontend.py
Expand Up @@ -32,9 +32,23 @@
from babel.messages.mofile import write_mo
from babel.messages.pofile import read_po, write_po
from babel.util import LOCALTZ
from distutils import log as distutils_log
from distutils.cmd import Command as _Command
from distutils.errors import DistutilsOptionError, DistutilsSetupError

log = logging.getLogger('babel')

try:
# See: https://setuptools.pypa.io/en/latest/deprecated/distutils-legacy.html
from setuptools import Command as _Command
distutils_log = log # "distutils.log → (no replacement yet)"

try:
from setuptools.errors import OptionError, SetupError
except ImportError: # Error aliases only added in setuptools 59 (2021-11).
OptionError = SetupError = Exception

except ImportError:
from distutils import log as distutils_log
from distutils.cmd import Command as _Command
from distutils.errors import OptionError as OptionError, DistutilsSetupError as SetupError


def listify_value(arg, split=None):
Expand Down Expand Up @@ -169,11 +183,9 @@ def initialize_options(self):
def finalize_options(self):
self.domain = listify_value(self.domain)
if not self.input_file and not self.directory:
raise DistutilsOptionError('you must specify either the input file '
'or the base directory')
raise OptionError('you must specify either the input file or the base directory')
if not self.output_file and not self.directory:
raise DistutilsOptionError('you must specify either the output file '
'or the base directory')
raise OptionError('you must specify either the output file or the base directory')

def run(self):
n_errors = 0
Expand Down Expand Up @@ -216,7 +228,7 @@ def _run_domain(self, domain):
domain + '.mo'))

if not po_files:
raise DistutilsOptionError('no message catalogs found')
raise OptionError('no message catalogs found')

catalogs_and_errors = {}

Expand Down Expand Up @@ -388,7 +400,7 @@ def finalize_options(self):
if not self.input_paths:
self.input_paths = self.input_dirs
else:
raise DistutilsOptionError(
raise OptionError(
'input-dirs and input-paths are mutually exclusive'
)

Expand All @@ -402,22 +414,25 @@ def finalize_options(self):
self.keywords = keywords

if not self.keywords:
raise DistutilsOptionError('you must specify new keywords if you '
'disable the default ones')
raise OptionError(
'you must specify new keywords if you disable the default ones'
)

if not self.output_file:
raise DistutilsOptionError('no output file specified')
raise OptionError('no output file specified')
if self.no_wrap and self.width:
raise DistutilsOptionError("'--no-wrap' and '--width' are mutually "
"exclusive")
raise OptionError(
"'--no-wrap' and '--width' are mutually exclusive"
)
if not self.no_wrap and not self.width:
self.width = 76
elif self.width is not None:
self.width = int(self.width)

if self.sort_output and self.sort_by_file:
raise DistutilsOptionError("'--sort-output' and '--sort-by-file' "
"are mutually exclusive")
raise OptionError(
"'--sort-output' and '--sort-by-file' are mutually exclusive"
)

if self.input_paths:
if isinstance(self.input_paths, str):
Expand All @@ -431,11 +446,11 @@ def finalize_options(self):
self.input_paths = []

if not self.input_paths:
raise DistutilsOptionError("no input files or directories specified")
raise OptionError("no input files or directories specified")

for path in self.input_paths:
if not os.path.exists(path):
raise DistutilsOptionError("Input path: %s does not exist" % path)
raise OptionError("Input path: %s does not exist" % path)

self.add_comments = listify_value(self.add_comments or (), ",")

Expand All @@ -456,7 +471,6 @@ def finalize_options(self):
else:
self.directory_filter = None


def run(self):
mappings = self._get_mappings()
with open(self.output_file, 'wb') as outfile:
Expand Down Expand Up @@ -558,8 +572,10 @@ def check_message_extractors(dist, name, value):
"""
assert name == 'message_extractors'
if not isinstance(value, dict):
raise DistutilsSetupError('the value of the "message_extractors" '
'parameter must be a dictionary')
raise SetupError(
'the value of the "message_extractors" '
'parameter must be a dictionary'
)


class init_catalog(Command):
Expand Down Expand Up @@ -609,27 +625,25 @@ def initialize_options(self):

def finalize_options(self):
if not self.input_file:
raise DistutilsOptionError('you must specify the input file')
raise OptionError('you must specify the input file')

if not self.locale:
raise DistutilsOptionError('you must provide a locale for the '
'new catalog')
raise OptionError('you must provide a locale for the new catalog')
try:
self._locale = Locale.parse(self.locale)
except UnknownLocaleError as e:
raise DistutilsOptionError(e)
raise OptionError(e) from e

if not self.output_file and not self.output_dir:
raise DistutilsOptionError('you must specify the output directory')
raise OptionError('you must specify the output directory')
if not self.output_file:
self.output_file = os.path.join(self.output_dir, self.locale,
'LC_MESSAGES', self.domain + '.po')

if not os.path.exists(os.path.dirname(self.output_file)):
os.makedirs(os.path.dirname(self.output_file))
if self.no_wrap and self.width:
raise DistutilsOptionError("'--no-wrap' and '--width' are mutually "
"exclusive")
raise OptionError("'--no-wrap' and '--width' are mutually exclusive")
if not self.no_wrap and not self.width:
self.width = 76
elif self.width is not None:
Expand Down Expand Up @@ -723,28 +737,28 @@ def initialize_options(self):

def finalize_options(self):
if not self.input_file:
raise DistutilsOptionError('you must specify the input file')
raise OptionError('you must specify the input file')
if not self.output_file and not self.output_dir:
raise DistutilsOptionError('you must specify the output file or '
'directory')
raise OptionError('you must specify the output file or directory')
if self.output_file and not self.locale:
raise DistutilsOptionError('you must specify the locale')
raise OptionError('you must specify the locale')

if self.init_missing:
if not self.locale:
raise DistutilsOptionError('you must specify the locale for '
'the init-missing option to work')
raise OptionError(
'you must specify the locale for '
'the init-missing option to work'
)

try:
self._locale = Locale.parse(self.locale)
except UnknownLocaleError as e:
raise DistutilsOptionError(e)
raise OptionError(e) from e
else:
self._locale = None

if self.no_wrap and self.width:
raise DistutilsOptionError("'--no-wrap' and '--width' are mutually "
"exclusive")
raise OptionError("'--no-wrap' and '--width' are mutually exclusive")
if not self.no_wrap and not self.width:
self.width = 76
elif self.width is not None:
Expand All @@ -771,7 +785,7 @@ def run(self):
po_files.append((self.locale, self.output_file))

if not po_files:
raise DistutilsOptionError('no message catalogs found')
raise OptionError('no message catalogs found')

domain = self.domain
if not domain:
Expand Down Expand Up @@ -910,7 +924,7 @@ def run(self, argv=None):
return cmdinst.run()

def _configure_logging(self, loglevel):
self.log = logging.getLogger('babel')
self.log = log
self.log.setLevel(loglevel)
# Don't add a new handler for every instance initialization (#227), this
# would cause duplicated output when the CommandLineInterface as an
Expand Down Expand Up @@ -976,7 +990,7 @@ def _configure_command(self, cmdname, argv):

try:
cmdinst.ensure_finalized()
except DistutilsOptionError as err:
except OptionError as err:
parser.error(str(err))

return cmdinst
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Expand Up @@ -2,9 +2,8 @@

import subprocess
import sys
from distutils.cmd import Command

from setuptools import setup
from setuptools import setup, Command

try:
from babel import __version__
Expand Down
29 changes: 12 additions & 17 deletions tests/messages/test_frontend.py
Expand Up @@ -11,12 +11,10 @@
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://babel.edgewall.org/log/.
import shlex
from freezegun import freeze_time
from datetime import datetime
from distutils.dist import Distribution
from distutils.errors import DistutilsOptionError
from distutils.log import _global_log
from freezegun import freeze_time
from io import StringIO
from setuptools import Distribution
import logging
import os
import shutil
Expand All @@ -29,7 +27,7 @@
from babel import __version__ as VERSION
from babel.dates import format_datetime
from babel.messages import frontend, Catalog
from babel.messages.frontend import CommandLineInterface, extract_messages, update_catalog
from babel.messages.frontend import CommandLineInterface, extract_messages, update_catalog, OptionError
from babel.util import LOCALTZ
from babel.messages.pofile import read_po, write_po

Expand All @@ -49,7 +47,6 @@ class CompileCatalogTestCase(unittest.TestCase):
def setUp(self):
self.olddir = os.getcwd()
os.chdir(data_dir)
_global_log.threshold = 5 # shut up distutils logging

self.dist = Distribution(dict(
name='TestProject',
Expand All @@ -65,20 +62,19 @@ def tearDown(self):
def test_no_directory_or_output_file_specified(self):
self.cmd.locale = 'en_US'
self.cmd.input_file = 'dummy'
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)

def test_no_directory_or_input_file_specified(self):
self.cmd.locale = 'en_US'
self.cmd.output_file = 'dummy'
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)


class ExtractMessagesTestCase(unittest.TestCase):

def setUp(self):
self.olddir = os.getcwd()
os.chdir(data_dir)
_global_log.threshold = 5 # shut up distutils logging

self.dist = Distribution(dict(
name='TestProject',
Expand All @@ -100,21 +96,21 @@ def assert_pot_file_exists(self):
def test_neither_default_nor_custom_keywords(self):
self.cmd.output_file = 'dummy'
self.cmd.no_default_keywords = True
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)

def test_no_output_file_specified(self):
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)

def test_both_sort_output_and_sort_by_file(self):
self.cmd.output_file = 'dummy'
self.cmd.sort_output = True
self.cmd.sort_by_file = True
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)

def test_invalid_file_or_dir_input_path(self):
self.cmd.input_paths = 'nonexistent_path'
self.cmd.output_file = 'dummy'
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)

def test_input_paths_is_treated_as_list(self):
self.cmd.input_paths = data_dir
Expand Down Expand Up @@ -146,7 +142,7 @@ def test_input_dirs_is_mutually_exclusive_with_input_paths(self):
self.cmd.input_dirs = this_dir
self.cmd.input_paths = this_dir
self.cmd.output_file = pot_file
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)

@freeze_time("1994-11-11")
def test_extraction_with_default_mapping(self):
Expand Down Expand Up @@ -354,7 +350,6 @@ class InitCatalogTestCase(unittest.TestCase):
def setUp(self):
self.olddir = os.getcwd()
os.chdir(data_dir)
_global_log.threshold = 5 # shut up distutils logging

self.dist = Distribution(dict(
name='TestProject',
Expand All @@ -375,12 +370,12 @@ def tearDown(self):
def test_no_input_file(self):
self.cmd.locale = 'en_US'
self.cmd.output_file = 'dummy'
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)

def test_no_locale(self):
self.cmd.input_file = 'dummy'
self.cmd.output_file = 'dummy'
self.assertRaises(DistutilsOptionError, self.cmd.finalize_options)
self.assertRaises(OptionError, self.cmd.finalize_options)

@freeze_time("1994-11-11")
def test_with_output_dir(self):
Expand Down