from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import pandas

from .dataframe import DataFrame


def concat(
    objs,
    axis=0,
    join="outer",
    join_axes=None,
    ignore_index=False,
    keys=None,
    levels=None,
    names=None,
    verify_integrity=False,
    copy=True,
    sort=False,
):
    if keys is not None:
        objs = [objs[k] for k in keys]
    else:
        objs = list(objs)
    if len(objs) == 0:
        raise ValueError("No objects to concatenate")

    objs = [obj for obj in objs if obj is not None]

    if len(objs) == 0:
        raise ValueError("All objects passed were None")

    try:
        type_check = next(
            obj
            for obj in objs
            if not isinstance(obj, (pandas.Series, pandas.DataFrame, DataFrame))
        )
    except StopIteration:
        type_check = None
    if type_check is not None:
        raise ValueError(
            'cannot concatenate object of type "{0}"; only '
            "pandas.Series, pandas.DataFrame, "
            "and modin.pandas.DataFrame objs are "
            "valid",
            type(type_check),
        )
    all_series = all(isinstance(obj, pandas.Series) for obj in objs)
    if all_series:
        return DataFrame(
            pandas.concat(
                objs,
                axis,
                join,
                join_axes,
                ignore_index,
                keys,
                levels,
                names,
                verify_integrity,
                copy,
                sort,
            )
        )
    if isinstance(objs, dict):
        raise NotImplementedError(
            "Obj as dicts not implemented. To contribute to "
            "Modin, please visit github.com/ray-project/ray."
        )
    axis = pandas.DataFrame()._get_axis_number(axis)

    if join not in ["inner", "outer"]:
        raise ValueError(
            "Only can inner (intersect) or outer (union) join the" " other axis"
        )
    # We have the weird Series and axis check because, when concatenating a
    # dataframe to a series on axis=0, pandas ignores the name of the series,
    # and this check aims to mirror that (possibly buggy) functionality
    objs = [
        obj
        if isinstance(obj, DataFrame)
        else DataFrame(obj.rename())
        if isinstance(obj, pandas.Series) and axis == 0
        else DataFrame(obj)
        for obj in objs
    ]
    df = objs[0]
    objs = [obj._query_compiler for obj in objs]
    new_manager = df._query_compiler.concat(
        axis,
        objs[1:],
        join=join,
        join_axes=None,
        ignore_index=False,
        keys=None,
        levels=None,
        names=None,
        verify_integrity=False,
        copy=True,
        sort=False,
    )
    return DataFrame(query_compiler=new_manager)

@@ -117,16 +117,41 @@
  pandas%0A
+from pandas import compat
 %0Afrom .d
@@ -346,24 +346,39 @@
 rity=False,%0A
+    sort=None,%0A
     copy=Tru
@@ -384,105 +384,321 @@
 ue,%0A
+):%0A
     
-sort=False,%0A):%0A    if keys is not None:%0A        objs = %5Bobjs%5Bk%5D for k in keys%5D%0A    else:%0A    
+if isinstance(%0A        objs, (pandas.Series, DataFrame, compat.string_types, pandas.DataFrame)%0A    ):%0A        raise TypeError(%0A            %22first argument must be an iterable of pandas %22%0A            %22objects, you passed an object of type %22%0A            '%22%7Bname%7D%22'.format(name=type(objs).__name__)%0A        )%0A
     
@@ -922,25 +922,24 @@
 were None%22)%0A
-%0A
     try:%0A   
@@ -1810,20 +1810,20 @@
         
-copy
+sort
 ,%0A      
@@ -1824,36 +1824,36 @@
                 
-sort
+copy
 ,%0A            )%0A
@@ -2782,25 +2782,463 @@
 js%5D%0A    
-new_manag
+if keys is not None:%0A        objs = %5Bobjs%5Bi%5D for i in range(min(len(objs), len(keys)))%5D%0A        new_idx_labels = %7B%0A            keys%5Bi%5D: objs%5Bi%5D.index if axis == 0 else objs%5Bi%5D.columns%0A            for i in range(len(objs))%0A        %7D%0A        print(new_idx_labels)%0A        tuples = %5B(k, o) for k, obj in new_idx_labels.items() for o in obj%5D%0A        new_idx = pandas.MultiIndex.from_tuples(tuples)%0A    else:%0A        new_idx = None%0A    new_query_compil
 er = df.
@@ -3503,28 +3503,33 @@
     )%0A    re
-turn
+sult_df =
  DataFrame(q
@@ -3550,13 +3550,183 @@
 new_
-manager)
+query_compiler)%0A    if new_idx is not None:%0A        if axis == 0:%0A            result_df.index = new_idx%0A        else:%0A            result_df.columns = new_idx%0A    return result_df
 %0A

Fix bug in concat where keys were improperly assigned (#317)