<commit_before># -*- coding: utf-8 -*-
import flask
import sys
import types
import os
import sqlalchemy as sa

__all__ = [
    'Alchemist',
]


def wrap_module(name, application):

    # Wrap the module with a nested module that
    # contains property accessors for late-bound configuration.
    class Module(types.ModuleType):

        @property
        def application(self):
            application.configure()
            return application

    # Update the inner module with the actual contents.
    instance = Module(__name__)
    instance.__dict__.update(sys.modules[name].__dict__)

    # Return the wrapped module.
    return instance


class Alchemist(flask.Flask):

    def __init__(self, name, *args, **kwargs):
        # Initialize the flask application context.
        super().__init__(name, *args, **kwargs)

        # Replace the package with a container module that contains
        # a property reference to the application.
        sys.modules[name] = wrap_module(name, self)

    def _apply_site_configuration(self):
        # Gather configuration from the following places (with precedence):
        #   1. $<package.application.name>_SETTINGS_MODULE
        #   2. $ALCHEMIST_SETTINGS_MODULE
        #   3. <project>.settings

        # Set default settings.
        # The default packages array contains just the alchemist lib which
        # includes all default commands.
        self.config['PACKAGES'] = ['alchemist']

        # The default database setting just includes an in-memory sqlite
        # database.
        self.config['DATABASES'] = {'default':{
            'engine': 'sqlite',
            'name': ':memory:'
        }}

        # The default server configuration enables threading.
        self.config['SERVER'] = {
            'host': 'localhost',
            'port': 8000,
            'threading': True
        }

        try:
            # Attempt to get configuration from the project settings.
            self.config.from_object('{}.settings'.format(self.name))

        except ImportError:
            # No settings module or package.
            pass

        # Attempt to get configuration from the environment variables.
        for name in ['ALCHEMIST', self.name.upper().replace('.', '_')]:
            var = '%s_SETTINGS_MODULE' % name
            if var in os.environ:
                self.config.from_envvar(var)

    def configure(self):
        """Collect settings and configure the application instance."""

        # Establish an application context.
        context = self.app_context()
        context.push()

        # Detect if we are being invoked by a test runner.
        # Checks the first and second arguments to determine if we are being
        # run by a test runner.
        # Able to match `py.test`, `nosetests`, `alchemist test`,
        # and `python setup.py test`.
        self.config['TESTING'] = False
        count = 3 if os.path.basename(sys.argv[0]).startswith('python') else 2
        for argument in sys.argv[0:count]:
            if 'test' in argument:
                # We are, in fact, being run by a test runner.
                self.testing = self.config['TESTING'] = True
                break

        # Apply the initial site configuration.
        self._apply_site_configuration()

        # After the initial configuration is gathered; each registered
        # package is searched for a settings module or package and that
        # is loaded then the site configuration is re-applied (to
        # keep precedence and allow dynamic behavior).
        for package in self.config.get('PACKAGES', ()):
            try:
                # Attempt to get configuration from the settings module.
                self.config.from_object('{}.settings'.format(package))

            except ImportError:
                # No settings module.
                pass

            # Re-apply the site configuration.
            self._apply_site_configuration()

        # Release the application context.
        context.pop()

        # # Process database configuration.
        # # Expand each reference into a database engine.
        # # TODO: Support PORT, HOST, USERNAME, and PASSWORD
        # for name in self.config.get('DATABASES', ()):
        #     db = self.config['DATABASES'][name]
        #     if isinstance(db, Mapping):
        #         uri = '{}:///{}'.format(db['engine'], db['name'])
        #         echo = db.get('echo', False)
        #         engine = sa.create_engine(uri, echo=echo)
        #         self.config['DATABASES'][name] = engine

        # # Iterate through the delayed mounts and run each handlers.
        # for handler in self._mounts:
        #     handler()<commit_msg>Add application proxy.<commit_after># -*- coding: utf-8 -*-
import flask
import sys
import types
import os
import sqlalchemy as sa

__all__ = [
    'Alchemist',
    'application',
]


def wrap_module(name, application):

    # Wrap the module with a nested module that
    # contains property accessors for late-bound configuration.
    class Module(types.ModuleType):

        @property
        def application(self):
            application.configure()
            return application

    # Update the inner module with the actual contents.
    instance = Module(__name__)
    instance.__dict__.update(sys.modules[name].__dict__)

    # Return the wrapped module.
    return instance


class Alchemist(flask.Flask):

    def __init__(self, name, *args, **kwargs):
        # Initialize the flask application context.
        super().__init__(name, *args, **kwargs)

        # Replace the package with a container module that contains
        # a property reference to the application.
        sys.modules[name] = wrap_module(name, self)

    def _apply_site_configuration(self):
        # Gather configuration from the following places (with precedence):
        #   1. $<package.application.name>_SETTINGS_MODULE
        #   2. $ALCHEMIST_SETTINGS_MODULE
        #   3. <project>.settings

        # Set default settings.
        # The default packages array contains just the alchemist lib which
        # includes all default commands.
        self.config['PACKAGES'] = ['alchemist']

        # The default database setting just includes an in-memory sqlite
        # database.
        self.config['DATABASES'] = {'default':{
            'engine': 'sqlite',
            'name': ':memory:'
        }}

        # The default server configuration enables threading.
        self.config['SERVER'] = {
            'host': 'localhost',
            'port': 8000,
            'threading': True
        }

        try:
            # Attempt to get configuration from the project settings.
            self.config.from_object('{}.settings'.format(self.name))

        except ImportError:
            # No settings module or package.
            pass

        # Attempt to get configuration from the environment variables.
        for name in ['ALCHEMIST', self.name.upper().replace('.', '_')]:
            var = '%s_SETTINGS_MODULE' % name
            if var in os.environ:
                self.config.from_envvar(var)

    def configure(self):
        """Collect settings and configure the application instance."""

        # Establish an application context.
        context = self.app_context()
        context.push()

        # Detect if we are being invoked by a test runner.
        # Checks the first and second arguments to determine if we are being
        # run by a test runner.
        # Able to match `py.test`, `nosetests`, `alchemist test`,
        # and `python setup.py test`.
        self.config['TESTING'] = False
        count = 3 if os.path.basename(sys.argv[0]).startswith('python') else 2
        for argument in sys.argv[0:count]:
            if 'test' in argument:
                # We are, in fact, being run by a test runner.
                self.testing = self.config['TESTING'] = True
                break

        # Apply the initial site configuration.
        self._apply_site_configuration()

        # After the initial configuration is gathered; each registered
        # package is searched for a settings module or package and that
        # is loaded then the site configuration is re-applied (to
        # keep precedence and allow dynamic behavior).
        for package in self.config.get('PACKAGES', ()):
            try:
                # Attempt to get configuration from the settings module.
                self.config.from_object('{}.settings'.format(package))

            except ImportError:
                # No settings module.
                pass

            # Re-apply the site configuration.
            self._apply_site_configuration()

        # Release the application context.
        context.pop()

        # # Process database configuration.
        # # Expand each reference into a database engine.
        # # TODO: Support PORT, HOST, USERNAME, and PASSWORD
        # for name in self.config.get('DATABASES', ()):
        #     db = self.config['DATABASES'][name]
        #     if isinstance(db, Mapping):
        #         uri = '{}:///{}'.format(db['engine'], db['name'])
        #         echo = db.get('echo', False)
        #         engine = sa.create_engine(uri, echo=echo)
        #         self.config['DATABASES'][name] = engine

        # # Iterate through the delayed mounts and run each handlers.
        # for handler in self._mounts:
        #     handler()


class ApplicationProxy:
    """Proxies access to the current application.
    """

    def __getattribute__(self, name):
        # Attempt to proxy to the current application.
        from flask import current_app
        return getattr(current_app, name)


# Construct the application proxy.
application = ApplicationProxy()
{'fraction_non_alphanumeric': 0.09567711534521614, 'fraction_numerical': 0.002458512599877074, 'mean_word_length': 2.1052798982188294, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '3679761', 'n_tokens_mistral': 2550, 'n_tokens_neox': 2440, 'n_words': 833}