<commit_before>from __future__ import print_function
from distutils.spawn import find_executable

import os
import subprocess

'''
A simple script written to mimic the functionality of 'chmod -R'. os.chmod is 
time consuming when done recursively, this workaround provides even faster 
computation than a simple subprocess call to 'chmod -R'.

Written by <NAME>: https://gist.github.com/jhunkeler/7a7761d8ce0f66d36483d6a6038caa4d
and commented by <NAME>.
'''


def find(root='.', filetype=None):
    ''' 
    Simple BSD/GNU find wrapper.
    
    Parameters:
    -----------
        root : str
            Name of directory to be modified.
        filetype : str
            "f" = traverse only files
            "d" = traverse only directories
            None = traverse both files and directories.
    
    Returns:
    --------
        Directory or filename to be modified.    
    '''

    accepted_types = ['f', 'd']
    cmd = ['find', root]

    if not find_executable('find'):
        raise OSError('Unable to locate "find" program.'
                      'Cannot continue.')

    if filetype is not None:
        assert isinstance(filetype, str)
        if len(filetype) > 1 or filetype not in accepted_types:
            raise ValueError('Unsupported file type: "{0}"'.format(filetype))

        selector = '-type {0}'.format(filetype).split()
        cmd += selector

    try:
        output = subprocess.check_output(cmd)
    except subprocess.CalledProcessError as cpe:
        print('Failed to execute: "{0}" (exit: {1})'.format(cpe.cmd,
                                                            cpe.returncode))

        print('Failure message: {0}'.format(cpe.stderr or None))
        exit(cpe.returncode)

    for x in output.splitlines():
        yield os.path.abspath(x) or None


def chmod(basepath, mode, filetype=None, recursive=False):
    ''' 
    Recursive-capable replacement for os.chmod.
    
    Parameters:
    -----------
        basepath : str
            Name of directory to be modified.
        mode : int (octal)
            Permission for directory/files to be set to.
        filetype : str
            "f" = traverse only files
            "d" = traverse only directories
            None = traverse both files and directories.
        recursive : Bool
            Switch to change permissions recursively.
            
    Returns:
    -------- 
        Nothing
    '''
    
    assert(isinstance(basepath, str))
    assert(isinstance(mode, int))
    assert(bool(filetype is None or isinstance(filetype, str)))
    assert(isinstance(recursive, bool))

    if mode < 0 or mode > 0o1777:
        raise ValueError('Invalid mode: {0}'.format(oct(mode)))

    if recursive:
        for path in find(basepath, filetype):
            os.chmod(path, mode)
    else:
        os.chmod(basepath, mode)<commit_msg>Updated octal check to allow sticky setting, added print statement<commit_after>from __future__ import print_function
from distutils.spawn import find_executable

import os
import subprocess

'''
A simple script written to mimic the functionality of 'chmod -R'. os.chmod is 
time consuming when done recursively, this workaround provides even faster 
computation than a simple subprocess call to 'chmod -R'.

Written by <NAME>: https://gist.github.com/jhunkeler/7a7761d8ce0f66d36483d6a6038caa4d
and commented by <NAME>.
'''


def find(root='.', filetype=None):
    ''' 
    Simple BSD/GNU find wrapper.
    
    Parameters:
    -----------
        root : str
            Name of directory to be modified.
        filetype : str
            "f" = traverse only files
            "d" = traverse only directories
            None = traverse both files and directories.
    
    Returns:
    --------
        Directory or filename to be modified.    
    '''

    accepted_types = ['f', 'd']
    cmd = ['find', root]

    if not find_executable('find'):
        raise OSError('Unable to locate "find" program.'
                      'Cannot continue.')

    if filetype is not None:
        assert isinstance(filetype, str)
        if len(filetype) > 1 or filetype not in accepted_types:
            raise ValueError('Unsupported file type: "{0}"'.format(filetype))

        selector = '-type {0}'.format(filetype).split()
        cmd += selector

    try:
        output = subprocess.check_output(cmd)
    except subprocess.CalledProcessError as cpe:
        print('Failed to execute: "{0}" (exit: {1})'.format(cpe.cmd,
                                                            cpe.returncode))

        print('Failure message: {0}'.format(cpe.stderr or None))
        exit(cpe.returncode)

    for x in output.splitlines():
        yield os.path.abspath(x) or None


def chmod(basepath, mode, filetype=None, recursive=False):
    ''' 
    Recursive-capable replacement for os.chmod.
    
    Parameters:
    -----------
        basepath : str
            Name of directory to be modified.
        mode : int (octal)
            Permission for directory/files to be set to.
        filetype : str
            "f" = traverse only files
            "d" = traverse only directories
            None = traverse both files and directories.
        recursive : Bool
            Switch to change permissions recursively.
            
    Returns:
    -------- 
        Nothing
    '''
    
    assert(isinstance(basepath, str))
    assert(isinstance(mode, int))
    assert(bool(filetype is None or isinstance(filetype, str)))
    assert(isinstance(recursive, bool))

    if mode < 0 or mode > 0o7777:
        raise ValueError('Invalid mode: {0}'.format(oct(mode)))

    print("Changing permissions on {0} to {1}".format(basepath, mode)) 
    if recursive:
        for path in find(basepath, filetype):
            os.chmod(path, mode)
    else:
        os.chmod(basepath, mode)
{'fraction_non_alphanumeric': 0.10614140719077929, 'fraction_numerical': 0.011697918458627214, 'mean_word_length': 2.0974960042621205, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1067240', 'n_tokens_mistral': 1689, 'n_tokens_neox': 1593, 'n_words': 515}