diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49beef513..cc2ba1250 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,9 +9,9 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['3.9', '3.10', '3.11', '3.12'] celery-version: ['5.2.*', '5.3.*', '5.4.*', '5.5.*'] - tornado-version: ['6.0'] + tornado-version: ['6.5'] exclude: # https://docs.celeryq.dev/en/v5.2.7/whatsnew-5.2.html#step-5-upgrade-to-celery-5-2 - python-version: '3.12' celery-version: '5.2.*' diff --git a/docs/conf.py b/docs/conf.py index 7f9da2b71..dbe2472e0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# # flower documentation build configuration file, created by # sphinx-quickstart on Fri Apr 11 17:26:01 2014. # diff --git a/examples/tasks.py b/examples/tasks.py index 94f3af52f..f9d6c457b 100644 --- a/examples/tasks.py +++ b/examples/tasks.py @@ -24,7 +24,7 @@ def sleep(seconds): @app.task def echo(msg, timestamp=False): - return "%s: %s" % (datetime.now(), msg) if timestamp else msg + return f"{datetime.now()}: {msg}" if timestamp else msg @app.task diff --git a/flower/command.py b/flower/command.py index 94ed6c7b6..35ca83c0a 100644 --- a/flower/command.py +++ b/flower/command.py @@ -87,7 +87,7 @@ def apply_options(prog_name, argv): try: parse_config_file(os.path.abspath(options.conf), final=False) parse_command_line([prog_name] + argv) - except IOError: + except OSError: if os.path.basename(options.conf) != DEFAULT_CONFIG_FILE: raise diff --git a/flower/utils/__init__.py b/flower/utils/__init__.py index 915187d53..059b52a80 100644 --- a/flower/utils/__init__.py +++ b/flower/utils/__init__.py @@ -18,7 +18,7 @@ def bugreport(app=None): app = app or celery.Celery() # pylint: disable=consider-using-f-string - return 'flower -> flower:%s tornado:%s humanize:%s%s' % ( + return 'flower -> flower:{} tornado:{} humanize:{}{}'.format( __version__, tornado.version, getattr(humanize, '__version__', None) or getattr(humanize, 'VERSION'), diff --git a/flower/utils/broker.py b/flower/utils/broker.py index f04208ac6..21cf87153 100644 --- a/flower/utils/broker.py +++ b/flower/utils/broker.py @@ -2,7 +2,6 @@ import json import logging import numbers -import socket import sys from urllib.parse import quote, unquote, urljoin, urlparse @@ -67,7 +66,7 @@ async def queues(self, names): url, auth_username=username, auth_password=password, connect_timeout=1.0, request_timeout=2.0, validate_cert=False) - except (socket.error, httpclient.HTTPError) as e: + except (OSError, httpclient.HTTPError) as e: logger.error("RabbitMQ management API call failed: %s", e) return [] finally: @@ -106,7 +105,7 @@ def _q_for_pri(self, queue, pri): if pri not in self.priority_steps: raise ValueError('Priority not in priority steps') # pylint: disable=consider-using-f-string - return '{0}{1}{2}'.format(*((queue, self.sep, pri) if pri else (queue, '', ''))) + return '{}{}{}'.format(*((queue, self.sep, pri) if pri else (queue, '', ''))) async def queues(self, names): queue_stats = [] @@ -115,7 +114,7 @@ async def queues(self, names): name, pri) for pri in self.priority_steps] queue_stats.append({ 'name': name, - 'messages': sum((self.redis.llen(x) for x in priority_names)) + 'messages': sum(self.redis.llen(x) for x in priority_names) }) return queue_stats diff --git a/flower/utils/search.py b/flower/utils/search.py index fba842b6c..670828dfa 100644 --- a/flower/utils/search.py +++ b/flower/utils/search.py @@ -21,7 +21,7 @@ def parse_search_terms(raw_search_value): if 'kwargs'not in parsed_search: parsed_search['kwargs'] = {} try: - key, value = [p.strip() for p in query_part[len('kwargs:'):].split('=')] + key, value = (p.strip() for p in query_part[len('kwargs:'):].split('=')) except ValueError: continue parsed_search['kwargs'][key] = preprocess_search_value(value) diff --git a/flower/views/__init__.py b/flower/views/__init__.py index fbd80b016..378d0c04d 100644 --- a/flower/views/__init__.py +++ b/flower/views/__init__.py @@ -125,12 +125,12 @@ def format_task(self, task): return task def get_active_queue_names(self): - queues = set([]) + queues = set() for _, info in self.application.workers.items(): for queue in info.get('active_queues', []): queues.add(queue['name']) if not queues: - queues = set([self.capp.conf.task_default_queue]) |\ + queues = {self.capp.conf.task_default_queue} |\ {q.name for q in self.capp.conf.task_queues or [] if q.name} return sorted(queues) diff --git a/flower/views/workers.py b/flower/views/workers.py index defd0469a..0b08d3af4 100644 --- a/flower/views/workers.py +++ b/flower/views/workers.py @@ -77,7 +77,7 @@ async def get(self): @classmethod def _as_dict(cls, worker): if hasattr(worker, '_fields'): - return dict((k, getattr(worker, k)) for k in worker._fields) + return {k: getattr(worker, k) for k in worker._fields} return cls._info(worker) @classmethod diff --git a/requirements/default.txt b/requirements/default.txt index 93c831efb..17e46fdc9 100644 --- a/requirements/default.txt +++ b/requirements/default.txt @@ -1,5 +1,5 @@ celery>=5.0.5 -tornado>=5.0.0,<7.0.0 +tornado>=6.5.0,<7.0.0 prometheus_client>=0.8.0 humanize pytz diff --git a/setup.py b/setup.py index 7e028ec93..b5dc5d33b 100644 --- a/setup.py +++ b/setup.py @@ -31,8 +31,6 @@ def get_requirements(filename): Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 diff --git a/tests/unit/test_command.py b/tests/unit/test_command.py index c0f7414ef..05e92daff 100644 --- a/tests/unit/test_command.py +++ b/tests/unit/test_command.py @@ -166,7 +166,7 @@ def test_empty_conf(self): def test_conf_abs(self): with tempfile.NamedTemporaryFile() as cf: with self.mock_option('conf', cf.name), self.mock_option('debug', False): - cf.write('debug=True\n'.encode('utf-8')) + cf.write(b'debug=True\n') cf.flush() apply_options('flower', argv=['--conf=%s' % cf.name]) self.assertEqual(cf.name, options.conf) @@ -175,7 +175,7 @@ def test_conf_abs(self): def test_conf_relative(self): with tempfile.NamedTemporaryFile(dir='.') as cf: with self.mock_option('conf', cf.name), self.mock_option('debug', False): - cf.write('debug=True\n'.encode('utf-8')) + cf.write(b'debug=True\n') cf.flush() apply_options('flower', argv=['--conf=%s' % os.path.basename(cf.name)]) self.assertTrue(options.debug) @@ -184,7 +184,7 @@ def test_conf_relative(self): def test_all_options_documented(self): def grep(patter, filename): return int(subprocess.check_output( - 'grep "%s" %s|wc -l' % (patter, filename), shell=True)) + f'grep "{patter}" {filename}|wc -l', shell=True)) defined = grep('^define(', 'flower/options.py') documented = grep('^~~', 'docs/config.rst') diff --git a/tests/unit/views/test_auth.py b/tests/unit/views/test_auth.py index 941ed4aa1..3068456e6 100644 --- a/tests/unit/views/test_auth.py +++ b/tests/unit/views/test_auth.py @@ -59,4 +59,4 @@ def test_authenticate_wildcard_email(self): self.assertTrue(authenticate("one.*@example.com", "one.two@example.com")) self.assertFalse(authenticate(".*@example.com", "attacker@example.com.attacker.com")) self.assertFalse(authenticate(".*@corp.example.com", "attacker@corpZexample.com")) - self.assertFalse(authenticate(".*@corp\.example\.com", "attacker@corpZexample.com")) + self.assertFalse(authenticate(r".*@corp\.example\.com", "attacker@corpZexample.com")) diff --git a/tox.ini b/tox.ini index 111e28f15..f0d0b119d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,13 @@ [tox] envlist = # Celery 5.2: only py38–py311 (py312 excluded) - {py38,py39,py310,py311}-celery52-{tornado60,tornado61,tornado62,tornado63,tornado64,tornado65}, + {py38,py39,py310,py311}-celery52-tornado65, # Celery 5.3: py38–py312 - {py38,py39,py310,py311,py312}-celery53-{tornado60,tornado61,tornado62,tornado63,tornado64,tornado65}, + {py38,py39,py310,py311,py312}-celery53-tornado65, # Celery 5.4: py38–py312 - {py38,py39,py310,py311,py312}-celery54-{tornado60,tornado61,tornado62,tornado63,tornado64,tornado65}, + {py38,py39,py310,py311,py312}-celery54-tornado65, # Celery 5.5: py38–py312 - {py38,py39,py310,py311,py312}-celery55-{tornado60,tornado61,tornado62,tornado63,tornado64,tornado65}, + {py38,py39,py310,py311,py312}-celery55-tornado65, lint skip_missing_interpreters = true @@ -19,11 +19,6 @@ deps = celery53: celery==5.3.* celery54: celery==5.4.* celery55: celery==5.5.* - tornado60: tornado==6.0.* - tornado61: tornado==6.1.* - tornado62: tornado==6.2.* - tornado63: tornado==6.3.* - tornado64: tornado==6.4.* tornado65: tornado==6.5.* commands = python -m flower --version