diff --git a/CMake/VTKConfig.cmake.in b/CMake/VTKConfig.cmake.in
index 8042930a7bdde23ecb4f5e7ee2fc8a46c4a15fbe..3102900ff2680b2028992020c297a7a7ea228d67 100644
--- a/CMake/VTKConfig.cmake.in
+++ b/CMake/VTKConfig.cmake.in
@@ -83,6 +83,7 @@ SET(VTK_WRAP_PYTHON "@VTK_WRAP_PYTHON@")
 SET(VTK_WRAP_TCL "@VTK_WRAP_TCL@")
 SET(VTK_WRAP_JAVA "@VTK_WRAP_JAVA@")
 SET(VTK_QT_VERSION "@VTK_QT_VERSION@")
+SET(VTK_ENABLE_KITS "@VTK_ENABLE_KITS@")
 
 # Do not add options or information here that is specific to a
 # particular module.  Instead set <module>_EXPORT_OPTIONS and/or
diff --git a/CMake/vtkModuleTop.cmake b/CMake/vtkModuleTop.cmake
index d10dd488b97978b24ac6f92f67440dfc9c3fd0e4..53adb15fbd0a806ed579594da8c674b7a7db69e7 100644
--- a/CMake/vtkModuleTop.cmake
+++ b/CMake/vtkModuleTop.cmake
@@ -238,6 +238,8 @@ if(VTK_ENABLE_KITS)
     endforeach()
   endforeach()
 
+  list(REMOVE_DUPLICATES vtk_kits)
+
   # Put all kits in the list (if they are not dependencies of any module, they
   # will be dropped otherwise).
   list(APPEND vtk_modules_and_kits ${vtk_kits})
diff --git a/CMake/vtkPythonWrapping.cmake b/CMake/vtkPythonWrapping.cmake
index 217dfcf09632c5eb7309a40af8d7423a1173a413..1f6497efc007fa03937673832e77a711c97a8160 100644
--- a/CMake/vtkPythonWrapping.cmake
+++ b/CMake/vtkPythonWrapping.cmake
@@ -8,7 +8,34 @@ if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND)
    endif()
 endif()
 
-function(vtk_add_python_wrapping module_name)
+# To support wrapping of either module or kit, this function
+# has two signatures:
+# 1) vtk_add_python_wrapping(<module_name> <sources_var>)
+# 2) vtk_add_python_wrapping("<module_name>[ <module_name>]" <sources_var> <kit_name>)
+#
+# Legacy code may call this function with a single argument. In that case,
+# vtk_add_python_wrapping_library() is called internally to maintain backwards
+# compatibility.
+function(vtk_add_python_wrapping module_names)
+  if(${ARGC} EQUAL 1)
+    set(_legacy TRUE)
+    message(AUTHOR_WARNING
+      "Calling vtk_add_python_wrapping() with a single argument is deprecated.\n"
+      "Replace calls like:\n"
+      "    vtk_add_python_wrapping(\${module})\n"
+      "with:\n"
+      "    vtk_add_python_wrapping(\${module} module_srcs)\n"
+      "    vtk_add_python_wrapping_library(\${module} module_srcs \${module})")
+  endif()
+  if("${ARGV1}" MATCHES ".+")
+    set(sources_var ${ARGV1})
+  endif()
+  if("${ARGV2}" MATCHES ".+")
+    list(REMOVE_AT ARGN 0)
+    set(target ${ARGN})
+  else()
+    set(target ${module_names})
+  endif()
   if(NOT VTK_WRAP_PYTHON_INIT_EXE)
     if(TARGET vtkWrapPythonInit)
       set (VTK_WRAP_PYTHON_INIT_EXE vtkWrapPythonInit)
@@ -16,6 +43,37 @@ function(vtk_add_python_wrapping module_name)
       message(FATAL_ERROR "VTK must be built with Python wrapping turned on.")
     endif()
   endif()
+
+  set(EXTRA_PYTHON_INCLUDE_DIRS)
+  set(KIT_HIERARCHY_FILE)
+  set(VTK_WRAP_HINTS_FILES)
+
+  foreach(module_name IN LISTS module_names)
+    list(APPEND EXTRA_PYTHON_INCLUDE_DIRS ${${module_name}_PYTHON_INCLUDE_DIRS})
+
+    if(NOT ${module_name}_EXCLUDE_FROM_WRAP_HIERARCHY)
+      list(APPEND KIT_HIERARCHY_FILE ${${module_name}_WRAP_HIERARCHY_FILE})
+    endif()
+
+    if(${module_name}_WRAP_HINTS AND EXISTS "${${module_name}_WRAP_HINTS}")
+      list(APPEND VTK_WRAP_HINTS_FILES "${${module_name}_WRAP_HINTS}")
+    endif()
+  endforeach()
+
+  if(VTK_WRAP_HINTS_FILES)
+    set(VTK_WRAP_HINTS ${VTK_WRAP_HINTS_FILES})
+  endif()
+
+  vtk_wrap_python(${target}Python Python_SRCS "${module_names}")
+  if(_legacy)
+    set(_sources "${Python_SRCS}" "${extra_srcs}")
+    vtk_add_python_wrapping_library(${module_names} _sources ${module_names})
+  else()
+    set(${sources_var} "${Python_SRCS}" "${extra_srcs}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+function(vtk_add_python_wrapping_library module srcs)
   # Need to add the Wrapping/Python to the include directory
   set(_python_include_dirs
     ${VTK_SOURCE_DIR}/Wrapping/Python
@@ -23,57 +81,52 @@ function(vtk_add_python_wrapping module_name)
     ${VTK_SOURCE_DIR}/Utilities/Python
     ${VTK_BINARY_DIR}/Utilities/Python
     ${PYTHON_INCLUDE_DIRS})
+  set(XY ${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION})
 
   if(NOT CMAKE_HAS_TARGET_INCLUDES)
     include_directories(${_python_include_dirs})
   endif()
 
-  if(NOT ${module_name}_EXCLUDE_FROM_WRAP_HIERARCHY)
-    set(KIT_HIERARCHY_FILE ${${module_name}_WRAP_HIERARCHY_FILE})
-  endif()
-
-  string(REGEX REPLACE "^vtk" "" kit_name "${module_name}")
-  set(KIT ${kit_name})
-  set(XY ${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION})
-
   # Figure out the dependent PythonXYD libraries for the module
-  unset(extra_links)
-  set(EXTRA_PYTHON_INCLUDE_DIRS ${${module_name}_PYTHON_INCLUDE_DIRS})
-  foreach(dep ${${module_name}_DEPENDS})
-    if(NOT "${module_name}" STREQUAL "${dep}" AND TARGET ${dep}PythonD)
+  set(extra_links)
+  foreach(dep IN LISTS ${module}_DEPENDS)
+    if(NOT "${module}" STREQUAL "${dep}" AND TARGET ${dep}PythonD)
       list(APPEND extra_links ${dep}PythonD)
     endif()
   endforeach()
 
-  if(${module_name}_WRAP_HINTS AND EXISTS "${${module_name}_WRAP_HINTS}")
-    set(VTK_WRAP_HINTS "${${module_name}_WRAP_HINTS}")
-  endif()
-
-  vtk_wrap_python(${module_name}Python Python_SRCS ${module_name})
-  vtk_add_library(${module_name}PythonD ${Python_SRCS} ${extra_srcs})
-  get_property(output_name TARGET ${module_name}PythonD PROPERTY OUTPUT_NAME)
+  vtk_add_library(${module}PythonD ${${srcs}})
+  get_property(output_name TARGET ${module}PythonD PROPERTY OUTPUT_NAME)
   string(REPLACE "PythonD" "Python${XY}D" output_name "${output_name}")
-  set_property(TARGET ${module_name}PythonD PROPERTY OUTPUT_NAME ${output_name})
+  set_property(TARGET ${module}PythonD PROPERTY OUTPUT_NAME ${output_name})
   if(CMAKE_HAS_TARGET_INCLUDES)
-    set_property(TARGET ${module_name}PythonD APPEND
+    set_property(TARGET ${module}PythonD APPEND
       PROPERTY INCLUDE_DIRECTORIES ${_python_include_dirs})
   endif()
-  if(${module_name}_IMPLEMENTS)
-    set_property(TARGET ${module_name}PythonD PROPERTY COMPILE_DEFINITIONS
-      "${module_name}_AUTOINIT=1(${module_name})")
-  endif()
-  target_link_libraries(${module_name}PythonD LINK_PUBLIC ${module_name}
+  target_link_libraries(${module}PythonD LINK_PUBLIC
     vtkWrappingPythonCore ${extra_links} ${VTK_PYTHON_LIBRARIES})
 
   if (MSVC)
-    set_target_properties(${module_name}PythonD
+    set_target_properties(${module}PythonD
       PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_MODULE_LINKER_FLAGS})
   endif()
 
-  _vtk_add_python_module(${module_name}Python ${module_name}PythonInit.cxx)
-  target_link_libraries(${module_name}Python ${module_name}PythonD)
+  foreach (submodule IN LISTS ARGN)
+    if(${submodule}_IMPLEMENTS)
+      set_property(TARGET ${module}PythonD APPEND PROPERTY COMPILE_DEFINITIONS
+        "${submodule}_AUTOINIT=1(${submodule})")
+    endif()
+    target_link_libraries(${module}PythonD LINK_PUBLIC ${submodule})
+  endforeach ()
+
+  set(prefix ${module})
+  if(_${module}_is_kit)
+    set(prefix ${prefix}${VTK_KIT_SUFFIX})
+  endif()
+  _vtk_add_python_module(${module}Python ${prefix}PythonInit.cxx)
+  target_link_libraries(${module}Python ${module}PythonD)
   if(CMAKE_HAS_TARGET_INCLUDES)
-    set_property(TARGET ${module_name}Python APPEND
+    set_property(TARGET ${module}Python APPEND
       PROPERTY INCLUDE_DIRECTORIES ${_python_include_dirs})
   endif()
 endfunction()
diff --git a/CMake/vtkWrapPython.cmake b/CMake/vtkWrapPython.cmake
index e550a6c0a69d551018edf4771b46b0e29cc69810..eecb44c2dc7f487bca5fe93e38bf9c3d1623b137 100644
--- a/CMake/vtkWrapPython.cmake
+++ b/CMake/vtkWrapPython.cmake
@@ -36,12 +36,12 @@ macro(VTK_WRAP_PYTHON3 TARGET SRC_LIST_NAME SOURCES)
 
   # collect the common wrapper-tool arguments
   set(_common_args)
-  if(VTK_WRAP_HINTS)
-    set(_common_args "${_common_args}--hints \"${VTK_WRAP_HINTS}\"\n")
-  endif()
-  if(KIT_HIERARCHY_FILE)
-    set(_common_args "${_common_args}--types \"${KIT_HIERARCHY_FILE}\"\n")
-  endif()
+  foreach(file IN LISTS VTK_WRAP_HINTS)
+    set(_common_args "${_common_args}--hints \"${file}\"\n")
+  endforeach()
+  foreach(file IN LISTS KIT_HIERARCHY_FILE)
+    set(_common_args "${_common_args}--types \"${file}\"\n")
+  endforeach()
 
   if(NOT CMAKE_VERSION VERSION_LESS 3.1 AND NOT VTK_ENABLE_KITS)
     # write wrapper-tool arguments to a file
@@ -56,13 +56,21 @@ $<$<BOOL:$<TARGET_PROPERTY:${TARGET},INCLUDE_DIRECTORIES>>:
 ")
   else()
     # all the include directories
-    string(REGEX REPLACE "Python\$" "" module "${TARGET}")
-    if(${module}_INCLUDE_DIRS)
-      set(TMP_INCLUDE_DIRS ${${module}_INCLUDE_DIRS})
-    elseif(VTK_WRAP_INCLUDE_DIRS)
-      set(TMP_INCLUDE_DIRS ${VTK_WRAP_INCLUDE_DIRS})
+    set(TMP_INCLUDE_DIRS)
+    set(_modules ${ARGN})
+    if(NOT _modules)
+      string(REGEX REPLACE "Python\$" "" module "${TARGET}")
+      set(_modules ${module})
+    endif()
+    foreach(module IN LISTS ${_modules})
+      if(${module}_INCLUDE_DIRS)
+        list(APPEND TMP_INCLUDE_DIRS ${${module}_INCLUDE_DIRS})
+      endif()
+    endforeach()
+    if(VTK_WRAP_INCLUDE_DIRS)
+      list(APPEND TMP_INCLUDE_DIRS ${VTK_WRAP_INCLUDE_DIRS})
     else()
-      set(TMP_INCLUDE_DIRS ${VTK_INCLUDE_DIRS})
+      list(APPEND TMP_INCLUDE_DIRS ${VTK_INCLUDE_DIRS})
     endif()
     if(EXTRA_PYTHON_INCLUDE_DIRS)
       list(APPEND TMP_INCLUDE_DIRS ${EXTRA_PYTHON_INCLUDE_DIRS})
@@ -220,11 +228,13 @@ macro(vtk_find_header header include_dirs full_path)
   endforeach()
 endmacro()
 
-# Macro that just takes the name of the module, figure the rest out from there.
-macro(vtk_wrap_python TARGET SRC_LIST_NAME module)
+# Macro that just takes the a list of module names, figure the rest out from there.
+macro(vtk_wrap_python TARGET SRC_LIST_NAME)
   # List of all headers to wrap.
   set(headers_to_wrap)
 
+  foreach(module ${ARGN})
+
   # Decide what to do for each header.
   foreach(header ${${module}_HEADERS})
     # Everything in this block is for headers that will be wrapped.
@@ -241,6 +251,8 @@ macro(vtk_wrap_python TARGET SRC_LIST_NAME module)
     endif()
   endforeach()
 
+  endforeach() # end ARGN loop
+
   # Delegate to vtk_wrap_python3
-  vtk_wrap_python3(${TARGET} ${SRC_LIST_NAME} "${headers_to_wrap}")
+  vtk_wrap_python3(${TARGET} ${SRC_LIST_NAME} "${headers_to_wrap}" ${ARGN})
 endmacro()
diff --git a/Wrapping/Python/CMakeLists.txt b/Wrapping/Python/CMakeLists.txt
index ff9706e8927e29bc8b7673bcb7aaf73a7f48cdf5..1e8ab79095012034fe40803c27a7d6c334d989f4 100644
--- a/Wrapping/Python/CMakeLists.txt
+++ b/Wrapping/Python/CMakeLists.txt
@@ -29,21 +29,143 @@ macro(vtk_include_recurse module)
   include_directories(${${module}_PYTHON_INCLUDE_DIRS})
 endmacro()
 
-# Loop through all modules that should be wrapped, and wrap them.
-foreach(module ${VTK_PYTHON_MODULES})
-  vtk_module_load(${module})
-  vtk_module_headers_load(${module})
-  vtk_include_recurse(${module})
-  vtk_add_python_wrapping(${module})
-endforeach()
+
+set(VTK_PYTHON_MODULES_AND_KITS ${VTK_PYTHON_MODULES})
+set(_vtk_python_modules_only ${VTK_PYTHON_MODULES})
+
+if(VTK_ENABLE_KITS)
+  set(_vtk_kits_with_suffix)
+  set(VTK_KIT_SUFFIX "Kit") # Required to avoid conflict with targets like vtkFiltersPython
+  # Create list of module that do not belong to any kits
+  foreach(kit IN LISTS vtk_kits)
+    # XXX Variable '_${kit}_modules' is set in vtkModuleTop.cmake
+    list(REMOVE_ITEM _vtk_python_modules_only ${_${kit}_modules})
+    list(APPEND _vtk_kits_with_suffix ${kit}${VTK_KIT_SUFFIX})
+  endforeach()
+  set(VTK_PYTHON_MODULES_AND_KITS ${_vtk_kits_with_suffix} ${_vtk_python_modules_only})
+
+  # Create dependency lists for kits (suffix: _DEPENDS). The function
+  # vtk_add_python_wrapping_libary uses these lists.
+  #
+  # Additionally, create subsets of the full dependency lists that contain only
+  # Python-wrapped kits and modules (suffix: _PYTHON_DEPENDS). These lists are
+  # used to topologically sort the dependency graph.
+  foreach(kit IN LISTS vtk_kits)
+    set(_module_depends)
+    foreach(module IN LISTS _${kit}_modules)
+      vtk_module_load(${module})
+      list(APPEND _module_depends ${${module}_DEPENDS})
+    endforeach()
+
+    set(_kit_depends)
+    foreach(dep IN LISTS _module_depends)
+      if(${dep}_KIT)
+        list(APPEND _kit_depends ${${dep}_KIT}${VTK_KIT_SUFFIX})
+      else()
+        list(APPEND _kit_depends ${dep})
+      endif()
+    endforeach()
+    list(REMOVE_DUPLICATES _kit_depends)
+    set(${kit}${VTK_KIT_SUFFIX}_DEPENDS ${_kit_depends})
+
+    set(_kit_python_depends)
+    foreach(module IN LISTS ${kit}${VTK_KIT_SUFFIX}_DEPENDS)
+      list(FIND VTK_PYTHON_MODULES_AND_KITS ${module} _module_index)
+      if (_module_index GREATER -1)
+        list(APPEND _kit_python_depends ${module})
+      endif()
+    endforeach()
+    list(REMOVE_DUPLICATES _kit_python_depends)
+    set(${kit}${VTK_KIT_SUFFIX}_PYTHON_DEPENDS ${_kit_python_depends})
+  endforeach()
+
+  # Create dependency lists for modules that also consider any dependent kits
+  # (suffix: _DEPENDS_WITH_KITS). These lists are used to override
+  # <module>_DEPENDS when calling vtk_add_python_wrapping_library.
+  #
+  # Additionally, create subsets of the full dependency lists that contain only
+  # Python-wrapped kits and modules (suffix: _PYTHON_DEPENDS). These lists are
+  # used to topologically sort the dependency graph.
+  foreach(module IN LISTS _vtk_python_modules_only)
+    vtk_module_load(${module})
+    set(_saved_${module}_DEPENDS ${${module}_DEPENDS})
+
+    set(_module_depends_with_kits)
+    foreach(dep IN LISTS ${module}_DEPENDS)
+      if(${dep}_KIT)
+        list(APPEND _module_depends_with_kits ${${dep}_KIT}${VTK_KIT_SUFFIX})
+      else()
+        list(APPEND _module_depends_with_kits ${dep})
+      endif()
+    endforeach()
+    list(REMOVE_DUPLICATES _module_depends_with_kits)
+    set(${module}_DEPENDS_WITH_KITS ${_module_depends_with_kits})
+
+    set(_module_python_depends)
+    foreach(module IN LISTS ${module}_DEPENDS_WITH_KITS)
+      list(FIND VTK_PYTHON_MODULES_AND_KITS ${module} _module_index)
+      if (_module_index GREATER -1)
+        list(APPEND _module_python_depends ${module})
+      endif()
+    endforeach()
+    list(REMOVE_DUPLICATES _module_python_depends)
+    set(${module}_PYTHON_DEPENDS ${_module_python_depends})
+  endforeach()
+
+  # Create list of kits and modules to wrap, ordered to satisfy dependencies.
+  include(${VTK_CMAKE_DIR}/TopologicalSort.cmake)
+  set(_vtk_python_wrapping_work_list ${VTK_PYTHON_MODULES_AND_KITS})
+  topological_sort(_vtk_python_wrapping_work_list "" _PYTHON_DEPENDS)
+
+  # Wrap kits and modules.
+  foreach(target IN LISTS _vtk_python_wrapping_work_list)
+    # Determine whether target is a kit or module
+    string(REGEX REPLACE "(.+)${VTK_KIT_SUFFIX}\$" "\\1" _stripped_target ${target})
+    if(_${_stripped_target}_is_kit)
+      # Wrap kit
+      set(kit ${_stripped_target})
+      set(kit_srcs)
+      foreach(module IN LISTS _${kit}_modules)
+        vtk_module_headers_load(${module})
+        vtk_include_recurse(${module})
+      endforeach()
+      vtk_add_python_wrapping("${_${kit}_modules}" kit_srcs ${kit}${VTK_KIT_SUFFIX})
+      vtk_add_python_wrapping_library(${kit}${VTK_KIT_SUFFIX} kit_srcs ${_${kit}_modules})
+    else()
+      # Wrap module
+      set(module ${_stripped_target})
+      vtk_module_headers_load(${module})
+      vtk_include_recurse(${module})
+      vtk_add_python_wrapping(${module} module_srcs)
+      # Override module dependency list for vtk_add_python_wrapping_library
+      set(${module}_DEPENDS ${${module}_DEPENDS_WITH_KITS})
+      vtk_add_python_wrapping_library(${module} module_srcs ${module})
+      set(${module}_DEPENDS ${_saved_${module}_DEPENDS})
+    endif()
+  endforeach()
+
+  # Ensure that original module dependency lists are restored
+  foreach(module IN LISTS _vtk_python_modules_only)
+    set(${module}_DEPENDS ${_saved_${module}_DEPENDS})
+    unset(_saved_${module}_DEPENDS)
+  endforeach()
+
+else(VTK_ENABLE_KITS)
+  # Loop through all modules that should be wrapped, and wrap them.
+  foreach(module IN LISTS _vtk_python_modules_only)
+    vtk_module_load(${module})
+    vtk_module_headers_load(${module})
+    vtk_include_recurse(${module})
+    vtk_add_python_wrapping(${module} module_srcs)
+    vtk_add_python_wrapping_library(${module} module_srcs ${module})
+  endforeach()
+endif(VTK_ENABLE_KITS)
+
 
 option(VTK_ENABLE_VTKPYTHON "Enable vtkpython and pvtkpython binaries" ON)
 mark_as_advanced(VTK_ENABLE_VTKPYTHON)
 if(VTK_ENABLE_VTKPYTHON)
 
-# Now to build the vtkPython executable, configure the .py files etc.
-get_property(VTK_PYTHON_MODULES GLOBAL PROPERTY VTK_PYTHON_WRAPPED)
-
 vtk_module_load(vtkWrappingPythonCore)
 vtk_module_load(vtkPython)
 include_directories(${CMAKE_CURRENT_BINARY_DIR}
@@ -166,7 +288,7 @@ if(PYTHON_EXECUTABLE)
 # Wrapping/Python/vtk/*.py
   unset(VTK_PYTHON_FILES)
   unset(VTK_PYTHON_IMPORT_ALL)
-  foreach(module ${VTK_PYTHON_MODULES})
+  foreach(module IN LISTS VTK_PYTHON_MODULES_AND_KITS)
     set(VTK_PYTHON_IMPORT_ALL
       "${VTK_PYTHON_IMPORT_ALL}from .${module} import *\n")
     configure_file(vtk/module.py.in vtk/${module}.py @ONLY)
@@ -295,7 +417,7 @@ if(PYTHON_EXECUTABLE)
 
     # Install python extension library that backs the modules
     if (BUILD_SHARED_LIBS AND NOT VTK_INSTALL_NO_LIBRARIES)
-      foreach(module ${VTK_PYTHON_MODULES})
+      foreach(module IN LISTS VTK_PYTHON_MODULES_AND_KITS)
         install(TARGETS ${module}Python
           RUNTIME DESTINATION ${VTK_INSTALL_RUNTIME_DIR} COMPONENT RuntimeLibraries
           LIBRARY DESTINATION ${VTK_INSTALL_PYTHON_MODULE_DIR}/vtk COMPONENT RuntimeLibraries