Exemplo n.º 1
0
def test_local_critical_no_thread_to_task():
    """
    Tests that local does not go through async_to_sync when the local is set
    as thread-critical
    """
    # Set up the local
    test_local = Local(thread_critical=True)
    test_local.foo = 89
    # Look at it in an async context
    async def async_function():
        with pytest.raises(AttributeError):
            test_local.foo
        test_local.foo = "numbers"
        assert test_local.foo == "numbers"

    async_to_sync(async_function)()
    # Check the value outside
    assert test_local.foo == 89
Exemplo n.º 2
0
def language_changed(**kwargs):
    if kwargs['setting'] in {'LANGUAGES', 'LANGUAGE_CODE', 'LOCALE_PATHS'}:
        from django.utils.translation import trans_real
        trans_real._default = None
        trans_real._active = Local()
    if kwargs['setting'] in {'LANGUAGES', 'LOCALE_PATHS'}:
        from django.utils.translation import trans_real
        trans_real._translations = {}
        trans_real.check_for_language.cache_clear()
Exemplo n.º 3
0
async def test_local_critical_no_task_to_thread():
    """
    Tests that local doesn't go through sync_to_async when the local is set
    as thread-critical.
    """
    # Set up the local
    test_local = Local(thread_critical=True)
    test_local.foo = 86
    # Look at it in a sync context
    def sync_function():
        with pytest.raises(AttributeError):
            test_local.foo
        test_local.foo = "secret"
        assert test_local.foo == "secret"

    await sync_to_async(sync_function)()
    # Check the value outside is not touched
    assert test_local.foo == 86
Exemplo n.º 4
0
def translation_file_changed(sender, file_path, **kwargs):
    """Clear the internal translations cache if a .mo file is modified."""
    if file_path.suffix == '.mo':
        import gettext
        from django.utils.translation import trans_real
        gettext._translations = {}
        trans_real._translations = {}
        trans_real._default = None
        trans_real._active = Local()
        return True
Exemplo n.º 5
0
async def test_local_task_to_sync_to_task():
    """
    Tests that local carries through sync_to_async and then back through
    async_to_sync
    """
    # Set up the local
    test_local = Local()
    test_local.foo = 756
    # Look at it in an async context inside a sync context
    def sync_function():
        async def async_function():
            assert test_local.foo == 756
            test_local.foo = "dragons"

        async_to_sync(async_function)()

    await sync_to_async(sync_function)()
    # Check the value passed out again
    assert test_local.foo == "dragons"
Exemplo n.º 6
0
    def test_template_tags_pgettext(self):
        """{% translate %} takes message contexts into account (#14806)."""
        trans_real._active = Local()
        trans_real._translations = {}
        with translation.override('de'):
            # Nonexistent context...
            t = self.get_template(
                '{% load i18n %}{% translate "May" context "nonexistent" %}')
            rendered = t.render(Context())
            self.assertEqual(rendered, 'May')

            # Existing context... using a literal
            t = self.get_template(
                '{% load i18n %}{% translate "May" context "month name" %}')
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Mai')
            t = self.get_template(
                '{% load i18n %}{% translate "May" context "verb" %}')
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Kann')

            # Using a variable
            t = self.get_template(
                '{% load i18n %}{% translate "May" context message_context %}')
            rendered = t.render(Context({'message_context': 'month name'}))
            self.assertEqual(rendered, 'Mai')
            t = self.get_template(
                '{% load i18n %}{% translate "May" context message_context %}')
            rendered = t.render(Context({'message_context': 'verb'}))
            self.assertEqual(rendered, 'Kann')

            # Using a filter
            t = self.get_template(
                '{% load i18n %}{% translate "May" context message_context|lower %}'
            )
            rendered = t.render(Context({'message_context': 'MONTH NAME'}))
            self.assertEqual(rendered, 'Mai')
            t = self.get_template(
                '{% load i18n %}{% translate "May" context message_context|lower %}'
            )
            rendered = t.render(Context({'message_context': 'VERB'}))
            self.assertEqual(rendered, 'Kann')

            # Using 'as'
            t = self.get_template(
                '{% load i18n %}{% translate "May" context "month name" as var %}Value: {{ var }}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Value: Mai')
            t = self.get_template(
                '{% load i18n %}{% translate "May" as var context "verb" %}Value: {{ var }}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Value: Kann')
Exemplo n.º 7
0
    def test_template_tags_pgettext(self):
        """{% translate %} takes message contexts into account (#14806)."""
        trans_real._active = Local()
        trans_real._translations = {}
        with translation.override("de"):
            # Nonexistent context...
            t = self.get_template(
                '{% load i18n %}{% translate "May" context "nonexistent" %}')
            rendered = t.render(Context())
            self.assertEqual(rendered, "May")

            # Existing context... using a literal
            t = self.get_template(
                '{% load i18n %}{% translate "May" context "month name" %}')
            rendered = t.render(Context())
            self.assertEqual(rendered, "Mai")
            t = self.get_template(
                '{% load i18n %}{% translate "May" context "verb" %}')
            rendered = t.render(Context())
            self.assertEqual(rendered, "Kann")

            # Using a variable
            t = self.get_template(
                '{% load i18n %}{% translate "May" context message_context %}')
            rendered = t.render(Context({"message_context": "month name"}))
            self.assertEqual(rendered, "Mai")
            t = self.get_template(
                '{% load i18n %}{% translate "May" context message_context %}')
            rendered = t.render(Context({"message_context": "verb"}))
            self.assertEqual(rendered, "Kann")

            # Using a filter
            t = self.get_template(
                '{% load i18n %}{% translate "May" context message_context|lower %}'
            )
            rendered = t.render(Context({"message_context": "MONTH NAME"}))
            self.assertEqual(rendered, "Mai")
            t = self.get_template(
                '{% load i18n %}{% translate "May" context message_context|lower %}'
            )
            rendered = t.render(Context({"message_context": "VERB"}))
            self.assertEqual(rendered, "Kann")

            # Using 'as'
            t = self.get_template(
                '{% load i18n %}{% translate "May" context "month name" as var %}'
                "Value: {{ var }}")
            rendered = t.render(Context())
            self.assertEqual(rendered, "Value: Mai")
            t = self.get_template(
                '{% load i18n %}{% translate "May" as var context "verb" %}Value: '
                "{{ var }}")
            rendered = t.render(Context())
            self.assertEqual(rendered, "Value: Kann")
Exemplo n.º 8
0
def language_changed(*, setting, **kwargs):
    if setting in {"LANGUAGES", "LANGUAGE_CODE", "LOCALE_PATHS"}:
        from django.utils.translation import trans_real

        trans_real._default = None
        trans_real._active = Local()
    if setting in {"LANGUAGES", "LOCALE_PATHS"}:
        from django.utils.translation import trans_real

        trans_real._translations = {}
        trans_real.check_for_language.cache_clear()
Exemplo n.º 9
0
 def __init__(self, databases=None):
     """
     databases is an optional dictionary of database definitions (structured
     like settings.DATABASES).
     """
     self._databases = databases
     # Connections needs to still be an actual thread local, as it's truly
     # thread-critical. Database backends should use @async_unsafe to protect
     # their code from async contexts, but this will give those contexts
     # separate connections in case it's needed as well. There's no cleanup
     # after async contexts, though, so we don't allow that if we can help it.
     self._connections = Local(thread_critical=True)
Exemplo n.º 10
0
def test_local_thread_nested():
    """
    Tests that local does not leak across threads
    """

    test_local = Local()
    # Unassigned should be an error
    with pytest.raises(AttributeError):
        test_local.foo
    print("outside ID", Local._get_context_id())
    # Assign and check it does not persist inside the thread
    class TestThread(threading.Thread):
        # Failure reason
        failed = "unknown"

        def run(self):
            print("inside ID", Local._get_context_id())
            # Make sure the attribute is not there
            try:
                test_local.foo
                self.failed = "leak inside"
                return
            except AttributeError:
                pass
            # Check the value is good
            self.failed = "set inside"
            test_local.foo = 123
            assert test_local.foo == 123
            # Binary signal that these tests passed to the outer thread
            self.failed = ""

    test_local.foo = 8
    thread = TestThread()
    thread.start()
    thread.join()
    assert thread.failed == ""
    # Check it didn't leak back out
    assert test_local.foo == 8
Exemplo n.º 11
0
 def run(self):
     print("inside ID", Local._get_context_id())
     # Make sure the attribute is not there
     try:
         test_local.foo
         self.failed = "leak inside"
         return
     except AttributeError:
         pass
     # Check the value is good
     self.failed = "set inside"
     test_local.foo = 123
     assert test_local.foo == 123
     # Binary signal that these tests passed to the outer thread
     self.failed = ""
Exemplo n.º 12
0
async def test_local_many_layers():
    """
    Tests that local carries through a lot of layers of sync/async
    """
    # Set up the local
    test_local = Local()
    test_local.foo = 8374
    # Make sure we go between each world at least twice
    def sync_function():
        async def async_function():
            def sync_function_2():
                async def async_function_2():
                    assert test_local.foo == 8374
                    test_local.foo = "miracles"

                async_to_sync(async_function_2)()

            await sync_to_async(sync_function_2)()

        async_to_sync(async_function)()

    await sync_to_async(sync_function)()
    # Check the value passed out again
    assert test_local.foo == "miracles"
Exemplo n.º 13
0
 def __init__(self, pattern, urlconf_name, default_kwargs=None, app_name=None, namespace=None):
     self.pattern = pattern
     # urlconf_name is the dotted Python path to the module defining
     # urlpatterns. It may also be an object with an urlpatterns attribute
     # or urlpatterns itself.
     self.urlconf_name = urlconf_name
     self.callback = None
     self.default_kwargs = default_kwargs or {}
     self.namespace = namespace
     self.app_name = app_name
     self._reverse_dict = {}
     self._namespace_dict = {}
     self._app_dict = {}
     # set of dotted paths to all functions and classes that are used in
     # urlpatterns
     self._callback_strs = set()
     self._populated = False
     self._local = Local()
Exemplo n.º 14
0
    def f():
        nonlocal matched
        # Involve Local in a cycle
        cycle = [Local()]
        cycle.append(cycle)
        cycle[0].foo = "bar"

        # GC the cycle
        del cycle
        gc.collect()

        # Trigger the local creation outside
        e1.set()
        e2.wait()

        # New Locals should be empty
        matched = len([
            local for local in locals if getattr(local, "foo", None) == "bar"
        ])
Exemplo n.º 15
0
def test_local_cycle():
    """
    Tests that Local can handle cleanup up a cycle to itself
    (Borrowed and modified from the CPython threadlocal tests)
    """

    locals = None
    matched = 0
    e1 = threading.Event()
    e2 = threading.Event()

    def f():
        nonlocal matched
        # Involve Local in a cycle
        cycle = [Local()]
        cycle.append(cycle)
        cycle[0].foo = "bar"

        # GC the cycle
        del cycle
        gc.collect()

        # Trigger the local creation outside
        e1.set()
        e2.wait()

        # New Locals should be empty
        matched = len([
            local for local in locals if getattr(local, "foo", None) == "bar"
        ])

    t = threading.Thread(target=f)
    t.start()
    e1.wait()
    # Creates locals outside of the inner thread
    locals = [Local() for i in range(100)]
    e2.set()
    t.join()

    assert matched == 0
Exemplo n.º 16
0
 def __init__(self,
              pattern,
              urlconf_name,
              default_kwargs=None,
              app_name=None,
              namespace=None):
     # 该属性值是当前模块中定义的 RoutePattern 类的实例,叫「正则模式对象」
     self.pattern = pattern
     # 该属性值是字符串,它指向项目的路由配置模块 'xxx.urls'
     self.urlconf_name = urlconf_name
     self.callback = None
     self.default_kwargs = default_kwargs or {}
     self.namespace = namespace
     self.app_name = app_name
     self._reverse_dict = {}
     self._namespace_dict = {}
     self._app_dict = {}
     # set of dotted paths to all functions and classes that are used in
     # urlpatterns
     self._callback_strs = set()
     self._populated = False
     self._local = Local()
Exemplo n.º 17
0
    To be registered with log_registry.register_action.
    """

    label = ""
    message = ""
    comment = ""

    def format_message(self, log_entry):
        return self.message

    def format_comment(self, log_entry):
        return self.comment


_active = Local()


class LogContext:
    """
    Stores data about the environment in which a logged action happens -
    e.g. the active user - to be stored in the log entry for that action.
    """
    def __init__(self, user=None, generate_uuid=True):
        self.user = user
        if generate_uuid:
            self.uuid = uuid.uuid4()
        else:
            self.uuid = None

    def __enter__(self):
Exemplo n.º 18
0
    def test_template_tags_pgettext(self):
        """{% blocktranslate %} takes message contexts into account (#14806)."""
        trans_real._active = Local()
        trans_real._translations = {}
        with translation.override("de"):
            # Nonexistent context
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context "nonexistent" %}May'
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "May")

            # Existing context...  using a literal
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate context "month name" %}May{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "Mai")
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate context "verb" %}May{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "Kann")

            # Using a variable
            t = self.get_template(
                "{% load i18n %}{% blocktranslate context message_context %}"
                "May{% endblocktranslate %}"
            )
            rendered = t.render(Context({"message_context": "month name"}))
            self.assertEqual(rendered, "Mai")
            t = self.get_template(
                "{% load i18n %}{% blocktranslate context message_context %}"
                "May{% endblocktranslate %}"
            )
            rendered = t.render(Context({"message_context": "verb"}))
            self.assertEqual(rendered, "Kann")

            # Using a filter
            t = self.get_template(
                "{% load i18n %}"
                "{% blocktranslate context message_context|lower %}May"
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context({"message_context": "MONTH NAME"}))
            self.assertEqual(rendered, "Mai")
            t = self.get_template(
                "{% load i18n %}"
                "{% blocktranslate context message_context|lower %}May"
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context({"message_context": "VERB"}))
            self.assertEqual(rendered, "Kann")

            # Using 'count'
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate count number=1 context "super search" %}{{ number }}'
                " super result{% plural %}{{ number }} super results"
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "1 Super-Ergebnis")
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate count number=2 context "super search" %}{{ number }}'
                " super result{% plural %}{{ number }} super results"
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "2 Super-Ergebnisse")
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate context "other super search" count number=1 %}'
                "{{ number }} super result{% plural %}{{ number }} super results"
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "1 anderen Super-Ergebnis")
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate context "other super search" count number=2 %}'
                "{{ number }} super result{% plural %}{{ number }} super results"
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "2 andere Super-Ergebnisse")

            # Using 'with'
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate with num_comments=5 context "comment count" %}'
                "There are {{ num_comments }} comments{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "Es gibt 5 Kommentare")
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate with num_comments=5 context "other comment count" %}'
                "There are {{ num_comments }} comments{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "Andere: Es gibt 5 Kommentare")

            # Using trimmed
            t = self.get_template(
                "{% load i18n %}{% blocktranslate trimmed %}\n\nThere\n\t are 5  "
                "\n\n   comments\n{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "There are 5 comments")
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate with num_comments=5 context "comment count" trimmed '
                "%}\n\n"
                "There are  \t\n  \t {{ num_comments }} comments\n\n"
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "Es gibt 5 Kommentare")
            t = self.get_template(
                "{% load i18n %}"
                '{% blocktranslate context "other super search" count number=2 trimmed '
                "%}\n{{ number }} super \n result{% plural %}{{ number }} super results"
                "{% endblocktranslate %}"
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, "2 andere Super-Ergebnisse")

            # Misuses
            msg = "Unknown argument for 'blocktranslate' tag: %r."
            with self.assertRaisesMessage(TemplateSyntaxError, msg % 'month="May"'):
                self.get_template(
                    '{% load i18n %}{% blocktranslate context with month="May" %}'
                    "{{ month }}{% endblocktranslate %}"
                )
            msg = (
                '"context" in %r tag expected exactly one argument.' % "blocktranslate"
            )
            with self.assertRaisesMessage(TemplateSyntaxError, msg):
                self.get_template(
                    "{% load i18n %}{% blocktranslate context %}{% endblocktranslate %}"
                )
            with self.assertRaisesMessage(TemplateSyntaxError, msg):
                self.get_template(
                    "{% load i18n %}{% blocktranslate count number=2 context %}"
                    "{{ number }} super result{% plural %}{{ number }}"
                    " super results{% endblocktranslate %}"
                )
Exemplo n.º 19
0
 def __init__(self):
     self._caches = Local()
Exemplo n.º 20
0
    def test_template_tags_pgettext(self):
        """{% blocktranslate %} takes message contexts into account (#14806)."""
        trans_real._active = Local()
        trans_real._translations = {}
        with translation.override('de'):
            # Nonexistent context
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context "nonexistent" %}May'
                '{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, 'May')

            # Existing context...  using a literal
            t = self.get_template('{% load i18n %}{% blocktranslate context "month name" %}May{% endblocktranslate %}')
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Mai')
            t = self.get_template('{% load i18n %}{% blocktranslate context "verb" %}May{% endblocktranslate %}')
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Kann')

            # Using a variable
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context message_context %}'
                'May{% endblocktranslate %}'
            )
            rendered = t.render(Context({'message_context': 'month name'}))
            self.assertEqual(rendered, 'Mai')
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context message_context %}'
                'May{% endblocktranslate %}'
            )
            rendered = t.render(Context({'message_context': 'verb'}))
            self.assertEqual(rendered, 'Kann')

            # Using a filter
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context message_context|lower %}May{% endblocktranslate %}'
            )
            rendered = t.render(Context({'message_context': 'MONTH NAME'}))
            self.assertEqual(rendered, 'Mai')
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context message_context|lower %}May{% endblocktranslate %}'
            )
            rendered = t.render(Context({'message_context': 'VERB'}))
            self.assertEqual(rendered, 'Kann')

            # Using 'count'
            t = self.get_template(
                '{% load i18n %}{% blocktranslate count number=1 context "super search" %}'
                '{{ number }} super result{% plural %}{{ number }} super results{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, '1 Super-Ergebnis')
            t = self.get_template(
                '{% load i18n %}{% blocktranslate count number=2 context "super search" %}{{ number }}'
                ' super result{% plural %}{{ number }} super results{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, '2 Super-Ergebnisse')
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context "other super search" count number=1 %}'
                '{{ number }} super result{% plural %}{{ number }} super results{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, '1 anderen Super-Ergebnis')
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context "other super search" count number=2 %}'
                '{{ number }} super result{% plural %}{{ number }} super results{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, '2 andere Super-Ergebnisse')

            # Using 'with'
            t = self.get_template(
                '{% load i18n %}{% blocktranslate with num_comments=5 context "comment count" %}'
                'There are {{ num_comments }} comments{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Es gibt 5 Kommentare')
            t = self.get_template(
                '{% load i18n %}{% blocktranslate with num_comments=5 context "other comment count" %}'
                'There are {{ num_comments }} comments{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Andere: Es gibt 5 Kommentare')

            # Using trimmed
            t = self.get_template(
                '{% load i18n %}{% blocktranslate trimmed %}\n\nThere\n\t are 5  '
                '\n\n   comments\n{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, 'There are 5 comments')
            t = self.get_template(
                '{% load i18n %}{% blocktranslate with num_comments=5 context "comment count" trimmed %}\n\n'
                'There are  \t\n  \t {{ num_comments }} comments\n\n{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, 'Es gibt 5 Kommentare')
            t = self.get_template(
                '{% load i18n %}{% blocktranslate context "other super search" count number=2 trimmed %}\n'
                '{{ number }} super \n result{% plural %}{{ number }} super results{% endblocktranslate %}'
            )
            rendered = t.render(Context())
            self.assertEqual(rendered, '2 andere Super-Ergebnisse')

            # Misuses
            msg = "Unknown argument for 'blocktranslate' tag: %r."
            with self.assertRaisesMessage(TemplateSyntaxError, msg % 'month="May"'):
                self.get_template(
                    '{% load i18n %}{% blocktranslate context with month="May" %}{{ month }}{% endblocktranslate %}'
                )
            msg = '"context" in %r tag expected exactly one argument.' % 'blocktranslate'
            with self.assertRaisesMessage(TemplateSyntaxError, msg):
                self.get_template('{% load i18n %}{% blocktranslate context %}{% endblocktranslate %}')
            with self.assertRaisesMessage(TemplateSyntaxError, msg):
                self.get_template(
                    '{% load i18n %}{% blocktranslate count number=2 context %}'
                    '{{ number }} super result{% plural %}{{ number }}'
                    ' super results{% endblocktranslate %}'
                )
Exemplo n.º 21
0
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, unicode_literals

from contextlib import contextmanager

from asgiref.local import Local
from django.utils.translation import get_language, override

_thread_locals = Local()


def notify_items_pre_save(**kwargs):
    return notify_items(signal_type='pre_save', **kwargs)


def notify_items_post_save(**kwargs):
    return notify_items(signal_type='post_save', **kwargs)


def notify_items_pre_delete(**kwargs):
    return notify_items(signal_type='pre_delete', **kwargs)


def notify_items_post_delete(**kwargs):
    return notify_items(signal_type='post_delete', **kwargs)


def notify_items(signal_type, **kwargs):
    """
    Signal endpoint that actually sends knocks whenever an instance is created / saved
    """
Exemplo n.º 22
0
from .payloads import generate_api_call_payload, generate_event_delivery_attempt_payload
from .tracing import opentracing_trace

if TYPE_CHECKING:

    from celery.exceptions import Retry
    from django.http import HttpRequest, HttpResponse

    from ...core.models import EventDeliveryAttempt

logger = logging.getLogger(__name__)
CACHE_TIMEOUT = parse("2 minutes")
BUFFER_KEY = "observability_buffer"
WEBHOOKS_KEY = "observability_webhooks"
_active_webhooks_exists_cache: Dict[str, Tuple[bool, float]] = {}
_context = Local()


@dataclass
class WebhookData:
    id: int
    saleor_domain: str
    target_url: str
    secret_key: Optional[str] = None


def get_buffer_name() -> str:
    return cache.make_key(BUFFER_KEY)


_webhooks_mem_cache: Dict[str, Tuple[List[WebhookData], float]] = {}
Exemplo n.º 23
0
from urllib.parse import urlsplit, urlunsplit

from asgiref.local import Local

from django.utils.encoding import iri_to_uri
from django.utils.functional import lazy
from django.utils.translation import override

from .exceptions import NoReverseMatch, Resolver404
from .resolvers import _get_cached_resolver, get_ns_resolver, get_resolver
from .utils import get_callable

# SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for
# the current thread (which is the only one we ever access), it is assumed to
# be empty.
_prefixes = Local()

# Overridden URLconfs for each thread are stored here.
_urlconfs = Local()


def resolve(path, urlconf=None):
    if urlconf is None:
        urlconf = get_urlconf()
    return get_resolver(urlconf).resolve(path)


def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
    if urlconf is None:
        urlconf = get_urlconf()
    resolver = get_resolver(urlconf)
Exemplo n.º 24
0
def clear_cache_handlers(**kwargs):
    if kwargs['setting'] == 'CACHES':
        from django.core.cache import caches, close_caches
        close_caches()
        caches._settings = caches.settings = caches.configure_settings(None)
        caches._connections = Local()
Exemplo n.º 25
0
def clear_cache_handlers(**kwargs):
    if kwargs['setting'] == 'CACHES':
        from django.core.cache import caches
        caches._caches = Local()
Exemplo n.º 26
0
import warnings
from pprint import pformat

from asgiref.local import Local
from django.template import Node
from django.utils.html import format_html
from django.utils.safestring import mark_safe

from debug_toolbar import settings as dt_settings

try:
    import threading
except ImportError:
    threading = None

_local_data = Local()


def _is_excluded_frame(frame, excluded_modules):
    if not excluded_modules:
        return False
    frame_module = frame.f_globals.get("__name__")
    if not isinstance(frame_module, str):
        return False
    return any(frame_module == excluded_module
               or frame_module.startswith(excluded_module + ".")
               for excluded_module in excluded_modules)


def _stack_trace_deprecation_warning():
    warnings.warn(
Exemplo n.º 27
0
 def __init__(self, settings=None):
     self._settings = settings
     self._connections = Local(self.thread_critical)
Exemplo n.º 28
0
from contextlib import contextmanager

from django.apps import apps
from django.conf import settings
from django.db import connections

from .cache import cachalot_caches
from .settings import cachalot_settings
from .signals import post_invalidation
from .transaction import AtomicCache
from .utils import _invalidate_tables

try:
    from asgiref.local import Local
    LOCAL_STORAGE = Local()
except ImportError:
    import threading
    LOCAL_STORAGE = threading.local()

__all__ = ('invalidate', 'get_last_invalidation', 'cachalot_disabled')


def _cache_db_tables_iterator(tables, cache_alias, db_alias):
    no_tables = not tables
    cache_aliases = settings.CACHES if cache_alias is None else (cache_alias, )
    db_aliases = settings.DATABASES if db_alias is None else (db_alias, )
    for db_alias in db_aliases:
        if no_tables:
            tables = connections[db_alias].introspection.table_names()
        if tables:
            for cache_alias in cache_aliases:
Exemplo n.º 29
0
class CachePanel(Panel):
    """
    Panel that displays the cache statistics.
    """

    template = "debug_toolbar/panels/cache.html"

    _context_locals = Local()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.total_time = 0
        self.hits = 0
        self.misses = 0
        self.calls = []
        self.counts = {name: 0 for name in WRAPPED_CACHE_METHODS}

    @classmethod
    def current_instance(cls):
        """
        Return the currently enabled CachePanel instance or None.

        If a request is in process with a CachePanel enabled, this will return that
        panel (based on the current thread or async task).  Otherwise it will return
        None.
        """
        return getattr(cls._context_locals, "current_instance", None)

    @classmethod
    def ready(cls):
        if not hasattr(CacheHandler, "_djdt_patched"):
            # Wrap the CacheHander.create_connection() method to monkey patch any new
            # cache connections that are opened while instrumentation is enabled.  In
            # the interests of thread safety, this is done once at startup time and
            # never removed.
            original_method = CacheHandler.create_connection

            @functools.wraps(original_method)
            def wrapper(self, alias):
                cache = original_method(self, alias)
                panel = cls.current_instance()
                if panel is not None:
                    panel._monkey_patch_cache(cache)
                return cache

            CacheHandler.create_connection = wrapper
            CacheHandler._djdt_patched = True

    def _store_call_info(
        self,
        name,
        time_taken,
        return_value,
        args,
        kwargs,
        trace,
        template_info,
        backend,
    ):
        if name == "get" or name == "get_or_set":
            if return_value is None:
                self.misses += 1
            else:
                self.hits += 1
        elif name == "get_many":
            for key, value in return_value.items():
                if value is None:
                    self.misses += 1
                else:
                    self.hits += 1
        time_taken *= 1000

        self.total_time += time_taken
        self.counts[name] += 1
        self.calls.append({
            "time": time_taken,
            "name": name,
            "args": args,
            "kwargs": kwargs,
            "trace": render_stacktrace(trace),
            "template_info": template_info,
            "backend": backend,
        })

    def _record_call(self, cache, name, original_method, args, kwargs):
        # Some cache backends implement certain cache methods in terms of other cache
        # methods (e.g. get_or_set() in terms of get() and add()).  In order to only
        # record the calls made directly by the user code, set the _djdt_recording flag
        # here to cause the monkey patched cache methods to skip recording additional
        # calls made during the course of this call.
        cache._djdt_recording = True
        t = time.time()
        value = original_method(*args, **kwargs)
        t = time.time() - t
        cache._djdt_recording = False

        if dt_settings.get_config()["ENABLE_STACKTRACES"]:
            stacktrace = tidy_stacktrace(reversed(get_stack()))
        else:
            stacktrace = []

        self._store_call_info(
            name=name,
            time_taken=t,
            return_value=value,
            args=args,
            kwargs=kwargs,
            trace=stacktrace,
            template_info=get_template_info(),
            backend=cache,
        )
        return value

    def _monkey_patch_method(self, cache, name):
        original_method = getattr(cache, name)

        @functools.wraps(original_method)
        def wrapper(*args, **kwargs):
            # If this call is being made as part of the implementation of another cache
            # method, don't record it.
            if cache._djdt_recording:
                return original_method(*args, **kwargs)
            else:
                return self._record_call(cache, name, original_method, args,
                                         kwargs)

        wrapper._djdt_wrapped = original_method
        setattr(cache, name, wrapper)

    def _monkey_patch_cache(self, cache):
        if not hasattr(cache, "_djdt_patched"):
            for name in WRAPPED_CACHE_METHODS:
                self._monkey_patch_method(cache, name)
            cache._djdt_patched = True
            cache._djdt_recording = False

    @staticmethod
    def _unmonkey_patch_cache(cache):
        if hasattr(cache, "_djdt_patched"):
            for name in WRAPPED_CACHE_METHODS:
                original_method = getattr(cache, name)._djdt_wrapped
                if original_method.__func__ == getattr(cache.__class__, name):
                    delattr(cache, name)
                else:
                    setattr(cache, name, original_method)
            del cache._djdt_patched
            del cache._djdt_recording

    # Implement the Panel API

    nav_title = _("Cache")

    @property
    def nav_subtitle(self):
        cache_calls = len(self.calls)
        return ngettext(
            "%(cache_calls)d call in %(time).2fms",
            "%(cache_calls)d calls in %(time).2fms",
            cache_calls,
        ) % {
            "cache_calls": cache_calls,
            "time": self.total_time
        }

    @property
    def title(self):
        count = len(getattr(settings, "CACHES", ["default"]))
        return ngettext(
            "Cache calls from %(count)d backend",
            "Cache calls from %(count)d backends",
            count,
        ) % {
            "count": count
        }

    def enable_instrumentation(self):
        # Monkey patch all open cache connections.  Django maintains cache connections
        # on a per-thread/async task basis, so this will not affect any concurrent
        # requests.  The monkey patch of CacheHander.create_connection() installed in
        # the .ready() method will ensure that any new cache connections that get opened
        # during this request will also be monkey patched.
        for cache in caches.all(initialized_only=True):
            self._monkey_patch_cache(cache)
        # Mark this panel instance as the current one for the active thread/async task
        # context.  This will be used by the CacheHander.create_connection() monkey
        # patch.
        self._context_locals.current_instance = self

    def disable_instrumentation(self):
        if hasattr(self._context_locals, "current_instance"):
            del self._context_locals.current_instance
        for cache in caches.all(initialized_only=True):
            self._unmonkey_patch_cache(cache)

    def generate_stats(self, request, response):
        self.record_stats({
            "total_calls": len(self.calls),
            "calls": self.calls,
            "total_time": self.total_time,
            "hits": self.hits,
            "misses": self.misses,
            "counts": self.counts,
        })

    def generate_server_timing(self, request, response):
        stats = self.get_stats()
        value = stats.get("total_time", 0)
        title = "Cache {} Calls".format(stats.get("total_calls", 0))
        self.record_server_timing("total_time", title, value)
Exemplo n.º 30
0
def clear_cache_handlers(**kwargs):
    if kwargs["setting"] == "CACHES":
        from django.core.cache import caches, close_caches

        close_caches()
        caches._caches = Local()