utils/scanpypi: add flit package support
These packages don't have a setup.py so we instead need to parse their pyproject.toml file. It is possible that such a package does not define a project_urls config item, so ensure we do not choke on it (None.get() would raise). Note that this currently doesn't handle flit package dependency resolution. Signed-off-by: James Hilliard <james.hilliard1@gmail.com> Reviewed-by: Yegor Yefremov <yegorslists@googlemail.com> [yann.morin.1998@free.fr: - add sentence about the project_urls rewrite - fix flake8 errors ] Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
This commit is contained in:
parent
efb5d3fbd8
commit
e241419490
@ -43,6 +43,56 @@ except ImportError:
|
||||
liclookup = None
|
||||
|
||||
|
||||
def toml_load(f):
|
||||
with open(f, 'rb') as fh:
|
||||
ex = None
|
||||
|
||||
# Try standard library tomllib first
|
||||
try:
|
||||
from tomllib import load
|
||||
return load(fh)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Try regular tomli next
|
||||
try:
|
||||
from tomli import load
|
||||
return load(fh)
|
||||
except ImportError as e:
|
||||
ex = e
|
||||
|
||||
# Try pip's vendored tomli
|
||||
try:
|
||||
from pip._vendor.tomli import load
|
||||
try:
|
||||
return load(fh)
|
||||
except TypeError:
|
||||
# Fallback to handle older version
|
||||
try:
|
||||
fh.seek(0)
|
||||
w = io.TextIOWrapper(fh, encoding="utf8", newline="")
|
||||
return load(w)
|
||||
finally:
|
||||
w.detach()
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Try regular toml last
|
||||
try:
|
||||
from toml import load
|
||||
fh.seek(0)
|
||||
w = io.TextIOWrapper(fh, encoding="utf8", newline="")
|
||||
try:
|
||||
return load(w)
|
||||
finally:
|
||||
w.detach()
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
print('This package needs tomli')
|
||||
raise ex
|
||||
|
||||
|
||||
def setup_decorator(func, method):
|
||||
"""
|
||||
Decorator for distutils.core.setup and setuptools.setup.
|
||||
@ -316,6 +366,35 @@ class BuildrootPackage():
|
||||
os.chdir(current_dir)
|
||||
sys.path.remove(self.tmp_extract)
|
||||
|
||||
def load_pyproject(self):
|
||||
"""
|
||||
Loads the corresponding pyproject.toml and store its metadata
|
||||
"""
|
||||
current_dir = os.getcwd()
|
||||
os.chdir(self.tmp_extract)
|
||||
sys.path.insert(0, self.tmp_extract)
|
||||
try:
|
||||
pyproject_data = toml_load('pyproject.toml')
|
||||
try:
|
||||
self.setup_metadata = pyproject_data.get('project', {})
|
||||
self.metadata_name = self.setup_metadata.get('name', self.real_name)
|
||||
build_system = pyproject_data.get('build-system', {})
|
||||
build_backend = build_system.get('build-backend', None)
|
||||
if build_backend and build_backend == 'flit_core.buildapi':
|
||||
self.setup_metadata['method'] = 'flit'
|
||||
elif build_system.get('backend-path', None):
|
||||
self.setup_metadata['method'] = 'pep517'
|
||||
else:
|
||||
self.setup_metadata['method'] = 'unknown'
|
||||
except KeyError:
|
||||
print('ERROR: Could not determine package metadata for {pkg}.\n'
|
||||
.format(pkg=self.real_name))
|
||||
raise
|
||||
except FileNotFoundError:
|
||||
raise
|
||||
os.chdir(current_dir)
|
||||
sys.path.remove(self.tmp_extract)
|
||||
|
||||
def get_requirements(self, pkg_folder):
|
||||
"""
|
||||
Retrieve dependencies from the metadata found in the setup.py script of
|
||||
@ -620,8 +699,12 @@ class BuildrootPackage():
|
||||
if help_lines[-1][-1] != '.':
|
||||
help_lines[-1] += '.'
|
||||
|
||||
home_page = md_info.get('home_page', None) or \
|
||||
md_info.get('project_urls', {}).get('Homepage', None) # noqa: E127
|
||||
home_page = md_info.get('home_page', None)
|
||||
|
||||
if not home_page:
|
||||
project_urls = md_info.get('project_urls', None)
|
||||
if project_urls:
|
||||
home_page = project_urls.get('Homepage', None)
|
||||
|
||||
if home_page:
|
||||
# \t + two spaces is 3 char long
|
||||
@ -699,9 +782,12 @@ def main():
|
||||
except ImportError as err:
|
||||
if 'buildutils' in str(err):
|
||||
print('This package needs buildutils')
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
continue
|
||||
try:
|
||||
package.load_pyproject()
|
||||
except Exception:
|
||||
raise
|
||||
except (AttributeError, KeyError) as error:
|
||||
print('Error: Could not install package {pkg}: {error}'.format(
|
||||
pkg=package.real_name, error=error))
|
||||
|
Loading…
Reference in New Issue
Block a user