Best Python code snippet using localstack_python
writer.py
Source:writer.py  
1from __future__ import unicode_literals2import collections3import datetime4import decimal5import inspect6import math7import os8import re9import sys10import types11from importlib import import_module12from django.apps import apps13from django.db import migrations, models14from django.db.migrations.loader import MigrationLoader15from django.utils import datetime_safe, six16from django.utils._os import upath17from django.utils.encoding import force_text18from django.utils.functional import Promise19from django.utils.timezone import utc20from django.utils.version import get_docs_version21COMPILED_REGEX_TYPE = type(re.compile(''))22class SettingsReference(str):23    """24    Special subclass of string which actually references a current settings25    value. It's treated as the value in memory, but serializes out to a26    settings.NAME attribute reference.27    """28    def __new__(self, value, setting_name):29        return str.__new__(self, value)30    def __init__(self, value, setting_name):31        self.setting_name = setting_name32class OperationWriter(object):33    indentation = 234    def __init__(self, operation):35        self.operation = operation36        self.buff = []37    def serialize(self):38        def _write(_arg_name, _arg_value):39            if (_arg_name in self.operation.serialization_expand_args and40                    isinstance(_arg_value, (list, tuple, dict))):41                if isinstance(_arg_value, dict):42                    self.feed('%s={' % _arg_name)43                    self.indent()44                    for key, value in _arg_value.items():45                        key_string, key_imports = MigrationWriter.serialize(key)46                        arg_string, arg_imports = MigrationWriter.serialize(value)47                        self.feed('%s: %s,' % (key_string, arg_string))48                        imports.update(key_imports)49                        imports.update(arg_imports)50                    self.unindent()51                    self.feed('},')52                else:53                    self.feed('%s=[' % _arg_name)54                    self.indent()55                    for item in _arg_value:56                        arg_string, arg_imports = MigrationWriter.serialize(item)57                        self.feed('%s,' % arg_string)58                        imports.update(arg_imports)59                    self.unindent()60                    self.feed('],')61            else:62                arg_string, arg_imports = MigrationWriter.serialize(_arg_value)63                self.feed('%s=%s,' % (_arg_name, arg_string))64                imports.update(arg_imports)65        imports = set()66        name, args, kwargs = self.operation.deconstruct()67        argspec = inspect.getargspec(self.operation.__init__)68        # See if this operation is in django.db.migrations. If it is,69        # We can just use the fact we already have that imported,70        # otherwise, we need to add an import for the operation class.71        if getattr(migrations, name, None) == self.operation.__class__:72            self.feed('migrations.%s(' % name)73        else:74            imports.add('import %s' % (self.operation.__class__.__module__))75            self.feed('%s.%s(' % (self.operation.__class__.__module__, name))76        self.indent()77        # Start at one because argspec includes "self"78        for i, arg in enumerate(args, 1):79            arg_value = arg80            arg_name = argspec.args[i]81            _write(arg_name, arg_value)82        i = len(args)83        # Only iterate over remaining arguments84        for arg_name in argspec.args[i + 1:]:85            if arg_name in kwargs:86                arg_value = kwargs[arg_name]87                _write(arg_name, arg_value)88        self.unindent()89        self.feed('),')90        return self.render(), imports91    def indent(self):92        self.indentation += 193    def unindent(self):94        self.indentation -= 195    def feed(self, line):96        self.buff.append(' ' * (self.indentation * 4) + line)97    def render(self):98        return '\n'.join(self.buff)99class MigrationWriter(object):100    """101    Takes a Migration instance and is able to produce the contents102    of the migration file from it.103    """104    def __init__(self, migration):105        self.migration = migration106        self.needs_manual_porting = False107    def as_string(self):108        """109        Returns a string of the file contents.110        """111        items = {112            "replaces_str": "",113        }114        imports = set()115        # Deconstruct operations116        operations = []117        for operation in self.migration.operations:118            operation_string, operation_imports = OperationWriter(operation).serialize()119            imports.update(operation_imports)120            operations.append(operation_string)121        items["operations"] = "\n".join(operations) + "\n" if operations else ""122        # Format dependencies and write out swappable dependencies right123        dependencies = []124        for dependency in self.migration.dependencies:125            if dependency[0] == "__setting__":126                dependencies.append("        migrations.swappable_dependency(settings.%s)," % dependency[1])127                imports.add("from django.conf import settings")128            else:129                # No need to output bytestrings for dependencies130                dependency = tuple(force_text(s) for s in dependency)131                dependencies.append("        %s," % self.serialize(dependency)[0])132        items["dependencies"] = "\n".join(dependencies) + "\n" if dependencies else ""133        # Format imports nicely, swapping imports of functions from migration files134        # for comments135        migration_imports = set()136        for line in list(imports):137            if re.match("^import (.*)\.\d+[^\s]*$", line):138                migration_imports.add(line.split("import")[1].strip())139                imports.remove(line)140                self.needs_manual_porting = True141        imports.discard("from django.db import models")142        items["imports"] = "\n".join(imports) + "\n" if imports else ""143        if migration_imports:144            items["imports"] += (145                "\n\n# Functions from the following migrations need manual "146                "copying.\n# Move them and any dependencies into this file, "147                "then update the\n# RunPython operations to refer to the local "148                "versions:\n# %s"149            ) % "\n# ".join(migration_imports)150        # If there's a replaces, make a string for it151        if self.migration.replaces:152            items['replaces_str'] = "\n    replaces = %s\n" % self.serialize(self.migration.replaces)[0]153        return (MIGRATION_TEMPLATE % items).encode("utf8")154    @staticmethod155    def serialize_datetime(value):156        """157        Returns a serialized version of a datetime object that is valid,158        executable python code. It converts timezone-aware values to utc with159        an 'executable' utc representation of tzinfo.160        """161        if value.tzinfo is not None and value.tzinfo != utc:162            value = value.astimezone(utc)163        value_repr = repr(value).replace("<UTC>", "utc")164        if isinstance(value, datetime_safe.datetime):165            value_repr = "datetime.%s" % value_repr166        return value_repr167    @property168    def filename(self):169        return "%s.py" % self.migration.name170    @property171    def path(self):172        migrations_package_name = MigrationLoader.migrations_module(self.migration.app_label)173        # See if we can import the migrations module directly174        try:175            migrations_module = import_module(migrations_package_name)176            # Python 3 fails when the migrations directory does not have a177            # __init__.py file178            if not hasattr(migrations_module, '__file__'):179                raise ImportError180            basedir = os.path.dirname(upath(migrations_module.__file__))181        except ImportError:182            app_config = apps.get_app_config(self.migration.app_label)183            migrations_package_basename = migrations_package_name.split(".")[-1]184            # Alright, see if it's a direct submodule of the app185            if '%s.%s' % (app_config.name, migrations_package_basename) == migrations_package_name:186                basedir = os.path.join(app_config.path, migrations_package_basename)187            else:188                # In case of using MIGRATION_MODULES setting and the custom189                # package doesn't exist, create one.190                package_dirs = migrations_package_name.split(".")191                create_path = os.path.join(upath(sys.path[0]), *package_dirs)192                if not os.path.isdir(create_path):193                    os.makedirs(create_path)194                for i in range(1, len(package_dirs) + 1):195                    init_dir = os.path.join(upath(sys.path[0]), *package_dirs[:i])196                    init_path = os.path.join(init_dir, "__init__.py")197                    if not os.path.isfile(init_path):198                        open(init_path, "w").close()199                return os.path.join(create_path, self.filename)200        return os.path.join(basedir, self.filename)201    @classmethod202    def serialize_deconstructed(cls, path, args, kwargs):203        name, imports = cls._serialize_path(path)204        strings = []205        for arg in args:206            arg_string, arg_imports = cls.serialize(arg)207            strings.append(arg_string)208            imports.update(arg_imports)209        for kw, arg in kwargs.items():210            arg_string, arg_imports = cls.serialize(arg)211            imports.update(arg_imports)212            strings.append("%s=%s" % (kw, arg_string))213        return "%s(%s)" % (name, ", ".join(strings)), imports214    @classmethod215    def _serialize_path(cls, path):216        module, name = path.rsplit(".", 1)217        if module == "django.db.models":218            imports = {"from django.db import models"}219            name = "models.%s" % name220        else:221            imports = {"import %s" % module}222            name = path223        return name, imports224    @classmethod225    def serialize(cls, value):226        """227        Serializes the value to a string that's parsable by Python, along228        with any needed imports to make that string work.229        More advanced than repr() as it can encode things230        like datetime.datetime.now.231        """232        # FIXME: Ideally Promise would be reconstructible, but for now we233        # use force_text on them and defer to the normal string serialization234        # process.235        if isinstance(value, Promise):236            value = force_text(value)237        # Sequences238        if isinstance(value, (list, set, tuple)):239            imports = set()240            strings = []241            for item in value:242                item_string, item_imports = cls.serialize(item)243                imports.update(item_imports)244                strings.append(item_string)245            if isinstance(value, set):246                # Don't use the literal "{%s}" as it doesn't support empty set247                format = "set([%s])"248            elif isinstance(value, tuple):249                # When len(value)==0, the empty tuple should be serialized as250                # "()", not "(,)" because (,) is invalid Python syntax.251                format = "(%s)" if len(value) != 1 else "(%s,)"252            else:253                format = "[%s]"254            return format % (", ".join(strings)), imports255        # Dictionaries256        elif isinstance(value, dict):257            imports = set()258            strings = []259            for k, v in value.items():260                k_string, k_imports = cls.serialize(k)261                v_string, v_imports = cls.serialize(v)262                imports.update(k_imports)263                imports.update(v_imports)264                strings.append((k_string, v_string))265            return "{%s}" % (", ".join("%s: %s" % (k, v) for k, v in strings)), imports266        # Datetimes267        elif isinstance(value, datetime.datetime):268            value_repr = cls.serialize_datetime(value)269            imports = ["import datetime"]270            if value.tzinfo is not None:271                imports.append("from django.utils.timezone import utc")272            return value_repr, set(imports)273        # Dates274        elif isinstance(value, datetime.date):275            value_repr = repr(value)276            if isinstance(value, datetime_safe.date):277                value_repr = "datetime.%s" % value_repr278            return value_repr, {"import datetime"}279        # Times280        elif isinstance(value, datetime.time):281            value_repr = repr(value)282            if isinstance(value, datetime_safe.time):283                value_repr = "datetime.%s" % value_repr284            return value_repr, {"import datetime"}285        # Settings references286        elif isinstance(value, SettingsReference):287            return "settings.%s" % value.setting_name, {"from django.conf import settings"}288        # Simple types289        elif isinstance(value, float):290            if math.isnan(value) or math.isinf(value):291                return 'float("{}")'.format(value), set()292            return repr(value), set()293        elif isinstance(value, six.integer_types + (bool, type(None))):294            return repr(value), set()295        elif isinstance(value, six.binary_type):296            value_repr = repr(value)297            if six.PY2:298                # Prepend the `b` prefix since we're importing unicode_literals299                value_repr = 'b' + value_repr300            return value_repr, set()301        elif isinstance(value, six.text_type):302            value_repr = repr(value)303            if six.PY2:304                # Strip the `u` prefix since we're importing unicode_literals305                value_repr = value_repr[1:]306            return value_repr, set()307        # Decimal308        elif isinstance(value, decimal.Decimal):309            return repr(value), {"from decimal import Decimal"}310        # Django fields311        elif isinstance(value, models.Field):312            attr_name, path, args, kwargs = value.deconstruct()313            return cls.serialize_deconstructed(path, args, kwargs)314        # Classes315        elif isinstance(value, type):316            special_cases = [317                (models.Model, "models.Model", []),318            ]319            for case, string, imports in special_cases:320                if case is value:321                    return string, set(imports)322            if hasattr(value, "__module__"):323                module = value.__module__324                if module == six.moves.builtins.__name__:325                    return value.__name__, set()326                else:327                    return "%s.%s" % (module, value.__name__), {"import %s" % module}328        elif isinstance(value, models.manager.BaseManager):329            as_manager, manager_path, qs_path, args, kwargs = value.deconstruct()330            if as_manager:331                name, imports = cls._serialize_path(qs_path)332                return "%s.as_manager()" % name, imports333            else:334                return cls.serialize_deconstructed(manager_path, args, kwargs)335        # Anything that knows how to deconstruct itself.336        elif hasattr(value, 'deconstruct'):337            return cls.serialize_deconstructed(*value.deconstruct())338        # Functions339        elif isinstance(value, (types.FunctionType, types.BuiltinFunctionType)):340            # @classmethod?341            if getattr(value, "__self__", None) and isinstance(value.__self__, type):342                klass = value.__self__343                module = klass.__module__344                return "%s.%s.%s" % (module, klass.__name__, value.__name__), {"import %s" % module}345            # Further error checking346            if value.__name__ == '<lambda>':347                raise ValueError("Cannot serialize function: lambda")348            if value.__module__ is None:349                raise ValueError("Cannot serialize function %r: No module" % value)350            # Python 3 is a lot easier, and only uses this branch if it's not local.351            if getattr(value, "__qualname__", None) and getattr(value, "__module__", None):352                if "<" not in value.__qualname__:  # Qualname can include <locals>353                    return "%s.%s" % (value.__module__, value.__qualname__), {"import %s" % value.__module__}354            # Python 2/fallback version355            module_name = value.__module__356            # Make sure it's actually there and not an unbound method357            module = import_module(module_name)358            if not hasattr(module, value.__name__):359                raise ValueError(360                    "Could not find function %s in %s.\n"361                    "Please note that due to Python 2 limitations, you cannot "362                    "serialize unbound method functions (e.g. a method "363                    "declared and used in the same class body). Please move "364                    "the function into the main module body to use migrations.\n"365                    "For more information, see "366                    "https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values"367                    % (value.__name__, module_name, get_docs_version()))368            return "%s.%s" % (module_name, value.__name__), {"import %s" % module_name}369        # Other iterables370        elif isinstance(value, collections.Iterable):371            imports = set()372            strings = []373            for item in value:374                item_string, item_imports = cls.serialize(item)375                imports.update(item_imports)376                strings.append(item_string)377            # When len(strings)==0, the empty iterable should be serialized as378            # "()", not "(,)" because (,) is invalid Python syntax.379            format = "(%s)" if len(strings) != 1 else "(%s,)"380            return format % (", ".join(strings)), imports381        # Compiled regex382        elif isinstance(value, COMPILED_REGEX_TYPE):383            imports = {"import re"}384            regex_pattern, pattern_imports = cls.serialize(value.pattern)385            regex_flags, flag_imports = cls.serialize(value.flags)386            imports.update(pattern_imports)387            imports.update(flag_imports)388            args = [regex_pattern]389            if value.flags:390                args.append(regex_flags)391            return "re.compile(%s)" % ', '.join(args), imports392        # Uh oh.393        else:394            raise ValueError(395                "Cannot serialize: %r\nThere are some values Django cannot serialize into "396                "migration files.\nFor more, see https://docs.djangoproject.com/en/%s/"397                "topics/migrations/#migration-serializing" % (value, get_docs_version())398            )399MIGRATION_TEMPLATE = """\400# -*- coding: utf-8 -*-401from __future__ import unicode_literals402from django.db import models, migrations403%(imports)s404class Migration(migrations.Migration):405%(replaces_str)s406    dependencies = [407%(dependencies)s\408    ]409    operations = [410%(operations)s\411    ]...__init__.py
Source:__init__.py  
...15    """16    def __init__(self, project):17        self.project = project18        self.import_tools = ImportTools(self.project)19    def organize_imports(self, resource, offset=None):20        return self._perform_command_on_import_tools(21            self.import_tools.organize_imports, resource, offset)22    def expand_star_imports(self, resource, offset=None):23        return self._perform_command_on_import_tools(24            self.import_tools.expand_stars, resource, offset)25    def froms_to_imports(self, resource, offset=None):26        return self._perform_command_on_import_tools(27            self.import_tools.froms_to_imports, resource, offset)28    def relatives_to_absolutes(self, resource, offset=None):29        return self._perform_command_on_import_tools(30            self.import_tools.relatives_to_absolutes, resource, offset)31    def handle_long_imports(self, resource, offset=None):32        return self._perform_command_on_import_tools(33            self.import_tools.handle_long_imports, resource, offset)34    def _perform_command_on_import_tools(self, method, resource, offset):35        pymodule = self.project.get_pymodule(resource)36        before_performing = pymodule.source_code37        import_filter = None38        if offset is not None:39            import_filter = self._line_filter(40                pymodule.lines.get_line_number(offset))41        result = method(pymodule, import_filter=import_filter)42        if result is not None and result != before_performing:43            changes = ChangeSet(method.__name__.replace('_', ' ') +44                                ' in <%s>' % resource.path)45            changes.add_change(ChangeContents(resource, result))46            return changes47    def _line_filter(self, lineno):48        def import_filter(import_stmt):49            return import_stmt.start_line <= lineno < import_stmt.end_line50        return import_filter51class ImportTools(object):52    def __init__(self, project):53        self.project = project54    def get_import(self, resource):55        """The import statement for `resource`"""56        module_name = libutils.modname(resource)57        return NormalImport(((module_name, None), ))58    def get_from_import(self, resource, name):59        """The from import statement for `name` in `resource`"""60        module_name = libutils.modname(resource)61        names = []62        if isinstance(name, list):63            names = [(imported, None) for imported in name]64        else:65            names = [(name, None), ]66        return FromImport(module_name, 0, tuple(names))67    def module_imports(self, module, imports_filter=None):68        return module_imports.ModuleImports(self.project, module,69                                            imports_filter)70    def froms_to_imports(self, pymodule, import_filter=None):71        pymodule = self._clean_up_imports(pymodule, import_filter)72        module_imports = self.module_imports(pymodule, import_filter)73        for import_stmt in module_imports.imports:74            if import_stmt.readonly or \75               not self._is_transformable_to_normal(import_stmt.import_info):76                continue77            pymodule = self._from_to_normal(pymodule, import_stmt)78        # Adding normal imports in place of froms79        module_imports = self.module_imports(pymodule, import_filter)80        for import_stmt in module_imports.imports:81            if not import_stmt.readonly and \82               self._is_transformable_to_normal(import_stmt.import_info):83                import_stmt.import_info = \84                    NormalImport(((import_stmt.import_info.module_name,85                                 None),))86        module_imports.remove_duplicates()87        return module_imports.get_changed_source()88    def expand_stars(self, pymodule, import_filter=None):89        module_imports = self.module_imports(pymodule, import_filter)90        module_imports.expand_stars()91        return module_imports.get_changed_source()92    def _from_to_normal(self, pymodule, import_stmt):93        resource = pymodule.get_resource()94        from_import = import_stmt.import_info95        module_name = from_import.module_name96        for name, alias in from_import.names_and_aliases:97            imported = name98            if alias is not None:99                imported = alias100            occurrence_finder = occurrences.create_finder(101                self.project, imported, pymodule[imported], imports=False)102            source = rename.rename_in_module(103                occurrence_finder, module_name + '.' + name,104                pymodule=pymodule, replace_primary=True)105            if source is not None:106                pymodule = libutils.get_string_module(107                    self.project, source, resource)108        return pymodule109    def _clean_up_imports(self, pymodule, import_filter):110        resource = pymodule.get_resource()111        module_with_imports = self.module_imports(pymodule, import_filter)112        module_with_imports.expand_stars()113        source = module_with_imports.get_changed_source()114        if source is not None:115            pymodule = libutils.get_string_module(116                self.project, source, resource)117        source = self.relatives_to_absolutes(pymodule)118        if source is not None:119            pymodule = libutils.get_string_module(120                self.project, source, resource)121        module_with_imports = self.module_imports(pymodule, import_filter)122        module_with_imports.remove_duplicates()123        module_with_imports.remove_unused_imports()124        source = module_with_imports.get_changed_source()125        if source is not None:126            pymodule = libutils.get_string_module(127                self.project, source, resource)128        return pymodule129    def relatives_to_absolutes(self, pymodule, import_filter=None):130        module_imports = self.module_imports(pymodule, import_filter)131        to_be_absolute_list = module_imports.get_relative_to_absolute_list()132        for name, absolute_name in to_be_absolute_list:133            pymodule = self._rename_in_module(pymodule, name, absolute_name)134        module_imports = self.module_imports(pymodule, import_filter)135        module_imports.get_relative_to_absolute_list()136        source = module_imports.get_changed_source()137        if source is None:138            source = pymodule.source_code139        return source140    def _is_transformable_to_normal(self, import_info):141        if not isinstance(import_info, FromImport):142            return False143        return True144    def organize_imports(self, pymodule,145                         unused=True, duplicates=True,146                         selfs=True, sort=True, import_filter=None):147        if unused or duplicates:148            module_imports = self.module_imports(pymodule, import_filter)149            if unused:150                module_imports.remove_unused_imports()151            if self.project.prefs.get("split_imports"):152                module_imports.force_single_imports()153            if duplicates:154                module_imports.remove_duplicates()155            source = module_imports.get_changed_source()156            if source is not None:157                pymodule = libutils.get_string_module(158                    self.project, source, pymodule.get_resource())159        if selfs:160            pymodule = self._remove_self_imports(pymodule, import_filter)161        if sort:162            return self.sort_imports(pymodule, import_filter)163        else:164            return pymodule.source_code165    def _remove_self_imports(self, pymodule, import_filter=None):166        module_imports = self.module_imports(pymodule, import_filter)167        to_be_fixed, to_be_renamed = \168            module_imports.get_self_import_fix_and_rename_list()169        for name in to_be_fixed:170            try:171                pymodule = self._rename_in_module(pymodule, name, '',172                                                  till_dot=True)173            except ValueError:174                # There is a self import with direct access to it175                return pymodule176        for name, new_name in to_be_renamed:177            pymodule = self._rename_in_module(pymodule, name, new_name)178        module_imports = self.module_imports(pymodule, import_filter)179        module_imports.get_self_import_fix_and_rename_list()180        source = module_imports.get_changed_source()181        if source is not None:182            pymodule = libutils.get_string_module(183                self.project, source, pymodule.get_resource())184        return pymodule185    def _rename_in_module(self, pymodule, name, new_name, till_dot=False):186        old_name = name.split('.')[-1]187        old_pyname = rope.base.evaluate.eval_str(pymodule.get_scope(), name)188        occurrence_finder = occurrences.create_finder(189            self.project, old_name, old_pyname, imports=False)190        changes = rope.base.codeanalyze.ChangeCollector(pymodule.source_code)191        for occurrence in occurrence_finder.find_occurrences(192                pymodule=pymodule):193            start, end = occurrence.get_primary_range()194            if till_dot:195                new_end = pymodule.source_code.index('.', end) + 1196                space = pymodule.source_code[end:new_end - 1].strip()197                if not space == '':198                    for c in space:199                        if not c.isspace() and c not in '\\':200                            raise ValueError()201                end = new_end202            changes.add_change(start, end, new_name)203        source = changes.get_changed()204        if source is not None:205            pymodule = libutils.get_string_module(206                self.project, source, pymodule.get_resource())207        return pymodule208    def sort_imports(self, pymodule, import_filter=None):209        module_imports = self.module_imports(pymodule, import_filter)210        module_imports.sort_imports()211        return module_imports.get_changed_source()212    def handle_long_imports(self, pymodule, maxdots=2, maxlength=27,213                            import_filter=None):214        # IDEA: `maxdots` and `maxlength` can be specified in project config215        # adding new from imports216        module_imports = self.module_imports(pymodule, import_filter)217        to_be_fixed = module_imports.handle_long_imports(maxdots, maxlength)218        # performing the renaming219        pymodule = libutils.get_string_module(220            self.project, module_imports.get_changed_source(),221            resource=pymodule.get_resource())222        for name in to_be_fixed:223            pymodule = self._rename_in_module(pymodule, name,224                                              name.split('.')[-1])225        # organizing imports226        return self.organize_imports(pymodule, selfs=False, sort=False,227                                     import_filter=import_filter)228def get_imports(project, pydefined):229    """A shortcut for getting the `ImportInfo`\s used in a scope"""230    pymodule = pydefined.get_module()231    module = module_imports.ModuleImports(project, pymodule)232    if pymodule == pydefined:233        return [stmt.import_info for stmt in module.imports]234    return module.get_used_imports(pydefined)235def get_module_imports(project, pymodule):236    """A shortcut for creating a `module_imports.ModuleImports` object"""237    return module_imports.ModuleImports(project, pymodule)238def add_import(project, pymodule, module_name, name=None):239    imports = get_module_imports(project, pymodule)240    candidates = []241    names = []242    selected_import = None243    # from mod import name244    if name is not None:245        from_import = FromImport(module_name, 0, [(name, None)])246        names.append(name)247        candidates.append(from_import)248    # from pkg import mod249    if '.' in module_name:250        pkg, mod = module_name.rsplit('.', 1)251        from_import = FromImport(pkg, 0, [(mod, None)])252        if project.prefs.get('prefer_module_from_imports'):253            selected_import = from_import...serializer.py
Source:serializer.py  
1import builtins2import collections.abc3import datetime4import decimal5import enum6import functools7import math8import re9import types10import uuid11from django.conf import SettingsReference12from django.db import models13from django.db.migrations.operations.base import Operation14from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject15from django.utils.functional import LazyObject, Promise16from django.utils.timezone import utc17from django.utils.version import get_docs_version18class BaseSerializer:19    def __init__(self, value):20        self.value = value21    def serialize(self):22        raise NotImplementedError('Subclasses of BaseSerializer must implement the serialize() method.')23class BaseSequenceSerializer(BaseSerializer):24    def _format(self):25        raise NotImplementedError('Subclasses of BaseSequenceSerializer must implement the _format() method.')26    def serialize(self):27        imports = set()28        strings = []29        for item in self.value:30            item_string, item_imports = serializer_factory(item).serialize()31            imports.update(item_imports)32            strings.append(item_string)33        value = self._format()34        return value % (", ".join(strings)), imports35class BaseSimpleSerializer(BaseSerializer):36    def serialize(self):37        return repr(self.value), set()38class DateTimeSerializer(BaseSerializer):39    """For datetime.*, except datetime.datetime."""40    def serialize(self):41        return repr(self.value), {'import datetime'}42class DatetimeDatetimeSerializer(BaseSerializer):43    """For datetime.datetime."""44    def serialize(self):45        if self.value.tzinfo is not None and self.value.tzinfo != utc:46            self.value = self.value.astimezone(utc)47        imports = ["import datetime"]48        if self.value.tzinfo is not None:49            imports.append("from django.utils.timezone import utc")50        return repr(self.value).replace('<UTC>', 'utc'), set(imports)51class DecimalSerializer(BaseSerializer):52    def serialize(self):53        return repr(self.value), {"from decimal import Decimal"}54class DeconstructableSerializer(BaseSerializer):55    @staticmethod56    def serialize_deconstructed(path, args, kwargs):57        name, imports = DeconstructableSerializer._serialize_path(path)58        strings = []59        for arg in args:60            arg_string, arg_imports = serializer_factory(arg).serialize()61            strings.append(arg_string)62            imports.update(arg_imports)63        for kw, arg in sorted(kwargs.items()):64            arg_string, arg_imports = serializer_factory(arg).serialize()65            imports.update(arg_imports)66            strings.append("%s=%s" % (kw, arg_string))67        return "%s(%s)" % (name, ", ".join(strings)), imports68    @staticmethod69    def _serialize_path(path):70        module, name = path.rsplit(".", 1)71        if module == "django.db.models":72            imports = {"from django.db import models"}73            name = "models.%s" % name74        else:75            imports = {"import %s" % module}76            name = path77        return name, imports78    def serialize(self):79        return self.serialize_deconstructed(*self.value.deconstruct())80class DictionarySerializer(BaseSerializer):81    def serialize(self):82        imports = set()83        strings = []84        for k, v in sorted(self.value.items()):85            k_string, k_imports = serializer_factory(k).serialize()86            v_string, v_imports = serializer_factory(v).serialize()87            imports.update(k_imports)88            imports.update(v_imports)89            strings.append((k_string, v_string))90        return "{%s}" % (", ".join("%s: %s" % (k, v) for k, v in strings)), imports91class EnumSerializer(BaseSerializer):92    def serialize(self):93        enum_class = self.value.__class__94        module = enum_class.__module__95        v_string, v_imports = serializer_factory(self.value.value).serialize()96        imports = {'import %s' % module, *v_imports}97        return "%s.%s(%s)" % (module, enum_class.__name__, v_string), imports98class FloatSerializer(BaseSimpleSerializer):99    def serialize(self):100        if math.isnan(self.value) or math.isinf(self.value):101            return 'float("{}")'.format(self.value), set()102        return super().serialize()103class FrozensetSerializer(BaseSequenceSerializer):104    def _format(self):105        return "frozenset([%s])"106class FunctionTypeSerializer(BaseSerializer):107    def serialize(self):108        if getattr(self.value, "__self__", None) and isinstance(self.value.__self__, type):109            klass = self.value.__self__110            module = klass.__module__111            return "%s.%s.%s" % (module, klass.__name__, self.value.__name__), {"import %s" % module}112        # Further error checking113        if self.value.__name__ == '<lambda>':114            raise ValueError("Cannot serialize function: lambda")115        if self.value.__module__ is None:116            raise ValueError("Cannot serialize function %r: No module" % self.value)117        module_name = self.value.__module__118        if '<' not in self.value.__qualname__:  # Qualname can include <locals>119            return '%s.%s' % (module_name, self.value.__qualname__), {'import %s' % self.value.__module__}120        raise ValueError(121            'Could not find function %s in %s.\n' % (self.value.__name__, module_name)122        )123class FunctoolsPartialSerializer(BaseSerializer):124    def serialize(self):125        # Serialize functools.partial() arguments126        func_string, func_imports = serializer_factory(self.value.func).serialize()127        args_string, args_imports = serializer_factory(self.value.args).serialize()128        keywords_string, keywords_imports = serializer_factory(self.value.keywords).serialize()129        # Add any imports needed by arguments130        imports = {'import functools', *func_imports, *args_imports, *keywords_imports}131        return (132            'functools.%s(%s, *%s, **%s)' % (133                self.value.__class__.__name__,134                func_string,135                args_string,136                keywords_string,137            ),138            imports,139        )140class IterableSerializer(BaseSerializer):141    def serialize(self):142        imports = set()143        strings = []144        for item in self.value:145            item_string, item_imports = serializer_factory(item).serialize()146            imports.update(item_imports)147            strings.append(item_string)148        # When len(strings)==0, the empty iterable should be serialized as149        # "()", not "(,)" because (,) is invalid Python syntax.150        value = "(%s)" if len(strings) != 1 else "(%s,)"151        return value % (", ".join(strings)), imports152class ModelFieldSerializer(DeconstructableSerializer):153    def serialize(self):154        attr_name, path, args, kwargs = self.value.deconstruct()155        return self.serialize_deconstructed(path, args, kwargs)156class ModelManagerSerializer(DeconstructableSerializer):157    def serialize(self):158        as_manager, manager_path, qs_path, args, kwargs = self.value.deconstruct()159        if as_manager:160            name, imports = self._serialize_path(qs_path)161            return "%s.as_manager()" % name, imports162        else:163            return self.serialize_deconstructed(manager_path, args, kwargs)164class OperationSerializer(BaseSerializer):165    def serialize(self):166        from django.db.migrations.writer import OperationWriter167        string, imports = OperationWriter(self.value, indentation=0).serialize()168        # Nested operation, trailing comma is handled in upper OperationWriter._write()169        return string.rstrip(','), imports170class RegexSerializer(BaseSerializer):171    def serialize(self):172        regex_pattern, pattern_imports = serializer_factory(self.value.pattern).serialize()173        # Turn off default implicit flags (e.g. re.U) because regexes with the174        # same implicit and explicit flags aren't equal.175        flags = self.value.flags ^ re.compile('').flags176        regex_flags, flag_imports = serializer_factory(flags).serialize()177        imports = {'import re', *pattern_imports, *flag_imports}178        args = [regex_pattern]179        if flags:180            args.append(regex_flags)181        return "re.compile(%s)" % ', '.join(args), imports182class SequenceSerializer(BaseSequenceSerializer):183    def _format(self):184        return "[%s]"185class SetSerializer(BaseSequenceSerializer):186    def _format(self):187        # Serialize as a set literal except when value is empty because {}188        # is an empty dict.189        return '{%s}' if self.value else 'set(%s)'190class SettingsReferenceSerializer(BaseSerializer):191    def serialize(self):192        return "settings.%s" % self.value.setting_name, {"from django.conf import settings"}193class TupleSerializer(BaseSequenceSerializer):194    def _format(self):195        # When len(value)==0, the empty tuple should be serialized as "()",196        # not "(,)" because (,) is invalid Python syntax.197        return "(%s)" if len(self.value) != 1 else "(%s,)"198class TypeSerializer(BaseSerializer):199    def serialize(self):200        special_cases = [201            (models.Model, "models.Model", []),202            (type(None), 'type(None)', []),203        ]204        for case, string, imports in special_cases:205            if case is self.value:206                return string, set(imports)207        if hasattr(self.value, "__module__"):208            module = self.value.__module__209            if module == builtins.__name__:210                return self.value.__name__, set()211            else:212                return "%s.%s" % (module, self.value.__name__), {"import %s" % module}213class UUIDSerializer(BaseSerializer):214    def serialize(self):215        return "uuid.%s" % repr(self.value), {"import uuid"}216class Serializer:217    _registry = {218        # Some of these are order-dependent.219        frozenset: FrozensetSerializer,220        list: SequenceSerializer,221        set: SetSerializer,222        tuple: TupleSerializer,223        dict: DictionarySerializer,224        enum.Enum: EnumSerializer,225        datetime.datetime: DatetimeDatetimeSerializer,226        (datetime.date, datetime.timedelta, datetime.time): DateTimeSerializer,227        SettingsReference: SettingsReferenceSerializer,228        float: FloatSerializer,229        (bool, int, type(None), bytes, str, range): BaseSimpleSerializer,230        decimal.Decimal: DecimalSerializer,231        (functools.partial, functools.partialmethod): FunctoolsPartialSerializer,232        (types.FunctionType, types.BuiltinFunctionType, types.MethodType): FunctionTypeSerializer,233        collections.abc.Iterable: IterableSerializer,234        (COMPILED_REGEX_TYPE, RegexObject): RegexSerializer,235        uuid.UUID: UUIDSerializer,236    }237    @classmethod238    def register(cls, type_, serializer):239        if not issubclass(serializer, BaseSerializer):240            raise ValueError("'%s' must inherit from 'BaseSerializer'." % serializer.__name__)241        cls._registry[type_] = serializer242    @classmethod243    def unregister(cls, type_):244        cls._registry.pop(type_)245def serializer_factory(value):246    if isinstance(value, Promise):247        value = str(value)248    elif isinstance(value, LazyObject):249        # The unwrapped value is returned as the first item of the arguments250        # tuple.251        value = value.__reduce__()[1][0]252    if isinstance(value, models.Field):253        return ModelFieldSerializer(value)254    if isinstance(value, models.manager.BaseManager):255        return ModelManagerSerializer(value)256    if isinstance(value, Operation):257        return OperationSerializer(value)258    if isinstance(value, type):259        return TypeSerializer(value)260    # Anything that knows how to deconstruct itself.261    if hasattr(value, 'deconstruct'):262        return DeconstructableSerializer(value)263    for type_, serializer_cls in Serializer._registry.items():264        if isinstance(value, type_):265            return serializer_cls(value)266    raise ValueError(267        "Cannot serialize: %r\nThere are some values Django cannot serialize into "268        "migration files.\nFor more, see https://docs.djangoproject.com/en/%s/"269        "topics/migrations/#migration-serializing" % (value, get_docs_version())...replace-imports.test.js
Source:replace-imports.test.js  
1const path = require('path');2const cloneDeep = require('lodash/cloneDeep');3const toVfile = require('to-vfile');4const selectAll = require('unist-util-select').selectAll;5const originalImportsExtraAST = require('../__fixtures__/ast-imports-extra.json');6const originalImportsTwoAST = require('../__fixtures__/ast-imports-two.json');7const originalImportsAST = require('../__fixtures__/ast-imports.json');8const originalMarkerAST = require('../__fixtures__/ast-marker-imports.json');9const originalSimpleAST = require('../__fixtures__/ast-simple.json');10const addImports = require('./replace-imports');11describe('replace-imports', () => {12  let importsAST;13  let importsTwoAST;14  let importsExtraAST;15  let simpleAST;16  let markerAST;17  let correctFile;18  let incorrectFile;19  beforeEach(() => {20    importsAST = cloneDeep(originalImportsAST);21    importsTwoAST = cloneDeep(originalImportsTwoAST);22    importsExtraAST = cloneDeep(originalImportsExtraAST);23    simpleAST = cloneDeep(originalSimpleAST);24    markerAST = cloneDeep(originalMarkerAST);25    correctFile = toVfile(26      path.resolve(__dirname, '../__fixtures__/with-imports.md')27    );28    incorrectFile = toVfile(29      path.resolve(__dirname, '../__fixtures__/incorrect-path/with-imports.md')30    );31  });32  it('should return a function', () => {33    expect.assertions(1);34    const plugin = addImports();35    expect(typeof plugin).toEqual('function');36  });37  it('should fail when the imported file is null', done => {38    const plugin = addImports();39    const next = err => {40      if (err) {41        done();42      } else {43        done('An error should have been thrown by addImports');44      }45    };46    plugin(importsAST, null, next);47  });48  it('should proceed when the imported file exists', done => {49    const plugin = addImports();50    plugin(importsAST, correctFile, done);51  });52  it('should fail when the imported file cannot be found', done => {53    expect.assertions(1);54    console.error = jest.fn();55    const plugin = addImports();56    // we have to rely on the next callback, because that is how you get error57    // messages out of transformers58    const next = err => {59      if (err) {60        expect(console.error).toHaveBeenCalledTimes(2);61        done();62      } else {63        done('An error should have been thrown by addImports');64      }65    };66    plugin(importsAST, incorrectFile, next);67  });68  it('should modify the tree when there are imports', done => {69    expect.assertions(1);70    const plugin = addImports();71    const next = err => {72      if (err) {73        done(err);74      } else {75        expect(importsAST).not.toEqual(originalImportsAST);76        done();77      }78    };79    plugin(importsAST, correctFile, next);80  });81  it('should NOT modify the tree when there are NO imports', done => {82    expect.assertions(1);83    const plugin = addImports();84    const next = err => {85      if (err) {86        done(err);87      } else {88        expect(simpleAST).toEqual(originalSimpleAST);89        done();90      }91    };92    plugin(simpleAST, correctFile, next);93  });94  it('should remove all import statements', done => {95    expect.assertions(2);96    const selector = 'leafDirective[name=import]';97    const plugin = addImports();98    const importNodes = selectAll(selector, importsAST);99    expect(importNodes.length).toBe(1);100    const next = err => {101      if (err) {102        done(err);103      } else {104        const importNodes = selectAll(selector, importsAST);105        expect(importNodes.length).toBe(0);106        done();107      }108    };109    plugin(importsAST, correctFile, next);110  });111  it('should not remove an ::import without the required attributes', done => {112    expect.assertions(2);113    const selector = 'leafDirective[name=import]';114    const plugin = addImports();115    const importNodes = selectAll(selector, importsExtraAST);116    expect(importNodes.length).toBe(3);117    const next = err => {118      if (err) {119        done(err);120      } else {121        const importNodes = selectAll(selector, importsExtraAST);122        expect(importNodes.length).toBe(1);123        done();124      }125    };126    plugin(importsExtraAST, correctFile, next);127  });128  it('should remove all matching ::use statements', done => {129    expect.assertions(2);130    const selector = 'leafDirective[name=use]';131    const plugin = addImports();132    const components = selectAll(selector, importsAST);133    // one matching component and two other jsx nodes134    expect(components.length).toBe(1);135    const next = err => {136      if (err) {137        done(err);138      } else {139        const components = selectAll(selector, importsAST);140        expect(components.length).toBe(0);141        done();142      }143    };144    plugin(importsAST, correctFile, next);145  });146  it('should replace the ::use statement with the imported content', done => {147    // checks the contents of script.md are there after the import step148    expect.assertions(2);149    const plugin = addImports();150    const next = err => {151      if (err) {152        done(err);153      } else {154        const jsNodes = selectAll('code[lang=js]', importsAST);155        expect(jsNodes.length).toBe(4);156        const codeValues = jsNodes.map(({ value }) => value);157        expect(codeValues).toEqual(158          expect.arrayContaining([159            `for (let index = 0; index < array.length; index++) {160  const element = array[index];161  // imported from script.md162}`163          ])164        );165        done();166      }167    };168    plugin(importsAST, correctFile, next);169  });170  it('should handle multiple import statements', done => {171    // checks the contents of script.md are there after the import step172    expect.assertions(4);173    const plugin = addImports();174    const next = err => {175      if (err) {176        done(err);177      } else {178        const jsNodes = selectAll('code[lang=js]', importsTwoAST);179        expect(jsNodes.length).toBe(4);180        const codeValues = jsNodes.map(({ value }) => value);181        expect(codeValues).toEqual(182          expect.arrayContaining([183            `for (let index = 0; index < array.length; index++) {184  const element = array[index];185  // imported from script.md186}`187          ])188        );189        const cssNodes = selectAll('code[lang=css]', importsTwoAST);190        expect(cssNodes.length).toBe(2);191        const cssValues = cssNodes.map(({ value }) => value);192        expect(cssValues).toEqual(193          expect.arrayContaining([194            `div {195  background: red196}`197          ])198        );199        done();200      }201    };202    plugin(importsTwoAST, correctFile, next);203  });204  it('should reject imported files with editable region markers', done => {205    expect.assertions(1);206    console.error = jest.fn();207    const plugin = addImports();208    const next = err => {209      if (err) {210        expect(console.error).toHaveBeenCalledTimes(2);211        done();212      } else {213        done('An error should have been thrown by addImports');214      }215    };216    plugin(markerAST, correctFile, next);217  });218  it('should have an output to match the snapshot', done => {219    const plugin = addImports();220    const next = err => {221      if (err) {222        done(err);223      } else {224        expect(importsAST).toMatchSnapshot();225        done();226      }227    };228    plugin(importsAST, correctFile, next);229  });...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
