diff --git a/fastcore/__init__.py b/fastcore/__init__.py
index a82b376d..72f26f59 100644
--- a/fastcore/__init__.py
+++ b/fastcore/__init__.py
@@ -1 +1 @@
-__version__ = "1.1.1"
+__version__ = "1.1.2"
diff --git a/fastcore/_nbdev.py b/fastcore/_nbdev.py
index cca82a19..1a2cda0f 100644
--- a/fastcore/_nbdev.py
+++ b/fastcore/_nbdev.py
@@ -131,6 +131,7 @@
          "defaults.cpus": "02_utils.ipynb",
          "add_props": "02_utils.ipynb",
          "ContextManagers": "02_utils.ipynb",
+         "typed": "02_utils.ipynb",
          "set_num_threads": "02_utils.ipynb",
          "ProcessPoolExecutor": "02_utils.ipynb",
          "ThreadPoolExecutor": "02_utils.ipynb",
diff --git a/fastcore/foundation.py b/fastcore/foundation.py
index 09cf0897..f05b550d 100644
--- a/fastcore/foundation.py
+++ b/fastcore/foundation.py
@@ -422,15 +422,15 @@ def setattrs(self, attr, val): [setattr(o,attr,val) for o in self]
 Sequence.register(L);
 
 # Cell
-def save_config_file(file, d):
+def save_config_file(file, d, **kwargs):
     "Write settings dict to a new config file, or overwrite the existing one."
-    config = ConfigParser()
+    config = ConfigParser(**kwargs)
     config['DEFAULT'] = d
     config.write(open(file, 'w'))
 
 # Cell
-def read_config_file(file):
-    config = ConfigParser()
+def read_config_file(file, **kwargs):
+    config = ConfigParser(**kwargs)
     config.read(file)
     return config
 
diff --git a/fastcore/utils.py b/fastcore/utils.py
index ad7f587c..ec2ae8d4 100644
--- a/fastcore/utils.py
+++ b/fastcore/utils.py
@@ -9,8 +9,8 @@
            'inum_methods', 'fastuple', 'trace', 'compose', 'maps', 'partialler', 'mapped', 'instantiate', 'using_attr',
            'Self', 'Self', 'save_pickle', 'load_pickle', 'bunzip', 'join_path_file', 'urlread', 'urljson', 'run',
            'do_request', 'sort_by_run', 'PrettyString', 'round_multiple', 'even_mults', 'num_cpus', 'add_props',
-           'ContextManagers', 'set_num_threads', 'ProcessPoolExecutor', 'ThreadPoolExecutor', 'parallel', 'run_procs',
-           'parallel_gen', 'threaded']
+           'ContextManagers', 'typed', 'set_num_threads', 'ProcessPoolExecutor', 'ThreadPoolExecutor', 'parallel',
+           'run_procs', 'parallel_gen', 'threaded']
 
 # Cell
 from .imports import *
@@ -675,6 +675,23 @@ def __init__(self, mgrs): self.default,self.stack = L(mgrs),ExitStack()
     def __enter__(self): self.default.map(self.stack.enter_context)
     def __exit__(self, *args, **kwargs): self.stack.__exit__(*args, **kwargs)
 
+# Cell
+def typed(f):
+    "Decorator to check param and return types at runtime"
+    names = f.__code__.co_varnames
+    anno = f.__annotations__
+    ret = anno.pop('return',None)
+    def _f(*args,**kwargs):
+        kw = {**kwargs}
+        if len(anno) > 0:
+            for i,arg in enumerate(args): kw[names[i]] = arg
+            for k,v in kw.items():
+                if not isinstance(v,anno[k]): raise TypeError(f"{k}=={v} not {anno[k]}")
+        res = f(*args,**kwargs)
+        if ret is not None and not isinstance(res,ret): raise TypeError(f"return=={res} not {ret}")
+        return res
+    return functools.update_wrapper(_f, f)
+
 # Cell
 from multiprocessing import Process, Queue
 import concurrent.futures
diff --git a/nbs/01_foundation.ipynb b/nbs/01_foundation.ipynb
index 6e6c4b17..0d8b85e1 100644
--- a/nbs/01_foundation.ipynb
+++ b/nbs/01_foundation.ipynb
@@ -1964,7 +1964,7 @@
     {
      "data": {
       "text/plain": [
-       "['k', 4, 'j']"
+       "[0, 9, 1]"
       ]
      },
      "execution_count": null,
@@ -2143,7 +2143,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### Class L Methods"
+    "### `L` Methods"
    ]
   },
   {
@@ -3036,9 +3036,9 @@
    "outputs": [],
    "source": [
     "#export\n",
-    "def save_config_file(file, d):\n",
+    "def save_config_file(file, d, **kwargs):\n",
     "    \"Write settings dict to a new config file, or overwrite the existing one.\"\n",
-    "    config = ConfigParser()\n",
+    "    config = ConfigParser(**kwargs)\n",
     "    config['DEFAULT'] = d\n",
     "    config.write(open(file, 'w'))"
    ]
@@ -3050,8 +3050,8 @@
    "outputs": [],
    "source": [
     "#export\n",
-    "def read_config_file(file):\n",
-    "    config = ConfigParser()\n",
+    "def read_config_file(file, **kwargs):\n",
+    "    config = ConfigParser(**kwargs)\n",
     "    config.read(file)\n",
     "    return config"
    ]
diff --git a/nbs/02_utils.ipynb b/nbs/02_utils.ipynb
index 6aac071d..4802a326 100644
--- a/nbs/02_utils.ipynb
+++ b/nbs/02_utils.ipynb
@@ -296,7 +296,7 @@
     {
      "data": {
       "text/plain": [
-       "<__main__._t at 0x7ff9a9c3deb0>"
+       "<__main__._t at 0x7f945b39e070>"
       ]
      },
      "execution_count": null,
@@ -2171,7 +2171,7 @@
     {
      "data": {
       "text/plain": [
-       "['g', 'd', 'h', 'a', 'f', 'c', 'b', 'e']"
+       "['h', 'g', 'f', 'b', 'd', 'e', 'a', 'c']"
       ]
      },
      "execution_count": null,
@@ -3513,7 +3513,7 @@
     {
      "data": {
       "text/plain": [
-       "64"
+       "8"
       ]
      },
      "execution_count": null,
@@ -3621,6 +3621,50 @@
     "show_doc(ContextManagers, title_level=4)"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#export\n",
+    "def typed(f):\n",
+    "    \"Decorator to check param and return types at runtime\"\n",
+    "    names = f.__code__.co_varnames\n",
+    "    anno = f.__annotations__\n",
+    "    ret = anno.pop('return',None)\n",
+    "    def _f(*args,**kwargs):\n",
+    "        kw = {**kwargs}\n",
+    "        if len(anno) > 0:\n",
+    "            for i,arg in enumerate(args): kw[names[i]] = arg\n",
+    "            for k,v in kw.items():\n",
+    "                if not isinstance(v,anno[k]): raise TypeError(f\"{k}=={v} not {anno[k]}\")\n",
+    "        res = f(*args,**kwargs)\n",
+    "        if ret is not None and not isinstance(res,ret): raise TypeError(f\"return=={res} not {ret}\")\n",
+    "        return res\n",
+    "    return functools.update_wrapper(_f, f)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "@typed\n",
+    "def foo(a:int, b:str='a'): return a\n",
+    "test_eq(foo(1, '2'), 1)\n",
+    "test_fail(partial(foo, 1, 2))\n",
+    "\n",
+    "@typed\n",
+    "def foo()->str: return 1\n",
+    "test_fail(partial(foo))\n",
+    "\n",
+    "@typed\n",
+    "def foo()->str: return '1'\n",
+    "assert foo()"
+   ]
+  },
   {
    "cell_type": "markdown",
    "metadata": {},
diff --git a/settings.ini b/settings.ini
index 790b00f0..dddd2249 100644
--- a/settings.ini
+++ b/settings.ini
@@ -7,7 +7,7 @@ author = Jeremy Howard and Sylvain Gugger
 author_email = infos@fast.ai
 copyright = fast.ai
 branch = master
-version = 1.1.1
+version = 1.1.2
 min_python = 3.6
 audience = Developers
 language = English