summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAarni Koskela <akx@iki.fi>2022-02-23 20:52:35 +0200
committerAarni Koskela <akx@iki.fi>2022-04-08 13:28:21 +0300
commit5aa000ec2955407271e660630e8db376adbc6858 (patch)
tree1f3c7ef308b9f4193d9c609deb24dc1ee45d639c
parent7e90d6b8fe1327ed863b626db51be9061b6b5781 (diff)
downloadbabel-5aa000ec2955407271e660630e8db376adbc6858.tar.gz
Prefer setuptools imports to distutils imports
The non-conditional imports have been around for 6 to 17 years, so they should be safe in conservative situations too. Refs #824
-rw-r--r--babel/messages/frontend.py94
-rwxr-xr-xsetup.py3
-rw-r--r--tests/messages/test_frontend.py29
3 files changed, 67 insertions, 59 deletions
diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py
index 41b75ce..c71bc0d 100644
--- a/babel/messages/frontend.py
+++ b/babel/messages/frontend.py
@@ -32,9 +32,23 @@ from babel.messages.extract import DEFAULT_KEYWORDS, DEFAULT_MAPPING, check_and_
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):
@@ -169,11 +183,9 @@ class compile_catalog(Command):
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
@@ -216,7 +228,7 @@ class compile_catalog(Command):
domain + '.mo'))
if not po_files:
- raise DistutilsOptionError('no message catalogs found')
+ raise OptionError('no message catalogs found')
catalogs_and_errors = {}
@@ -388,7 +400,7 @@ class extract_messages(Command):
if not self.input_paths:
self.input_paths = self.input_dirs
else:
- raise DistutilsOptionError(
+ raise OptionError(
'input-dirs and input-paths are mutually exclusive'
)
@@ -402,22 +414,25 @@ class extract_messages(Command):
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):
@@ -431,11 +446,11 @@ class extract_messages(Command):
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 (), ",")
@@ -456,7 +471,6 @@ class extract_messages(Command):
else:
self.directory_filter = None
-
def run(self):
mappings = self._get_mappings()
with open(self.output_file, 'wb') as outfile:
@@ -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):
@@ -609,18 +625,17 @@ class init_catalog(Command):
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')
@@ -628,8 +643,7 @@ class init_catalog(Command):
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:
@@ -723,28 +737,28 @@ class update_catalog(Command):
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:
@@ -771,7 +785,7 @@ class update_catalog(Command):
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:
@@ -910,7 +924,7 @@ class CommandLineInterface(object):
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
@@ -976,7 +990,7 @@ class CommandLineInterface(object):
try:
cmdinst.ensure_finalized()
- except DistutilsOptionError as err:
+ except OptionError as err:
parser.error(str(err))
return cmdinst
diff --git a/setup.py b/setup.py
index 9a4af23..e036bbd 100755
--- a/setup.py
+++ b/setup.py
@@ -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__
diff --git a/tests/messages/test_frontend.py b/tests/messages/test_frontend.py
index 2dc5330..ba78f50 100644
--- a/tests/messages/test_frontend.py
+++ b/tests/messages/test_frontend.py
@@ -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
@@ -29,7 +27,7 @@ import pytest
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
@@ -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',
@@ -65,12 +62,12 @@ class CompileCatalogTestCase(unittest.TestCase):
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):
@@ -78,7 +75,6 @@ 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',
@@ -100,21 +96,21 @@ class ExtractMessagesTestCase(unittest.TestCase):
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
@@ -146,7 +142,7 @@ class ExtractMessagesTestCase(unittest.TestCase):
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):
@@ -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',
@@ -375,12 +370,12 @@ class InitCatalogTestCase(unittest.TestCase):
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):