<commit_before>"""
Startmigration command, version 2.
"""

import sys
import os
import re
import string
import random
import inspect
import parser
from optparse import make_option

try:
    set
except NameError:
    from sets import Set as set

from django.core.management.base import BaseCommand
from django.core.management.color import no_style
from django.db import models
from django.db.models.fields.related import RECURSIVE_RELATIONSHIP_CONSTANT
from django.contrib.contenttypes.generic import GenericRelation
from django.db.models.fields import FieldDoesNotExist
from django.conf import settings

from south.migration import Migrations
from south.exceptions import NoMigrations
from south.creator import changes, actions, freezer

class Command(BaseCommand):
    option_list = BaseCommand.option_list + (
        make_option('--add-model', action='append', dest='added_model_list', type='string',
            help='Generate a Create Table migration for the specified model.  Add multiple models to this migration with subsequent --model parameters.'),
        make_option('--add-field', action='append', dest='added_field_list', type='string',
            help='Generate an Add Column migration for the specified modelname.fieldname - you can use this multiple times to add more than one column.'),
        make_option('--add-index', action='append', dest='added_index_list', type='string',
            help='Generate an Add Index migration for the specified modelname.fieldname - you can use this multiple times to add more than one column.'),
        make_option('--initial', action='store_true', dest='initial', default=False,
            help='Generate the initial schema for the app.'),
        make_option('--auto', action='store_true', dest='auto', default=False,
            help='Attempt to automatically detect differences from the last migration.'),
        make_option('--stdout', action='store_true', dest='stdout', default=False,
            help='Print the migration to stdout instead of writing it to a file.'),
    )
    help = "Creates a new template migration for the given app"
    usage_str = "Usage: ./manage.py schemamigration appname migrationname [--initial] [--auto] [--add-model ModelName] [--add-field ModelName.field_name] [--stdout]"

    def handle(self, app=None, name="", added_model_list=None, added_field_list=None, initial=False, auto=False, stdout=False, added_index_list=None, verbosity=1, **options):

        # Any supposed lists that are None become empty lists
        added_model_list = added_model_list or []
        added_field_list = added_field_list or []
        added_index_list = added_index_list or []

        # --stdout means name = -
        if stdout:
            name = "-"

        # Make sure options are compatable
        if initial and (added_model_list or added_field_list or auto):
            print "You cannot use --initial and other options together"
            print self.usage_str
            return

        if auto and (added_model_list or added_field_list or initial):
            print "You cannot use --auto and other options together"
            print self.usage_str
            return

        # specify the default name 'initial' if a name wasn't specified and we're
        # doing a migration for an entire app
        if not name and initial:
            name = 'initial'

        # if not name, there's an error
        if not name:
            print "You must name this migration"
            print self.usage_str
            return

        if not app:
            print "Please provide an app in which to create the migration."
            print self.usage_str
            return

        # Get the Migrations for this app (creating the migrations dir if needed)
        try:
            migrations = Migrations(app)
        except NoMigrations:
            Migrations.create_migrations_directory(app, verbose=verbosity > 0)
            migrations = Migrations(app)

        # See what filename is next in line. We assume they use numbers.
        highest_number = 0
        for migration in migrations:
            try:
                number = int(migration.name().split("_")[0])
                highest_number = max(highest_number, number)
            except ValueError:
                pass

        # Work out the new filename
        new_filename = "%04i_%s.py" % (
            highest_number + 1,
            name,
        )

        # What actions do we need to do?
        if auto:
            # Get the old migration, etc.
            raise NotImplementedError
        elif initial:
            change_source = changes.InitialChanges(migrations)
        else:
            raise NotImplementedError

        # Get the actions, and then insert them into the actions lists
        forwards_actions = []
        backwards_actions = []
        for action_name, params in change_source.get_changes():
            # Run the correct Action class
            try:
                action_class = getattr(actions, action_name)
            except AttributeError:
                raise ValueError("Invalid action name from source: %s" % action_name)
            else:
                action = action_class(**params)
                action.add_forwards(forwards_actions)
                action.add_backwards(backwards_actions)

        # Get the frozen models string.
        if getattr(settings, 'SOUTH_AUTO_FREEZE_APP', True):
            apps_to_freeze = [migrations.app_label()]
        else:
            apps_to_freeze = []

        # So, what's in this file, then?
        file_contents = MIGRATION_TEMPLATE % {
            "forwards": "\n".join(forwards_actions),
            "backwards": "\n".join(backwards_actions),
            "frozen_models":  freezer.freeze_apps(apps_to_freeze),
            "complete_apps": apps_to_freeze and "complete_apps = [%s]" % (", ".join(map(repr, apps_to_freeze))) or ""
        }

        # - is a special name which means 'print to stdout'
        if name == "-":
            print file_contents
        # Write the migration file if the name isn't -
        else:
            fp = open(os.path.join(migrations_dir, new_filename), "w")
            fp.write(file_contents)
            fp.close()
            print "Created %s." % new_filename

MIGRATION_TEMPLATE = """# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        %(forwards)s

    def backwards(self, orm):
        %(backwards)s

    models = %(frozen_models)s

    %(complete_apps)s
"""<commit_msg>More error reporting, and adding freezing back in<commit_after>"""
Startmigration command, version 2.
"""

import sys
import os
import re
import string
import random
import inspect
import parser
from optparse import make_option

try:
    set
except NameError:
    from sets import Set as set

from django.core.management.base import BaseCommand
from django.core.management.color import no_style
from django.db import models
from django.db.models.fields.related import RECURSIVE_RELATIONSHIP_CONSTANT
from django.contrib.contenttypes.generic import GenericRelation
from django.db.models.fields import FieldDoesNotExist
from django.conf import settings

from south.migration import Migrations
from south.exceptions import NoMigrations
from south.creator import changes, actions, freezer

class Command(BaseCommand):
    option_list = BaseCommand.option_list + (
        make_option('--add-model', action='append', dest='added_model_list', type='string',
            help='Generate a Create Table migration for the specified model.  Add multiple models to this migration with subsequent --model parameters.'),
        make_option('--add-field', action='append', dest='added_field_list', type='string',
            help='Generate an Add Column migration for the specified modelname.fieldname - you can use this multiple times to add more than one column.'),
        make_option('--add-index', action='append', dest='added_index_list', type='string',
            help='Generate an Add Index migration for the specified modelname.fieldname - you can use this multiple times to add more than one column.'),
        make_option('--freeze', action='append', dest='freeze_list', type='string',
            help='Freeze the specified model(s). Pass in either an app name (to freeze the whole app) or a single model, as appname.modelname.'),
        make_option('--initial', action='store_true', dest='initial', default=False,
            help='Generate the initial schema for the app.'),
        make_option('--auto', action='store_true', dest='auto', default=False,
            help='Attempt to automatically detect differences from the last migration.'),
        make_option('--stdout', action='store_true', dest='stdout', default=False,
            help='Print the migration to stdout instead of writing it to a file.'),
    )
    help = "Creates a new template migration for the given app"
    usage_str = "Usage: ./manage.py schemamigration appname migrationname [--initial] [--auto] [--add-model ModelName] [--add-field ModelName.field_name] [--stdout]"

    def handle(self, app=None, name="", added_model_list=None, added_field_list=None, freeze_list=None, initial=False, auto=False, stdout=False, added_index_list=None, verbosity=1, **options):

        # Any supposed lists that are None become empty lists
        added_model_list = added_model_list or []
        added_field_list = added_field_list or []
        added_index_list = added_index_list or []
        freeze_list = freeze_list or []

        # --stdout means name = -
        if stdout:
            name = "-"

        # Make sure options are compatable
        if initial and (added_model_list or added_field_list or auto):
            self.error("You cannot use --initial and other options together\n" + self.usage_str)

        if auto and (added_model_list or added_field_list or initial):
            self.error("You cannot use --auto and other options together\n" + self.usage_str)

        # specify the default name 'initial' if a name wasn't specified and we're
        # doing a migration for an entire app
        if not name and initial:
            name = 'initial'

        # if not name, there's an error
        if not name:
            self.error("You must provide a name for this migration\n" + self.usage_str)

        if not app:
            self.error("You must provide an app to create a migration for.\n" + self.usage_str)

        # Get the Migrations for this app (creating the migrations dir if needed)
        try:
            migrations = Migrations(app)
        except NoMigrations:
            Migrations.create_migrations_directory(app, verbose=verbosity > 0)
            migrations = Migrations(app)

        # See what filename is next in line. We assume they use numbers.
        highest_number = 0
        for migration in migrations:
            try:
                number = int(migration.name().split("_")[0])
                highest_number = max(highest_number, number)
            except ValueError:
                pass

        # Work out the new filename
        new_filename = "%04i_%s.py" % (
            highest_number + 1,
            name,
        )

        # What actions do we need to do?
        if auto:
            # Get the old migration
            try:
                last_migration = migrations[-1]
            except IndexError:
                self.error("You cannot use --auto on an app with no migrations. Try --initial.")
            # Make sure it has stored models
            if migrations.app_label() not in getattr(last_migration.migration_class(), "complete_apps", []):
                self.error("You cannot use automatic detection, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label())
        elif initial:
            # Do an initial migration
            change_source = changes.InitialChanges(migrations)
        else:
            raise NotImplementedError

        # Get the actions, and then insert them into the actions lists
        forwards_actions = []
        backwards_actions = []
        for action_name, params in change_source.get_changes():
            # Run the correct Action class
            try:
                action_class = getattr(actions, action_name)
            except AttributeError:
                raise ValueError("Invalid action name from source: %s" % action_name)
            else:
                action = action_class(**params)
                action.add_forwards(forwards_actions)
                action.add_backwards(backwards_actions)

        # Work out which apps to freeze
        apps_to_freeze = []
        for to_freeze in freeze_list:
            if "." in to_freeze:
                self.error("You cannot freeze %r; you must provide an app label, like 'auth' or 'books'." % to_freeze)
            # Make sure it's a real app
            if not models.get_app(to_freeze):
                self.error("You cannot freeze %r; it's not an installed app." % to_freeze)
            # OK, it's fine
            apps_to_freeze.append(to_freeze)
        if getattr(settings, 'SOUTH_AUTO_FREEZE_APP', True):
            apps_to_freeze.append(migrations.app_label())

        # So, what's in this file, then?
        file_contents = MIGRATION_TEMPLATE % {
            "forwards": "\n".join(forwards_actions),
            "backwards": "\n".join(backwards_actions),
            "frozen_models":  freezer.freeze_apps(apps_to_freeze),
            "complete_apps": apps_to_freeze and "complete_apps = [%s]" % (", ".join(map(repr, apps_to_freeze))) or ""
        }

        # - is a special name which means 'print to stdout'
        if name == "-":
            print file_contents
        # Write the migration file if the name isn't -
        else:
            fp = open(os.path.join(migrations_dir, new_filename), "w")
            fp.write(file_contents)
            fp.close()
            print "Created %s." % new_filename

    def error(self, message, code=1):
        """
        Prints the error, and exits with the given code.
        """
        print >>sys.stderr(message)
        sys.exit(code)

MIGRATION_TEMPLATE = """# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        %(forwards)s

    def backwards(self, orm):
        %(backwards)s

    models = %(frozen_models)s

    %(complete_apps)s
"""<|endoftext|>


<commit_before>from django import forms
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from django.core import urlresolvers
from django.core.urlresolvers import NoReverseMatch
from django.forms import CheckboxSelectMultiple

from isi_mip.sciencepaper.models import Author
from .models import *

class HideAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        """
        Return empty perms dict thus hiding the model from admin index.
        """
        return {}

class SimulationRoundAdmin(admin.ModelAdmin):
    model = SimulationRound
    prepopulated_fields = {'slug': ('name',), }
    list_display = ('name', 'order')

class HideSectorAdmin(HideAdmin):
    readonly_fields = ('impact_model',)
    exclude = ('data', )

class BaseImpactModelAdmin(admin.ModelAdmin):
    model = BaseImpactModel
    list_display = ('name', 'sector')
    list_filter = ('sector',)

class TechnicalInformationAdmin(admin.StackedInline):
    model = TechnicalInformation

class InputDataInformationAdmin(admin.StackedInline):
    model = InputDataInformation

class OtherInformationAdmin(admin.StackedInline):
    model = OtherInformation

class ImpactModelAdmin(admin.ModelAdmin):
    inlines = [TechnicalInformationAdmin, InputDataInformationAdmin, OtherInformationAdmin]
    model = ImpactModel

    def get_name(self, obj):
        return obj.base_model and obj.base_model.name or obj.id
    get_name.admin_order_field = 'base_model__name'
    get_name.short_description = 'Name'

    def get_sector(self, obj):
        return obj.base_model and obj.base_model.sector or None
    get_sector.admin_order_field = 'sector__name'
    get_sector.short_description = 'Sector'

    def sector_link(self, obj):
        try:
            adminurl = "admin:%s_%s_change" % (obj.fk_sector._meta.app_label, obj.fk_sector._meta.model_name)
            link = urlresolvers.reverse(adminurl, args=[obj.fk_sector.id])
            return '%s' % (link, obj.fk_sector)
        except NoReverseMatch:
            return '{} has no specific attributes.'.format(obj.fk_sector._meta.verbose_name)
        except KeyError:
            return 'will be shown, once the model is saved.'
    sector_link.allow_tags = True
    sector_link.short_description = 'Sector settings'
    readonly_fields = ('sector_link',)
    list_display = ('get_name', 'simulation_round', 'get_sector', 'public')
    list_filter = ('public', 'base_model__sector',)

class AgricultureAdmin(HideSectorAdmin):
    fieldsets = [
        ('Key input and management', {
            'fields': [
                'crops', 'land_coverage', 'planting_date_decision',
                'planting_density', 'crop_cultivars', 'fertilizer_application',
                'irrigation', 'crop_residue', 'initial_soil_water',
                'initial_soil_nitrate_and_ammonia',
                'initial_soil_C_and_OM', 'initial_crop_residue'
            ]}
         ),
        ('Key model processes', {
            'fields': [
                'lead_area_development', 'light_interception', 'light_utilization', 'yield_formation',
                'crop_phenology', 'root_distribution_over_depth', 'stresses_involved', 'type_of_water_stress',
                'type_of_heat_stress', 'water_dynamics', 'evapo_transpiration', 'soil_CN_modeling',
                'co2_effects',
            ],
        }),
        ('Methods for model calibration and validation', {
            'fields': [
                'parameters_number_and_description', 'calibrated_values', 'output_variable_and_dataset',
                'spatial_scale_of_calibration_validation', 'temporal_scale_of_calibration_validation',
                'criteria_for_evaluation']
        })
    ]

class DataTypeAdmin(admin.ModelAdmin):
    model = DataType
    list_display = ('name', 'is_climate_data_type')
    list_filter = ('is_climate_data_type',)

class SectorAdmin(admin.ModelAdmin):
    model = Sector
    list_display = ('name', 'class_name', 'has_sector_specific_values')
    prepopulated_fields = {'slug': ('name',), }

class SectorInformationFieldAdmin(admin.StackedInline):
    model = SectorInformationField
    prepopulated_fields = {'identifier': ('name',), }

class SectorInformationGroupAdmin(admin.ModelAdmin):
    model = SectorInformationGroup
    inlines = [SectorInformationFieldAdmin]
    prepopulated_fields = {'identifier': ('name',), }

    def get_sector(self, obj):
        return obj.sector.name
    get_sector.admin_order_field = 'sector__name'
    get_sector.short_description = 'Sector'
    list_display = ('get_sector', 'name', 'order')
    list_filter = ('sector__name', )

class InputDataAdmin(admin.ModelAdmin):
    model = InputData
    list_display = ('name', 'data_type', 'get_simulation_round')
    list_filter = ('data_type', 'simulation_round__name')
    formfield_overrides = {
        models.ManyToManyField: {'widget': CheckboxSelectMultiple},
    }
    def get_simulation_round(self, obj):
        return ', '.join([sr.name for sr in obj.simulation_round.all()])
    get_simulation_round.admin_order_field = 'simulation_round__name'
    get_simulation_round.short_description = 'Simulation rounds'

class OutputDataAdmin(admin.ModelAdmin):
    model = OutputData
    list_display = ('get_sector', 'get_model', 'get_simulation_round')
    list_filter = ('sector__name', 'simulation_round__name')
    formfield_overrides = {
        models.ManyToManyField: {'widget': CheckboxSelectMultiple},
    }
    def get_simulation_round(self, obj):
        return ', '.join([sr.name for sr in obj.simulation_round.all()])
    get_simulation_round.admin_order_field = 'simulation_round__name'
    get_simulation_round.short_description = 'Simulation rounds'

    def get_sector(self, obj):
        return obj.sector.name
    get_sector.admin_order_field = 'sector__name'
    get_sector.short_description = 'Sector'

    def get_model(self, obj):
        return obj.model and obj.model.base_model.name or obj.id
    get_model.admin_order_field = 'model__name'
    get_model.short_description = 'Impact Model'

class ClimateVariableAdmin(admin.ModelAdmin):
    model = ClimateVariable

    def get_type(self, obj):
        return ','.join(set([input_data.data_type.name for input_data in obj.inputdata_set.all().distinct()]))
    get_type.admin_order_field = 'sector__name'
    get_type.short_description = 'Data type'
    list_display = ('name', 'abbreviation', 'get_type')
    list_filter = ('inputdata__data_type__name',)

admin.site.register(BaseImpactModel, BaseImpactModelAdmin)
admin.site.register(ImpactModel, ImpactModelAdmin)
admin.site.register(InputData, InputDataAdmin)
admin.site.register(OutputData, OutputDataAdmin)
admin.site.register(Sector, SectorAdmin)
admin.site.register(Agriculture, AgricultureAdmin)
admin.site.register(Energy, HideSectorAdmin)
admin.site.register(WaterGlobal, HideSectorAdmin)
admin.site.register(WaterRegional, HideSectorAdmin)
admin.site.register(Biomes, HideSectorAdmin)
admin.site.register(Forests, HideSectorAdmin)
admin.site.register(MarineEcosystemsGlobal, HideSectorAdmin)
admin.site.register(MarineEcosystemsRegional, HideSectorAdmin)
admin.site.register(Biodiversity, HideSectorAdmin)
admin.site.register(GenericSector, HideSectorAdmin)

admin.site.register(SectorInformationGroup, SectorInformationGroupAdmin)

admin.site.register(DataType, DataTypeAdmin)
admin.site.register(ClimateVariable, ClimateVariableAdmin)
admin.site.register(ReferencePaper)
admin.site.register(Author, HideAdmin)
admin.site.register(Region)
admin.site.register(Scenario)
admin.site.register(SocioEconomicInputVariables)
admin.site.register(SimulationRound, SimulationRoundAdmin)
admin.site.register(SpatialAggregation)<commit_msg>add search field to admin<commit_after>from django import forms
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from django.core import urlresolvers
from django.core.urlresolvers import NoReverseMatch
from django.forms import CheckboxSelectMultiple

from isi_mip.sciencepaper.models import Author
from .models import *

class HideAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        """
        Return empty perms dict thus hiding the model from admin index.
        """
        return {}

class SimulationRoundAdmin(admin.ModelAdmin):
    model = SimulationRound
    prepopulated_fields = {'slug': ('name',), }
    list_display = ('name', 'order')

class HideSectorAdmin(HideAdmin):
    readonly_fields = ('impact_model',)
    exclude = ('data', )

class BaseImpactModelAdmin(admin.ModelAdmin):
    model = BaseImpactModel
    list_display = ('name', 'sector')
    list_filter = ('sector',)
    search_fields = ('name', 'sector__name')

class TechnicalInformationAdmin(admin.StackedInline):
    model = TechnicalInformation

class InputDataInformationAdmin(admin.StackedInline):
    model = InputDataInformation

class OtherInformationAdmin(admin.StackedInline):
    model = OtherInformation

class ImpactModelAdmin(admin.ModelAdmin):
    inlines = [TechnicalInformationAdmin, InputDataInformationAdmin, OtherInformationAdmin]
    model = ImpactModel
    search_fields = ('base_model__name', 'base_model__sector__name', 'simulation_round')

    def get_name(self, obj):
        return obj.base_model and obj.base_model.name or obj.id
    get_name.admin_order_field = 'base_model__name'
    get_name.short_description = 'Name'

    def get_sector(self, obj):
        return obj.base_model and obj.base_model.sector or None
    get_sector.admin_order_field = 'sector__name'
    get_sector.short_description = 'Sector'

    def sector_link(self, obj):
        try:
            adminurl = "admin:%s_%s_change" % (obj.fk_sector._meta.app_label, obj.fk_sector._meta.model_name)
            link = urlresolvers.reverse(adminurl, args=[obj.fk_sector.id])
            return '%s' % (link, obj.fk_sector)
        except NoReverseMatch:
            return '{} has no specific attributes.'.format(obj.fk_sector._meta.verbose_name)
        except KeyError:
            return 'will be shown, once the model is saved.'
    sector_link.allow_tags = True
    sector_link.short_description = 'Sector settings'
    readonly_fields = ('sector_link',)
    list_display = ('get_name', 'simulation_round', 'get_sector', 'public')
    list_filter = ('public', 'base_model__sector',)

class AgricultureAdmin(HideSectorAdmin):
    fieldsets = [
        ('Key input and management', {
            'fields': [
                'crops', 'land_coverage', 'planting_date_decision',
                'planting_density', 'crop_cultivars', 'fertilizer_application',
                'irrigation', 'crop_residue', 'initial_soil_water',
                'initial_soil_nitrate_and_ammonia',
                'initial_soil_C_and_OM', 'initial_crop_residue'
            ]}
         ),
        ('Key model processes', {
            'fields': [
                'lead_area_development', 'light_interception', 'light_utilization', 'yield_formation',
                'crop_phenology', 'root_distribution_over_depth', 'stresses_involved', 'type_of_water_stress',
                'type_of_heat_stress', 'water_dynamics', 'evapo_transpiration', 'soil_CN_modeling',
                'co2_effects',
            ],
        }),
        ('Methods for model calibration and validation', {
            'fields': [
                'parameters_number_and_description', 'calibrated_values', 'output_variable_and_dataset',
                'spatial_scale_of_calibration_validation', 'temporal_scale_of_calibration_validation',
                'criteria_for_evaluation']
        })
    ]

class DataTypeAdmin(admin.ModelAdmin):
    model = DataType
    list_display = ('name', 'is_climate_data_type')
    list_filter = ('is_climate_data_type',)

class SectorAdmin(admin.ModelAdmin):
    model = Sector
    list_display = ('name', 'class_name', 'has_sector_specific_values')
    prepopulated_fields = {'slug': ('name',), }

class SectorInformationFieldAdmin(admin.StackedInline):
    model = SectorInformationField
    prepopulated_fields = {'identifier': ('name',), }

class SectorInformationGroupAdmin(admin.ModelAdmin):
    model = SectorInformationGroup
    inlines = [SectorInformationFieldAdmin]
    prepopulated_fields = {'identifier': ('name',), }

    def get_sector(self, obj):
        return obj.sector.name
    get_sector.admin_order_field = 'sector__name'
    get_sector.short_description = 'Sector'
    list_display = ('get_sector', 'name', 'order')
    list_filter = ('sector__name', )

class InputDataAdmin(admin.ModelAdmin):
    model = InputData
    list_display = ('name', 'data_type', 'get_simulation_round')
    list_filter = ('data_type', 'simulation_round__name')
    formfield_overrides = {
        models.ManyToManyField: {'widget': CheckboxSelectMultiple},
    }
    def get_simulation_round(self, obj):
        return ', '.join([sr.name for sr in obj.simulation_round.all()])
    get_simulation_round.admin_order_field = 'simulation_round__name'
    get_simulation_round.short_description = 'Simulation rounds'

class OutputDataAdmin(admin.ModelAdmin):
    model = OutputData
    list_display = ('get_sector', 'get_model', 'get_simulation_round')
    list_filter = ('sector__name', 'simulation_round__name')
    formfield_overrides = {
        models.ManyToManyField: {'widget': CheckboxSelectMultiple},
    }
    def get_simulation_round(self, obj):
        return ', '.join([sr.name for sr in obj.simulation_round.all()])
    get_simulation_round.admin_order_field = 'simulation_round__name'
    get_simulation_round.short_description = 'Simulation rounds'

    def get_sector(self, obj):
        return obj.sector.name
    get_sector.admin_order_field = 'sector__name'
    get_sector.short_description = 'Sector'

    def get_model(self, obj):
        return obj.model and obj.model.base_model.name or obj.id
    get_model.admin_order_field = 'model__name'
    get_model.short_description = 'Impact Model'

class ClimateVariableAdmin(admin.ModelAdmin):
    model = ClimateVariable

    def get_type(self, obj):
        return ','.join(set([input_data.data_type.name for input_data in obj.inputdata_set.all().distinct()]))
    get_type.admin_order_field = 'sector__name'
    get_type.short_description = 'Data type'
    list_display = ('name', 'abbreviation', 'get_type')
    list_filter = ('inputdata__data_type__name',)

admin.site.register(BaseImpactModel, BaseImpactModelAdmin)
admin.site.register(ImpactModel, ImpactModelAdmin)
admin.site.register(InputData, InputDataAdmin)
admin.site.register(OutputData, OutputDataAdmin)
admin.site.register(Sector, SectorAdmin)
admin.site.register(Agriculture, AgricultureAdmin)
admin.site.register(Energy, HideSectorAdmin)
admin.site.register(WaterGlobal, HideSectorAdmin)
admin.site.register(WaterRegional, HideSectorAdmin)
admin.site.register(Biomes, HideSectorAdmin)
admin.site.register(Forests, HideSectorAdmin)
admin.site.register(MarineEcosystemsGlobal, HideSectorAdmin)
admin.site.register(MarineEcosystemsRegional, HideSectorAdmin)
admin.site.register(Biodiversity, HideSectorAdmin)
admin.site.register(GenericSector, HideSectorAdmin)

admin.site.register(SectorInformationGroup, SectorInformationGroupAdmin)

admin.site.register(DataType, DataTypeAdmin)
admin.site.register(ClimateVariable, ClimateVariableAdmin)
admin.site.register(ReferencePaper)
admin.site.register(Author, HideAdmin)
admin.site.register(Region)
admin.site.register(Scenario)
admin.site.register(SocioEconomicInputVariables)
admin.site.register(SimulationRound, SimulationRoundAdmin)
admin.site.register(SpatialAggregation)<|endoftext|>


<commit_before>from pyqode.core import modes
from pyqode.core.api import TextHelper

class AutoCompleteMode(modes.AutoCompleteMode):
    def __init__(self):
        super(AutoCompleteMode, self).__init__()
        self.QUOTES_FORMATS.pop("'")
        self.SELECTED_QUOTES_FORMATS.pop("'")
        self.MAPPING.pop("'")

    def _on_key_pressed(self, event):
        helper = TextHelper(self.editor)
        indent = helper.line_indent() * ' '
        if self.editor.textCursor().positionInBlock() == len(indent):
            self.QUOTES_FORMATS['"'] = '%s:'
        else:
            self.QUOTES_FORMATS['"'] = '%s'
        self.QUOTES_FORMATS['{'] = '\n' + indent + '%s'
        self.QUOTES_FORMATS['['] = '\n' + indent + '%s'
        super(AutoCompleteMode, self)._on_key_pressed(event)
<commit_msg>Fix issue with auto complete when more than 1 editor has been created<commit_after>from pyqode.core import modes
from pyqode.core.api import TextHelper

class AutoCompleteMode(modes.AutoCompleteMode):
    def __init__(self):
        super(AutoCompleteMode, self).__init__()
        try:
            self.QUOTES_FORMATS.pop("'")
            self.SELECTED_QUOTES_FORMATS.pop("'")
            self.MAPPING.pop("'")
        except KeyError:
            pass

    def _on_key_pressed(self, event):
        helper = TextHelper(self.editor)
        indent = helper.line_indent() * ' '
        if self.editor.textCursor().positionInBlock() == len(indent):
            self.QUOTES_FORMATS['"'] = '%s:'
        else:
            self.QUOTES_FORMATS['"'] = '%s'
        self.QUOTES_FORMATS['{'] = '\n' + indent + '%s'
        self.QUOTES_FORMATS['['] = '\n' + indent + '%s'
        super(AutoCompleteMode, self)._on_key_pressed(event)
<|endoftext|>


<commit_before># -------------------------------------------------------------------------------
# Copyright IBM Corp. 2017
#
# 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.
# -------------------------------------------------------------------------------
import os
import subprocess
import re
import inspect
from IPython.core.magic import (Magics, magics_class, cell_magic)
from pixiedust.utils.javaBridge import *
from pixiedust.utils.template import *
from pixiedust.utils.shellAccess import ShellAccess
from pixiedust.utils import Logger
import warnings
from six import iteritems
from IPython.core.getipython import get_ipython
from .environment import Environment

'''
Manages the variables defined interactively in the Notebook
'''
class InteractiveVariables(object):
    def __init__(self, shell):
        self.shell = shell

    def getVar(self, varName):
        return self.shell.user_ns.get(varName, None ) or self.shell.user_ns_hidden.get(varName, None)

    def transform(self, varName, varValue):
        pythonToScalaSimpleTypeMap = {"str":"String","unicode":"String","int":"Int"}
        scalaType = pythonToScalaSimpleTypeMap.get(varValue.__class__.__name__, None)
        codeValue = None
        initValue = None
        if scalaType is not None:
            primitive = True
            codeValue = "\"" + varValue.replace('\n','\\n').replace("\"", "\\\"") + "\"" if scalaType == "String" else varValue
        else:
            #Try the ConverterRegistry
            initValue,scalaType = ConverterRegistry.toJava(varValue)

        return {"value": varValue, "codeValue": codeValue, "type": scalaType or "Any", "initValue":initValue}

    def getVarsDict(self):
        user_ns = self.shell.user_ns
        user_ns_hidden = self.shell.user_ns_hidden
        nonmatching = object()  # This can never be in user_ns
        #for i in user_ns:
        #    print(user_ns[i].__class__)
        filtered = ["function"]
        out = { key : self.transform(key, user_ns[key]) for key in user_ns \
                if not key.startswith('_') \
                and key!="sc" and key!="sqlContext" \
                and (user_ns[key] is not user_ns_hidden.get(key, nonmatching)) \
                and not inspect.isclass(user_ns[key])\
                and not inspect.isfunction(user_ns[key])\
                and not inspect.ismodule(user_ns[key])}
        return out

    def updateVarsDict(self, vars):
        ShellAccess.update(**vars)

class ConverterRegistry(object):
    pythonToJavaConverters=[]

    @staticmethod
    def toJava(obj):
        for converter in ConverterRegistry.pythonToJavaConverters:
            v, t = converter(obj)
            if v is not None and t is not None:
                return (v,t)
        return (None,None)

def toJavaConverter(func):
    ConverterRegistry.pythonToJavaConverters.append( func )
    def wrapper(*args,**kwargs):
        return func(*args, **kwargs)
    return wrapper

runningClassLoaders = {}

@magics_class
@Logger()
class PixiedustScalaMagics(Magics):
    def __init__(self, shell):
        super(PixiedustScalaMagics,self).__init__(shell=shell)
        self.interactiveVariables = InteractiveVariables(shell)
        self.scala_home = os.environ.get("SCALA_HOME")
        self.class_path = JavaWrapper("java.lang.System").getProperty("java.class.path")
        self.env = PixiedustTemplateEnvironment()

    def getLineOption(self, line, optionName, defaultValue=None):
        m=re.search(r"\b" + optionName + r"=(\S+)",line)
        return m.group(1) if m is not None else defaultValue

    def hasLineOption(self, line, optionName):
        return re.search(r"\b" + optionName + r"\b", line) is not None

    def getReturnVars(self, code):
        vars=set()
        for m in re.finditer(r"\b__(\w+?)\b",code):
            vars.add(m.group(0))
        return vars

    def fromJava(self, stuff):
        if stuff.__class__.__name__ == "JavaObject":
            if stuff.getClass().getName() == "org.apache.spark.sql.DataFrame":
                return DataFrame(stuff, SQLContext(SparkContext.getOrCreate(), stuff.sqlContext()))
            elif stuff.getClass().getName() == "org.apache.spark.sql.SQLContext":
                return SQLContext(SparkContext.getOrCreate(),stuff)
        return stuff

    @cell_magic
    def scala(self, line, cell):
        if not self.scala_home:
            print("Error Cannot run scala code: SCALA_HOME environment variable not set")
            return

        #generate the code
        clSlot = self.getLineOption(line, "cl")
        clExt = "." + clSlot if clSlot is not None else ""
        scalaCode = self.env.getTemplate("scalaCell.template").render(
            scalaVersion=Environment.scalaVersion, cell=cell, variables=self.interactiveVariables.getVarsDict(), returnVars=self.getReturnVars(cell), cl=clExt
        )
        if self.hasLineOption(line, "debug"):
            print(scalaCode)
            return

        #build the scala object
        dir=os.environ.get("PIXIEDUST_HOME", os.path.expanduser('~')) + "/pixiedust"
        globalPath = self.getLineOption(line, "global")
        if globalPath is not None and globalPath == "true":
            dir = os.environ.get("PIXIEDUST_HOME", os.path.expanduser('~')) + "/data/libs"
        if not os.path.exists(dir):
            os.makedirs(dir)
        source="pixiedustRunner.scala"
        with open(dir + "/" + source, "wb") as f:
            f.write(scalaCode.encode("utf-8","ignore"))
        #Compile the code
        commands = [self.scala_home + "/bin/scalac","-classpath", self.class_path, source]
        self.debug("Calling scala compiler with command: {0}".format( " ".join(commands)))
        proc = subprocess.Popen(commands,stdout=subprocess.PIPE,stderr=subprocess.PIPE, cwd=dir)
        code = proc.wait()
        if code != 0:
            while True:
                line = proc.stderr.readline()
                if not line:
                    break
                print(line.rstrip())
            return

        #Load the class and initialize the variables
        f = sc._jvm.java.io.File(dir)
        url = f.toURL()
        urls=sc._gateway.new_array(sc._jvm.java.net.URL,1)
        urls[0]=url

        if clSlot is not None and runningClassLoaders.get(clSlot) is not None:
            #close the running classLoader
            runningCl = runningClassLoaders.get(clSlot)
            runningCl.close()
            runningClassLoaders.pop( clSlot, None )

        cl = sc._jvm.java.net.URLClassLoader(urls)
        cls = sc._jvm.java.lang.Class.forName("com.ibm.pixiedust{0}.PixiedustScalaRun$".format(clExt), True, cl)

        runnerObject = JavaWrapper(cls.getField("MODULE$").get(None), True,
            self.getLineOption(line, "channel"), self.getLineOption(line, "receiver"))
        safeAccess = lambda obj, fieldName: None if obj is None or not hasattr(obj, fieldName) else getattr(obj, fieldName)
        runnerObject.callMethod("init",
            pd_getJavaSparkContext(),
            None if self.hasLineOption(line, "noSqlContext") else safeAccess(self.interactiveVariables.getVar("sqlContext"), "_ssql_ctx" )
        )

        #Init the variables
        for key, val in iteritems(self.interactiveVariables.getVarsDict()):
            if val["initValue"] is not None:
                runnerObject.callMethod("set" + key[0].upper() + key[1:], val["initValue"])

        varMap = runnerObject.callMethod("runCell")

        #capture the return vars and update the interactive shell
        returnVars = {}
        it = varMap.iterator()
        while it.hasNext():
            t = it.next()
            returnVars[t._1()] = self.fromJava(t._2())
        self.interactiveVariables.updateVarsDict(returnVars)

        #discard the ClassLoader, we only use it within the context of a cell.
        #TODO: change that when we support inline scala class/object definition
        if clSlot:
            runningClassLoaders[clSlot] = cl
        else:
            cl.close()
        cl=None
        cls=None
        runnerObject=None

try:
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        get_ipython().register_magics(PixiedustScalaMagics)
except NameError:
    #IPython not available we must be in a spark executor
    pass

#converters
@toJavaConverter
def dataFrameConverter(var):
    from pyspark.sql import DataFrame
    if isinstance(var, DataFrame):
        return (var._jdf, "org.apache.spark.sql.DataFrame")
    return (None,None)

@toJavaConverter
def rddConverter(var):
    from pyspark.rdd import RDD
    if isinstance(var, RDD):
        return (var._jrdd, var._jrdd.getClass().getName() + "[Object]")
    return (None,None)

@toJavaConverter
def graphFrameConverter(var):
    if hasattr(var, "__module__") and hasattr(var, "__class__"):
        clazz = var.__module__ + "." + var.__class__.__name__
        if clazz == "graphframes.graphframe.GraphFrame":
            return (var._jvm_graph, "org.graphframes.GraphFrame")
    return (None,None)<commit_msg>#425 Spark 2.x Error when trying to display a DataFrame generated using scala magic<commit_after># -------------------------------------------------------------------------------
# Copyright IBM Corp. 2017
#
# 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.
# -------------------------------------------------------------------------------
import os
import subprocess
import re
import inspect
from IPython.core.magic import (Magics, magics_class, cell_magic)
from pixiedust.utils.javaBridge import *
from pixiedust.utils.template import *
from pixiedust.utils.shellAccess import ShellAccess
from pixiedust.utils import Logger
import warnings
from six import iteritems
from IPython.core.getipython import get_ipython
from .environment import Environment

'''
Manages the variables defined interactively in the Notebook
'''
class InteractiveVariables(object):
    def __init__(self, shell):
        self.shell = shell

    def getVar(self, varName):
        return self.shell.user_ns.get(varName, None ) or self.shell.user_ns_hidden.get(varName, None)

    def transform(self, varName, varValue):
        pythonToScalaSimpleTypeMap = {"str":"String","unicode":"String","int":"Int"}
        scalaType = pythonToScalaSimpleTypeMap.get(varValue.__class__.__name__, None)
        codeValue = None
        initValue = None
        if scalaType is not None:
            primitive = True
            codeValue = "\"" + varValue.replace('\n','\\n').replace("\"", "\\\"") + "\"" if scalaType == "String" else varValue
        else:
            #Try the ConverterRegistry
            initValue,scalaType = ConverterRegistry.toJava(varValue)

        return {"value": varValue, "codeValue": codeValue, "type": scalaType or "Any", "initValue":initValue}

    def getVarsDict(self):
        user_ns = self.shell.user_ns
        user_ns_hidden = self.shell.user_ns_hidden
        nonmatching = object()  # This can never be in user_ns
        #for i in user_ns:
        #    print(user_ns[i].__class__)
        filtered = ["function"]
        out = { key : self.transform(key, user_ns[key]) for key in user_ns \
                if not key.startswith('_') \
                and key!="sc" and key!="sqlContext" \
                and (user_ns[key] is not user_ns_hidden.get(key, nonmatching)) \
                and not inspect.isclass(user_ns[key])\
                and not inspect.isfunction(user_ns[key])\
                and not inspect.ismodule(user_ns[key])}
        return out

    def updateVarsDict(self, vars):
        ShellAccess.update(**vars)

class ConverterRegistry(object):
    pythonToJavaConverters=[]

    @staticmethod
    def toJava(obj):
        for converter in ConverterRegistry.pythonToJavaConverters:
            v, t = converter(obj)
            if v is not None and t is not None:
                return (v,t)
        return (None,None)

def toJavaConverter(func):
    ConverterRegistry.pythonToJavaConverters.append( func )
    def wrapper(*args,**kwargs):
        return func(*args, **kwargs)
    return wrapper

runningClassLoaders = {}

@magics_class
@Logger()
class PixiedustScalaMagics(Magics):
    def __init__(self, shell):
        super(PixiedustScalaMagics,self).__init__(shell=shell)
        self.interactiveVariables = InteractiveVariables(shell)
        self.scala_home = os.environ.get("SCALA_HOME")
        self.class_path = JavaWrapper("java.lang.System").getProperty("java.class.path")
        self.env = PixiedustTemplateEnvironment()

    def getLineOption(self, line, optionName, defaultValue=None):
        m=re.search(r"\b" + optionName + r"=(\S+)",line)
        return m.group(1) if m is not None else defaultValue

    def hasLineOption(self, line, optionName):
        return re.search(r"\b" + optionName + r"\b", line) is not None

    def getReturnVars(self, code):
        vars=set()
        for m in re.finditer(r"\b__(\w+?)\b",code):
            vars.add(m.group(0))
        return vars

    def fromJava(self, stuff):
        if stuff.__class__.__name__ == "JavaObject":
            clazz = stuff.getClass().getName()
            if clazz == "org.apache.spark.sql.Dataset":
                stuff = stuff.toDF()
                clazz = "org.apache.spark.sql.DataFrame"

            if clazz == "org.apache.spark.sql.DataFrame":
                return DataFrame(stuff, SQLContext(SparkContext.getOrCreate(), stuff.sqlContext()))
            elif clazz == "org.apache.spark.sql.SQLContext":
                return SQLContext(SparkContext.getOrCreate(),stuff)
        return stuff

    @cell_magic
    def scala(self, line, cell):
        if not self.scala_home:
            print("Error Cannot run scala code: SCALA_HOME environment variable not set")
            return

        #generate the code
        clSlot = self.getLineOption(line, "cl")
        clExt = "." + clSlot if clSlot is not None else ""
        scalaCode = self.env.getTemplate("scalaCell.template").render(
            scalaVersion=Environment.scalaVersion, cell=cell, variables=self.interactiveVariables.getVarsDict(), returnVars=self.getReturnVars(cell), cl=clExt
        )
        if self.hasLineOption(line, "debug"):
            print(scalaCode)
            return

        #build the scala object
        dir=os.environ.get("PIXIEDUST_HOME", os.path.expanduser('~')) + "/pixiedust"
        globalPath = self.getLineOption(line, "global")
        if globalPath is not None and globalPath == "true":
            dir = os.environ.get("PIXIEDUST_HOME", os.path.expanduser('~')) + "/data/libs"
        if not os.path.exists(dir):
            os.makedirs(dir)
        source="pixiedustRunner.scala"
        with open(dir + "/" + source, "wb") as f:
            f.write(scalaCode.encode("utf-8","ignore"))
        #Compile the code
        commands = [self.scala_home + "/bin/scalac","-classpath", self.class_path, source]
        self.debug("Calling scala compiler with command: {0}".format( " ".join(commands)))
        proc = subprocess.Popen(commands,stdout=subprocess.PIPE,stderr=subprocess.PIPE, cwd=dir)
        code = proc.wait()
        if code != 0:
            while True:
                line = proc.stderr.readline()
                if not line:
                    break
                print(line.rstrip())
            return

        #Load the class and initialize the variables
        f = sc._jvm.java.io.File(dir)
        url = f.toURL()
        urls=sc._gateway.new_array(sc._jvm.java.net.URL,1)
        urls[0]=url

        if clSlot is not None and runningClassLoaders.get(clSlot) is not None:
            #close the running classLoader
            runningCl = runningClassLoaders.get(clSlot)
            runningCl.close()
            runningClassLoaders.pop( clSlot, None )

        cl = sc._jvm.java.net.URLClassLoader(urls)
        cls = sc._jvm.java.lang.Class.forName("com.ibm.pixiedust{0}.PixiedustScalaRun$".format(clExt), True, cl)

        runnerObject = JavaWrapper(cls.getField("MODULE$").get(None), True,
            self.getLineOption(line, "channel"), self.getLineOption(line, "receiver"))
        safeAccess = lambda obj, fieldName: None if obj is None or not hasattr(obj, fieldName) else getattr(obj, fieldName)
        runnerObject.callMethod("init",
            pd_getJavaSparkContext(),
            None if self.hasLineOption(line, "noSqlContext") else safeAccess(self.interactiveVariables.getVar("sqlContext"), "_ssql_ctx" )
        )

        #Init the variables
        for key, val in iteritems(self.interactiveVariables.getVarsDict()):
            if val["initValue"] is not None:
                runnerObject.callMethod("set" + key[0].upper() + key[1:], val["initValue"])

        varMap = runnerObject.callMethod("runCell")

        #capture the return vars and update the interactive shell
        returnVars = {}
        it = varMap.iterator()
        while it.hasNext():
            t = it.next()
            returnVars[t._1()] = self.fromJava(t._2())
        self.interactiveVariables.updateVarsDict(returnVars)

        #discard the ClassLoader, we only use it within the context of a cell.
        #TODO: change that when we support inline scala class/object definition
        if clSlot:
            runningClassLoaders[clSlot] = cl
        else:
            cl.close()
        cl=None
        cls=None
        runnerObject=None

try:
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        get_ipython().register_magics(PixiedustScalaMagics)
except NameError:
    #IPython not available we must be in a spark executor
    pass

#converters
@toJavaConverter
def dataFrameConverter(var):
    from pyspark.sql import DataFrame
    if isinstance(var, DataFrame):
        return (var._jdf, "org.apache.spark.sql.DataFrame")
    return (None,None)

@toJavaConverter
def rddConverter(var):
    from pyspark.rdd import RDD
    if isinstance(var, RDD):
        return (var._jrdd, var._jrdd.getClass().getName() + "[Object]")
    return (None,None)

@toJavaConverter
def graphFrameConverter(var):
    if hasattr(var, "__module__") and hasattr(var, "__class__"):
        clazz = var.__module__ + "." + var.__class__.__name__
        if clazz == "graphframes.graphframe.GraphFrame":
            return (var._jvm_graph, "org.graphframes.GraphFrame")
    return (None,None)<|endoftext|>


<commit_before>from collections import OrderedDict
import xlsxwriter

from django.db.models import ManyToOneRel, ManyToManyRel, ManyToManyRel, ManyToManyField, ForeignKey

from isi_mip.climatemodels.models import BaseImpactModel, ImpactModel, Sector, TechnicalInformation, \
    InputDataInformation, OtherInformation, SectorInformationField

EMPTY_SECTORS = [
    'Agro-Economic Modelling',
    'Biodiversity',
    'Coastal Infrastructure',
    'Computable General Equilibrium Modelling',
    'Health',
    'Permafrost',
]

SKIP_FIELDS = [
    'id',
    'base_model',
    'public',
    'impact_model',
    'impact_model_involved',
    'technicalinformation',
    'inputdatainformation',
    'otherinformation',
    'genericsector',
    'agriculture',
    'biomes',
    'forests',
    'energy',
    'marineecosystemsglobal',
    'marineecosystemsregional',
    'waterglobal',
    'waterregional',
    'biodiversity',
    'health',
    'coastalinfrastructure',
    'permafrost',
    'computablegeneralequilibriummodelling',
    'agroeconomicmodelling',
    'outputdata',
    'confirmation',
    'contactperson',
]

SORT_ORDER = {
    "impact_model_owner": 1,
    "main_reference_paper": 1,
    "other_references": 2,
}

class ImpactModelToXLSX:
    # https://xlsxwriter.readthedocs.org/en/latest/
    def __init__(self, res, qs):
        self.workbook = xlsxwriter.Workbook(res, {'in_memory': True})
        self.qs = qs
        self.xlsxdings()

    def get_field_data(self, model, field_name):
        field = model._meta.get_field(field_name)
        if isinstance(field, ManyToManyField):
            data = ", ".join(["%s" % i for i in getattr(model, field_name).all()])
        elif isinstance(field, ManyToOneRel) or isinstance(field, ManyToManyRel):
            try:
                data = ", ".join(["%s" % i for i in getattr(model, "%s_set" % field_name).all()])
            except AttributeError:
                data = ", ".join(["%s" % i for i in getattr(model, "%s" % field_name).all()])

        else:
            data = getattr(model, field_name) or ''
        return data

    def xlsxdings(self):
        general = self.workbook.add_worksheet('General Information')
        general.set_column('A:A', 20)
        bold = self.workbook.add_format({'bold': True})
        models = [BaseImpactModel, ImpactModel, TechnicalInformation, InputDataInformation, OtherInformation]
        model_fields = OrderedDict()
        all_field_titles = []
        for model in models:
            fields = model._meta.get_fields()
            filtered_fields = [field for field in fields if field.name not in (SKIP_FIELDS)]
            filtered_fields.sort(key=lambda val: SORT_ORDER[val.name] if val.name in SORT_ORDER else 0)
            model_fields[model.__name__] = {
                'class': model,
                'fields': [f.name for f in filtered_fields],
            }
            for field in filtered_fields:
                if hasattr(field, 'verbose_name'):
                    all_field_titles.append(field.verbose_name.capitalize())
                else:
                    if field.name == 'impact_model_owner':
                        all_field_titles.append('Contact person')
                    else:
                        name = field.name.replace("_", " ").capitalize()
                        all_field_titles.append(name)
        general.write_row(0, 0, data=all_field_titles, cell_format=bold)
        for i, impact_model in enumerate(self.qs):
            for j, field in enumerate(model_fields['BaseImpactModel']['fields']):
                data = self.get_field_data(impact_model.base_model, field)
                general.write(i + 1, j, str(data))
            for j, field in enumerate(model_fields['ImpactModel']['fields'], start=j + 1):
                data = self.get_field_data(impact_model, field)
                general.write(i + 1, j, str(data))
            for j, field in enumerate(model_fields['TechnicalInformation']['fields'], start=j + 1):
                instance = impact_model.technicalinformation
                data = getattr(instance, field) or ''
                general.write(i + 1, j, str(data))
            for j, field in enumerate(model_fields['InputDataInformation']['fields'], start=j + 1):
                instance = impact_model.inputdatainformation
                data = self.get_field_data(instance, field)
                general.write(i + 1, j, str(data))
            for j, field in enumerate(model_fields['OtherInformation']['fields'], start=j + 1):
                instance = impact_model.otherinformation
                data = self.get_field_data(instance, field)
                general.write(i + 1, j, str(data))

        for sector in Sector.objects.all():
            fields = []
            if sector.name in EMPTY_SECTORS:
                continue
            elif not sector.model.objects.filter(impact_model__in=self.qs).exists():
                continue
            else:
                fields = [field.name for field in sector.model._meta.fields if field.name not in ('id', 'data')]

            sector_name = 'M. E. and Fisheries (regional)' if sector.name == 'Marine Ecosystems and Fisheries (regional)' else sector.name
            sector_name = 'M. E. and Fisheries (global)' if sector.name == 'Marine Ecosystems and Fisheries (global)' else sector.name
            for ch in ['[', ']', ':', '*', '?', '/', '\\']:
                if ch in sector_name:
                    sector_name = sector_name.replace(ch, '-')
            sectorsheet = self.workbook.add_worksheet(sector_name[0:31])
            generic_fields = SectorInformationField.objects.filter(information_group__sector=sector).order_by('information_group')
            sectorsheet.write_row(0, 0, data=[x.title() for x in fields], cell_format=bold)
            sectorsheet.write_row(0, len(fields), data=[x.name for x in generic_fields], cell_format=bold)
            for i, entry in enumerate(sector.model.objects.filter(impact_model__in=self.qs)):
                for j, f in enumerate(fields):
                    value = getattr(entry, f) or ''
                    sectorsheet.write(i + 1, j, str(value))
                for j, f in enumerate(generic_fields):
                    value = entry.data and entry.data.get(f.unique_identifier, '') or ''
                    sectorsheet.write(i + 1, len(fields) + j, str(value))

        self.workbook.close()

class ParticpantModelToXLSX:
    # https://xlsxwriter.readthedocs.org/en/latest/
    def __init__(self, res, qs):
        self.workbook = xlsxwriter.Workbook(res, {'in_memory': True})
        self.qs = qs
        self.process_xlsx()

    def process_xlsx(self):
        general = self.workbook.add_worksheet('Participants')
        general.set_column('A:A', 20)
        bold = self.workbook.add_format({'bold': True})
        header = ['Name', 'Email', 'Instiute', 'Country', 'Model', 'Sector', 'Comment']
        general.write_row(0, 0, data=header, cell_format=bold)
        for i, participant in enumerate(self.qs):
            general.write(i + 1, 0, participant.userprofile.name)
            general.write(i + 1, 1, participant.email)
            general.write(i + 1, 2, participant.userprofile.institute)
            general.write(i + 1, 3, participant.userprofile.country and participant.userprofile.country.name or '')
            models = [str(model) for model in participant.userprofile.involved.all()]
            general.write(i + 1, 4, ", ".join(models))
            sectors = [sector.name for sector in participant.userprofile.sector.all()]
            general.write(i + 1, 5, ", ".join(sectors))
            general.write(i + 1, 6, participant.userprofile.comment)
        self.workbook.close()
<commit_msg>fix xlsx download<commit_after>from collections import OrderedDict
import xlsxwriter

from django.db.models import ManyToOneRel, ManyToManyRel, ManyToManyRel, ManyToManyField, ForeignKey

from isi_mip.climatemodels.models import BaseImpactModel, ImpactModel, Sector, TechnicalInformation, \
    InputDataInformation, OtherInformation, SectorInformationField

EMPTY_SECTORS = [
    'Agro-Economic Modelling',
    'Biodiversity',
    'Coastal Infrastructure',
    'Computable General Equilibrium Modelling',
    'Health',
    'Permafrost',
]

SKIP_FIELDS = [
    'id',
    'base_model',
    'public',
    'impact_model',
    'impact_model_involved',
    'technicalinformation',
    'inputdatainformation',
    'otherinformation',
    'genericsector',
    'agriculture',
    'biomes',
    'forests',
    'energy',
    'marineecosystemsglobal',
    'marineecosystemsregional',
    'waterglobal',
    'waterregional',
    'biodiversity',
    'health',
    'coastalinfrastructure',
    'permafrost',
    'computablegeneralequilibriummodelling',
    'agroeconomicmodelling',
    'outputdata',
    'confirmation',
    'contactperson',
    'attachment',
]

SORT_ORDER = {
    "impact_model_owner": 1,
    "main_reference_paper": 1,
    "other_references": 2,
}

class ImpactModelToXLSX:
    # https://xlsxwriter.readthedocs.org/en/latest/
    def __init__(self, res, qs):
        self.workbook = xlsxwriter.Workbook(res, {'in_memory': True})
        self.qs = qs
        self.xlsxdings()

    def get_field_data(self, model, field_name):
        field = model._meta.get_field(field_name)
        if isinstance(field, ManyToManyField):
            data = ", ".join(["%s" % i for i in getattr(model, field_name).all()])
        elif isinstance(field, ManyToOneRel) or isinstance(field, ManyToManyRel):
            try:
                data = ", ".join(["%s" % i for i in getattr(model, "%s_set" % field_name).all()])
            except AttributeError:
                data = ", ".join(["%s" % i for i in getattr(model, "%s" % field_name).all()])

        else:
            data = getattr(model, field_name) or ''
        return data

    def xlsxdings(self):
        general = self.workbook.add_worksheet('General Information')
        general.set_column('A:A', 20)
        bold = self.workbook.add_format({'bold': True})
        models = [BaseImpactModel, ImpactModel, TechnicalInformation, InputDataInformation, OtherInformation]
        model_fields = OrderedDict()
        all_field_titles = []
        for model in models:
            fields = model._meta.get_fields()
            filtered_fields = [field for field in fields if field.name not in (SKIP_FIELDS)]
            filtered_fields.sort(key=lambda val: SORT_ORDER[val.name] if val.name in SORT_ORDER else 0)
            model_fields[model.__name__] = {
                'class': model,
                'fields': [f.name for f in filtered_fields],
            }
            for field in filtered_fields:
                if hasattr(field, 'verbose_name'):
                    all_field_titles.append(field.verbose_name.capitalize())
                else:
                    if field.name == 'impact_model_owner':
                        all_field_titles.append('Contact person')
                    else:
                        name = field.name.replace("_", " ").capitalize()
                        all_field_titles.append(name)
        general.write_row(0, 0, data=all_field_titles, cell_format=bold)
        for i, impact_model in enumerate(self.qs):
            for j, field in enumerate(model_fields['BaseImpactModel']['fields']):
                data = self.get_field_data(impact_model.base_model, field)
                general.write(i + 1, j, str(data))
            for j, field in enumerate(model_fields['ImpactModel']['fields'], start=j + 1):
                data = self.get_field_data(impact_model, field)
                general.write(i + 1, j, str(data))
            for j, field in enumerate(model_fields['TechnicalInformation']['fields'], start=j + 1):
                instance = impact_model.technicalinformation
                data = getattr(instance, field) or ''
                general.write(i + 1, j, str(data))
            for j, field in enumerate(model_fields['InputDataInformation']['fields'], start=j + 1):
                instance = impact_model.inputdatainformation
                data = self.get_field_data(instance, field)
                general.write(i + 1, j, str(data))
            for j, field in enumerate(model_fields['OtherInformation']['fields'], start=j + 1):
                instance = impact_model.otherinformation
                data = self.get_field_data(instance, field)
                general.write(i + 1, j, str(data))

        for sector in Sector.objects.all():
            fields = []
            if sector.name in EMPTY_SECTORS:
                continue
            elif not sector.model.objects.filter(impact_model__in=self.qs).exists():
                continue
            else:
                fields = [field.name for field in sector.model._meta.fields if field.name not in ('id', 'data')]

            sector_name = 'M. E. and Fisheries (regional)' if sector.name == 'Marine Ecosystems and Fisheries (regional)' else sector.name
            sector_name = 'M. E. and Fisheries (global)' if sector.name == 'Marine Ecosystems and Fisheries (global)' else sector.name
            for ch in ['[', ']', ':', '*', '?', '/', '\\']:
                if ch in sector_name:
                    sector_name = sector_name.replace(ch, '-')
            sectorsheet = self.workbook.add_worksheet(sector_name[0:31])
            generic_fields = SectorInformationField.objects.filter(information_group__sector=sector).order_by('information_group')
            sectorsheet.write_row(0, 0, data=[x.title() for x in fields], cell_format=bold)
            sectorsheet.write_row(0, len(fields), data=[x.name for x in generic_fields], cell_format=bold)
            for i, entry in enumerate(sector.model.objects.filter(impact_model__in=self.qs)):
                for j, f in enumerate(fields):
                    value = getattr(entry, f) or ''
                    sectorsheet.write(i + 1, j, str(value))
                for j, f in enumerate(generic_fields):
                    value = entry.data and entry.data.get(f.unique_identifier, '') or ''
                    sectorsheet.write(i + 1, len(fields) + j, str(value))

        self.workbook.close()

class ParticpantModelToXLSX:
    # https://xlsxwriter.readthedocs.org/en/latest/
    def __init__(self, res, qs):
        self.workbook = xlsxwriter.Workbook(res, {'in_memory': True})
        self.qs = qs
        self.process_xlsx()

    def process_xlsx(self):
        general = self.workbook.add_worksheet('Participants')
        general.set_column('A:A', 20)
        bold = self.workbook.add_format({'bold': True})
        header = ['Name', 'Email', 'Instiute', 'Country', 'Model', 'Sector', 'Comment']
        general.write_row(0, 0, data=header, cell_format=bold)
        for i, participant in enumerate(self.qs):
            general.write(i + 1, 0, participant.userprofile.name)
            general.write(i + 1, 1, participant.email)
            general.write(i + 1, 2, participant.userprofile.institute)
            general.write(i + 1, 3, participant.userprofile.country and participant.userprofile.country.name or '')
            models = [str(model) for model in participant.userprofile.involved.all()]
            general.write(i + 1, 4, ", ".join(models))
            sectors = [sector.name for sector in participant.userprofile.sector.all()]
            general.write(i + 1, 5, ", ".join(sectors))
            general.write(i + 1, 6, participant.userprofile.comment)
        self.workbook.close()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# Copyright (c) 2015 Angel Terrones (<angelterrones@gmail.com>)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from Simulation.core.memory import Memory
from Core.icache import ICache
from Core.wishbone import WishboneIntercon
from Simulation.modules.ram_bus import RamBus
import random
from myhdl import instance
from myhdl import always_comb
from myhdl import Signal
from myhdl import instances
from myhdl import Simulation
from myhdl import StopSimulation
from myhdl import delay
from myhdl import Error
from myhdl import traceSignals
import pytest

MEM_SIZE      = 2**15  # Bytes
MEM_TEST_FILE = 'Simulation/modules/mem.hex'
BYTES_X_LINE  = 16

def _testbench():
    rb = RamBus(memory_size=MEM_SIZE >> 2)
    dmem = WishboneIntercon()
    invalidate = Signal(False)
    dut = ICache(clk_i=rb.clkb,               # noqa
                 rst_i=False,
                 cpu=rb.dmem_intercon,
                 mem=dmem,
                 invalidate=invalidate,
                 D_WIDTH=32,
                 BLOCK_WIDTH=3,
                 SET_WIDTH=5,
                 WAYS=4,
                 LIMIT_WIDTH=32)
    mem = Memory(clka_i=rb.clka,              # noqa
                 rsta_i=False,
                 imem=rb.imem_intercon,
                 clkb_i=rb.clkb,
                 rstb_i=False,
                 dmem=dmem,
                 SIZE=MEM_SIZE,
                 HEX=MEM_TEST_FILE,
                 BYTES_X_LINE=BYTES_X_LINE)

    tb_clk = rb.gen_clocks()  # noqa

    # Load the test file. Used as reference.
    with open(MEM_TEST_FILE) as f:
        words_x_line = BYTES_X_LINE >> 2
        lines_f = [line.strip() for line in f]
        lines = [line[8 * i:8 * (i + 1)] for line in lines_f for i in range(words_x_line - 1, -1, -1)]

    @instance
    def timeout():
        # Avoid waiting until armageddon
        yield delay(100000)
        raise Error("Test failed: Timeout")

    # @always_comb
    # def port_assign():
    #     # This assignments are for the purpose of being able to watch this
    #     # signal GTKWave.
    #     cpu.addr.next      = rb.dmem.addr
    #     cpu.wdata.next     = rb.dmem.wdata
    #     cpu.wr.next        = rb.dmem.wr
    #     cpu.fcn.next       = rb.dmem.fcn
    #     cpu.valid.next     = rb.dmem.valid
    #     rb.dmem.rdata.next = cpu.rdata
    #     rb.dmem.ready.next = cpu.ready
    #     rb.dmem.fault.next = cpu.fault

    @instance
    def stimulus():
        # rb.rst.next = True
        # yield delay(10)
        # rb.rst.next = False
        # Read data from memory: first round
        for addr in range(rb.depth >> 5):  # Address in words
            yield rb.read(addr << 2)  # Address in bytes
            data = int(lines[addr], 16)
            assert rb.dmem.dat_i == data, "Data loading (1): Data mismatch! Addr = {0:#x}: {1} != {2:#x}".format(addr << 2,
                                                                                hex(rb.dmem.dat_i),
                                                                                data)
        invalidate.next = True
        yield delay(10)
        invalidate.next = False
        # Read data from memory: second round.
        # This time, depending in the cache configuration, should
        # make each access a hit (big cache)
        for addr in range(rb.depth >> 5):  # Address in words
            yield rb.read(addr << 2)  # Address in bytes
            data = int(lines[addr], 16)
            assert rb.dmem.dat_i == data, "Data loading (2): Data mismatch! Addr = {0:#x}: {1} != {2:#x}".format(addr << 2,
                                                                                hex(rb.dmem.dat_i),
                                                                                data)
        raise StopSimulation

    return instances()

def gen_test_file():
    """
    Generate a HEX file, with random values.
    """
    with open(MEM_TEST_FILE, 'w') as f:
        depth = int(MEM_SIZE / BYTES_X_LINE)
        for _ in range(depth):
            for _ in range(BYTES_X_LINE >> 2):
                f.write(format(random.randint(0, 2**32), 'x').zfill(8))
            f.write('\n')

def test_cache():
    """
    Cache: Test loading from memory
    """
    gen_test_file()
    sim = Simulation(traceSignals(_testbench))
    sim.run()

def test_cache_assertions():
    """
    Memory: Test assertions
    """
    clk = Signal(False)
    rst = Signal(False)
    invalidate = Signal(False)
    cpu = WishboneIntercon()
    mem = WishboneIntercon()

    # Test data width size
    with pytest.raises(AssertionError):
        ICache(clk,
               rst,
               cpu,
               mem,
               invalidate,
               D_WIDTH=64,
               BLOCK_WIDTH=5,
               SET_WIDTH=9,
               WAYS=2,
               LIMIT_WIDTH=32)

    # Test block width size
    with pytest.raises(AssertionError):
        ICache(clk,
               rst,
               cpu,
               mem,
               invalidate,
               D_WIDTH=32,
               BLOCK_WIDTH=-4,
               SET_WIDTH=9,
               WAYS=2,
               LIMIT_WIDTH=32)

    # Test ways size
    with pytest.raises(AssertionError):
        ICache(clk,
               rst,
               cpu,
               mem,
               invalidate,
               D_WIDTH=32,
               BLOCK_WIDTH=6,
               SET_WIDTH=9,
               WAYS=3,
               LIMIT_WIDTH=32)

# Local Variables:
# flycheck-flake8-maximum-line-length: 200
# flycheck-flake8rc: ".flake8rc"
# End:
<commit_msg>Use an aux intercon signal for debug.<commit_after>#!/usr/bin/env python
# Copyright (c) 2015 Angel Terrones (<angelterrones@gmail.com>)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from Simulation.core.memory import Memory
from Core.icache import ICache
from Core.wishbone import WishboneIntercon
from Simulation.modules.ram_bus import RamBus
import random
from myhdl import instance
from myhdl import always_comb
from myhdl import Signal
from myhdl import instances
from myhdl import Simulation
from myhdl import StopSimulation
from myhdl import delay
from myhdl import Error
from myhdl import traceSignals
import pytest

MEM_SIZE      = 2**15  # Bytes
MEM_TEST_FILE = 'Simulation/modules/mem.hex'
BYTES_X_LINE  = 16

def _testbench():
    rb = RamBus(memory_size=MEM_SIZE >> 2)
    cpu = WishboneIntercon()
    dmem = WishboneIntercon()
    invalidate = Signal(False)
    dut = ICache(clk_i=rb.clkb,               # noqa
                 rst_i=False,
                 cpu=rb.dmem_intercon,
                 mem=dmem,
                 invalidate=invalidate,
                 D_WIDTH=32,
                 BLOCK_WIDTH=3,
                 SET_WIDTH=5,
                 WAYS=4,
                 LIMIT_WIDTH=32)
    mem = Memory(clka_i=rb.clka,              # noqa
                 rsta_i=False,
                 imem=rb.imem_intercon,
                 clkb_i=rb.clkb,
                 rstb_i=False,
                 dmem=dmem,
                 SIZE=MEM_SIZE,
                 HEX=MEM_TEST_FILE,
                 BYTES_X_LINE=BYTES_X_LINE)

    tb_clk = rb.gen_clocks()  # noqa

    # Load the test file. Used as reference.
    with open(MEM_TEST_FILE) as f:
        words_x_line = BYTES_X_LINE >> 2
        lines_f = [line.strip() for line in f]
        lines = [line[8 * i:8 * (i + 1)] for line in lines_f for i in range(words_x_line - 1, -1, -1)]

    @instance
    def timeout():
        # Avoid waiting until armageddon
        yield delay(100000)
        raise Error("Test failed: Timeout")

    @always_comb
    def port_assign():
        # This assignments are for the purpose of being able to watch this
        # signal GTKWave.
        cpu.addr.next  = rb.dmem_intercon.addr
        cpu.dat_o.next = rb.dmem_intercon.dat_o
        cpu.dat_i.next = rb.dmem_intercon.dat_i
        cpu.sel.next   = rb.dmem_intercon.sel
        cpu.cti.next   = rb.dmem_intercon.cti
        cpu.cyc.next   = rb.dmem_intercon.cyc
        cpu.we.next    = rb.dmem_intercon.we
        cpu.stb.next   = rb.dmem_intercon.stb
        cpu.stall.next = rb.dmem_intercon.stall
        cpu.ack.next   = rb.dmem_intercon.ack
        cpu.err.next   = rb.dmem_intercon.err

    @instance
    def stimulus():
        # rb.rst.next = True
        # yield delay(10)
        # rb.rst.next = False
        # Read data from memory: first round
        for addr in range(rb.depth >> 5):  # Address in words
            yield rb.read(addr << 2)  # Address in bytes
            data = int(lines[addr], 16)
            assert rb.dmem.dat_i == data, "Data loading (1): Data mismatch! Addr = {0:#x}: {1} != {2:#x}".format(addr << 2,
                                                                                hex(rb.dmem.dat_i),
                                                                                data)
        invalidate.next = True
        yield delay(10)
        invalidate.next = False
        # Read data from memory: second round.
        # This time, depending in the cache configuration, should
        # make each access a hit (big cache)
        for addr in range(rb.depth >> 5):  # Address in words
            yield rb.read(addr << 2)  # Address in bytes
            data = int(lines[addr], 16)
            assert rb.dmem.dat_i == data, "Data loading (2): Data mismatch! Addr = {0:#x}: {1} != {2:#x}".format(addr << 2,
                                                                                hex(rb.dmem.dat_i),
                                                                                data)
        raise StopSimulation

    return instances()

def gen_test_file():
    """
    Generate a HEX file, with random values.
    """
    with open(MEM_TEST_FILE, 'w') as f:
        depth = int(MEM_SIZE / BYTES_X_LINE)
        for _ in range(depth):
            for _ in range(BYTES_X_LINE >> 2):
                f.write(format(random.randint(0, 2**32), 'x').zfill(8))
            f.write('\n')

def test_cache():
    """
    Cache: Test loading from memory
    """
    gen_test_file()
    sim = Simulation(traceSignals(_testbench))
    sim.run()

def test_cache_assertions():
    """
    Memory: Test assertions
    """
    clk = Signal(False)
    rst = Signal(False)
    invalidate = Signal(False)
    cpu = WishboneIntercon()
    mem = WishboneIntercon()

    # Test data width size
    with pytest.raises(AssertionError):
        ICache(clk,
               rst,
               cpu,
               mem,
               invalidate,
               D_WIDTH=64,
               BLOCK_WIDTH=5,
               SET_WIDTH=9,
               WAYS=2,
               LIMIT_WIDTH=32)

    # Test block width size
    with pytest.raises(AssertionError):
        ICache(clk,
               rst,
               cpu,
               mem,
               invalidate,
               D_WIDTH=32,
               BLOCK_WIDTH=-4,
               SET_WIDTH=9,
               WAYS=2,
               LIMIT_WIDTH=32)

    # Test ways size
    with pytest.raises(AssertionError):
        ICache(clk,
               rst,
               cpu,
               mem,
               invalidate,
               D_WIDTH=32,
               BLOCK_WIDTH=6,
               SET_WIDTH=9,
               WAYS=3,
               LIMIT_WIDTH=32)

# Local Variables:
# flycheck-flake8-maximum-line-length: 200
# flycheck-flake8rc: ".flake8rc"
# End:
<|endoftext|>