<s> import collections <EOL> import datetime <EOL> import random <EOL> import pretend <EOL> import pytest <EOL> from warehouse . legacy . api import xmlrpc <EOL> from warehouse . packaging . interfaces import IDownloadStatService <EOL> from warehouse . packaging . models import Classifier <EOL> from ... . common . db . accounts import UserFactory <EOL> from ... . common . db . packaging import ( <EOL> ProjectFactory , ReleaseFactory , FileFactory , RoleFactory , <EOL> JournalEntryFactory , <EOL> ) <EOL> class TestSearch : <EOL> def test_fails_with_invalid_operator ( self ) : <EOL> with pytest . raises ( ValueError ) : <EOL> xmlrpc . search ( pretend . stub ( ) , { } , "<STR_LIT>" ) <EOL> def test_default_search_operator ( self ) : <EOL> class FakeQuery : <EOL> def __init__ ( self , type , must ) : <EOL> self . type = type <EOL> self . must = must <EOL> def __getitem__ ( self , name ) : <EOL> self . offset = name . start <EOL> self . limit = name . stop <EOL> self . step = name . step <EOL> return self <EOL> def execute ( self ) : <EOL> assert self . type == "<STR_LIT:bool>" <EOL> assert [ q . to_dict ( ) for q in self . must ] == [ <EOL> { "<STR_LIT>" : { "<STR_LIT:name>" : "<STR_LIT:foo>" } } , <EOL> { <EOL> "<STR_LIT:bool>" : { <EOL> "<STR_LIT>" : [ <EOL> { "<STR_LIT>" : { "<STR_LIT>" : "<STR_LIT>" } } , <EOL> { "<STR_LIT>" : { "<STR_LIT>" : "<STR_LIT>" } } , <EOL> ] , <EOL> } , <EOL> } , <EOL> ] <EOL> assert self . offset is None <EOL> assert self . limit == <NUM_LIT:1000> <EOL> assert self . step is None <EOL> return [ <EOL> pretend . stub ( <EOL> name = "<STR_LIT:foo>" , <EOL> summary = "<STR_LIT>" , <EOL> version = [ "<STR_LIT:1.0>" ] , <EOL> ) , <EOL> pretend . stub ( <EOL> name = "<STR_LIT>" , <EOL> summary = "<STR_LIT>" , <EOL> version = [ "<STR_LIT>" , "<STR_LIT:1.0>" ] , <EOL> ) , <EOL> ] <EOL> request = pretend . stub ( es = pretend . stub ( query = FakeQuery ) ) <EOL> results = xmlrpc . search ( <EOL> request , <EOL> { "<STR_LIT:name>" : "<STR_LIT:foo>" , "<STR_LIT>" : [ "<STR_LIT>" , "<STR_LIT>" ] } , <EOL> ) <EOL> assert results == [ <EOL> { "<STR_LIT:name>" : "<STR_LIT:foo>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT:1.0>" } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT>" } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT:1.0>" } , <EOL> ] <EOL> def test_searches_with_and ( self ) : <EOL> class FakeQuery : <EOL> def __init__ ( self , type , must ) : <EOL> self . type = type <EOL> self . must = must <EOL> def __getitem__ ( self , name ) : <EOL> self . offset = name . start <EOL> self . limit = name . stop <EOL> self . step = name . step <EOL> return self <EOL> def execute ( self ) : <EOL> assert self . type == "<STR_LIT:bool>" <EOL> assert [ q . to_dict ( ) for q in self . must ] == [ <EOL> { "<STR_LIT>" : { "<STR_LIT:name>" : "<STR_LIT:foo>" } } , <EOL> { <EOL> "<STR_LIT:bool>" : { <EOL> "<STR_LIT>" : [ <EOL> { "<STR_LIT>" : { "<STR_LIT>" : "<STR_LIT>" } } , <EOL> { "<STR_LIT>" : { "<STR_LIT>" : "<STR_LIT>" } } , <EOL> ] , <EOL> } , <EOL> } , <EOL> ] <EOL> assert self . offset is None <EOL> assert self . limit == <NUM_LIT:1000> <EOL> assert self . step is None <EOL> return [ <EOL> pretend . stub ( <EOL> name = "<STR_LIT:foo>" , <EOL> summary = "<STR_LIT>" , <EOL> version = [ "<STR_LIT:1.0>" ] , <EOL> ) , <EOL> pretend . stub ( <EOL> name = "<STR_LIT>" , <EOL> summary = "<STR_LIT>" , <EOL> version = [ "<STR_LIT>" , "<STR_LIT:1.0>" ] , <EOL> ) , <EOL> ] <EOL> request = pretend . stub ( es = pretend . stub ( query = FakeQuery ) ) <EOL> results = xmlrpc . search ( <EOL> request , <EOL> { "<STR_LIT:name>" : "<STR_LIT:foo>" , "<STR_LIT>" : [ "<STR_LIT>" , "<STR_LIT>" ] } , <EOL> "<STR_LIT>" , <EOL> ) <EOL> assert results == [ <EOL> { "<STR_LIT:name>" : "<STR_LIT:foo>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT:1.0>" } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT>" } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT:1.0>" } , <EOL> ] <EOL> def test_searches_with_or ( self ) : <EOL> class FakeQuery : <EOL> def __init__ ( self , type , should ) : <EOL> self . type = type <EOL> self . should = should <EOL> def __getitem__ ( self , name ) : <EOL> self . offset = name . start <EOL> self . limit = name . stop <EOL> self . step = name . step <EOL> return self <EOL> def execute ( self ) : <EOL> assert self . type == "<STR_LIT:bool>" <EOL> assert [ q . to_dict ( ) for q in self . should ] == [ <EOL> { "<STR_LIT>" : { "<STR_LIT:name>" : "<STR_LIT:foo>" } } , <EOL> { <EOL> "<STR_LIT:bool>" : { <EOL> "<STR_LIT>" : [ <EOL> { "<STR_LIT>" : { "<STR_LIT>" : "<STR_LIT>" } } , <EOL> { "<STR_LIT>" : { "<STR_LIT>" : "<STR_LIT>" } } , <EOL> ] , <EOL> } , <EOL> } , <EOL> ] <EOL> assert self . offset is None <EOL> assert self . limit == <NUM_LIT:1000> <EOL> assert self . step is None <EOL> return [ <EOL> pretend . stub ( <EOL> name = "<STR_LIT:foo>" , <EOL> summary = "<STR_LIT>" , <EOL> version = [ "<STR_LIT:1.0>" ] , <EOL> ) , <EOL> pretend . stub ( <EOL> name = "<STR_LIT>" , <EOL> summary = "<STR_LIT>" , <EOL> version = [ "<STR_LIT>" , "<STR_LIT:1.0>" ] , <EOL> ) , <EOL> ] <EOL> request = pretend . stub ( es = pretend . stub ( query = FakeQuery ) ) <EOL> results = xmlrpc . search ( <EOL> request , <EOL> { "<STR_LIT:name>" : "<STR_LIT:foo>" , "<STR_LIT>" : [ "<STR_LIT>" , "<STR_LIT>" ] } , <EOL> "<STR_LIT>" , <EOL> ) <EOL> assert results == [ <EOL> { "<STR_LIT:name>" : "<STR_LIT:foo>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT:1.0>" } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT>" } , <EOL> { "<STR_LIT:name>" : "<STR_LIT>" , "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:version>" : "<STR_LIT:1.0>" } , <EOL> ] <EOL> def test_list_packages ( db_request ) : <EOL> projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:10> ) ] <EOL> assert set ( xmlrpc . list_packages ( db_request ) ) == { p . name for p in projects } <EOL> def test_list_packages_with_serial ( db_request ) : <EOL> projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:10> ) ] <EOL> expected = { } <EOL> for project in projects : <EOL> expected . setdefault ( project . name , <NUM_LIT:0> ) <EOL> for _ in range ( <NUM_LIT:10> ) : <EOL> entry = JournalEntryFactory . create ( name = project . name ) <EOL> if entry . id > expected [ project . name ] : <EOL> expected [ project . name ] = entry . id <EOL> assert xmlrpc . list_packages_with_serial ( db_request ) == expected <EOL> def test_package_hosting_mode_shows_none ( db_request ) : <EOL> assert xmlrpc . package_hosting_mode ( db_request , "<STR_LIT>" ) is None <EOL> def test_package_hosting_mode_results ( db_request ) : <EOL> project = ProjectFactory . create ( hosting_mode = "<STR_LIT>" ) <EOL> assert xmlrpc . package_hosting_mode ( db_request , project . name ) == "<STR_LIT>" <EOL> def test_user_packages ( db_request ) : <EOL> user = UserFactory . create ( ) <EOL> other_user = UserFactory . create ( ) <EOL> owned_projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:5> ) ] <EOL> maintained_projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:5> ) ] <EOL> unowned_projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:5> ) ] <EOL> for project in owned_projects : <EOL> RoleFactory . create ( project = project , user = user ) <EOL> for project in maintained_projects : <EOL> RoleFactory . create ( project = project , user = user , role_name = "<STR_LIT>" ) <EOL> for project in unowned_projects : <EOL> RoleFactory . create ( project = project , user = other_user ) <EOL> assert set ( xmlrpc . user_packages ( db_request , user . username ) ) == set ( [ <EOL> ( "<STR_LIT>" , p . name ) <EOL> for p in sorted ( owned_projects , key = lambda x : x . name ) <EOL> ] + [ <EOL> ( "<STR_LIT>" , p . name ) <EOL> for p in sorted ( maintained_projects , key = lambda x : x . name ) <EOL> ] ) <EOL> @ pytest . mark . parametrize ( "<STR_LIT>" , [ None , <NUM_LIT:1> , <NUM_LIT:5> ] ) <EOL> def test_top_packages ( db_request , num ) : <EOL> projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:10> ) ] <EOL> files = collections . Counter ( ) <EOL> for project in projects : <EOL> releases = [ ReleaseFactory . create ( project = project ) for _ in range ( <NUM_LIT:3> ) ] <EOL> for release in releases : <EOL> file_ = FileFactory . create ( <EOL> release = release , <EOL> filename = "<STR_LIT>" . format ( project . name , release . version ) , <EOL> downloads = random . randint ( <NUM_LIT:0> , <NUM_LIT:1000> ) , <EOL> ) <EOL> files [ project . name ] += file_ . downloads <EOL> assert set ( xmlrpc . top_packages ( db_request , num ) ) == set ( files . most_common ( num ) ) <EOL> def test_package_releases ( db_request ) : <EOL> project1 = ProjectFactory . create ( ) <EOL> releases1 = [ ReleaseFactory . create ( project = project1 ) for _ in range ( <NUM_LIT:10> ) ] <EOL> project2 = ProjectFactory . create ( ) <EOL> [ ReleaseFactory . create ( project = project2 ) for _ in range ( <NUM_LIT:10> ) ] <EOL> result = xmlrpc . package_releases ( db_request , project1 . name ) <EOL> assert result == [ <EOL> r . version <EOL> for r in sorted ( releases1 , key = lambda x : x . _pypi_ordering ) <EOL> ] <EOL> def test_release_data_no_project ( db_request ) : <EOL> assert xmlrpc . release_data ( db_request , "<STR_LIT:foo>" , "<STR_LIT:1.0>" ) == { } <EOL> def test_release_data_no_release ( db_request ) : <EOL> project = ProjectFactory . create ( ) <EOL> assert xmlrpc . release_data ( db_request , project . name , "<STR_LIT:1.0>" ) == { } <EOL> def test_release_data ( db_request ) : <EOL> project = ProjectFactory . create ( ) <EOL> release = ReleaseFactory . create ( project = project ) <EOL> svc = pretend . stub ( <EOL> get_daily_stats = pretend . call_recorder ( lambda n : <NUM_LIT:10> ) , <EOL> get_weekly_stats = pretend . call_recorder ( lambda n : <NUM_LIT> ) , <EOL> get_monthly_stats = pretend . call_recorder ( lambda n : <NUM_LIT> ) , <EOL> ) <EOL> db_request . find_service = pretend . call_recorder ( lambda s : svc ) <EOL> urls = [ pretend . stub ( ) , pretend . stub ( ) ] <EOL> urls_iter = iter ( urls ) <EOL> db_request . route_url = pretend . call_recorder ( <EOL> lambda r , ** kw : next ( urls_iter ) <EOL> ) <EOL> assert xmlrpc . release_data ( db_request , project . name , release . version ) == { <EOL> "<STR_LIT:name>" : release . project . name , <EOL> "<STR_LIT:version>" : release . version , <EOL> "<STR_LIT>" : release . project . stable_version , <EOL> "<STR_LIT>" : release . project . bugtrack_url , <EOL> "<STR_LIT>" : urls [ <NUM_LIT:0> ] , <EOL> "<STR_LIT>" : urls [ <NUM_LIT:1> ] , <EOL> "<STR_LIT>" : release . project . documentation_url , <EOL> "<STR_LIT>" : release . home_page , <EOL> "<STR_LIT>" : release . download_url , <EOL> "<STR_LIT>" : list ( release . project_urls ) , <EOL> "<STR_LIT>" : release . author , <EOL> "<STR_LIT>" : release . author_email , <EOL> "<STR_LIT>" : release . maintainer , <EOL> "<STR_LIT>" : release . maintainer_email , <EOL> "<STR_LIT>" : release . summary , <EOL> "<STR_LIT:description>" : release . description , <EOL> "<STR_LIT>" : release . license , <EOL> "<STR_LIT>" : release . keywords , <EOL> "<STR_LIT>" : release . platform , <EOL> "<STR_LIT>" : list ( release . classifiers ) , <EOL> "<STR_LIT>" : list ( release . requires ) , <EOL> "<STR_LIT>" : list ( release . requires_dist ) , <EOL> "<STR_LIT>" : list ( release . provides ) , <EOL> "<STR_LIT>" : list ( release . provides_dist ) , <EOL> "<STR_LIT>" : list ( release . obsoletes ) , <EOL> "<STR_LIT>" : list ( release . obsoletes_dist ) , <EOL> "<STR_LIT>" : release . requires_python , <EOL> "<STR_LIT>" : list ( release . requires_external ) , <EOL> "<STR_LIT>" : release . _pypi_ordering , <EOL> "<STR_LIT>" : release . _pypi_hidden , <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT>" : <NUM_LIT:10> , <EOL> "<STR_LIT>" : <NUM_LIT> , <EOL> "<STR_LIT>" : <NUM_LIT> , <EOL> } , <EOL> } <EOL> assert db_request . find_service . calls == [ <EOL> pretend . call ( IDownloadStatService ) , <EOL> ] <EOL> assert svc . get_daily_stats . calls == [ pretend . call ( project . name ) ] <EOL> assert svc . get_weekly_stats . calls == [ pretend . call ( project . name ) ] <EOL> assert svc . get_monthly_stats . calls == [ pretend . call ( project . name ) ] <EOL> db_request . route_url . calls == [ <EOL> pretend . call ( "<STR_LIT>" , name = project . name ) , <EOL> pretend . call ( <EOL> "<STR_LIT>" , <EOL> name = project . name , <EOL> version = release . version , <EOL> ) , <EOL> ] <EOL> def test_release_urls ( db_request ) : <EOL> project = ProjectFactory . create ( ) <EOL> release = ReleaseFactory . create ( project = project ) <EOL> file_ = FileFactory . create ( <EOL> release = release , <EOL> filename = "<STR_LIT>" . format ( project . name , release . version ) , <EOL> python_version = "<STR_LIT:source>" , <EOL> ) <EOL> urls = [ pretend . stub ( ) ] <EOL> urls_iter = iter ( urls ) <EOL> db_request . route_url = pretend . call_recorder ( <EOL> lambda r , ** kw : next ( urls_iter ) <EOL> ) <EOL> assert xmlrpc . release_urls ( db_request , project . name , release . version ) == [ <EOL> { <EOL> "<STR_LIT:filename>" : file_ . filename , <EOL> "<STR_LIT>" : file_ . packagetype , <EOL> "<STR_LIT>" : file_ . python_version , <EOL> "<STR_LIT:size>" : file_ . size , <EOL> "<STR_LIT>" : file_ . md5_digest , <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT>" : file_ . md5_digest , <EOL> "<STR_LIT>" : file_ . sha256_digest , <EOL> } , <EOL> "<STR_LIT>" : file_ . has_signature , <EOL> "<STR_LIT>" : file_ . upload_time , <EOL> "<STR_LIT>" : file_ . comment_text , <EOL> "<STR_LIT>" : file_ . downloads , <EOL> "<STR_LIT:url>" : urls [ <NUM_LIT:0> ] , <EOL> } <EOL> ] <EOL> assert db_request . route_url . calls == [ <EOL> pretend . call ( "<STR_LIT>" , path = file_ . path ) , <EOL> ] <EOL> def test_package_roles ( db_request ) : <EOL> project1 , project2 = ProjectFactory . create ( ) , ProjectFactory . create ( ) <EOL> owners1 = [ RoleFactory . create ( project = project1 ) for _ in range ( <NUM_LIT:3> ) ] <EOL> for _ in range ( <NUM_LIT:3> ) : <EOL> RoleFactory . create ( project = project2 ) <EOL> maintainers1 = [ <EOL> RoleFactory . create ( project = project1 , role_name = "<STR_LIT>" ) <EOL> for _ in range ( <NUM_LIT:3> ) <EOL> ] <EOL> for _ in range ( <NUM_LIT:3> ) : <EOL> RoleFactory . create ( project = project2 , role_name = "<STR_LIT>" ) <EOL> result = xmlrpc . package_roles ( db_request , project1 . name ) <EOL> assert result == [ <EOL> ( r . role_name , r . user . username ) <EOL> for r in ( <EOL> sorted ( owners1 , key = lambda x : x . user . username . lower ( ) ) + <EOL> sorted ( maintainers1 , key = lambda x : x . user . username . lower ( ) ) <EOL> ) <EOL> ] <EOL> def test_changelog_last_serial_none ( db_request ) : <EOL> assert xmlrpc . changelog_last_serial ( db_request ) is None <EOL> def test_changelog_last_serial ( db_request ) : <EOL> projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:10> ) ] <EOL> entries = [ ] <EOL> for project in projects : <EOL> for _ in range ( <NUM_LIT:10> ) : <EOL> entries . append ( JournalEntryFactory . create ( name = project . name ) ) <EOL> expected = max ( e . id for e in entries ) <EOL> assert xmlrpc . changelog_last_serial ( db_request ) == expected <EOL> def test_changelog_since_serial ( db_request ) : <EOL> projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:10> ) ] <EOL> entries = [ ] <EOL> for project in projects : <EOL> for _ in range ( <NUM_LIT:10> ) : <EOL> entries . append ( JournalEntryFactory . create ( name = project . name ) ) <EOL> expected = [ <EOL> ( <EOL> e . name , <EOL> e . version , <EOL> int ( <EOL> e . submitted_date <EOL> . replace ( tzinfo = datetime . timezone . utc ) <EOL> . timestamp ( ) <EOL> ) , <EOL> e . action , <EOL> e . id , <EOL> ) <EOL> for e in entries <EOL> ] [ int ( len ( entries ) / <NUM_LIT:2> ) : ] <EOL> serial = entries [ int ( len ( entries ) / <NUM_LIT:2> ) - <NUM_LIT:1> ] . id <EOL> assert xmlrpc . changelog_since_serial ( db_request , serial ) == expected <EOL> @ pytest . mark . parametrize ( "<STR_LIT>" , [ True , False , None ] ) <EOL> def test_changelog ( db_request , with_ids ) : <EOL> projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:10> ) ] <EOL> entries = [ ] <EOL> for project in projects : <EOL> for _ in range ( <NUM_LIT:10> ) : <EOL> entries . append ( JournalEntryFactory . create ( name = project . name ) ) <EOL> entries = sorted ( entries , key = lambda x : x . id ) <EOL> since = int ( <EOL> entries [ int ( len ( entries ) / <NUM_LIT:2> ) ] . submitted_date <EOL> . replace ( tzinfo = datetime . timezone . utc ) <EOL> . timestamp ( ) <EOL> ) <EOL> expected = [ <EOL> ( <EOL> e . name , <EOL> e . version , <EOL> int ( <EOL> e . submitted_date <EOL> . replace ( tzinfo = datetime . timezone . utc ) <EOL> . timestamp ( ) <EOL> ) , <EOL> e . action , <EOL> e . id , <EOL> ) <EOL> for e in entries <EOL> if ( e . submitted_date . replace ( <EOL> tzinfo = datetime . timezone . utc ) . timestamp ( ) > since ) <EOL> ] <EOL> if not with_ids : <EOL> expected = [ e [ : - <NUM_LIT:1> ] for e in expected ] <EOL> extra_args = [ ] <EOL> if with_ids is not None : <EOL> extra_args . append ( with_ids ) <EOL> assert xmlrpc . changelog ( db_request , since - <NUM_LIT:1> , * extra_args ) == expected <EOL> def test_browse ( db_request ) : <EOL> classifiers = [ <EOL> Classifier ( classifier = "<STR_LIT>" ) , <EOL> Classifier ( classifier = "<STR_LIT>" ) , <EOL> Classifier ( classifier = "<STR_LIT>" ) , <EOL> ] <EOL> for classifier in classifiers : <EOL> db_request . db . add ( classifier ) <EOL> projects = [ ProjectFactory . create ( ) for _ in range ( <NUM_LIT:3> ) ] <EOL> releases = [ ] <EOL> for project in projects : <EOL> for _ in range ( <NUM_LIT:10> ) : <EOL> releases . append ( <EOL> ReleaseFactory . create ( <EOL> project = project , <EOL> _classifiers = [ classifiers [ <NUM_LIT:0> ] ] <EOL> ) , <EOL> ) <EOL> releases = sorted ( releases , key = lambda x : ( x . project . name , x . version ) ) <EOL> expected_release = releases [ <NUM_LIT:0> ] <EOL> expected_release . _classifiers = classifiers <EOL> assert set ( xmlrpc . browse ( <EOL> db_request , <EOL> [ "<STR_LIT>" ] <EOL> ) ) == { ( r . name , r . version ) for r in releases } <EOL> assert set ( xmlrpc . browse ( <EOL> db_request , <EOL> [ <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ] , <EOL> ) ) == { ( expected_release . name , expected_release . version ) } <EOL> assert set ( xmlrpc . browse ( <EOL> db_request , <EOL> [ <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ] , <EOL> ) ) == { ( expected_release . name , expected_release . version ) } <EOL> assert set ( xmlrpc . browse ( <EOL> db_request , <EOL> [ <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ] , <EOL> ) ) == { ( expected_release . name , expected_release . version ) } </s>
