<commit_before>from copy import copy
import ctypes
from functools import cmp_to_key
import threading
import traceback
import time

from datetime import datetime

from . import screencapturer
from .enumeration import TestFixtureStatus, TestClassRunMode, TestCaseStatus
from .plogger import preporter, pconsole
from .testsuite import AfterSuite, BeforeSuite, AfterClass, BeforeClass, BeforeGroup, AfterGroup, AfterMethod, \
    BeforeMethod, Test
from .plistener import test_listeners

__author__ = 'karl.gong'


class TestExecutor(threading.Thread):
    def __init__(self, parent_test_executor):
        threading.Thread.__init__(self)
        self.parent_test_executor = parent_test_executor
        if self.parent_test_executor:
            self.__properties = copy(self.parent_test_executor.get_properties())
        else:
            self.__properties = {}
        self.workers = 0
        self._lock = threading.Lock()

    def start_and_join(self):
        self.start()
        self.join()

    def update_properties(self, properties):
        self.__properties.update(properties)

    def clear_properties(self):
        self.__properties.clear()

    def get_property(self, key):
        try:
            return self.__properties[key]
        except KeyError:
            return None

    def get_properties(self):
        return self.__properties

    def allocate_worker(self, child_test_executor):
        with self._lock:
            if self.workers > 0:
                self.workers -= 1
                child_test_executor.workers += 1
                return True
            else:
                return False
<commit_msg>Use RLock instead of Lock.<commit_after>from copy import copy
import ctypes
from functools import cmp_to_key
import threading
import traceback
import time

from datetime import datetime

from . import screencapturer
from .enumeration import TestFixtureStatus, TestClassRunMode, TestCaseStatus
from .plogger import preporter, pconsole
from .testsuite import AfterSuite, BeforeSuite, AfterClass, BeforeClass, BeforeGroup, AfterGroup, AfterMethod, \
    BeforeMethod, Test
from .plistener import test_listeners

__author__ = 'karl.gong'


class TestExecutor(threading.Thread):
    def __init__(self, parent_test_executor):
        threading.Thread.__init__(self)
        self.parent_test_executor = parent_test_executor
        if self.parent_test_executor:
            self.__properties = copy(self.parent_test_executor.get_properties())
        else:
            self.__properties = {}
        self.workers = 0
        self._lock = threading.RLock()

    def start_and_join(self):
        self.start()
        self.join()

    def update_properties(self, properties):
        self.__properties.update(properties)

    def clear_properties(self):
        self.__properties.clear()

    def get_property(self, key):
        try:
            return self.__properties[key]
        except KeyError:
            return None

    def get_properties(self):
        return self.__properties

    def allocate_worker(self, child_test_executor):
        with self._lock:
            if self.workers > 0:
                self.workers -= 1
                child_test_executor.workers += 1
                return True
            else:
                return False

{'fraction_non_alphanumeric': 0.06908094948265368, 'fraction_numerical': 0.002434570906877663, 'mean_word_length': 2.652222222222222, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '730891', 'n_tokens_mistral': 907, 'n_tokens_neox': 868, 'n_words': 228}