<commit_before>#!/usr/bin/python
# -- Content-Encoding: UTF-8 --
"""
Python modules repository

:author: <NAME>
:license: Apache Software License 2.0

..

    Copyright 2014 isandlaTech

    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.
"""

# Documentation strings format
__docformat__ = "restructuredtext en"

# Boot module version
__version__ = "1.0.0"

# ------------------------------------------------------------------------------

# Repository beans
import cohorte.repositories
from cohorte.repositories.beans import Artifact
# ######### added by: <NAME>.
from cohorte.repositories.beans import Version
# #########

# Pelix
from pelix.ipopo.decorators import ComponentFactory, Provides, Property, \
    Invalidate, Validate
from pelix.utilities import is_string

# Standard library
import ast
import imp
import logging
import os

# ######### added by: <NAME>.
import json
# #########

# ------------------------------------------------------------------------------

_logger = logging.getLogger(__name__)

# ------------------------------------------------------------------------------


class Module(Artifact):
    """
    Represents a bundle
    """
    def __init__(self, name, version, imports, filename):
        """
        Sets up the bundle details

        :param name: Name of the module
        :param version: Version of the module (as a string)
        :param imports: List of names of imported modules
        :param filename: Path to the .py file
        :raise ValueError: Invalid argument
        """
        Artifact.__init__(self, "python", name, version, filename)

        # Store information
        self.all_imports = imports

    def imports(self, artifact):
        """
        Tests if this module might import the given artifact

        :param artifact: Another artifact
        :return: True if this module imports the given one
        """
        if artifact.language != self.language:
            # No inter-language imports
            return False

        return artifact.name in self.all_imports

# ------------------------------------------------------------------------------


class AstVisitor(ast.NodeVisitor):
    """
    AST visitor to extract imports and version
    """
    # pylint: disable=invalid-name
    def __init__(self, filepath):
        """
        Sets up the visitor
        """
        ast.NodeVisitor.__init__(self)
        self.imports = set()
        self.version = None
        self.path_parts = filepath.split(os.sep)[:-1]

    def generic_visit(self, node):
        """
        Custom default visit method that avoids to visit further that the
        module level.
        """
        if type(node) is ast.Module:
            ast.NodeVisitor.generic_visit(self, node)

    def resolve_relative_import_from(self, node):
        """
        Converts a relative import (import .module) into an absolute one

        :param node: An ImportFrom AST node
        :return: The absolute module name
        """
        if node.level > 0:
            # Relative import
            return '.'.join(self.path_parts[-node.level:] + [node.module])
        else:
            # Absolute import
            return node.module

    def visit_Import(self, node):
        """
        Found an "import"
        """
        for alias in node.names:
            self.imports.add(alias.name)

    def visit_ImportFrom(self, node):
        """
        Found a "from ... import ..."
        """
        self.imports.add(self.resolve_relative_import_from(node))

    def visit_Assign(self, node):
        """
        Found an assignment
        """
        field = getattr(node.targets[0], 'id', None)<commit_msg>Handle "from . import" imports<commit_after>#!/usr/bin/python
# -- Content-Encoding: UTF-8 --
"""
Python modules repository

:author: <NAME>
:license: Apache Software License 2.0

..

    Copyright 2014 isandlaTech

    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.
"""

# Documentation strings format
__docformat__ = "restructuredtext en"

# Boot module version
__version__ = "1.0.0"

# ------------------------------------------------------------------------------

# Repository beans
import cohorte.repositories
from cohorte.repositories.beans import Artifact
# ######### added by: <NAME>.
from cohorte.repositories.beans import Version
# #########

# Pelix
from pelix.ipopo.decorators import ComponentFactory, Provides, Property, \
    Invalidate, Validate
from pelix.utilities import is_string

# Standard library
import ast
import imp
import logging
import os

# ######### added by: <NAME>.
import json
# #########

# ------------------------------------------------------------------------------

_logger = logging.getLogger(__name__)

# ------------------------------------------------------------------------------


class Module(Artifact):
    """
    Represents a bundle
    """
    def __init__(self, name, version, imports, filename):
        """
        Sets up the bundle details

        :param name: Name of the module
        :param version: Version of the module (as a string)
        :param imports: List of names of imported modules
        :param filename: Path to the .py file
        :raise ValueError: Invalid argument
        """
        Artifact.__init__(self, "python", name, version, filename)

        # Store information
        self.all_imports = imports

    def imports(self, artifact):
        """
        Tests if this module might import the given artifact

        :param artifact: Another artifact
        :return: True if this module imports the given one
        """
        if artifact.language != self.language:
            # No inter-language imports
            return False

        return artifact.name in self.all_imports

# ------------------------------------------------------------------------------


class AstVisitor(ast.NodeVisitor):
    """
    AST visitor to extract imports and version
    """
    # pylint: disable=invalid-name
    def __init__(self, filepath):
        """
        Sets up the visitor
        """
        ast.NodeVisitor.__init__(self)
        self.imports = set()
        self.version = None
        self.path_parts = filepath.split(os.sep)[:-1]

    def generic_visit(self, node):
        """
        Custom default visit method that avoids to visit further that the
        module level.
        """
        if type(node) is ast.Module:
            ast.NodeVisitor.generic_visit(self, node)

    def resolve_relative_import_from(self, node):
        """
        Converts a relative import (import .module) into an absolute one

        :param node: An ImportFrom AST node
        :return: The absolute module name
        """
        if node.level > 0:
            # Relative import
            parent = '.'.join(self.path_parts[-node.level:])
            if node.module:
                # from .module import ...
                return '.'.join((parent, node.module))
            else:
                # from . import ...
                return parent
        else:
            # Absolute import
            return node.module

    def visit_Import(self, node):
        """
        Found an "import"
        """
        for alias in node.names:
            self.imports.add(alias.name)

    def visit_ImportFrom(self, node):
        """
        Found a "from ... import ..."
        """
        self.imports.add(self.resolve_relative_import_from(node))

    def visit_Assign(self, node):
        """
        Found an assignment
        """
        field = getattr(node.targets[0], 'id', None)
{'fraction_non_alphanumeric': 0.16335360149672593, 'fraction_numerical': 0.003975678203928906, 'mean_word_length': 1.8358753315649867, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, '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': '6430374', 'n_tokens_mistral': 2190, 'n_tokens_neox': 2093, 'n_words': 732}