<commit_before>#  This file is part of PyBuilder
#
#  Copyright 2011-2014 PyBuilder Team
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
"""
    The PyBuilder core module.
    Contains the most important classes and syntax used in a
    build.py project descriptor.
"""

import os
import string

from os.path import sep as PATH_SEPARATOR

from pybuilder.errors import MissingPropertyException
from .utils import as_list

INITIALIZER_ATTRIBUTE = "_python_builder_initializer"

ENVIRONMENTS_ATTRIBUTE = "_python_builder_environments"

NAME_ATTRIBUTE = "_python_builder_name"
ACTION_ATTRIBUTE = "_python_builder_action"
ONLY_ONCE_ATTRIBUTE = "_python_builder_action_only_once"
BEFORE_ATTRIBUTE = "_python_builder_before"
AFTER_ATTRIBUTE = "_python_builder_after"

TASK_ATTRIBUTE = "_python_builder_task"
DEPENDS_ATTRIBUTE = "_python_builder_depends"

DESCRIPTION_ATTRIBUTE = "_python_builder_description"


def init(*possible_callable, **additional_arguments):
    """
    Decorator for functions that wish to perform initialization steps.
    The decorated functions are called "initializers".

    Initializers are executed after all plugins and projects have been loaded
    but before any task is executed.

    Initializers may take an additional named argument "environments" which should contain a string or list of strings
    naming the environments this initializer applies for.

    Examples:

    @init
    def some_initializer(): pass

    @init()
    def some_initializer(): pass

    @init(environments="spam")
    def some_initializer(): pass

    @init(environments=["spam", "eggs"])
    def some_initializer(): pass
    """

    def do_decoration(callable):
        setattr(callable, INITIALIZER_ATTRIBUTE, True)

        if "environments" in additional_arguments:
            setattr(callable, ENVIRONMENTS_ATTRIBUTE, as_list(additional_arguments["environments"]))

        return callable

    if possible_callable:
        return do_decoration(possible_callable[0])

    return do_decoration


def task(callable_or_string):
    """
    Decorator for functions that should be used as tasks. Tasks are the main
    building blocks of projects.
    You can use this decorator either plain (no argument) or with
    a string argument, which overrides the default name.
    """
    if isinstance(callable_or_string, str):
        def set_name_and_task_attribute(callable):
            setattr(callable, TASK_ATTRIBUTE, True)
            setattr(callable, NAME_ATTRIBUTE, callable_or_string)
            return callable
        return set_name_and_task_attribute
    else:
        setattr(callable_or_string, TASK_ATTRIBUTE, True)
        return callable_or_string


class description(object):
    def __init__(self, description):
        self._description = description

    def __call__(self, callable):
        setattr(callable, DESCRIPTION_ATTRIBUTE, self._description)
        return callable


class depends(object):
    def __init__(self, *depends):
        self._depends = depends

    def __call__(self, callable):
        setattr(callable, DEPENDS_ATTRIBUTE, self._depends)
        return callable


class BaseAction(object):
    def __init__(self, attribute, only_once, tasks):
        self.tasks = tasks
        self.attribute = attribute
        self.only_once = only_once

    def __call__(self, callable):
        setattr(callable, ACTION_ATTRIBUTE, True)
        setattr(callable, self.attribute, self.tasks)
        if self.only_once:
            setattr(callable, ONLY_ONCE_ATTRIBUTE, True)

        return callable


class before(BaseAction):
    def __init__(self, tasks, only_once=False):
        super(before, self).__init__(BEFORE_ATTRIBUTE, only_once, tasks)


class after(BaseAction):
    def __init__(self, tasks, only_once=False):
        super(after, self).__init__(AFTER_ATTRIBUTE, only_once, tasks)


def use_plugin(name):
    from pybuilder.reactor import Reactor
    reactor = Reactor.current_instance()
    if reactor is not None:
        reactor.require_plugin(name)


class Author(object):
    def __init__(self, name, email=None, roles=[]):
        self.name = name
        self.email = email
        self.roles = roles


class Dependency(object):
    """
    Defines a dependency to another module. Use the
        depends_on
    method from class Project to add a dependency to a project.
    """
    def __init__(self, name, version=None, url=None):
        self.name = name
        self.version = version
        self.url = url

    def __eq__(self, other):
        return self.name == other.name and self.version == other.version and self.url == other.url

    def __ne__(self, other):
        return not(self == other)

    def __hash__(self):
        return 13 * hash(self.name) + 17 * hash(self.version)

    def __lt__(self, other):
        return self.name < other.name


class Project(object):<commit_msg>a mutable kwarg is a recipe for disaster<commit_after>#  This file is part of PyBuilder
#
#  Copyright 2011-2014 PyBuilder Team
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
"""
    The PyBuilder core module.
    Contains the most important classes and syntax used in a
    build.py project descriptor.
"""

import os
import string

from os.path import sep as PATH_SEPARATOR

from pybuilder.errors import MissingPropertyException
from .utils import as_list

INITIALIZER_ATTRIBUTE = "_python_builder_initializer"

ENVIRONMENTS_ATTRIBUTE = "_python_builder_environments"

NAME_ATTRIBUTE = "_python_builder_name"
ACTION_ATTRIBUTE = "_python_builder_action"
ONLY_ONCE_ATTRIBUTE = "_python_builder_action_only_once"
BEFORE_ATTRIBUTE = "_python_builder_before"
AFTER_ATTRIBUTE = "_python_builder_after"

TASK_ATTRIBUTE = "_python_builder_task"
DEPENDS_ATTRIBUTE = "_python_builder_depends"

DESCRIPTION_ATTRIBUTE = "_python_builder_description"


def init(*possible_callable, **additional_arguments):
    """
    Decorator for functions that wish to perform initialization steps.
    The decorated functions are called "initializers".

    Initializers are executed after all plugins and projects have been loaded
    but before any task is executed.

    Initializers may take an additional named argument "environments" which should contain a string or list of strings
    naming the environments this initializer applies for.

    Examples:

    @init
    def some_initializer(): pass

    @init()
    def some_initializer(): pass

    @init(environments="spam")
    def some_initializer(): pass

    @init(environments=["spam", "eggs"])
    def some_initializer(): pass
    """

    def do_decoration(callable):
        setattr(callable, INITIALIZER_ATTRIBUTE, True)

        if "environments" in additional_arguments:
            setattr(callable, ENVIRONMENTS_ATTRIBUTE, as_list(additional_arguments["environments"]))

        return callable

    if possible_callable:
        return do_decoration(possible_callable[0])

    return do_decoration


def task(callable_or_string):
    """
    Decorator for functions that should be used as tasks. Tasks are the main
    building blocks of projects.
    You can use this decorator either plain (no argument) or with
    a string argument, which overrides the default name.
    """
    if isinstance(callable_or_string, str):
        def set_name_and_task_attribute(callable):
            setattr(callable, TASK_ATTRIBUTE, True)
            setattr(callable, NAME_ATTRIBUTE, callable_or_string)
            return callable
        return set_name_and_task_attribute
    else:
        setattr(callable_or_string, TASK_ATTRIBUTE, True)
        return callable_or_string


class description(object):
    def __init__(self, description):
        self._description = description

    def __call__(self, callable):
        setattr(callable, DESCRIPTION_ATTRIBUTE, self._description)
        return callable


class depends(object):
    def __init__(self, *depends):
        self._depends = depends

    def __call__(self, callable):
        setattr(callable, DEPENDS_ATTRIBUTE, self._depends)
        return callable


class BaseAction(object):
    def __init__(self, attribute, only_once, tasks):
        self.tasks = tasks
        self.attribute = attribute
        self.only_once = only_once

    def __call__(self, callable):
        setattr(callable, ACTION_ATTRIBUTE, True)
        setattr(callable, self.attribute, self.tasks)
        if self.only_once:
            setattr(callable, ONLY_ONCE_ATTRIBUTE, True)

        return callable


class before(BaseAction):
    def __init__(self, tasks, only_once=False):
        super(before, self).__init__(BEFORE_ATTRIBUTE, only_once, tasks)


class after(BaseAction):
    def __init__(self, tasks, only_once=False):
        super(after, self).__init__(AFTER_ATTRIBUTE, only_once, tasks)


def use_plugin(name):
    from pybuilder.reactor import Reactor
    reactor = Reactor.current_instance()
    if reactor is not None:
        reactor.require_plugin(name)


class Author(object):
    def __init__(self, name, email=None, roles=None):
        self.name = name
        self.email = email
        self.roles = roles or []


class Dependency(object):
    """
    Defines a dependency to another module. Use the
        depends_on
    method from class Project to add a dependency to a project.
    """
    def __init__(self, name, version=None, url=None):
        self.name = name
        self.version = version
        self.url = url

    def __eq__(self, other):
        return self.name == other.name and self.version == other.version and self.url == other.url

    def __ne__(self, other):
        return not(self == other)

    def __hash__(self):
        return 13 * hash(self.name) + 17 * hash(self.version)

    def __lt__(self, other):
        return self.name < other.name


class Project(object):
{'fraction_non_alphanumeric': 0.07571680430546535, 'fraction_numerical': 0.003154866846061056, 'mean_word_length': 3.4908333333333332, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '5276841', 'n_tokens_mistral': 3128, 'n_tokens_neox': 3061, 'n_words': 951}