Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sage
Path: blob/develop/build/sage_bootstrap/pypi.py
4052 views
1
# -*- coding: utf-8 -*-
2
"""
3
PyPi Version Information
4
"""
5
6
7
# ****************************************************************************
8
# Copyright (C) 2016 Volker Braun <[email protected]>
9
# 2020-2023 Matthias Koeppe
10
#
11
# This program is free software: you can redistribute it and/or modify
12
# it under the terms of the GNU General Public License as published by
13
# the Free Software Foundation, either version 2 of the License, or
14
# (at your option) any later version.
15
# https://www.gnu.org/licenses/
16
# ****************************************************************************
17
18
import logging
19
log = logging.getLogger()
20
21
import json
22
23
from sage_bootstrap.package import Package
24
from sage_bootstrap.updater import PackageUpdater
25
from sage_bootstrap.compat import urllib
26
27
28
class PyPiNotFound(Exception):
29
pass
30
31
32
class PyPiError(Exception):
33
pass
34
35
36
class PyPiVersion(object):
37
38
def __init__(self, package_name, source='normal'):
39
self.name = package_name
40
self.json = self._get_json()
41
# Replace provided name with the canonical name
42
self.name = self.json['info']['name']
43
if source == 'wheel':
44
self.python_version = 'py3'
45
else:
46
self.python_version = 'source'
47
48
def _get_json(self):
49
response = urllib.urlopen(self.json_url)
50
if response.getcode() != 200:
51
raise PyPiNotFound('%s not on pypi', self.name)
52
data = response.read()
53
text = data.decode('utf-8')
54
return json.loads(text)
55
56
@property
57
def json_url(self):
58
return 'https://pypi.python.org/pypi/{0}/json'.format(self.name)
59
60
@property
61
def version(self):
62
"""
63
Return the current version
64
"""
65
return self.json['info']['version']
66
67
@property
68
def url(self):
69
"""
70
Return the source url
71
"""
72
for download in self.json['urls']:
73
if self.python_version in download['python_version']:
74
self.python_version = download['python_version']
75
return download['url']
76
raise PyPiError('No %s url for %s found', self.python_version, self.name)
77
78
@property
79
def tarball(self):
80
"""
81
Return the source tarball name
82
"""
83
for download in self.json['urls']:
84
if self.python_version in download['python_version']:
85
self.python_version = download['python_version']
86
return download['filename']
87
raise PyPiError('No %s url for %s found', self.python_version, self.name)
88
89
@property
90
def package_url(self):
91
"""
92
Return the package URL
93
"""
94
return self.json['info']['package_url']
95
96
@property
97
def license(self):
98
"""
99
Return the package license
100
"""
101
return self.json['info']['license']
102
103
@property
104
def summary(self):
105
"""
106
Return the package summary
107
"""
108
return self.json['info']['summary']
109
110
@property
111
def requires_dist(self):
112
"""
113
Return the dependencies
114
"""
115
return self.json['info']['requires_dist']
116
117
@property
118
def requires_python(self):
119
"""
120
Return the requires_python attribute
121
"""
122
return self.json['info']['requires_python']
123
124
def update(self, package=None):
125
if package is None:
126
package = Package(self.name)
127
if package.version == self.version:
128
log.info('%s is already at the latest version', self.name)
129
return
130
log.info('Updating %s: %s -> %s', package.name, package.version, self.version)
131
update = PackageUpdater(package.name, self.version)
132
update.download_upstream(self.url)
133
update.fix_checksum()
134
135