Repository: sigmavirus24/github3.py

Issue:
Null Milestone creator causing Repository.issue() to crash
When trying to get an issue that has a Milestone without a creator, github3.py crashes.

I think the fix is simple -- add a guard check before trying to create the User for the milestone.creator (like what is done for getting the milestone from an issue -- it first checks if the milestone truth-y before acting on it).

I'm working on a PR with a regression test and a patch, which I should have up shortly.

Here's a simple test case to reproduce the exception:

```
import github3
repo = github3.repository("Code4HR", "localart")
milestone = repo.milestone(2)
```

Here's the traceback from iPython (with Python 3.5.0):
```
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-50-4132b3c2312f> in <module>()
----> 1 r.milestone(2)

python3.5/site-packages/github3/repos/repo.py in milestone(self, number)
   1664                                   base_url=self._api)
   1665             json = self._json(self._get(url), 200)
-> 1666         return Milestone(json, self) if json else None
   1667
   1668     @requires_auth

python3.5/site-packages/github3/issues/milestone.py in __init__(self, mile, session)
     28         #: :class:`User <github3.users.User>` object representing the creator
     29         #: of the milestone.
---> 30         self.creator = User(mile.get('creator'), self._session)
     31         #: Number of issues associated with this milestone which are still
     32         #: open.

python3.5/site-packages/github3/users.py in __init__(self, user, session)
    121
    122     def __init__(self, user, session=None):
--> 123         super(User, self).__init__(user, session)
    124         if not self.type:
    125             self.type = 'User'

python3.5/site-packages/github3/models.py in __init__(self, acct, session)
    312         #: Tells you what type of account this is
    313         self.type = None
--> 314         if acct.get('type'):
    315             self.type = acct.get('type')
    316         self._api = acct.get('url', '')

AttributeError: 'NoneType' object has no attribute 'get'
```

Discussion:

Patch:
diff --git a/AUTHORS.rst b/AUTHORS.rst
index 7bd1fec1..7d7615b9 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -106,3 +106,5 @@ Contributors
 - Sourav Singh(@souravsingh)
 
 - Matt Chung (@itsmemattchung)
+
+- Chris Thompson (@notyetsecure)
diff --git a/github3/issues/milestone.py b/github3/issues/milestone.py
index e55b9e74..55d86bd1 100644
--- a/github3/issues/milestone.py
+++ b/github3/issues/milestone.py
@@ -26,7 +26,9 @@ class Milestone(GitHubCore):
         self.description = mile.get('description')
         #: :class:`User <github3.users.User>` object representing the creator
         #: of the milestone.
-        self.creator = User(mile.get('creator'), self)
+        self.creator = None
+        if mile.get('creator'):
+            self.creator = User(mile.get('creator'), self)
         #: Number of issues associated with this milestone which are still
         #: open.
         self.open_issues = mile.get('open_issues')


Test patch:
diff --git a/tests/test_issues.py b/tests/test_issues.py
index c36e3267..cdfa422b 100644
--- a/tests/test_issues.py
+++ b/tests/test_issues.py
@@ -121,6 +121,12 @@ class TestMilestone(BaseCase):
                              '2013-12-31T23:59:59Z')
         self.mock_assertions()
 
+    def test_issue_465(self):
+        json = self.m.as_dict().copy()
+        json['creator'] = None
+        m = Milestone(json)
+        assert m.creator is None
+
 
 class TestIssue(BaseCase):
     def __init__(self, methodName='runTest'):