Manual implementation of typing of last parameters

This commit is contained in:
Vincent Jacques
2012-06-01 18:54:35 +01:00
parent ed75bb74ec
commit 9954a3fd1b
21 changed files with 160 additions and 77 deletions
@@ -182,7 +182,7 @@
"createElement": {
"mandatoryParameters": [
{ "name": "public", "type": "bool" },
{ "name": "files", "type": "@todo" }
{ "name": "files", "type": "dict:string-InputFileContent" }
],
"optionalParameters": [
{ "name": "description", "type": "string" }
@@ -422,7 +422,7 @@
"edit": {
"optionalParameters": [
{ "name": "description", "type": "string" },
{ "name": "files", "type": "@todo" }
{ "name": "files", "type": "dict:string-InputFileContent" }
]
},
"delete": true,
@@ -934,7 +934,7 @@
"createElement": {
"mandatoryParameters": [
{ "name": "public", "type": "bool" },
{ "name": "files", "type": "@todo" }
{ "name": "files", "type": "dict:string-InputFileContent" }
],
"optionalParameters": [
{ "name": "description", "type": "string" }
@@ -1463,8 +1463,8 @@
{ "name": "parents", "type": "list:GitCommit" }
],
"optionalParameters": [
{ "name": "author", "type": "@todo" },
{ "name": "committer", "type": "@todo" }
{ "name": "author", "type": "InputGitAuthor" },
{ "name": "committer", "type": "InputGitAuthor" }
]
},
"url": [
@@ -1510,7 +1510,7 @@
{ "name": "type", "type": "string" }
],
"optionalParameters": [
{ "name": "tagger", "type": "@todo" }
{ "name": "tagger", "type": "InputGitAuthor" }
]
},
"getElement": {
@@ -1527,7 +1527,7 @@
"type": "GitTree",
"createElement": {
"mandatoryParameters": [
{ "name": "tree", "type": "@todo" }
{ "name": "tree", "type": "list:InputGitTreeElement" }
],
"optionalParameters": [
{ "name": "base_tree", "type": "string" }
@@ -1205,8 +1205,9 @@
{
"type": {
"simple": false,
"cardinality": "scalar",
"name": "@todo"
"key_name": "string",
"cardinality": "dict",
"name": "InputFileContent"
},
"name": "files"
}
@@ -2585,8 +2586,9 @@
{
"type": {
"simple": false,
"cardinality": "scalar",
"name": "@todo"
"key_name": "string",
"cardinality": "dict",
"name": "InputFileContent"
},
"name": "files"
}
@@ -5331,8 +5333,9 @@
{
"type": {
"simple": false,
"cardinality": "scalar",
"name": "@todo"
"key_name": "string",
"cardinality": "dict",
"name": "InputFileContent"
},
"name": "files"
}
@@ -8453,7 +8456,7 @@
"type": {
"simple": false,
"cardinality": "scalar",
"name": "@todo"
"name": "InputGitAuthor"
},
"name": "author"
},
@@ -8461,7 +8464,7 @@
"type": {
"simple": false,
"cardinality": "scalar",
"name": "@todo"
"name": "InputGitAuthor"
},
"name": "committer"
}
@@ -8707,7 +8710,7 @@
"type": {
"simple": false,
"cardinality": "scalar",
"name": "@todo"
"name": "InputGitAuthor"
},
"name": "tagger"
}
@@ -8774,8 +8777,8 @@
{
"type": {
"simple": false,
"cardinality": "scalar",
"name": "@todo"
"cardinality": "list",
"name": "InputGitTreeElement"
},
"name": "tree"
}
+10 -5
View File
@@ -19,20 +19,25 @@ description = json.load( open( os.path.join( os.path.dirname( __file__ ), "JsonD
for class_ in description[ "classes" ]:
dependencies = set()
class_[ "needsPaginatedList" ] = False
class_[ "needsDefaultValue" ] = False
for method in class_[ "methods" ]:
if method[ "type" ][ "cardinality" ] == "list":
class_[ "needsPaginatedList" ] = True
if len( method[ "optionalParameters" ] ) != 0:
class_[ "needsDefaultValue" ] = True
if not method[ "type" ][ "simple" ]:
dependencies.add( method[ "type" ][ "name" ] )
for parameter in itertools.chain( method[ "mandatoryParameters" ], method[ "optionalParameters" ] ):
if not parameter[ "type" ][ "simple" ]:
dependencies.add( parameter[ "type" ][ "name" ] )
for attribute in class_[ "attributes" ]:
if not attribute[ "type" ][ "simple" ]:
dependencies.add( attribute[ "type" ][ "name" ] )
for thing in itertools.chain( class_[ "methods" ], class_[ "attributes" ] ):
if not thing[ "type" ][ "simple" ]:
dependencies.add( thing[ "type" ][ "name" ] )
class_[ "dependencies" ] = list( dependencies )
class_[ "needsUrllib" ] = class_[ "name" ] in [ "Label", "Repository" ]
githubObjectTemplate = django.template.loader.get_template( "GithubObject.py" )
@@ -12,14 +12,12 @@
def _useAttributes( self, attributes ):
{% for attribute in class.attributes|dictsort:"name" %}
{% if attribute.type.name != "@todo" %}
{% with simple_or_complex=attribute.type.simple|yesno:"simple,complex_as_dict" %}
{% with simple_or_complex=attribute.type.simple|yesno:"simple,complex_as_dict" %}
if "{{ attribute.name }}" in attributes: # pragma no branch
{% with template_name="GithubObject.IsInstance."|add:attribute.type.cardinality|add:"."|add:simple_or_complex|add:".py" %}
{% with template_name="GithubObject.IsInstance."|add:attribute.type.cardinality|add:"."|add:simple_or_complex|add:".py" %}
assert attributes[ "{{ attribute.name }}" ] is None or {% include template_name with variable="attributes[ \""|add:attribute.name|add:"\" ]"|safe type=attribute.type only %}, attributes[ "{{ attribute.name }}" ]
{% endwith %}
{% endwith %}
{% endif %}
{% endwith %}
{% endwith %}
{% with simple_or_complex=attribute.type.simple|yesno:"simple,complex" %}
{% with template_name="GithubObject.AttributeValue."|add:simple_or_complex|add:".py" %}
@@ -0,0 +1 @@
all( {% include "GithubObject.IsInstance.py" with variable="element" type=type.name|add:"."|add:type.name only %} for element in {{ variable }}.itervalues() )
@@ -1,21 +1,17 @@
{% for parameter in method.mandatoryParameters %}
{% if parameter.type.name != "@todo" %}
{% with simple_or_complex=parameter.type.simple|yesno:"simple,complex" %}
{% with template_name="GithubObject.IsInstance."|add:parameter.type.cardinality|add:"."|add:simple_or_complex|add:".py" %}
{% with simple_or_complex=parameter.type.simple|yesno:"simple,complex" %}
{% with template_name="GithubObject.IsInstance."|add:parameter.type.cardinality|add:"."|add:simple_or_complex|add:".py" %}
assert {% include template_name with variable=parameter.name type=parameter.type only %}, {{ parameter.name }}
{% endwith %}
{% endwith %}
{% endif %}
{% endwith %}
{% endfor %}
{% for parameter in method.optionalParameters %}
{% if parameter.type.name != "@todo" %}
{% with simple_or_complex=parameter.type.simple|yesno:"simple,complex" %}
{% with template_name="GithubObject.IsInstance."|add:parameter.type.cardinality|add:"."|add:simple_or_complex|add:".py" %}
{% with simple_or_complex=parameter.type.simple|yesno:"simple,complex" %}
{% with template_name="GithubObject.IsInstance."|add:parameter.type.cardinality|add:"."|add:simple_or_complex|add:".py" %}
assert {{ parameter.name }} is GithubObject.NotSet or {% include template_name with variable=parameter.name type=parameter.type only %}, {{ parameter.name }}
{% endwith %}
{% endwith %}
{% endif %}
{% endwith %}
{% endfor %}
{% if method.variadicParameter %}
+1 -1
View File
@@ -1 +1 @@
{% if type.name != "void" and type.name != "@todo" %}: {% if type.cardinality == "list" %}list of {% endif %}{% if type.cardinality == "dict" %}dict of {{ type.key_name }} to {% endif %}{% if not type.simple %}`{% endif %}{{ type.name }}{% if not type.simple %}`{% endif %}{% endif %}
{% if type.name != "void" %}: {% if type.cardinality == "list" %}list of {% endif %}{% if type.cardinality == "dict" %}dict of {{ type.key_name }} to {% endif %}{% if not type.simple %}`{% endif %}{{ type.name }}{% if not type.simple %}`{% endif %}{% endif %}
+7 -7
View File
@@ -88,7 +88,7 @@ Gists
-----
* `create_gist( public, files, [description] )`: `Gist`
* `public`: bool
* `files`
* `files`: dict of string to `InputFileContent`
* `description`: string
* `get_gists()`: list of `Gist`
* `get_starred_gists()`: list of `Gist`
@@ -368,7 +368,7 @@ Modification
------------
* `edit( [description, files] )`
* `description`: string
* `files`
* `files`: dict of string to `InputFileContent`
Starring
--------
@@ -758,7 +758,7 @@ Gists
-----
* `create_gist( public, files, [description] )`: `Gist`
* `public`: bool
* `files`
* `files`: dict of string to `InputFileContent`
* `description`: string
* `get_gists()`: list of `Gist`
@@ -1107,8 +1107,8 @@ Git_commits
* `message`: string
* `tree`: string
* `parents`: list of `GitCommit`
* `author`
* `committer`
* `author`: `InputGitAuthor`
* `committer`: `InputGitAuthor`
* `get_git_commit( sha )`: `GitCommit`
* `sha`: string
@@ -1128,14 +1128,14 @@ Git_tags
* `message`: string
* `object`: string
* `type`: string
* `tagger`
* `tagger`: `InputGitAuthor`
* `get_git_tag( sha )`: `GitTag`
* `sha`: string
Git_trees
---------
* `create_git_tree( tree, [base_tree] )`: `GitTree`
* `tree`
* `tree`: list of `InputGitTreeElement`
* `base_tree`: string
* `get_git_tree( sha, [recursive] )`: `GitTree`
* `sha`: string
+3 -1
View File
@@ -4,6 +4,7 @@
import GithubObject
import PaginatedList
##########
import InputFileContent
import Gist
import Repository
import NamedUser
@@ -204,10 +205,11 @@ class AuthenticatedUser( GithubObject.GithubObject ):
def create_gist( self, public, files, description = GithubObject.NotSet ):
assert isinstance( public, bool ), public
assert all( isinstance( element, InputFileContent.InputFileContent ) for element in files.itervalues() ), files
assert description is GithubObject.NotSet or isinstance( description, ( str, unicode ) ), description
post_parameters = {
"public": public,
"files": files,
"files": { key : value._identity() for key, value in files.iteritems() },
}
if description is not GithubObject.NotSet:
post_parameters[ "description" ] = description
+6 -4
View File
@@ -4,11 +4,12 @@
import GithubObject
import PaginatedList
##########
import NamedUser
import GistHistoryState
import GistFile
import Gist
import GistComment
import NamedUser
import GistFile
import InputFileContent
import GistHistoryState
class Gist( GithubObject.GithubObject ):
@property
@@ -121,11 +122,12 @@ class Gist( GithubObject.GithubObject ):
def edit( self, description = GithubObject.NotSet, files = GithubObject.NotSet ):
assert description is GithubObject.NotSet or isinstance( description, ( str, unicode ) ), description
assert files is GithubObject.NotSet or all( isinstance( element, InputFileContent.InputFileContent ) for element in files.itervalues() ), files
post_parameters = dict()
if description is not GithubObject.NotSet:
post_parameters[ "description" ] = description
if files is not GithubObject.NotSet:
post_parameters[ "files" ] = files
post_parameters[ "files" ] = { key : value._identity() for key, value in files.iteritems() }
status, headers, data = self._request(
"PATCH",
str( self.url ),
+8
View File
@@ -0,0 +1,8 @@
class InputFileContent:
def __init__( self, content ):
self.__content = content
def _identity( self ):
return {
"content": self.__content,
}
+12
View File
@@ -0,0 +1,12 @@
class InputGitAuthor:
def __init__( self, name, email, date ):
self.__name = name
self.__email = email
self.__date = date
def _identity( self ):
return {
"name": self.__name,
"email": self.__email,
"date": self.__date,
}
+21
View File
@@ -0,0 +1,21 @@
import GithubObject
class InputGitTreeElement:
def __init__( self, path, mode, type, content = GithubObject.NotSet, sha = GithubObject.NotSet ):
self.__path = path
self.__mode = mode
self.__type = type
self.__content = content
self.__sha = sha
def _identity( self ):
identity = {
"path": self.__path,
"mode": self.__mode,
"type": self.__type,
}
if self.__sha is not GithubObject.NotSet:
identity[ "sha" ] = self.__sha
if self.__content is not GithubObject.NotSet:
identity[ "content" ] = self.__content
return identity
+3 -1
View File
@@ -9,6 +9,7 @@ import Repository
import NamedUser
import Plan
import Organization
import InputFileContent
import Event
class NamedUser( GithubObject.GithubObject ):
@@ -144,10 +145,11 @@ class NamedUser( GithubObject.GithubObject ):
def create_gist( self, public, files, description = GithubObject.NotSet ):
assert isinstance( public, bool ), public
assert all( isinstance( element, InputFileContent.InputFileContent ) for element in files.itervalues() ), files
assert description is GithubObject.NotSet or isinstance( description, ( str, unicode ) ), description
post_parameters = {
"public": public,
"files": files,
"files": { key : value._identity() for key, value in files.iteritems() },
}
if description is not GithubObject.NotSet:
post_parameters[ "description" ] = description
+11 -5
View File
@@ -9,6 +9,7 @@ import PaginatedList
import Branch
import IssueEvent
import Label
import InputGitAuthor
import GitBlob
import Organization
import GitRef
@@ -18,7 +19,7 @@ import PullRequest
import RepositoryKey
import NamedUser
import Milestone
import Permissions
import InputGitTreeElement
import Comparison
import CommitComment
import GitCommit
@@ -29,6 +30,7 @@ import Hook
import Tag
import GitTag
import Download
import Permissions
import Event
class Repository( GithubObject.GithubObject ):
@@ -246,15 +248,17 @@ class Repository( GithubObject.GithubObject ):
assert isinstance( message, ( str, unicode ) ), message
assert isinstance( tree, ( str, unicode ) ), tree
assert all( isinstance( element, GitCommit.GitCommit ) for element in parents ), parents
assert author is GithubObject.NotSet or isinstance( author, InputGitAuthor.InputGitAuthor ), author
assert committer is GithubObject.NotSet or isinstance( committer, InputGitAuthor.InputGitAuthor ), committer
post_parameters = {
"message": message,
"tree": tree,
"parents": parents,
}
if author is not GithubObject.NotSet:
post_parameters[ "author" ] = author
post_parameters[ "author" ] = author._identity()
if committer is not GithubObject.NotSet:
post_parameters[ "committer" ] = committer
post_parameters[ "committer" ] = committer._identity()
status, headers, data = self._request(
"POST",
str( self.url ) + "/git/commits",
@@ -285,6 +289,7 @@ class Repository( GithubObject.GithubObject ):
assert isinstance( message, ( str, unicode ) ), message
assert isinstance( object, ( str, unicode ) ), object
assert isinstance( type, ( str, unicode ) ), type
assert tagger is GithubObject.NotSet or isinstance( tagger, InputGitAuthor.InputGitAuthor ), tagger
post_parameters = {
"tag": tag,
"message": message,
@@ -292,7 +297,7 @@ class Repository( GithubObject.GithubObject ):
"type": type,
}
if tagger is not GithubObject.NotSet:
post_parameters[ "tagger" ] = tagger
post_parameters[ "tagger" ] = tagger._identity()
status, headers, data = self._request(
"POST",
str( self.url ) + "/git/tags",
@@ -303,9 +308,10 @@ class Repository( GithubObject.GithubObject ):
return GitTag.GitTag( self._requester, data, completed = True )
def create_git_tree( self, tree, base_tree = GithubObject.NotSet ):
assert all( isinstance( element, InputGitTreeElement.InputGitTreeElement ) for element in tree ), tree
assert base_tree is GithubObject.NotSet or isinstance( base_tree, ( str, unicode ) ), base_tree
post_parameters = {
"tree": tree,
"tree": [ element._identity() for element in tree ],
}
if base_tree is not GithubObject.NotSet:
post_parameters[ "base_tree" ] = base_tree
+3
View File
@@ -1,2 +1,5 @@
from Github import Github
from GithubException import GithubException
from InputFileContent import InputFileContent
from InputGitAuthor import InputGitAuthor
from InputGitTreeElement import InputGitTreeElement
+4 -2
View File
@@ -1,5 +1,7 @@
import Framework
import github
class AuthenticatedUser( Framework.TestCase ):
def setUp( self ):
Framework.TestCase.setUp( self )
@@ -94,13 +96,13 @@ class AuthenticatedUser( Framework.TestCase ):
self.assertEqual( authorization.id, 372294 )
def testCreateGist( self ):
gist = self.user.create_gist( True, { "foobar.txt": { "content": "File created by PyGithub" } }, "Gist created by PyGithub" )
gist = self.user.create_gist( True, { "foobar.txt": github.InputFileContent( "File created by PyGithub" ) }, "Gist created by PyGithub" )
self.assertEqual( gist.description, "Gist created by PyGithub" )
self.assertEqual( gist.files.keys(), [ "foobar.txt" ] )
self.assertEqual( gist.files[ "foobar.txt" ].content, "File created by PyGithub" )
def testCreateGistWithoutDescription( self ):
gist = self.user.create_gist( True, { "foobar.txt": { "content": "File created by PyGithub" } } )
gist = self.user.create_gist( True, { "foobar.txt": github.InputFileContent( "File created by PyGithub" ) } )
self.assertEqual( gist.description, None )
self.assertEqual( gist.files.keys(), [ "foobar.txt" ] )
self.assertEqual( gist.files[ "foobar.txt" ].content, "File created by PyGithub" )
+3 -1
View File
@@ -1,5 +1,7 @@
import Framework
import github
class Gist( Framework.TestCase ):
def setUp( self ):
Framework.TestCase.setUp( self )
@@ -39,7 +41,7 @@ class Gist( Framework.TestCase ):
self.assertEquals( self.gist.updated_at, "2012-05-19T07:00:58Z" )
def testEditWithAllParameters( self ):
self.gist.edit( "Description edited by PyGithub", { "barbaz.txt": { "content": "File also created by PyGithub" } } )
self.gist.edit( "Description edited by PyGithub", { "barbaz.txt": github.InputFileContent( "File also created by PyGithub" ) } )
self.assertEquals( self.gist.description, "Description edited by PyGithub" )
self.assertEquals( self.gist.updated_at, "2012-05-19T07:06:10Z" )
self.assertEquals( self.gist.files.keys(), [ "foobar.txt", "barbaz.txt" ] )
+4 -2
View File
@@ -1,5 +1,7 @@
import Framework
import github
class NamedUser( Framework.TestCase ):
def setUp( self ):
Framework.TestCase.setUp( self )
@@ -64,11 +66,11 @@ class NamedUser( Framework.TestCase ):
self.assertEqual( self.user.url, "https://api.github.com/users/jacquev6" )
def testCreateGist( self ):
gist = self.user.create_gist( True, { "foobar.txt": { "content": "File created by PyGithub" } }, "Gist created by PyGithub on a NamedUser" )
gist = self.user.create_gist( True, { "foobar.txt": github.InputFileContent( "File created by PyGithub" ) }, "Gist created by PyGithub on a NamedUser" )
self.assertEqual( gist.description, "Gist created by PyGithub on a NamedUser" )
def testCreateGistWithoutDescription( self ):
gist = self.user.create_gist( True, { "foobar.txt": { "content": "File created by PyGithub" } } )
gist = self.user.create_gist( True, { "foobar.txt": github.InputFileContent( "File created by PyGithub" ) } )
self.assertEqual( gist.description, None )
def testGetGists( self ):
@@ -0,0 +1,5 @@
POST /repos/jacquev6/PyGithub/git/trees {'Authorization': 'Basic login_and_password_removed'} {"tree": [{"path": "Barbaz.txt", "type": "blob", "mode": "100644", "sha": "5dd930f591cd5188e9ea7200e308ad355182a1d8"}]}
201
[('status', '201 Created'), ('x-ratelimit-remaining', '4997'), ('content-length', '381'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"f33782d7031ff19c5301bb52068533cf"'), ('date', 'Fri, 01 Jun 2012 17:51:04 GMT'), ('content-type', 'application/json; charset=utf-8'), ('location', 'https://api.github.com/repos/jacquev6/PyGithub/git/trees/fae707821159639589bf94f3fb0a7154ec5d441b')]
{"url":"https://api.github.com/repos/jacquev6/PyGithub/git/trees/fae707821159639589bf94f3fb0a7154ec5d441b","sha":"fae707821159639589bf94f3fb0a7154ec5d441b","tree":[{"type":"blob","url":"https://api.github.com/repos/jacquev6/PyGithub/git/blobs/5dd930f591cd5188e9ea7200e308ad355182a1d8","sha":"5dd930f591cd5188e9ea7200e308ad355182a1d8","size":0,"path":"Barbaz.txt","mode":"100644"}]}
+27 -14
View File
@@ -1,5 +1,7 @@
import Framework
import github
class Repository( Framework.TestCase ):
def setUp( self ):
Framework.TestCase.setUp( self )
@@ -125,33 +127,44 @@ class Repository( Framework.TestCase ):
def testCreateGitTree( self ):
tree = self.repo.create_git_tree(
[ {
"path": "Foobar.txt",
"mode": "100644",
"type": "blob",
"content": "File created by PyGithub"
} ]
[ github.InputGitTreeElement(
"Foobar.txt",
"100644",
"blob",
content = "File created by PyGithub"
) ]
)
self.assertEqual( tree.sha, "41cf8c178c636a018d537cb20daae09391efd70b" )
def testCreateGitTreeWithBaseTree( self ):
tree = self.repo.create_git_tree(
[ {
"path": "Barbaz.txt",
"mode": "100644",
"type": "blob",
"content": "File also created by PyGithub"
} ],
[ github.InputGitTreeElement(
"Barbaz.txt",
"100644",
"blob",
content = "File also created by PyGithub"
) ],
"41cf8c178c636a018d537cb20daae09391efd70b"
)
self.assertEqual( tree.sha, "107139a922f33bab6fbeb9f9eb8787e7f19e0528" )
def testCreateGitTreeWithSha( self ):
tree = self.repo.create_git_tree(
[ github.InputGitTreeElement(
"Barbaz.txt",
"100644",
"blob",
sha = "5dd930f591cd5188e9ea7200e308ad355182a1d8"
) ]
)
self.assertEqual( tree.sha, "fae707821159639589bf94f3fb0a7154ec5d441b" )
def testCreateGitCommit( self ):
commit = self.repo.create_git_commit( "Commit created by PyGithub", "107139a922f33bab6fbeb9f9eb8787e7f19e0528", [] )
self.assertEqual( commit.sha, "0b820628236ab8bab3890860fc414fa757ca15f4" )
def testCreateGitCommitWithAllArguments( self ):
commit = self.repo.create_git_commit( "Commit created by PyGithub", "107139a922f33bab6fbeb9f9eb8787e7f19e0528", [], { "name" : "John Doe", "email" : "j.doe@vincent-jacques.net", "date": "2008-07-09T16:13:30+12:00" }, { "name" : "John Doe", "email" : "j.doe@vincent-jacques.net", "date": "2008-07-09T16:13:30+12:00" } )
commit = self.repo.create_git_commit( "Commit created by PyGithub", "107139a922f33bab6fbeb9f9eb8787e7f19e0528", [], github.InputGitAuthor( "John Doe", "j.doe@vincent-jacques.net", "2008-07-09T16:13:30+12:00" ), github.InputGitAuthor( "John Doe", "j.doe@vincent-jacques.net", "2008-07-09T16:13:30+12:00" ) )
self.assertEqual( commit.sha, "526946197ae9da59c6507cacd13ad6f1cfb686ea" )
def testCreateGitTag( self ):
@@ -159,7 +172,7 @@ class Repository( Framework.TestCase ):
self.assertEqual( tag.sha, "5ba561eaa2b7ca9015662510157b15d8f3b0232a" )
def testCreateGitTagWithAllArguments( self ):
tag = self.repo.create_git_tag( "TaggedByPyGithub2", "Tag also created by PyGithub", "526946197ae9da59c6507cacd13ad6f1cfb686ea", "commit", { "name" : "John Doe", "email" : "j.doe@vincent-jacques.net", "date": "2008-07-09T16:13:30+12:00" } )
tag = self.repo.create_git_tag( "TaggedByPyGithub2", "Tag also created by PyGithub", "526946197ae9da59c6507cacd13ad6f1cfb686ea", "commit", github.InputGitAuthor( "John Doe", "j.doe@vincent-jacques.net", "2008-07-09T16:13:30+12:00" ) )
self.assertEqual( tag.sha, "f0e99a8335fbc84c53366c4a681118468f266625" )
def testCreateKey( self ):