1

I am trying to access issue comments using PyGithub library.

this is the function which I implemented,

    def get_issue_comments_dict(self, repository):
        """
        get issue comments
        outputs reponame: issue title, issue url, comments
        Return type: dict 
        """

        repo = self.user_obj.get_repo(repository)
        issues = repo.get_issues()
        issues_dict = {}
        i = 1
        for issue in issues:
            issue_dict = {}
            issue_dict['url'] = issue.url
            issue_dict['title'] = issue.title
            issue_dict['comments'] = [comment for comment in
                    issue.get_issue_comments()]
            issues_dict[i] = issue_dict
            i += 1
        return issues_dict

and this is the error which I face.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "GithubWrapper.py", line 164, in get_issue_comments_dict
    issue.get_issue_comments()]
AttributeError: 'Issue' object has no attribute 'get_issue_comments'

What am I doing wrong here?

  • Can you provide a [mre], and also include the full error traceback? Without it, it will be difficult for people to answer your question. – wovano Aug 12 '19 at 21:37
  • hey @wovano I am trying to solve a specific usecase where I am trying to find details about Github issues, using PyGithub which provides Typed interactions with the GitHub API v3.. I will be using these comments later on for applying another purpose PyGithub documentation doesn't have enough examples and things are not clear there. – code-monk08 Aug 12 '19 at 21:58
  • Well, there are steps that you took that resulted in that error, but we don't know them (i.e. it is not reproducible). And since your code is not complete, we have to guess how it should be used (what is `user_obj`? what is `repository`?). There's really a good reason that Stack Overflow requires a [mre]. If you don't include it, you take the risk that you won't get a qood answer and your question is being closed as off-topic. – wovano Aug 13 '19 at 06:40

2 Answers2

2

Okay, first of all, a Minimal Reproducible Example for your question is:

import github

gh = github.Github()
repo = gh.get_repo('PyGithub/PyGithub')
for issue in repo.get_issues():
    comments = issue.get_issue_comments()

which results in:

AttributeError: 'Issue' object has no attribute 'get_issue_comments'

How to solve this?

Python is literally telling you that the Issue object does not have a method (or any attribute, for that matter) called get_issue_comments. Apparently you're calling the wrong method.

So how can you know which methods are available? I agree the documentation is (at the time of writing) quite limited. You have a number of other options:

Using help()

For any Python object (module, class, method, ...) that has a proper docstring, the built-in help() function is really very helpful ;-)

issue = repo.get_issues()[0]
help(issue)

This will print:

Help on Issue in module github.Issue object:

class Issue(github.GithubObject.CompletableGithubObject)
 |  Issue(requester, headers, attributes, completed)
 |
 |  This class represents Issues. The reference can be found here https://developer.github.com/v3/issues/
 |
 |  Method resolution order:
 |      Issue
 |      github.GithubObject.CompletableGithubObject
 |      github.GithubObject.GithubObject
 |      builtins.object
 |
 |  Methods defined here:
 |
 |  __repr__(self)
 |      Return repr(self).
 |
...
 |
 |  get_comments(self, since=NotSet)
 |      :calls: `GET /repos/:owner/:repo/issues/:number/comments <http://developer.github.com/v3/issues/comments>`_
 |      :param since: datetime.datetime format YYYY-MM-DDTHH:MM:SSZ
 |      :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.IssueComment.IssueComment`
 |
...

As you can see, the class is well documented and apparently it contains a method 'get_comments', which you can use.

Using dir()

You can also see which attributes (such as methods) an object contains, using the built-in function dir():

issue = repo.get_issues()[0]
print(dir(issue))  # in an interactive shell you don't have to print()

This will print:

['CHECK_AFTER_INIT_FLAG', '_CompletableGithubObject__complete', '_CompletableGithubObject__completed', '_GithubObject__makeSimpleAttribute', '_GithubObject__makeSimpleListAttribute', '_GithubObject__makeTransformedAttribute', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_assignee', '_assignees', '_body', '_closed_at', '_closed_by', '_comments', '_comments_url', '_completeIfNeeded', '_completeIfNotSet', '_created_at', '_events_url', '_headers', '_html_url', '_id', '_identity', '_initAttributes', '_labels', '_labels_url', '_locked', '_makeBoolAttribute', '_makeClassAttribute', '_makeDatetimeAttribute', '_makeDictAttribute', '_makeDictOfStringsToClassesAttribute', '_makeIntAttribute', '_makeListOfClassesAttribute', '_makeListOfDictsAttribute', '_makeListOfIntsAttribute', '_makeListOfListOfStringsAttribute', '_makeListOfStringsAttribute', '_makeStringAttribute', '_makeTimestampAttribute', '_milestone', '_number', '_parentUrl', '_pull_request', '_rawData', '_repository', '_requester', '_state', '_storeAndUseAttributes', '_title', '_updated_at', '_url', '_useAttributes', '_user', 'active_lock_reason', 'add_to_assignees', 'add_to_labels', 'as_pull_request', 'assignee', 'assignees', 'body', 'closed_at', 'closed_by', 'comments', 'comments_url', 'create_comment', 'create_reaction', 'created_at', 'delete_labels', 'edit', 'etag', 'events_url', 'get__repr__', 'get_comment', 'get_comments', 'get_events', 'get_labels', 'get_reactions', 'html_url', 'id', 'labels', 'labels_url', 'last_modified', 'lock', 'locked', 'milestone', 'number', 'pull_request', 'raw_data', 'raw_headers', 'remove_from_assignees', 'remove_from_labels', 'repository', 'setCheckAfterInitFlag', 'set_labels', 'state', 'title', 'unlock', 'update', 'updated_at', 'url', 'user']

Here you will also see that it does not include a name 'get_issue_comments', but that it does contain a name 'get_comments'.

Solution

Change the following line:

issue_dict['comments'] = [comment for comment in issue.get_issue_comments()]

to:

issue_dict['comments'] = [comment for comment in issue.get_comments()]
wovano
  • 4,543
  • 5
  • 22
  • 49
  • Thanks @wovano your solutions works perfectly for me, I certainly missed using *dir* or *help* methods while facing this problem. – code-monk08 Aug 13 '19 at 11:01
0

For those who can't see comments themselves, to get comments you should get body of comments, like this:

issues['comment'] = [comment.body for comment in issue.get_comments()]