diff --git a/hobo/middleware/cookies_samesite.py b/hobo/middleware/cookies_samesite.py index 2b455cd..c53edc2 100644 --- a/hobo/middleware/cookies_samesite.py +++ b/hobo/middleware/cookies_samesite.py @@ -15,7 +15,6 @@ # along with this program. If not, see . from django.conf import settings -from django.utils import six from django.utils.deprecation import MiddlewareMixin @@ -34,10 +33,6 @@ class CookiesSameSiteFixMiddleware(MiddlewareMixin): return response -if six.PY2: - import Cookie - Cookie.Morsel._reserved.setdefault('samesite', 'SameSite') -else: - # required for Python <3.8 - import http.cookies - http.cookies.Morsel._reserved.setdefault('samesite', 'SameSite') +# required for Python <3.8 +import http.cookies +http.cookies.Morsel._reserved.setdefault('samesite', 'SameSite') diff --git a/hobo/multitenant/threads.py b/hobo/multitenant/threads.py index bac5b2b..18c44b9 100644 --- a/hobo/multitenant/threads.py +++ b/hobo/multitenant/threads.py @@ -14,167 +14,41 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import sys import threading -from django.utils import six + +_Thread_bootstrap_inner = threading.Thread._bootstrap_inner +_Thread__init__ = threading.Thread.__init__ -if six.PY2: - class TenantAwareThread(threading.Thread): - def __init__(self, *args, **kwargs): - from django.db import connection - try: - if hasattr(connection, 'get_tenant'): - self.tenant = connection.get_tenant() - else: - self.tenant = None - except RuntimeError: - # this happens when ImportError is raised at startup; ignore - # the error to let the real one be displayed. - self.tenant = None - super(TenantAwareThread, self).__init__(*args, **kwargs) - - def run(self): - if self.tenant is not None: - from django.db import connection - old_tenant = connection.get_tenant() - connection.set_tenant(self.tenant) - try: - super(TenantAwareThread, self).run() - finally: - connection.set_tenant(old_tenant) - connection.close() - else: - super(TenantAwareThread, self).run() - - class _Timer(TenantAwareThread): - """Call a function after a specified number of seconds: - - t = Timer(30.0, f, args=[], kwargs={}) - t.start() - t.cancel() # stop the timer's action if it's still waiting - - """ - - def __init__(self, interval, function, args=[], kwargs={}): - super(_Timer, self).__init__() - self.interval = interval - self.function = function - self.args = args - self.kwargs = kwargs - self.finished = threading.Event() - - def cancel(self): - """Stop the timer if it hasn't finished yet""" - self.finished.set() - - def run(self): - self.finished.wait(self.interval) - if not self.finished.is_set(): - self.function(*self.args, **self.kwargs) - self.finished.set() - - class _MainThread(TenantAwareThread): - - def __init__(self): - if six.PY3: - super(_MainThread, self).__init__(name="MainThread", daemon=False) - self._set_tstate_lock() - self._started.set() - self._set_ident() - with threading._active_limbo_lock: - threading._active[self._ident] = self - else: - super(_MainThread, self).__init__(name="MainThread") - self._Thread__started.set() - self._set_ident() - with threading._active_limbo_lock: - threading._active[threading._get_ident()] = self - - def _set_daemon(self): - return False - - def _exitfunc(self): - self._Thread__stop() - t = threading._pickSomeNonDaemonThread() - if t: - if __debug__: - self._note("%s: waiting for other threads", self) - while t: - t.join() - t = threading._pickSomeNonDaemonThread() - if __debug__: - self._note("%s: exiting", self) - self._Thread__delete() - - class _DummyThread(TenantAwareThread): - def __init__(self): - if six.PY3: - super(_DummyThread, self).__init__(name=threading._newname("Dummy-%d"), daemon=True) - self._started.set() - self._set_ident() - with threading._active_limbo_lock: - threading._active[self._ident] = self - return - - super(_DummyThread, self).__init__(name=threading._newname("Dummy-%d")) - - # Thread.__block consumes an OS-level locking primitive, which - # can never be used by a _DummyThread. Since a _DummyThread - # instance is immortal, that's bad, so release this resource. - del self._Thread__block - - self._Thread__started.set() - self._set_ident() - with threading._active_limbo_lock: - threading._active[threading._get_ident()] = self - - def _set_daemon(self): - return True - - def join(self, timeout=None): - assert False, "cannot join a dummy thread" - - def install_tenant_aware_threads(): - if getattr(threading, 'multitenant', False): - return - # Install tenant aware Thread class - threading.Thread = TenantAwareThread - threading._DummyThread = _DummyThread - threading._MainThread = _MainThread - threading._Timer = _Timer - threading.multitenant = True -else: - _Thread_bootstrap_inner = threading.Thread._bootstrap_inner - _Thread__init__ = threading.Thread.__init__ - - def _new__init__(self, *args, **kwargs): - from django.db import connection - try: - if hasattr(connection, 'get_tenant'): - self.tenant = connection.get_tenant() - else: - self.tenant = None - except RuntimeError: - # this happens when ImportError is raised at startup; ignore - # the error to let the real one be displayed. - self.tenant = None - _Thread__init__(self, *args, **kwargs) - - def _new_bootstrap_inner(self): - if self.tenant is not None: - from django.db import connection - old_tenant = connection.get_tenant() - connection.set_tenant(self.tenant) - try: - _Thread_bootstrap_inner(self) - finally: - connection.set_tenant(old_tenant) - connection.close() +def _new__init__(self, *args, **kwargs): + from django.db import connection + try: + if hasattr(connection, 'get_tenant'): + self.tenant = connection.get_tenant() else: - _Thread_bootstrap_inner(self) + self.tenant = None + except RuntimeError: + # this happens when ImportError is raised at startup; ignore + # the error to let the real one be displayed. + self.tenant = None + _Thread__init__(self, *args, **kwargs) - def install_tenant_aware_threads(): - threading.Thread.__init__ = _new__init__ - threading.Thread._bootstrap_inner = _new_bootstrap_inner + +def _new_bootstrap_inner(self): + if self.tenant is not None: + from django.db import connection + old_tenant = connection.get_tenant() + connection.set_tenant(self.tenant) + try: + _Thread_bootstrap_inner(self) + finally: + connection.set_tenant(old_tenant) + connection.close() + else: + _Thread_bootstrap_inner(self) + + +def install_tenant_aware_threads(): + threading.Thread.__init__ = _new__init__ + threading.Thread._bootstrap_inner = _new_bootstrap_inner diff --git a/hobo/signature.py b/hobo/signature.py index 8ac3fea..61a7ec6 100644 --- a/hobo/signature.py +++ b/hobo/signature.py @@ -77,10 +77,6 @@ def check_string(s, signature, key, algo='sha256'): if len(signature2) != len(signature): return False res = 0 - if six.PY3: - for a, b in zip(signature, signature2): - res |= a ^ b - else: - for a, b in zip(signature, signature2): - res |= ord(a) ^ ord(b) + for a, b in zip(signature, signature2): + res |= a ^ b return res == 0 diff --git a/tests/test_emails.py b/tests/test_emails.py index fd163f9..e6a3724 100644 --- a/tests/test_emails.py +++ b/tests/test_emails.py @@ -12,7 +12,6 @@ import socket import threading from django.core.exceptions import ValidationError -from django.utils import six from django.utils.encoding import force_text from hobo.emails.validators import validate_email_address @@ -62,12 +61,8 @@ def dns_resolver(monkeypatch, port_available): def smtp_server(monkeypatch, port_available): class RecipientValidatingSMTPChannel(smtpd.SMTPChannel): def smtp_RCPT(self, arg): - if six.PY2: - address = self._SMTPChannel__getaddr('TO:', arg) - domain = address.split('@')[-1] - else: - address = self._getaddr(arg) - domain = address[1].split('@')[-1][:-1] + address = self._getaddr(arg) + domain = address[1].split('@')[-1][:-1] if domain in ('example.com', 'example-spf.com', 'example-spf-allow-all.com', 'example-invalid-spf.com'): self._SMTPChannel__rcpttos.append(address) self.push('250 Ok') diff --git a/tests/test_hobo_deploy.py b/tests/test_hobo_deploy.py index 6ada766..c0a5aa3 100644 --- a/tests/test_hobo_deploy.py +++ b/tests/test_hobo_deploy.py @@ -8,7 +8,6 @@ import pytest from mock import call, patch, Mock from requests import Response, exceptions -from django.utils import six from django.utils.six import StringIO from hobo.agent.common.management.commands.hobo_deploy import ( @@ -65,12 +64,8 @@ def test_handle_from_scratch(): command.deploy.reset_mock() with patch('hobo.agent.common.management.commands.hobo_deploy.open') as mocked_open: mocked_open.side_effect = [StringIO('malformated JSON')] - if six.PY2: - with pytest.raises(ValueError, match='No JSON object could be decoded'): - command.handle('https://combo.dev.publik.love/', 'env.json') - else: - with pytest.raises(json.decoder.JSONDecodeError): - command.handle('https://combo.dev.publik.love/', 'env.json') + with pytest.raises(json.decoder.JSONDecodeError): + command.handle('https://combo.dev.publik.love/', 'env.json') assert command.deploy.mock_calls == [] # missing args diff --git a/tests_multitenant/test_agent_worker.py b/tests_multitenant/test_agent_worker.py index f70ece6..9abec6e 100644 --- a/tests_multitenant/test_agent_worker.py +++ b/tests_multitenant/test_agent_worker.py @@ -4,7 +4,6 @@ import json import mock import os import pytest -import six from django.utils.encoding import force_text @@ -118,10 +117,7 @@ def test_deploy_host_with_agent_patterns(mocked_subprocess, mocked_exists, local mocked_subprocess.Popen = mock.Mock(return_value=mocked_opened) # load AGENT_HOST_PATTERNS from local_settings fixture - if six.PY2: - reload(settings) - else: - importlib.reload(settings) + importlib.reload(settings) deploy(ENVIRONMENT) # process called mock_calls = set(x[1][0] for x in mocked_subprocess.Popen.mock_calls) diff --git a/tests_multitenant/test_tenant_command.py b/tests_multitenant/test_tenant_command.py index 131b5cf..5fc8064 100644 --- a/tests_multitenant/test_tenant_command.py +++ b/tests_multitenant/test_tenant_command.py @@ -7,7 +7,6 @@ import sys from django.core.management import BaseCommand, call_command, load_command_class from django.utils.encoding import force_bytes -from django.utils import six from django.core.management.base import CommandError from hobo.multitenant.models import Tenant @@ -124,10 +123,7 @@ def test_tenant_command_all_tenants_errors(tenants, monkeypatch, capsys): klass.run_from_argv(['manage.py', 'tenant_command', 'bytes-error', '--all-tenants']) captured = capsys.readouterr() - if six.PY2: - assert u'héhé' in captured.err - else: - assert repr(force_bytes('héhé')) in captured.err + assert repr(force_bytes('héhé')) in captured.err with pytest.raises(SystemExit): klass.run_from_argv(['manage.py', 'tenant_command', 'mix-error', '--all-tenants'])