<commit_before>import os
from weakref import WeakKeyDictionary

import attr

from twisted.trial.unittest import TestCase

class TXAWSTestCase(TestCase):
    """Support for isolation of txaws tests."""

    def setUp(self):
        TestCase.setUp(self)
        self._stash_environ()

    def _stash_environ(self):
        self.orig_environ = dict(os.environ)
        self.addCleanup(self._restore_environ)
        to_delete = [
            "AWS_ACCESS_KEY_ID",
            "AWS_SECRET_ACCESS_KEY",
            "AWS_ENDPOINT",
        ]
        for key in to_delete:
            if key in os.environ:
                del os.environ[key]

    def _restore_environ(self):
        os.environ.clear()
        os.environ.update(self.orig_environ)



class ControllerState(object):
    def __get__(self, oself, type):
        return oself._controller.get_state(oself)



@attr.s
class MemoryClient(object):
    _state = ControllerState()

    _controller = attr.ib()



@attr.s(frozen=True)
class MemoryService(object):
    clientFactory = attr.ib()
    stateFactory = attr.ib()

    _state = attr.ib(
        default=attr.Factory(WeakKeyDictionary),
        init=False,
        hash=False,
    )

    def get_state(self, client):
        return self._state.setdefault(client, self.stateFactory())

    def client(self, *a, **kw):
        client = self.clientFactory(self, *a, **kw)
        return client, self.get_state(client)<commit_msg>Key the cache on credentials so state persists across multiple client objects.<commit_after>import os
from weakref import WeakKeyDictionary

import attr

from twisted.trial.unittest import TestCase

class TXAWSTestCase(TestCase):
    """Support for isolation of txaws tests."""

    def setUp(self):
        TestCase.setUp(self)
        self._stash_environ()

    def _stash_environ(self):
        self.orig_environ = dict(os.environ)
        self.addCleanup(self._restore_environ)
        to_delete = [
            "AWS_ACCESS_KEY_ID",
            "AWS_SECRET_ACCESS_KEY",
            "AWS_ENDPOINT",
        ]
        for key in to_delete:
            if key in os.environ:
                del os.environ[key]

    def _restore_environ(self):
        os.environ.clear()
        os.environ.update(self.orig_environ)



class ControllerState(object):
    def __get__(self, oself, type):
        return oself._controller.get_state(oself)



@attr.s
class MemoryClient(object):
    _state = ControllerState()

    _controller = attr.ib()



@attr.s(frozen=True)
class MemoryService(object):
    clientFactory = attr.ib()
    stateFactory = attr.ib()

    _state = attr.ib(
        default=attr.Factory(dict),
        init=False,
        hash=False,
    )

    def get_state(self, creds):
        return self._state.setdefault(creds, self.stateFactory())

    def client(self, creds, *a, **kw):
        client = self.clientFactory(self, creds, *a, **kw)
        return client, self.get_state(creds)
{'fraction_non_alphanumeric': 0.10488554834301332, 'fraction_numerical': 0.0, 'mean_word_length': 2.6463262764632627, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1641775', 'n_tokens_mistral': 927, 'n_tokens_neox': 909, 'n_words': 194}