{"action":"created","comment":{"url":"https://api.github.com/repos/firedrakeproject/dcore/pulls/comments/55575260","id":55575260,"diff_hunk":"@@ -0,0 +1,81 @@\n+\"\"\"\n+Some simple tools for making model configuration nicer.\n+\"\"\"\n+\n+\n+class Configuration(object):\n+    def __init__(self, **kwargs):\n+\n+        self.__setattr__ = self._proto__setattr__\n+        for name, value in kwargs.iteritems():\n+            print name, value\n+            self.__setattr__(name, value)\n+\n+    def _proto__setattr__(self, name, value):\n+        \"\"\"Cause setting an unknown attribute to be an error\"\"\"\n+        self.__getattribute__(name)\n+        object.__setattr__(self, name, value)\n+\n+\n+class TimesteppingParameters(Configuration):\n+\n+    \"\"\"\n+    Timestepping parameters for dcore\n+    \"\"\"\n+\n+    def __init__(self, **kwargs):\n+        self.dt = None\n+        self.alpha = 0.5\n+        self.maxk = 2\n+        self.maxi = 2\n+\n+        super(TimesteppingParameters, self).__init__(**kwargs)\n+\n+\n+class OutputParameters(Configuration):\n+\n+    \"\"\"\n+    Output parameters for dcore\n+    \"\"\"\n+\n+    def __init__(self, **kwargs):\n+        self.Verbose = False\n+        self.dumpfreq = 10\n+        self.dumplist = (True,True,True)\n+\n+        super(OutputParameters, self).__init__(**kwargs)\n+\n+\n+class CompressibleParameters(Configuration):\n+\n+    \"\"\"\n+    Physical parameters for 3d Compressible Euler\n+    \"\"\"\n+\n+    def __init__(self, **kwargs):\n+        self.g = 9.81\n+        self.N = 0.01\n+        self.cp = 1004.5\n+        self.R_d = 287.\n+        self.p_0 = 1000.0*1000.0\n+        self.kappa = 2.0/7.0\n+        self.k = None\n+        self.Omega = None\n+\n+        super(CompressibleParameters, self).__init__(**kwargs)","path":"dcore/configuration.py","position":65,"original_position":65,"commit_id":"e30d0373685432a2e1e49be2caf200089e392100","original_commit_id":"e30d0373685432a2e1e49be2caf200089e392100","user":{"login":"wence-","id":1126981,"avatar_url":"https://avatars.githubusercontent.com/u/1126981?v=3","gravatar_id":"","url":"https://api.github.com/users/wence-","html_url":"https://github.com/wence-","followers_url":"https://api.github.com/users/wence-/followers","following_url":"https://api.github.com/users/wence-/following{/other_user}","gists_url":"https://api.github.com/users/wence-/gists{/gist_id}","starred_url":"https://api.github.com/users/wence-/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wence-/subscriptions","organizations_url":"https://api.github.com/users/wence-/orgs","repos_url":"https://api.github.com/users/wence-/repos","events_url":"https://api.github.com/users/wence-/events{/privacy}","received_events_url":"https://api.github.com/users/wence-/received_events","type":"User","site_admin":false},"body":"If I understand this class correctly, I would use:\r\n\r\n```python\r\nclass Configuration(object):\r\n\r\n    def __init__(self, **kwargs):\r\n        for name, value in kwargs.iteritems():\r\n            self.__setattr__(name, value)\r\n\r\n    def __setattr__(self, name, value):\r\n        if not hasattr(self, name):\r\n            raise AttributeError(\"'%s' object has no attribute '%s'\" % (type(self).__name__, name))\r\n        object.__setattr__(self, name, value)\r\n```\r\n\r\nNow the inherited configuration object don't have an init, they just provide a default value for each of the parameters you're allowed to set:\r\n\r\n```python\r\nclass SubConfig(Configuration):\r\n    a = None\r\n    g = 9.81\r\n```\r\n\r\nNow, when I make a `SubConfig`, I can either just select the defaults:\r\n\r\n```python\r\nconf = SubConfig()\r\n```\r\n\r\nOr else override some defaults:\r\n```python\r\nconf = SubConfig(a=55)\r\n```\r\n\r\nIf I try and set an \"unsupported\" parameter, then I get an attribute error:\r\n\r\n```python\r\nx.c = 14321\r\n\r\nTruncated Traceback (Use C-c C-x to view full TB):\r\n<ipython-input-31-d5c9fd37ecc0> in __setattr__(self, name, value)\r\n      2     def __setattr__(self, name, value):\r\n      3         if not hasattr(self, name):\r\n----> 4             raise AttributeError(\"'%s' object has no attribute '%s'\" % (type(self).__name__, name))\r\n      5         object.__setattr__(self, name, value)\r\n      6 \r\n\r\nAttributeError: 'SubConfig' object has no attribute 'c'\r\n```\r\n\r\nI think this makes the code somewhat simpler, because you don't need init and so on.\r\n\r\nCertainly, that's what the example below suggests the mechanism is.","created_at":"2016-03-09T19:35:15Z","updated_at":"2016-03-09T19:35:15Z","html_url":"https://github.com/firedrakeproject/dcore/pull/20#discussion_r55575260","pull_request_url":"https://api.github.com/repos/firedrakeproject/dcore/pulls/20","_links":{"self":{"href":"https://api.github.com/repos/firedrakeproject/dcore/pulls/comments/55575260"},"html":{"href":"https://github.com/firedrakeproject/dcore/pull/20#discussion_r55575260"},"pull_request":{"href":"https://api.github.com/repos/firedrakeproject/dcore/pulls/20"}}},"pull_request":{"url":"https://api.github.com/repos/firedrakeproject/dcore/pulls/20","id":62249604,"html_url":"https://github.com/firedrakeproject/dcore/pull/20","diff_url":"https://github.com/firedrakeproject/dcore/pull/20.diff","patch_url":"https://github.com/firedrakeproject/dcore/pull/20.patch","issue_url":"https://api.github.com/repos/firedrakeproject/dcore/issues/20","number":20,"state":"open","locked":false,"title":"Tidy configuration","user":{"login":"jshipton","id":6875594,"avatar_url":"https://avatars.githubusercontent.com/u/6875594?v=3","gravatar_id":"","url":"https://api.github.com/users/jshipton","html_url":"https://github.com/jshipton","followers_url":"https://api.github.com/users/jshipton/followers","following_url":"https://api.github.com/users/jshipton/following{/other_user}","gists_url":"https://api.github.com/users/jshipton/gists{/gist_id}","starred_url":"https://api.github.com/users/jshipton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jshipton/subscriptions","organizations_url":"https://api.github.com/users/jshipton/orgs","repos_url":"https://api.github.com/users/jshipton/repos","events_url":"https://api.github.com/users/jshipton/events{/privacy}","received_events_url":"https://api.github.com/users/jshipton/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-03-09T15:53:59Z","updated_at":"2016-03-09T19:35:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f7bd2740fa13a25e0283b8c4a84f57b076bf7d8e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/firedrakeproject/dcore/pulls/20/commits","review_comments_url":"https://api.github.com/repos/firedrakeproject/dcore/pulls/20/comments","review_comment_url":"https://api.github.com/repos/firedrakeproject/dcore/pulls/comments{/number}","comments_url":"https://api.github.com/repos/firedrakeproject/dcore/issues/20/comments","statuses_url":"https://api.github.com/repos/firedrakeproject/dcore/statuses/e30d0373685432a2e1e49be2caf200089e392100","head":{"label":"firedrakeproject:tidy_configuration","ref":"tidy_configuration","sha":"e30d0373685432a2e1e49be2caf200089e392100","user":{"login":"firedrakeproject","id":5558005,"avatar_url":"https://avatars.githubusercontent.com/u/5558005?v=3","gravatar_id":"","url":"https://api.github.com/users/firedrakeproject","html_url":"https://github.com/firedrakeproject","followers_url":"https://api.github.com/users/firedrakeproject/followers","following_url":"https://api.github.com/users/firedrakeproject/following{/other_user}","gists_url":"https://api.github.com/users/firedrakeproject/gists{/gist_id}","starred_url":"https://api.github.com/users/firedrakeproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firedrakeproject/subscriptions","organizations_url":"https://api.github.com/users/firedrakeproject/orgs","repos_url":"https://api.github.com/users/firedrakeproject/repos","events_url":"https://api.github.com/users/firedrakeproject/events{/privacy}","received_events_url":"https://api.github.com/users/firedrakeproject/received_events","type":"Organization","site_admin":false},"repo":{"id":49564954,"name":"dcore","full_name":"firedrakeproject/dcore","owner":{"login":"firedrakeproject","id":5558005,"avatar_url":"https://avatars.githubusercontent.com/u/5558005?v=3","gravatar_id":"","url":"https://api.github.com/users/firedrakeproject","html_url":"https://github.com/firedrakeproject","followers_url":"https://api.github.com/users/firedrakeproject/followers","following_url":"https://api.github.com/users/firedrakeproject/following{/other_user}","gists_url":"https://api.github.com/users/firedrakeproject/gists{/gist_id}","starred_url":"https://api.github.com/users/firedrakeproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firedrakeproject/subscriptions","organizations_url":"https://api.github.com/users/firedrakeproject/orgs","repos_url":"https://api.github.com/users/firedrakeproject/repos","events_url":"https://api.github.com/users/firedrakeproject/events{/privacy}","received_events_url":"https://api.github.com/users/firedrakeproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/firedrakeproject/dcore","description":"Three dimensional atmospheric dynamical core using the Gung Ho numerics.","fork":false,"url":"https://api.github.com/repos/firedrakeproject/dcore","forks_url":"https://api.github.com/repos/firedrakeproject/dcore/forks","keys_url":"https://api.github.com/repos/firedrakeproject/dcore/keys{/key_id}","collaborators_url":"https://api.github.com/repos/firedrakeproject/dcore/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/firedrakeproject/dcore/teams","hooks_url":"https://api.github.com/repos/firedrakeproject/dcore/hooks","issue_events_url":"https://api.github.com/repos/firedrakeproject/dcore/issues/events{/number}","events_url":"https://api.github.com/repos/firedrakeproject/dcore/events","assignees_url":"https://api.github.com/repos/firedrakeproject/dcore/assignees{/user}","branches_url":"https://api.github.com/repos/firedrakeproject/dcore/branches{/branch}","tags_url":"https://api.github.com/repos/firedrakeproject/dcore/tags","blobs_url":"https://api.github.com/repos/firedrakeproject/dcore/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/firedrakeproject/dcore/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/firedrakeproject/dcore/git/refs{/sha}","trees_url":"https://api.github.com/repos/firedrakeproject/dcore/git/trees{/sha}","statuses_url":"https://api.github.com/repos/firedrakeproject/dcore/statuses/{sha}","languages_url":"https://api.github.com/repos/firedrakeproject/dcore/languages","stargazers_url":"https://api.github.com/repos/firedrakeproject/dcore/stargazers","contributors_url":"https://api.github.com/repos/firedrakeproject/dcore/contributors","subscribers_url":"https://api.github.com/repos/firedrakeproject/dcore/subscribers","subscription_url":"https://api.github.com/repos/firedrakeproject/dcore/subscription","commits_url":"https://api.github.com/repos/firedrakeproject/dcore/commits{/sha}","git_commits_url":"https://api.github.com/repos/firedrakeproject/dcore/git/commits{/sha}","comments_url":"https://api.github.com/repos/firedrakeproject/dcore/comments{/number}","issue_comment_url":"https://api.github.com/repos/firedrakeproject/dcore/issues/comments{/number}","contents_url":"https://api.github.com/repos/firedrakeproject/dcore/contents/{+path}","compare_url":"https://api.github.com/repos/firedrakeproject/dcore/compare/{base}...{head}","merges_url":"https://api.github.com/repos/firedrakeproject/dcore/merges","archive_url":"https://api.github.com/repos/firedrakeproject/dcore/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/firedrakeproject/dcore/downloads","issues_url":"https://api.github.com/repos/firedrakeproject/dcore/issues{/number}","pulls_url":"https://api.github.com/repos/firedrakeproject/dcore/pulls{/number}","milestones_url":"https://api.github.com/repos/firedrakeproject/dcore/milestones{/number}","notifications_url":"https://api.github.com/repos/firedrakeproject/dcore/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/firedrakeproject/dcore/labels{/name}","releases_url":"https://api.github.com/repos/firedrakeproject/dcore/releases{/id}","deployments_url":"https://api.github.com/repos/firedrakeproject/dcore/deployments","created_at":"2016-01-13T09:51:17Z","updated_at":"2016-01-13T14:11:16Z","pushed_at":"2016-03-09T18:11:15Z","git_url":"git://github.com/firedrakeproject/dcore.git","ssh_url":"git@github.com:firedrakeproject/dcore.git","clone_url":"https://github.com/firedrakeproject/dcore.git","svn_url":"https://github.com/firedrakeproject/dcore","homepage":null,"size":70,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":9,"forks":0,"open_issues":9,"watchers":0,"default_branch":"master"}},"base":{"label":"firedrakeproject:master","ref":"master","sha":"ae88d3817279203e39a5c37c30a5dc52b6f6e40a","user":{"login":"firedrakeproject","id":5558005,"avatar_url":"https://avatars.githubusercontent.com/u/5558005?v=3","gravatar_id":"","url":"https://api.github.com/users/firedrakeproject","html_url":"https://github.com/firedrakeproject","followers_url":"https://api.github.com/users/firedrakeproject/followers","following_url":"https://api.github.com/users/firedrakeproject/following{/other_user}","gists_url":"https://api.github.com/users/firedrakeproject/gists{/gist_id}","starred_url":"https://api.github.com/users/firedrakeproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firedrakeproject/subscriptions","organizations_url":"https://api.github.com/users/firedrakeproject/orgs","repos_url":"https://api.github.com/users/firedrakeproject/repos","events_url":"https://api.github.com/users/firedrakeproject/events{/privacy}","received_events_url":"https://api.github.com/users/firedrakeproject/received_events","type":"Organization","site_admin":false},"repo":{"id":49564954,"name":"dcore","full_name":"firedrakeproject/dcore","owner":{"login":"firedrakeproject","id":5558005,"avatar_url":"https://avatars.githubusercontent.com/u/5558005?v=3","gravatar_id":"","url":"https://api.github.com/users/firedrakeproject","html_url":"https://github.com/firedrakeproject","followers_url":"https://api.github.com/users/firedrakeproject/followers","following_url":"https://api.github.com/users/firedrakeproject/following{/other_user}","gists_url":"https://api.github.com/users/firedrakeproject/gists{/gist_id}","starred_url":"https://api.github.com/users/firedrakeproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firedrakeproject/subscriptions","organizations_url":"https://api.github.com/users/firedrakeproject/orgs","repos_url":"https://api.github.com/users/firedrakeproject/repos","events_url":"https://api.github.com/users/firedrakeproject/events{/privacy}","received_events_url":"https://api.github.com/users/firedrakeproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/firedrakeproject/dcore","description":"Three dimensional atmospheric dynamical core using the Gung Ho numerics.","fork":false,"url":"https://api.github.com/repos/firedrakeproject/dcore","forks_url":"https://api.github.com/repos/firedrakeproject/dcore/forks","keys_url":"https://api.github.com/repos/firedrakeproject/dcore/keys{/key_id}","collaborators_url":"https://api.github.com/repos/firedrakeproject/dcore/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/firedrakeproject/dcore/teams","hooks_url":"https://api.github.com/repos/firedrakeproject/dcore/hooks","issue_events_url":"https://api.github.com/repos/firedrakeproject/dcore/issues/events{/number}","events_url":"https://api.github.com/repos/firedrakeproject/dcore/events","assignees_url":"https://api.github.com/repos/firedrakeproject/dcore/assignees{/user}","branches_url":"https://api.github.com/repos/firedrakeproject/dcore/branches{/branch}","tags_url":"https://api.github.com/repos/firedrakeproject/dcore/tags","blobs_url":"https://api.github.com/repos/firedrakeproject/dcore/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/firedrakeproject/dcore/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/firedrakeproject/dcore/git/refs{/sha}","trees_url":"https://api.github.com/repos/firedrakeproject/dcore/git/trees{/sha}","statuses_url":"https://api.github.com/repos/firedrakeproject/dcore/statuses/{sha}","languages_url":"https://api.github.com/repos/firedrakeproject/dcore/languages","stargazers_url":"https://api.github.com/repos/firedrakeproject/dcore/stargazers","contributors_url":"https://api.github.com/repos/firedrakeproject/dcore/contributors","subscribers_url":"https://api.github.com/repos/firedrakeproject/dcore/subscribers","subscription_url":"https://api.github.com/repos/firedrakeproject/dcore/subscription","commits_url":"https://api.github.com/repos/firedrakeproject/dcore/commits{/sha}","git_commits_url":"https://api.github.com/repos/firedrakeproject/dcore/git/commits{/sha}","comments_url":"https://api.github.com/repos/firedrakeproject/dcore/comments{/number}","issue_comment_url":"https://api.github.com/repos/firedrakeproject/dcore/issues/comments{/number}","contents_url":"https://api.github.com/repos/firedrakeproject/dcore/contents/{+path}","compare_url":"https://api.github.com/repos/firedrakeproject/dcore/compare/{base}...{head}","merges_url":"https://api.github.com/repos/firedrakeproject/dcore/merges","archive_url":"https://api.github.com/repos/firedrakeproject/dcore/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/firedrakeproject/dcore/downloads","issues_url":"https://api.github.com/repos/firedrakeproject/dcore/issues{/number}","pulls_url":"https://api.github.com/repos/firedrakeproject/dcore/pulls{/number}","milestones_url":"https://api.github.com/repos/firedrakeproject/dcore/milestones{/number}","notifications_url":"https://api.github.com/repos/firedrakeproject/dcore/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/firedrakeproject/dcore/labels{/name}","releases_url":"https://api.github.com/repos/firedrakeproject/dcore/releases{/id}","deployments_url":"https://api.github.com/repos/firedrakeproject/dcore/deployments","created_at":"2016-01-13T09:51:17Z","updated_at":"2016-01-13T14:11:16Z","pushed_at":"2016-03-09T18:11:15Z","git_url":"git://github.com/firedrakeproject/dcore.git","ssh_url":"git@github.com:firedrakeproject/dcore.git","clone_url":"https://github.com/firedrakeproject/dcore.git","svn_url":"https://github.com/firedrakeproject/dcore","homepage":null,"size":70,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":9,"forks":0,"open_issues":9,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/firedrakeproject/dcore/pulls/20"},"html":{"href":"https://github.com/firedrakeproject/dcore/pull/20"},"issue":{"href":"https://api.github.com/repos/firedrakeproject/dcore/issues/20"},"comments":{"href":"https://api.github.com/repos/firedrakeproject/dcore/issues/20/comments"},"review_comments":{"href":"https://api.github.com/repos/firedrakeproject/dcore/pulls/20/comments"},"review_comment":{"href":"https://api.github.com/repos/firedrakeproject/dcore/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/firedrakeproject/dcore/pulls/20/commits"},"statuses":{"href":"https://api.github.com/repos/firedrakeproject/dcore/statuses/e30d0373685432a2e1e49be2caf200089e392100"}}}}