def _new_func_from_source(source, func): """ Create new function defined in source but maintain context from func @param func: The function whose global + local context we will use @param source: Python source code containing def statement """ src_str = ''.join(source) frames = inspect.getouterframes(inspect.currentframe()) calling_frame = frames[2][0] context = {} # My initial instict was: exec src_str in func.func_globals.items(), calling_frame.f_locals # however this seems to break the function closure so caveat here is that we create a new # function with the locals merged into the globals. # # Possible consequences I can think of: # - If a global exists that already has the same name as the local, it will be overwritten in # in the context of this function. This shouldnt matter though as the global should have already # been hidden by the new name? # # This functionality should be considered experimental as no idea what other consequences there # could be. # # relevant: http://stackoverflow.com/questions/2749655/why-are-closures-broken-within-exec globals = six.get_function_globals(func) locals = calling_frame.f_locals combined = globals.copy() combined.update(locals) Logger.debug('New src_str:\n %s' % src_str) six.exec_(src_str, combined, context) new_func = context[func.__name__] return new_func
def get_function(path): """ get a function defined by path from the apps object. """ ns = {"all_apps": all_apps} six.exec_('a=' + path, ns) return ns['a']
def test_mysql_cache_migration(self): out = StringIO() call_command('mysql_cache_migration', stdout=out) output = out.getvalue() # Lint it with captured_stdout() as stderr: errors = check_code(output) self.assertEqual( errors, 0, "Encountered {} errors whilst trying to lint the mysql cache " "migration.\nMigration:\n\n{}\n\nLint errors:\n\n{}" .format(errors, output, stderr.getvalue()) ) # Dynamic import and check migration_mod = imp.new_module('0001_add_cache_tables') six.exec_(output, migration_mod.__dict__) self.assertTrue(hasattr(migration_mod, 'Migration')) migration = migration_mod.Migration self.assertTrue(hasattr(migration, 'dependencies')) self.assertTrue(hasattr(migration, 'operations')) # Since they all have the same table name, there should only be one # operation self.assertEqual(len(migration.operations), 1) # Now run the migration forwards and backwards to check it works operation = migration.operations[0] self.drop_table() self.assertTableNotExists(self.table_name) state = ProjectState() new_state = state.clone() with connection.schema_editor() as editor: operation.database_forwards("django_mysql_tests", editor, state, new_state) self.assertTableExists(self.table_name) new_state = state.clone() with connection.schema_editor() as editor: operation.database_backwards("django_mysql_tests", editor, new_state, state) self.assertTableNotExists(self.table_name) self.create_table()
def _process_conf_item(self, item, fn=False): """ process an item. item could be anything. if it is a string representing a function, convert to function. otherwise, pass through. """ model_fn = """ def a(all_models, all_apps, path_args, node, parent): return {} """ if not hasattr(item, "strip"): return item if ">>>" in item and item.index(">>>") == 0: item = item[3:].strip() fn = True if fn: ns = {} six.exec_(model_fn.format(item), ns) return ns['a'] else: return item
def test_mysql_cache_migration(self): out = StringIO() call_command('mysql_cache_migration', stdout=out) output = out.getvalue() # Lint it errors = flake8_code(output) assert errors == [], ( "Encountered {} errors whilst trying to lint the mysql cache " "migration.\nMigration:\n\n{}\n\nLint errors:\n\n{}" .format(len(errors), output, '\n'.join(errors)) ) # Dynamic import and check migration_mod = imp.new_module('0001_add_cache_tables') six.exec_(output, migration_mod.__dict__) assert hasattr(migration_mod, 'Migration') migration = migration_mod.Migration assert hasattr(migration, 'dependencies') assert hasattr(migration, 'operations') # Since they all have the same table name, there should only be one # operation assert len(migration.operations) == 1 # Now run the migration forwards and backwards to check it works operation = migration.operations[0] assert not self.table_exists(self.table_name) state = ProjectState() new_state = state.clone() with connection.schema_editor() as editor: operation.database_forwards("testapp", editor, state, new_state) assert self.table_exists(self.table_name) new_state = state.clone() with connection.schema_editor() as editor: operation.database_backwards("testapp", editor, new_state, state) assert not self.table_exists(self.table_name)
def test_mysql_cache_migration(self): out = StringIO() call_command('mysql_cache_migration', stdout=out) output = out.getvalue() # Lint it self.flake8dir.make_example_py(output) result = self.flake8dir.run_flake8() assert result.out_lines == [] # Dynamic import and check migration_mod = imp.new_module('0001_add_cache_tables') six.exec_(output, migration_mod.__dict__) assert hasattr(migration_mod, 'Migration') migration = migration_mod.Migration assert hasattr(migration, 'dependencies') assert hasattr(migration, 'operations') # Since they all have the same table name, there should only be one # operation assert len(migration.operations) == 1 # Now run the migration forwards and backwards to check it works operation = migration.operations[0] assert not self.table_exists(self.table_name) state = ProjectState() new_state = state.clone() with connection.schema_editor() as editor: operation.database_forwards("testapp", editor, state, new_state) assert self.table_exists(self.table_name) new_state = state.clone() with connection.schema_editor() as editor: operation.database_backwards("testapp", editor, new_state, state) assert not self.table_exists(self.table_name)
def _gen_classes(globals_, locals_): wrapper_classes = [ 'AddAnotherWidgetWrapper', 'EditSelectedWidgetWrapper', 'AddAnotherEditSelectedWidgetWrapper', ] select2_widgets = [ 'Select2Widget', 'HeavySelect2Widget', 'Select2MultipleWidget', 'HeavySelect2MultipleWidget', 'HeavySelect2TagWidget', 'ModelSelect2Widget', 'ModelSelect2MultipleWidget', 'ModelSelect2TagWidget', ] cls_template = textwrap.dedent(''' class {new_cls_name}({wrapper_cls}): """:class:`~{widget_cls}` wrapped with :class:`~{wrapper_cls}`.""" def __init__(self, *args, **kwargs): super({new_cls_name}, self).__init__( {widget_cls}, *args, **kwargs ) ''') for wrapper_cls in wrapper_classes: for widget_cls in select2_widgets: new_cls_name = widget_cls[:-len("Widget")] + wrapper_cls[:-len( "WidgetWrapper")] code = cls_template.format( new_cls_name=new_cls_name, widget_cls="django_select2.forms.%s" % widget_cls, wrapper_cls="django_addanother.widgets.%s" % wrapper_cls, ) six.exec_(code, globals_, locals_) yield new_cls_name
def _gen_classes(globals_, locals_): wrapper_classes = [ 'AddAnotherWidgetWrapper', 'EditSelectedWidgetWrapper', 'AddAnotherEditSelectedWidgetWrapper', ] select2_widgets = [ 'Select2Widget', 'HeavySelect2Widget', 'Select2MultipleWidget', 'HeavySelect2MultipleWidget', 'HeavySelect2TagWidget', 'ModelSelect2Widget', 'ModelSelect2MultipleWidget', 'ModelSelect2TagWidget', ] cls_template = textwrap.dedent(''' class {new_cls_name}({wrapper_cls}): """:class:`~{widget_cls}` wrapped with :class:`~{wrapper_cls}`.""" def __init__(self, *args, **kwargs): super({new_cls_name}, self).__init__( {widget_cls}, *args, **kwargs ) ''') for wrapper_cls in wrapper_classes: for widget_cls in select2_widgets: new_cls_name = widget_cls[:-len("Widget")] + wrapper_cls[:-len("WidgetWrapper")] code = cls_template.format( new_cls_name=new_cls_name, widget_cls="django_select2.forms.%s" % widget_cls, wrapper_cls="django_addanother.widgets.%s" % wrapper_cls, ) six.exec_(code, globals_, locals_) yield new_cls_name
if f.blank and raw_value in validators.EMPTY_VALUES: continue try: setattr(self, f.attname, f.clean(raw_value, self)) except ValidationError as e: errors[f.name] = e.messages if errors: raise ValidationError(errors) # For unknown reasons, six.with_metaclass doesn't work correctly for Model. # Fallback to exec'ing the appropriate syntax for each Python version. if six.PY3: six.exec_("class Model(ModelWithoutMeta, metaclass=ModelBase): pass") else: six.exec_("class Model(ModelWithoutMeta): __metaclass__ = ModelBase") ############################################ # HELPER FUNCTIONS (CURRIED MODEL METHODS) # ############################################ # ORDERING METHODS ######################### def method_set_order(ordered_obj, self, id_list, using=None): if using is None: using = DEFAULT_DB_ALIAS rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) order_name = ordered_obj._meta.order_with_respect_to.name
methods = set(methods) if methods - all_methods: raise TypeError('Unexpected method to be reload: %s' % list(methods - all_methods)) for item in all_methods - methods: attrs.pop(item) return type(fieldclass)(fieldclass.__name__, (fieldclass, ), attrs) def wrap_field(methods=()): '''make _wrap_field as a decorator''' return partial(_wrap_field, methods=methods) for _fieldclass_name in fields.__all__[1:]: six.exec_('{0} = _wrap_field(fields.{0})'.format(_fieldclass_name)) # overwrite BooleanField and NullBooleanField to accept 0,1 @wrap_field(methods=('to_python', )) class BooleanField(BooleanField): # NOQA widget = BooleanInput default_error_messages = { 'invalid': _('Enter a valid value.'), } def to_python(self, value): if isinstance(value, six.string_types): value = value.lower() if value in ('false', '0'):
from django.utils import six SETTINGS = '.dev' try: from .pre import SETTINGS except ImportError: pass six.exec_('from %s import *' % SETTINGS) try: from .local import * # NOQA except ImportError: pass