diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9fa13b3cd7d4835d0618f01344e4965b429ba7a0..ac2631b9f59136272c12eef87559701fc6a42d7e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,9 +36,6 @@ dune_enable_all_packages(INCLUDE_DIRS ${dune-xt-grid_SOURCE_DIR}/dune MODULE_LIB
 add_header_listing()
 make_dependent_modules_sys_included()
 
-add_subdirectory(dune)
-add_subdirectory(doc)
-
 include(DuneXTInstallPythonPackage)
 # this symlinks all files in python/ to the binary dir and install into the virtualenv from there thereby making the
 # compiled extensions directly usable from the venv
@@ -48,6 +45,10 @@ include_dependent_binary_python_dirs()
 add_subdirectory(python)
 dxt_add_make_dependent_bindings(dune-xt-common dune-xt-la)
 
+# this needs to come after the python install so we can use it in test generation
+add_subdirectory(dune)
+add_subdirectory(doc)
+
 # enable headercheck
 add_definitions("-DENABLE_HEADERCHECK=1")
 add_format(${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/python/dune/xt/grid/types.py b/python/dune/xt/grid/types.py
new file mode 100644
index 0000000000000000000000000000000000000000..6838a64036d40feb1a6ea52f3f5edcfa79b4f681
--- /dev/null
+++ b/python/dune/xt/grid/types.py
@@ -0,0 +1,35 @@
+from collections import namedtuple
+
+arguments = {'alu': namedtuple('alu_args', 'dim element_type refinement'),
+             'yasp': namedtuple('yasp_args', 'dim'),
+             'ug': namedtuple('ug_args', 'dim'),
+             'alberta': namedtuple('alberta_args', 'dim')}
+templates = { 'alu': 'Dune::ALUGrid<{dim},{dim},Dune::{element_type},Dune::{refinement}>',
+              'yasp': 'Dune::YaspGrid<{dim},Dune::EquidistantOffsetCoordinates<double,{dim}>>',
+              'ug': 'Dune::UGGrid<{}>',
+              'alberta': 'Dune::AlbertaGrid<{dim},{dim}>'}
+guards = { 'alu': 'dune-alugrid',
+           'yasp': 'dune-grid',
+           'ug': 'dune-uggrid',
+           'alberta': 'ALBERTA_FOUND'}
+
+
+def _is_usable(grid, cache):
+    return cache[guards[grid]]
+
+
+def all_args(dims):
+    two_and_three = [f for f in dims if 1 < f < 4]
+    return {'alu': [arguments['alu'](d, 'simplex', e) for e in ('nonconforming', 'conforming') for d in two_and_three] +
+                    [arguments['alu'](d, 'cube', 'nonconforming') for d in two_and_three],
+            'yasp': [arguments['yasp'](d) for d in dims if d > 0],
+            'ug': [arguments['ug'](d) for d in two_and_three],
+            'alberta': [arguments['alberta'](d) for d in two_and_three]}
+
+
+def all_types(cache, dims, gridnames=None):
+    gridnames = gridnames or templates.keys()
+    return [templates[grid].format(**arg._asdict()) \
+                for grid in  gridnames if _is_usable(grid, cache) \
+                for arg in all_args(dims)[grid]]
+