{"action":"created","comment":{"url":"https://api.github.com/repos/mkdocs/mkdocs/pulls/comments/29949157","id":29949157,"diff_hunk":"@@ -0,0 +1,86 @@\n+import six\n+\n+from mkdocs import exceptions\n+from mkdocs import utils\n+from mkdocs.config import config_options\n+\n+\n+class Config(six.moves.UserDict):\n+    \"\"\"\n+    MkDocs Configuration dict\n+\n+    This is a fairly simple extension of a standard dictionary. It adds methods\n+    for running validation on the structure and contents.\n+    \"\"\"\n+\n+    def __init__(self, schema):\n+        \"\"\"\n+        The schema is a Python dict which maps the config name to a validator.\n+        \"\"\"\n+\n+        self._schema = schema\n+        self.data = {}\n+\n+        self.set_defaults()\n+        self.user_configs = []\n+\n+    def set_defaults(self):\n+        \"\"\"\n+        Set the base config by going through each validator and getting the\n+        default if it has one.\n+        \"\"\"\n+\n+        for key, config_option in self._schema.items():\n+            self[key] = config_option.default\n+\n+    def validate_update(self, update):\n+\n+        failed, warnings = [], []\n+\n+        for key, value in update.items():\n+\n+            if key not in self._schema:\n+                warning = (\n+                    key, \"Unrecognised configuration name: {0}\".format(key)\n+                )\n+                warnings.append(warning)\n+                continue\n+\n+            config_option = self._schema[key]\n+\n+            try:\n+                update[key] = config_option.validate(value)\n+                warnings.extend(config_option.warnings)\n+            except config_options.ValidationError as e:\n+                failed.append((key, str(e)))\n+\n+        return failed, warnings\n+\n+    def validate(self):\n+\n+        failed, warnings = self.validate_update(self)\n+\n+        for key in set(self._schema.keys()) - set(self.keys()):\n+            config_option = self._schema[key]\n+            if config_option.is_required():\n+                failed.append((key, \"Required configuration not provided.\"))","path":"mkdocs/config/base.py","position":66,"original_position":66,"commit_id":"e34a516f411506c8753960ba36382e21f728fbc1","original_commit_id":"e34a516f411506c8753960ba36382e21f728fbc1","user":{"login":"d0ugal","id":48211,"avatar_url":"https://avatars.githubusercontent.com/u/48211?v=3","gravatar_id":"","url":"https://api.github.com/users/d0ugal","html_url":"https://github.com/d0ugal","followers_url":"https://api.github.com/users/d0ugal/followers","following_url":"https://api.github.com/users/d0ugal/following{/other_user}","gists_url":"https://api.github.com/users/d0ugal/gists{/gist_id}","starred_url":"https://api.github.com/users/d0ugal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/d0ugal/subscriptions","organizations_url":"https://api.github.com/users/d0ugal/orgs","repos_url":"https://api.github.com/users/d0ugal/repos","events_url":"https://api.github.com/users/d0ugal/events{/privacy}","received_events_url":"https://api.github.com/users/d0ugal/received_events","type":"User","site_admin":false},"body":"Good spot, I think that was left over from a previous approach. Will update.","created_at":"2015-05-08T15:29:48Z","updated_at":"2015-05-08T15:29:48Z","html_url":"https://github.com/mkdocs/mkdocs/pull/496#discussion_r29949157","pull_request_url":"https://api.github.com/repos/mkdocs/mkdocs/pulls/496","_links":{"self":{"href":"https://api.github.com/repos/mkdocs/mkdocs/pulls/comments/29949157"},"html":{"href":"https://github.com/mkdocs/mkdocs/pull/496#discussion_r29949157"},"pull_request":{"href":"https://api.github.com/repos/mkdocs/mkdocs/pulls/496"}}},"pull_request":{"url":"https://api.github.com/repos/mkdocs/mkdocs/pulls/496","id":34597990,"html_url":"https://github.com/mkdocs/mkdocs/pull/496","diff_url":"https://github.com/mkdocs/mkdocs/pull/496.diff","patch_url":"https://github.com/mkdocs/mkdocs/pull/496.patch","issue_url":"https://api.github.com/repos/mkdocs/mkdocs/issues/496","number":496,"state":"open","locked":false,"title":"Configuration Refactor","user":{"login":"d0ugal","id":48211,"avatar_url":"https://avatars.githubusercontent.com/u/48211?v=3","gravatar_id":"","url":"https://api.github.com/users/d0ugal","html_url":"https://github.com/d0ugal","followers_url":"https://api.github.com/users/d0ugal/followers","following_url":"https://api.github.com/users/d0ugal/following{/other_user}","gists_url":"https://api.github.com/users/d0ugal/gists{/gist_id}","starred_url":"https://api.github.com/users/d0ugal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/d0ugal/subscriptions","organizations_url":"https://api.github.com/users/d0ugal/orgs","repos_url":"https://api.github.com/users/d0ugal/repos","events_url":"https://api.github.com/users/d0ugal/events{/privacy}","received_events_url":"https://api.github.com/users/d0ugal/received_events","type":"User","site_admin":false},"body":"This change breaks up the config parsing into a set of validators. This\r\nmakes it somewhat easier to follow and add extra checks. As a result we\r\nnow also catch a few config errors we wouldn't have before.\r\n\r\nThe code probably still needs some tidying up, but it works well.","created_at":"2015-05-03T08:14:05Z","updated_at":"2015-05-08T15:29:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d13ab8fd3016ace56164895d80658ec5cde4b1be","assignee":null,"milestone":{"url":"https://api.github.com/repos/mkdocs/mkdocs/milestones/7","html_url":"https://github.com/mkdocs/mkdocs/milestones/0.13.0","labels_url":"https://api.github.com/repos/mkdocs/mkdocs/milestones/7/labels","id":1046452,"number":7,"title":"0.13.0","description":"","creator":{"login":"d0ugal","id":48211,"avatar_url":"https://avatars.githubusercontent.com/u/48211?v=3","gravatar_id":"","url":"https://api.github.com/users/d0ugal","html_url":"https://github.com/d0ugal","followers_url":"https://api.github.com/users/d0ugal/followers","following_url":"https://api.github.com/users/d0ugal/following{/other_user}","gists_url":"https://api.github.com/users/d0ugal/gists{/gist_id}","starred_url":"https://api.github.com/users/d0ugal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/d0ugal/subscriptions","organizations_url":"https://api.github.com/users/d0ugal/orgs","repos_url":"https://api.github.com/users/d0ugal/repos","events_url":"https://api.github.com/users/d0ugal/events{/privacy}","received_events_url":"https://api.github.com/users/d0ugal/received_events","type":"User","site_admin":false},"open_issues":8,"closed_issues":25,"state":"open","created_at":"2015-03-31T08:04:14Z","updated_at":"2015-05-08T06:35:16Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/mkdocs/mkdocs/pulls/496/commits","review_comments_url":"https://api.github.com/repos/mkdocs/mkdocs/pulls/496/comments","review_comment_url":"https://api.github.com/repos/mkdocs/mkdocs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mkdocs/mkdocs/issues/496/comments","statuses_url":"https://api.github.com/repos/mkdocs/mkdocs/statuses/e34a516f411506c8753960ba36382e21f728fbc1","head":{"label":"d0ugal:config-refactor","ref":"config-refactor","sha":"e34a516f411506c8753960ba36382e21f728fbc1","user":{"login":"d0ugal","id":48211,"avatar_url":"https://avatars.githubusercontent.com/u/48211?v=3","gravatar_id":"","url":"https://api.github.com/users/d0ugal","html_url":"https://github.com/d0ugal","followers_url":"https://api.github.com/users/d0ugal/followers","following_url":"https://api.github.com/users/d0ugal/following{/other_user}","gists_url":"https://api.github.com/users/d0ugal/gists{/gist_id}","starred_url":"https://api.github.com/users/d0ugal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/d0ugal/subscriptions","organizations_url":"https://api.github.com/users/d0ugal/orgs","repos_url":"https://api.github.com/users/d0ugal/repos","events_url":"https://api.github.com/users/d0ugal/events{/privacy}","received_events_url":"https://api.github.com/users/d0ugal/received_events","type":"User","site_admin":false},"repo":{"id":22102812,"name":"mkdocs","full_name":"d0ugal/mkdocs","owner":{"login":"d0ugal","id":48211,"avatar_url":"https://avatars.githubusercontent.com/u/48211?v=3","gravatar_id":"","url":"https://api.github.com/users/d0ugal","html_url":"https://github.com/d0ugal","followers_url":"https://api.github.com/users/d0ugal/followers","following_url":"https://api.github.com/users/d0ugal/following{/other_user}","gists_url":"https://api.github.com/users/d0ugal/gists{/gist_id}","starred_url":"https://api.github.com/users/d0ugal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/d0ugal/subscriptions","organizations_url":"https://api.github.com/users/d0ugal/orgs","repos_url":"https://api.github.com/users/d0ugal/repos","events_url":"https://api.github.com/users/d0ugal/events{/privacy}","received_events_url":"https://api.github.com/users/d0ugal/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/d0ugal/mkdocs","description":"Project documentation with Markdown.","fork":true,"url":"https://api.github.com/repos/d0ugal/mkdocs","forks_url":"https://api.github.com/repos/d0ugal/mkdocs/forks","keys_url":"https://api.github.com/repos/d0ugal/mkdocs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/d0ugal/mkdocs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/d0ugal/mkdocs/teams","hooks_url":"https://api.github.com/repos/d0ugal/mkdocs/hooks","issue_events_url":"https://api.github.com/repos/d0ugal/mkdocs/issues/events{/number}","events_url":"https://api.github.com/repos/d0ugal/mkdocs/events","assignees_url":"https://api.github.com/repos/d0ugal/mkdocs/assignees{/user}","branches_url":"https://api.github.com/repos/d0ugal/mkdocs/branches{/branch}","tags_url":"https://api.github.com/repos/d0ugal/mkdocs/tags","blobs_url":"https://api.github.com/repos/d0ugal/mkdocs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/d0ugal/mkdocs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/d0ugal/mkdocs/git/refs{/sha}","trees_url":"https://api.github.com/repos/d0ugal/mkdocs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/d0ugal/mkdocs/statuses/{sha}","languages_url":"https://api.github.com/repos/d0ugal/mkdocs/languages","stargazers_url":"https://api.github.com/repos/d0ugal/mkdocs/stargazers","contributors_url":"https://api.github.com/repos/d0ugal/mkdocs/contributors","subscribers_url":"https://api.github.com/repos/d0ugal/mkdocs/subscribers","subscription_url":"https://api.github.com/repos/d0ugal/mkdocs/subscription","commits_url":"https://api.github.com/repos/d0ugal/mkdocs/commits{/sha}","git_commits_url":"https://api.github.com/repos/d0ugal/mkdocs/git/commits{/sha}","comments_url":"https://api.github.com/repos/d0ugal/mkdocs/comments{/number}","issue_comment_url":"https://api.github.com/repos/d0ugal/mkdocs/issues/comments{/number}","contents_url":"https://api.github.com/repos/d0ugal/mkdocs/contents/{+path}","compare_url":"https://api.github.com/repos/d0ugal/mkdocs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/d0ugal/mkdocs/merges","archive_url":"https://api.github.com/repos/d0ugal/mkdocs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/d0ugal/mkdocs/downloads","issues_url":"https://api.github.com/repos/d0ugal/mkdocs/issues{/number}","pulls_url":"https://api.github.com/repos/d0ugal/mkdocs/pulls{/number}","milestones_url":"https://api.github.com/repos/d0ugal/mkdocs/milestones{/number}","notifications_url":"https://api.github.com/repos/d0ugal/mkdocs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/d0ugal/mkdocs/labels{/name}","releases_url":"https://api.github.com/repos/d0ugal/mkdocs/releases{/id}","created_at":"2014-07-22T12:20:40Z","updated_at":"2015-05-08T06:17:41Z","pushed_at":"2015-05-08T06:17:41Z","git_url":"git://github.com/d0ugal/mkdocs.git","ssh_url":"git@github.com:d0ugal/mkdocs.git","clone_url":"https://github.com/d0ugal/mkdocs.git","svn_url":"https://github.com/d0ugal/mkdocs","homepage":"http://www.mkdocs.org","size":3580,"stargazers_count":2,"watchers_count":2,"language":"CSS","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"mkdocs:master","ref":"master","sha":"ccc0d407700830a36886d10042772e58707dbd18","user":{"login":"mkdocs","id":9692741,"avatar_url":"https://avatars.githubusercontent.com/u/9692741?v=3","gravatar_id":"","url":"https://api.github.com/users/mkdocs","html_url":"https://github.com/mkdocs","followers_url":"https://api.github.com/users/mkdocs/followers","following_url":"https://api.github.com/users/mkdocs/following{/other_user}","gists_url":"https://api.github.com/users/mkdocs/gists{/gist_id}","starred_url":"https://api.github.com/users/mkdocs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mkdocs/subscriptions","organizations_url":"https://api.github.com/users/mkdocs/orgs","repos_url":"https://api.github.com/users/mkdocs/repos","events_url":"https://api.github.com/users/mkdocs/events{/privacy}","received_events_url":"https://api.github.com/users/mkdocs/received_events","type":"Organization","site_admin":false},"repo":{"id":15830664,"name":"mkdocs","full_name":"mkdocs/mkdocs","owner":{"login":"mkdocs","id":9692741,"avatar_url":"https://avatars.githubusercontent.com/u/9692741?v=3","gravatar_id":"","url":"https://api.github.com/users/mkdocs","html_url":"https://github.com/mkdocs","followers_url":"https://api.github.com/users/mkdocs/followers","following_url":"https://api.github.com/users/mkdocs/following{/other_user}","gists_url":"https://api.github.com/users/mkdocs/gists{/gist_id}","starred_url":"https://api.github.com/users/mkdocs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mkdocs/subscriptions","organizations_url":"https://api.github.com/users/mkdocs/orgs","repos_url":"https://api.github.com/users/mkdocs/repos","events_url":"https://api.github.com/users/mkdocs/events{/privacy}","received_events_url":"https://api.github.com/users/mkdocs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mkdocs/mkdocs","description":"Project documentation with Markdown.","fork":false,"url":"https://api.github.com/repos/mkdocs/mkdocs","forks_url":"https://api.github.com/repos/mkdocs/mkdocs/forks","keys_url":"https://api.github.com/repos/mkdocs/mkdocs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mkdocs/mkdocs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mkdocs/mkdocs/teams","hooks_url":"https://api.github.com/repos/mkdocs/mkdocs/hooks","issue_events_url":"https://api.github.com/repos/mkdocs/mkdocs/issues/events{/number}","events_url":"https://api.github.com/repos/mkdocs/mkdocs/events","assignees_url":"https://api.github.com/repos/mkdocs/mkdocs/assignees{/user}","branches_url":"https://api.github.com/repos/mkdocs/mkdocs/branches{/branch}","tags_url":"https://api.github.com/repos/mkdocs/mkdocs/tags","blobs_url":"https://api.github.com/repos/mkdocs/mkdocs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mkdocs/mkdocs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mkdocs/mkdocs/git/refs{/sha}","trees_url":"https://api.github.com/repos/mkdocs/mkdocs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mkdocs/mkdocs/statuses/{sha}","languages_url":"https://api.github.com/repos/mkdocs/mkdocs/languages","stargazers_url":"https://api.github.com/repos/mkdocs/mkdocs/stargazers","contributors_url":"https://api.github.com/repos/mkdocs/mkdocs/contributors","subscribers_url":"https://api.github.com/repos/mkdocs/mkdocs/subscribers","subscription_url":"https://api.github.com/repos/mkdocs/mkdocs/subscription","commits_url":"https://api.github.com/repos/mkdocs/mkdocs/commits{/sha}","git_commits_url":"https://api.github.com/repos/mkdocs/mkdocs/git/commits{/sha}","comments_url":"https://api.github.com/repos/mkdocs/mkdocs/comments{/number}","issue_comment_url":"https://api.github.com/repos/mkdocs/mkdocs/issues/comments{/number}","contents_url":"https://api.github.com/repos/mkdocs/mkdocs/contents/{+path}","compare_url":"https://api.github.com/repos/mkdocs/mkdocs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mkdocs/mkdocs/merges","archive_url":"https://api.github.com/repos/mkdocs/mkdocs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mkdocs/mkdocs/downloads","issues_url":"https://api.github.com/repos/mkdocs/mkdocs/issues{/number}","pulls_url":"https://api.github.com/repos/mkdocs/mkdocs/pulls{/number}","milestones_url":"https://api.github.com/repos/mkdocs/mkdocs/milestones{/number}","notifications_url":"https://api.github.com/repos/mkdocs/mkdocs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mkdocs/mkdocs/labels{/name}","releases_url":"https://api.github.com/repos/mkdocs/mkdocs/releases{/id}","created_at":"2014-01-11T21:05:21Z","updated_at":"2015-05-08T13:40:02Z","pushed_at":"2015-05-08T06:35:16Z","git_url":"git://github.com/mkdocs/mkdocs.git","ssh_url":"git@github.com:mkdocs/mkdocs.git","clone_url":"https://github.com/mkdocs/mkdocs.git","svn_url":"https://github.com/mkdocs/mkdocs","homepage":"http://www.mkdocs.org","size":23795,"stargazers_count":1181,"watchers_count":1181,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":201,"mirror_url":null,"open_issues_count":43,"forks":201,"open_issues":43,"watchers":1181,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mkdocs/mkdocs/pulls/496"},"html":{"href":"https://github.com/mkdocs/mkdocs/pull/496"},"issue":{"href":"https://api.github.com/repos/mkdocs/mkdocs/issues/496"},"comments":{"href":"https://api.github.com/repos/mkdocs/mkdocs/issues/496/comments"},"review_comments":{"href":"https://api.github.com/repos/mkdocs/mkdocs/pulls/496/comments"},"review_comment":{"href":"https://api.github.com/repos/mkdocs/mkdocs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mkdocs/mkdocs/pulls/496/commits"},"statuses":{"href":"https://api.github.com/repos/mkdocs/mkdocs/statuses/e34a516f411506c8753960ba36382e21f728fbc1"}}}}