Repository: PyGithub/PyGithub

Issue:
user.node_id missing 
https://api.github.com/users api has `node_id` but when I get user detail, miss it, why? please be sure all attrs from list can be contained on get user detail, thanks!


Discussion:
I will work on this.

Resolving patch:
diff --git a/github/AuthenticatedUser.py b/github/AuthenticatedUser.py
--- a/github/AuthenticatedUser.py
+++ b/github/AuthenticatedUser.py
@@ -238,6 +238,14 @@ def name(self):
         self._completeIfNotSet(self._name)
         return self._name.value
 
+    @property
+    def node_id(self):
+        """
+        :type: string
+        """
+        self._completeIfNotSet(self._node_id)
+        return self._node_id.value
+
     @property
     def organizations_url(self):
         """
@@ -1206,6 +1214,7 @@ def _initAttributes(self):
         self._location = github.GithubObject.NotSet
         self._login = github.GithubObject.NotSet
         self._name = github.GithubObject.NotSet
+        self._node_id = github.GithubObject.NotSet
         self._organizations_url = github.GithubObject.NotSet
         self._owned_private_repos = github.GithubObject.NotSet
         self._plan = github.GithubObject.NotSet
@@ -1265,6 +1274,8 @@ def _useAttributes(self, attributes):
             self._login = self._makeStringAttribute(attributes["login"])
         if "name" in attributes:  # pragma no branch
             self._name = self._makeStringAttribute(attributes["name"])
+        if "node_id" in attributes:  # pragma no branch
+            self._node_id = self._makeStringAttribute(attributes["node_id"])
         if "organizations_url" in attributes:  # pragma no branch
             self._organizations_url = self._makeStringAttribute(attributes["organizations_url"])
         if "owned_private_repos" in attributes:  # pragma no branch
diff --git a/github/NamedUser.py b/github/NamedUser.py
--- a/github/NamedUser.py
+++ b/github/NamedUser.py
@@ -59,6 +59,14 @@ class NamedUser(github.GithubObject.CompletableGithubObject):
     def __repr__(self):
         return self.get__repr__({"login": self._login.value})
 
+    @property
+    def node_id(self):
+        """
+        :type: string
+        """
+        self._completeIfNotSet(self._node_id)
+        return self._node_id.value
+
     def __hash__(self):
         return hash((self.id, self.login))
 
@@ -605,6 +613,7 @@ def _initAttributes(self):
         self._location = github.GithubObject.NotSet
         self._login = github.GithubObject.NotSet
         self._name = github.GithubObject.NotSet
+        self._node_id = github.GithubObject.NotSet
         self._organizations_url = github.GithubObject.NotSet
         self._owned_private_repos = github.GithubObject.NotSet
         self._permissions = github.GithubObject.NotSet
@@ -668,6 +677,8 @@ def _useAttributes(self, attributes):
             self._login = self._makeStringAttribute(attributes["login"])
         if "name" in attributes:  # pragma no branch
             self._name = self._makeStringAttribute(attributes["name"])
+        if "node_id" in attributes:  # pragma no branch
+            self._node_id = self._makeStringAttribute(attributes["node_id"])
         if "organizations_url" in attributes:  # pragma no branch
             self._organizations_url = self._makeStringAttribute(attributes["organizations_url"])
         if "owned_private_repos" in attributes:  # pragma no branch


Test patch:
diff --git a/github/tests/AuthenticatedUser.py b/github/tests/AuthenticatedUser.py
--- a/github/tests/AuthenticatedUser.py
+++ b/github/tests/AuthenticatedUser.py
@@ -72,6 +72,7 @@ def testAttributes(self):
         self.assertEqual(self.user.total_private_repos, 5)
         self.assertEqual(self.user.type, "User")
         self.assertEqual(self.user.url, "https://api.github.com/users/jacquev6")
+        self.assertEqual(self.user.node_id, "MDQ6VXNlcjMyNzE0Ng==")
 
         # test __repr__() based on this attributes
         self.assertEqual(self.user.__repr__(), 'AuthenticatedUser(login="jacquev6")')
diff --git a/github/tests/NamedUser.py b/github/tests/NamedUser.py
--- a/github/tests/NamedUser.py
+++ b/github/tests/NamedUser.py
@@ -70,6 +70,7 @@ def testAttributesOfOtherUser(self):
         self.assertEqual(self.user.total_private_repos, None)
         self.assertEqual(self.user.type, "User")
         self.assertEqual(self.user.url, "https://api.github.com/users/nvie")
+        self.assertEqual(self.user.node_id, "MDQ6VXNlcjgzODQ0")
 
         # test __repr__() based on this attributes
         self.assertEqual(self.user.__repr__(), 'NamedUser(login="nvie")')
@@ -104,6 +105,7 @@ def testAttributesOfSelf(self):
         self.assertEqual(self.user.total_private_repos, 5)
         self.assertEqual(self.user.type, "User")
         self.assertEqual(self.user.url, "https://api.github.com/users/jacquev6")
+        self.assertEqual(self.user.node_id, "MDQ6VXNlcjMyNzE0Ng==")
 
         # test __repr__() based on this attributes
         self.assertEqual(self.user.__repr__(), 'NamedUser(login="jacquev6")')
diff --git a/github/tests/ReplayData/AuthenticatedUser.testAttributes.txt b/github/tests/ReplayData/AuthenticatedUser.testAttributes.txt
--- a/github/tests/ReplayData/AuthenticatedUser.testAttributes.txt
+++ b/github/tests/ReplayData/AuthenticatedUser.testAttributes.txt
@@ -7,5 +7,5 @@ None
 None
 200
 [('status', '200 OK'), ('x-ratelimit-remaining', '4994'), ('content-length', '801'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"79f748546e5fc4492505a70de6542183"'), ('date', 'Tue, 08 May 2012 09:51:20 GMT'), ('content-type', 'application/json; charset=utf-8')]
-{"public_repos":10,"type":"User","url":"https://api.github.com/users/jacquev6","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","followers":13,"bio":"","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","disk_usage":16692,"plan":{"private_repos":5,"space":614400,"name":"micro","collaborators":1},"html_url":"https://github.com/jacquev6","blog":"http://vincent-jacques.net","login":"jacquev6","email":"vincent@vincent-jacques.net","created_at":"2010-07-09T06:10:06Z","company":"Criteo","location":"Paris, France","total_private_repos":5,"public_gists":1,"following":24,"name":"Vincent Jacques","id":327146,"owned_private_repos":5,"private_gists":5,"collaborators":0,"hireable":false}
+{"public_repos":10,"type":"User","url":"https://api.github.com/users/jacquev6","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","followers":13,"bio":"","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","disk_usage":16692,"plan":{"private_repos":5,"space":614400,"name":"micro","collaborators":1},"html_url":"https://github.com/jacquev6","blog":"http://vincent-jacques.net","login":"jacquev6","email":"vincent@vincent-jacques.net","created_at":"2010-07-09T06:10:06Z","company":"Criteo","location":"Paris, France","total_private_repos":5,"public_gists":1,"following":24,"name":"Vincent Jacques","id":327146,"owned_private_repos":5,"private_gists":5,"collaborators":0,"hireable":false,"node_id":"MDQ6VXNlcjMyNzE0Ng=="}
 
diff --git a/github/tests/ReplayData/NamedUser.setUp.txt b/github/tests/ReplayData/NamedUser.setUp.txt
--- a/github/tests/ReplayData/NamedUser.setUp.txt
+++ b/github/tests/ReplayData/NamedUser.setUp.txt
@@ -7,5 +7,5 @@ None
 None
 200
 [('status', '200 OK'), ('x-ratelimit-remaining', '4960'), ('content-length', '801'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"2b9d2167029cc33666d02e0b0e95f2b9"'), ('date', 'Sat, 26 May 2012 11:08:21 GMT'), ('content-type', 'application/json; charset=utf-8')]
-{"type":"User","disk_usage":17080,"public_gists":2,"url":"https://api.github.com/users/jacquev6","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","public_repos":11,"hireable":false,"private_gists":5,"plan":{"private_repos":5,"collaborators":1,"name":"micro","space":614400},"bio":"","company":"Criteo","blog":"http://vincent-jacques.net","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","login":"jacquev6","total_private_repos":5,"email":"vincent@vincent-jacques.net","collaborators":0,"followers":13,"name":"Vincent Jacques","owned_private_repos":5,"created_at":"2010-07-09T06:10:06Z","suspended_at":"2013-08-10T07:11:07Z","location":"Paris, France","id":327146,"following":24,"html_url":"https://github.com/jacquev6"}
+{"type":"User","disk_usage":17080,"public_gists":2,"url":"https://api.github.com/users/jacquev6","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","public_repos":11,"hireable":false,"private_gists":5,"plan":{"private_repos":5,"collaborators":1,"name":"micro","space":614400},"bio":"","company":"Criteo","blog":"http://vincent-jacques.net","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","login":"jacquev6","total_private_repos":5,"email":"vincent@vincent-jacques.net","collaborators":0,"followers":13,"name":"Vincent Jacques","owned_private_repos":5,"created_at":"2010-07-09T06:10:06Z","suspended_at":"2013-08-10T07:11:07Z","location":"Paris, France","id":327146,"following":24,"html_url":"https://github.com/jacquev6", "node_id":"MDQ6VXNlcjMyNzE0Ng=="}
 
diff --git a/github/tests/ReplayData/NamedUser.testAttributesOfOtherUser.txt b/github/tests/ReplayData/NamedUser.testAttributesOfOtherUser.txt
--- a/github/tests/ReplayData/NamedUser.testAttributesOfOtherUser.txt
+++ b/github/tests/ReplayData/NamedUser.testAttributesOfOtherUser.txt
@@ -7,5 +7,5 @@ None
 None
 200
 [('status', '200 OK'), ('x-ratelimit-remaining', '4994'), ('content-length', '598'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"66a516a2007fb7df8bbb3f9cc7cb2da8"'), ('date', 'Fri, 18 May 2012 19:46:37 GMT'), ('content-type', 'application/json; charset=utf-8')]
-{"public_gists":16,"type":"User","hireable":false,"company":"3rd Cloud","url":"https://api.github.com/users/nvie","gravatar_id":"c5a7f21b46df698f3db31c37ed0cf55a","bio":null,"followers":296,"blog":"http://nvie.com","avatar_url":"https://secure.gravatar.com/avatar/c5a7f21b46df698f3db31c37ed0cf55a?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","login":"nvie","email":"vincent@3rdcloud.com","public_repos":61,"html_url":"https://github.com/nvie","name":"Vincent Driessen","created_at":"2009-05-12T21:19:38Z","location":"Netherlands","id":83844,"following":41}
+{"public_gists":16,"type":"User","hireable":false,"company":"3rd Cloud","url":"https://api.github.com/users/nvie","gravatar_id":"c5a7f21b46df698f3db31c37ed0cf55a","bio":null,"followers":296,"blog":"http://nvie.com","avatar_url":"https://secure.gravatar.com/avatar/c5a7f21b46df698f3db31c37ed0cf55a?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","login":"nvie","email":"vincent@3rdcloud.com","public_repos":61,"html_url":"https://github.com/nvie","name":"Vincent Driessen","created_at":"2009-05-12T21:19:38Z","location":"Netherlands","id":83844,"following":41,"node_id":"MDQ6VXNlcjgzODQ0"}