|
2004 | 2004 | "#|export\n", |
2005 | 2005 | "class Config:\n", |
2006 | 2006 | " \"Reading and writing `ConfigParser` ini files\"\n", |
2007 | | - " def __init__(self, cfg_path, cfg_name, create=None, save=True):\n", |
| 2007 | + " def __init__(self, cfg_path, cfg_name, create=None, save=True, extra_files=None):\n", |
2008 | 2008 | " cfg_path = Path(cfg_path).expanduser().absolute()\n", |
2009 | 2009 | " self.config_path,self.config_file = cfg_path,cfg_path/cfg_name\n", |
2010 | | - " if self.config_file.exists(): self.d = read_config_file(self.config_file)\n", |
2011 | | - " elif create is not None:\n", |
2012 | | - " self.d = ConfigParser(create)['DEFAULT']\n", |
| 2010 | + " self._cfg = ConfigParser()\n", |
| 2011 | + " self.d = self._cfg['DEFAULT']\n", |
| 2012 | + " found = [Path(o) for o in self._cfg.read(L(extra_files)+[self.config_file])]\n", |
| 2013 | + " if self.config_file not in found and create is not None:\n", |
| 2014 | + " self._cfg.read_dict({'DEFAULT':create})\n", |
2013 | 2015 | " if save:\n", |
2014 | 2016 | " cfg_path.mkdir(exist_ok=True, parents=True)\n", |
2015 | | - " self.save()\n", |
| 2017 | + " save_config_file(self.config_file, create)\n", |
2016 | 2018 | "\n", |
| 2019 | + " def __repr__(self): return repr(dict(self._cfg.items('DEFAULT', raw=True)))\n", |
2017 | 2020 | " def __setitem__(self,k,v): self.d[k] = str(v)\n", |
2018 | 2021 | " def __contains__(self,k): return k in self.d\n", |
2019 | 2022 | " def save(self): save_config_file(self.config_file,self.d)\n", |
|
2033 | 2036 | "`Config` is a convenient wrapper around `ConfigParser` ini files with a single section (`DEFAULT`)." |
2034 | 2037 | ] |
2035 | 2038 | }, |
| 2039 | + { |
| 2040 | + "cell_type": "markdown", |
| 2041 | + "metadata": {}, |
| 2042 | + "source": [ |
| 2043 | + "Instantiate a `Config` from an ini file at `cfg_path/cfg_name`:" |
| 2044 | + ] |
| 2045 | + }, |
2036 | 2046 | { |
2037 | 2047 | "cell_type": "code", |
2038 | 2048 | "execution_count": null, |
2039 | 2049 | "metadata": {}, |
2040 | | - "outputs": [], |
| 2050 | + "outputs": [ |
| 2051 | + { |
| 2052 | + "data": { |
| 2053 | + "text/plain": [ |
| 2054 | + "{'user': 'fastai', 'lib_name': 'fastcore', 'some_path': 'test'}" |
| 2055 | + ] |
| 2056 | + }, |
| 2057 | + "execution_count": null, |
| 2058 | + "metadata": {}, |
| 2059 | + "output_type": "execute_result" |
| 2060 | + } |
| 2061 | + ], |
| 2062 | + "source": [ |
| 2063 | + "save_config_file('../tmp.ini', _d)\n", |
| 2064 | + "try: cfg = Config('..', 'tmp.ini')\n", |
| 2065 | + "finally: os.unlink('../tmp.ini')\n", |
| 2066 | + "cfg" |
| 2067 | + ] |
| 2068 | + }, |
| 2069 | + { |
| 2070 | + "cell_type": "markdown", |
| 2071 | + "metadata": {}, |
| 2072 | + "source": [ |
| 2073 | + "You can create a new file if one doesn't exist by providing a `create` dict:" |
| 2074 | + ] |
| 2075 | + }, |
| 2076 | + { |
| 2077 | + "cell_type": "code", |
| 2078 | + "execution_count": null, |
| 2079 | + "metadata": {}, |
| 2080 | + "outputs": [ |
| 2081 | + { |
| 2082 | + "data": { |
| 2083 | + "text/plain": [ |
| 2084 | + "{'user': 'fastai', 'lib_name': 'fastcore', 'some_path': 'test'}" |
| 2085 | + ] |
| 2086 | + }, |
| 2087 | + "execution_count": null, |
| 2088 | + "metadata": {}, |
| 2089 | + "output_type": "execute_result" |
| 2090 | + } |
| 2091 | + ], |
2041 | 2092 | "source": [ |
2042 | 2093 | "try: cfg = Config('..', 'tmp.ini', create=_d)\n", |
2043 | 2094 | "finally: os.unlink('../tmp.ini')\n", |
2044 | | - "\n", |
2045 | | - "test_eq(cfg.user,'fastai')\n", |
2046 | | - "test_eq(cfg['some_path'], 'test')\n", |
2047 | | - "test_eq(cfg.path('some_path'), Path('../test').absolute())\n", |
2048 | | - "test_eq(cfg.get('foo','bar'),'bar')" |
| 2095 | + "cfg" |
2049 | 2096 | ] |
2050 | 2097 | }, |
2051 | 2098 | { |
2052 | 2099 | "cell_type": "markdown", |
2053 | 2100 | "metadata": {}, |
2054 | 2101 | "source": [ |
2055 | | - "You can also create an in-memory `Config` by passing `save=False`:" |
| 2102 | + "If you additionally pass `save=False`, the `Config` will contain the items from `create` without writing a new file:" |
2056 | 2103 | ] |
2057 | 2104 | }, |
2058 | 2105 | { |
|
2066 | 2113 | "assert not Path('../tmp.ini').exists()" |
2067 | 2114 | ] |
2068 | 2115 | }, |
| 2116 | + { |
| 2117 | + "cell_type": "markdown", |
| 2118 | + "metadata": {}, |
| 2119 | + "source": [ |
| 2120 | + "Keys can be accessed as attributes, items, or with `get` and an optional default:" |
| 2121 | + ] |
| 2122 | + }, |
| 2123 | + { |
| 2124 | + "cell_type": "code", |
| 2125 | + "execution_count": null, |
| 2126 | + "metadata": {}, |
| 2127 | + "outputs": [], |
| 2128 | + "source": [ |
| 2129 | + "test_eq(cfg.user,'fastai')\n", |
| 2130 | + "test_eq(cfg['some_path'], 'test')\n", |
| 2131 | + "test_eq(cfg.get('foo','bar'),'bar')" |
| 2132 | + ] |
| 2133 | + }, |
| 2134 | + { |
| 2135 | + "cell_type": "markdown", |
| 2136 | + "metadata": {}, |
| 2137 | + "source": [ |
| 2138 | + "Use `path` to access keys as `pathlib.Path`s relative to `cfg_path`:" |
| 2139 | + ] |
| 2140 | + }, |
| 2141 | + { |
| 2142 | + "cell_type": "code", |
| 2143 | + "execution_count": null, |
| 2144 | + "metadata": {}, |
| 2145 | + "outputs": [], |
| 2146 | + "source": [ |
| 2147 | + "test_eq(cfg.path('some_path'), Path('../test').absolute())" |
| 2148 | + ] |
| 2149 | + }, |
| 2150 | + { |
| 2151 | + "cell_type": "markdown", |
| 2152 | + "metadata": {}, |
| 2153 | + "source": [ |
| 2154 | + "Extra files can be read _before_ `cfg_path/cfg_name` using `extra_files`, in the order they appear:" |
| 2155 | + ] |
| 2156 | + }, |
| 2157 | + { |
| 2158 | + "cell_type": "code", |
| 2159 | + "execution_count": null, |
| 2160 | + "metadata": {}, |
| 2161 | + "outputs": [], |
| 2162 | + "source": [ |
| 2163 | + "with tempfile.TemporaryDirectory() as d:\n", |
| 2164 | + " a = Config(d, 'a.ini', {'a':0,'b':0})\n", |
| 2165 | + " b = Config(d, 'b.ini', {'a':1,'c':0})\n", |
| 2166 | + " c = Config(d, 'c.ini', {'a':2,'d':0}, extra_files=[a.config_file,b.config_file])\n", |
| 2167 | + " test_eq(c.d, {'a':'2','b':'0','c':'0','d':'0'})" |
| 2168 | + ] |
| 2169 | + }, |
2069 | 2170 | { |
2070 | 2171 | "cell_type": "markdown", |
2071 | 2172 | "metadata": {}, |
|
0 commit comments