Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow getting version despite deps missing #382

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions flit_core/flit_core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,18 @@ def get_docstring_and_version_via_import(target):
from it.
"""
log.debug("Loading module %s", target.file)
from importlib.machinery import SourceFileLoader
sl = SourceFileLoader(target.name, str(target.file))
with _module_load_ctx():
m = sl.load_module()
from importlib.util import spec_from_file_location, module_from_spec
spec = spec_from_file_location(target.name, str(target.file))
m = module_from_spec(spec)
try:
error = None
with _module_load_ctx():
spec.loader.exec_module(m)
except ImportError as e:
error = e
docstring = m.__dict__.get('__doc__', None)
version = m.__dict__.get('__version__', None)
return docstring, version
return docstring, version, error


def get_info_from_module(target):
Expand All @@ -169,21 +174,22 @@ def get_info_from_module(target):
# build without necessarily requiring that our built package's
# requirements are installed.
docstring, version = get_docstring_and_version_via_ast(target)
error = None
if not (docstring and version):
docstring, version = get_docstring_and_version_via_import(target)
docstring, version, error = get_docstring_and_version_via_import(target)

if (not docstring) or not docstring.strip():
raise NoDocstringError('Flit cannot package module without docstring, '
'or empty docstring. Please add a docstring to your module '
'({}).'.format(target.file))

version = check_version(version)
version = check_version(version, error)

docstring_lines = docstring.lstrip().splitlines()
return {'summary': docstring_lines[0],
'version': version}

def check_version(version):
def check_version(version, error=None):
"""
Check whether a given version string match PEP 440, and do normalisation.

Expand All @@ -195,8 +201,12 @@ def check_version(version):
Returns the version in canonical PEP 440 format.
"""
if not version:
raise NoVersionError('Cannot package module without a version string. '
'Please define a `__version__ = "x.y.z"` in your module.')
msg = ('Cannot package module without a version string. '
'Please define a `__version__ = "x.y.z"` in your module.')
if error:
msg += (' Encountered error while retrieving version: {} '
.format(str(error)))
raise NoVersionError(msg)
if not isinstance(version, str):
raise InvalidVersion('__version__ must be a string, not {}.'
.format(type(version)))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""This module imports things that aren’t importable too early"""

from _a_package_that_definitely_does_not_exist import a_symbol_that_neither_exists

__version__ = '{v}.{v}'.format(v=1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""This module imports things that aren’t importable"""

__version__ = '{v}.{v}'.format(v=2)

from _a_package_that_definitely_does_not_exist import a_symbol_that_neither_exists
9 changes: 9 additions & 0 deletions flit_core/flit_core/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,18 @@ def test_get_info_from_module(self):
'version': '1.2.3'}
)

info = get_info_from_module(Module('module2', samples_dir / 'constructed_version'))
self.assertEqual(info, {'summary': 'This module imports things that aren’t importable',
'version': '2.2'}
)

with self.assertRaises(InvalidVersion):
get_info_from_module(Module('invalid_version1', samples_dir))

with self.assertRaises(NoVersionError) as cm:
get_info_from_module(Module('cannot_set_version', samples_dir / 'constructed_version'))
assert "error while retrieving version: No module named '_a_package_" in str(cm.exception)

def test_version_raise(self):
with pytest.raises(InvalidVersion):
check_version('a.1.0.beta0')
Expand Down