<commit_before>"""
Functions to be used in fabfiles and other non-core code, such as run()/sudo().
"""

from __future__ import with_statement

from glob import glob
import os
import os.path
import re
import stat
import subprocess

from context_managers import settings
from contextlib import closing
from network import output_thread, needs_host
from state import env, connections, output
from utils import abort, indent, warn


def _handle_failure(message, exception=None):
    """
    Call `abort` or `warn` with the given message.

    The value of ``env.warn_only`` determines which method is called.

    If ``exception`` is given, it is inspected to get a string message, which
    is printed alongside the user-generated ``message``.
    """
    func = env.warn_only and warn or abort
    if exception is not None:
        # Figure out how to get a string out of the exception; EnvironmentError
        # subclasses, for example, "are" integers and .strerror is the string.
        # Others "are" strings themselves. May have to expand this further for
        # other error types.
        if hasattr(exception, 'strerror'):
            underlying_msg = exception.strerror
        else:
            underlying_msg = exception
        func("%s\n\nUnderlying exception message:\n%s" % (
            message,
            indent(underlying_msg)
        ))
    else:
        func(message)


def _shell_escape(string):
    """
    Escape double quotes in given ``string``.
    """
    return string.replace(r'"', r'\"')


class _AttributeString(str):
    """
    Simple string subclass to allow arbitrary attribute access.
    """<commit_msg>Handle exceptions with strerror attributes that are None instead of strings.<commit_after>"""
Functions to be used in fabfiles and other non-core code, such as run()/sudo().
"""

from __future__ import with_statement

from glob import glob
import os
import os.path
import re
import stat
import subprocess

from context_managers import settings
from contextlib import closing
from network import output_thread, needs_host
from state import env, connections, output
from utils import abort, indent, warn


def _handle_failure(message, exception=None):
    """
    Call `abort` or `warn` with the given message.

    The value of ``env.warn_only`` determines which method is called.

    If ``exception`` is given, it is inspected to get a string message, which
    is printed alongside the user-generated ``message``.
    """
    func = env.warn_only and warn or abort
    if exception is not None:
        # Figure out how to get a string out of the exception; EnvironmentError
        # subclasses, for example, "are" integers and .strerror is the string.
        # Others "are" strings themselves. May have to expand this further for
        # other error types.
        if hasattr(exception, 'strerror') and exception.strerror is not None:
            underlying_msg = exception.strerror
        else:
            underlying_msg = exception
        func("%s\n\nUnderlying exception message:\n%s" % (
            message,
            indent(underlying_msg)
        ))
    else:
        func(message)


def _shell_escape(string):
    """
    Escape double quotes in given ``string``.
    """
    return string.replace(r'"', r'\"')


class _AttributeString(str):
    """
    Simple string subclass to allow arbitrary attribute access.
    """
{'fraction_non_alphanumeric': 0.08274231678486997, 'fraction_numerical': 0.0, 'mean_word_length': 3.0201900237529693, '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': '5483090', 'n_tokens_mistral': 891, 'n_tokens_neox': 880, 'n_words': 373}