Skip to content

Commit

Permalink
Merge pull request #400 from sbidoul/pep517-editable-sbi
Browse files Browse the repository at this point in the history
PEP 660 support
  • Loading branch information
takluyver committed Sep 29, 2021
2 parents 734ab12 + 2444dc2 commit 01e64e9
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 6 deletions.
4 changes: 2 additions & 2 deletions flit/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

log = logging.getLogger(__name__)

def make_wheel_in(ini_path, wheel_directory):
return core_wheel.make_wheel_in(ini_path, wheel_directory)
def make_wheel_in(ini_path, wheel_directory, editable=False):
return core_wheel.make_wheel_in(ini_path, wheel_directory, editable)

class WheelBuilder(core_wheel.WheelBuilder):
pass
Expand Down
11 changes: 11 additions & 0 deletions flit_core/flit_core/buildapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def get_requires_for_build_wheel(config_settings=None):
# Requirements to build an sdist are the same as for a wheel
get_requires_for_build_sdist = get_requires_for_build_wheel

# Requirements to build an editable are the same as for a wheel
get_requires_for_build_editable = get_requires_for_build_wheel

def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
"""Creates {metadata_directory}/foo-1.2.dist-info"""
ini_info = read_flit_config(pyproj_toml)
Expand All @@ -61,11 +64,19 @@ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):

return osp.basename(dist_info)

# Metadata for editable are the same as for a wheel
prepare_metadata_for_build_editable = prepare_metadata_for_build_wheel

def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
"""Builds a wheel, places it in wheel_directory"""
info = make_wheel_in(pyproj_toml, Path(wheel_directory))
return info.file.name

def build_editable(wheel_directory, config_settings=None, metadata_directory=None):
"""Builds an "editable" wheel, places it in wheel_directory"""
info = make_wheel_in(pyproj_toml, Path(wheel_directory), editable=True)
return info.file.name

def build_sdist(sdist_directory, config_settings=None):
"""Builds an sdist, places it in sdist_directory"""
path = SdistBuilder.from_ini_path(pyproj_toml).build(Path(sdist_directory))
Expand Down
23 changes: 23 additions & 0 deletions flit_core/flit_core/tests/test_buildapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ def test_get_build_requires():
# importing it, so there are no build dependencies.
with cwd(osp.join(samples_dir,'pep517')):
assert buildapi.get_requires_for_build_wheel() == []
assert buildapi.get_requires_for_build_editable() == []
assert buildapi.get_requires_for_build_sdist() == []

def test_get_build_requires_pep621_nodynamic():
# This module isn't inspected because version & description are specified
# as static metadata in pyproject.toml, so there are no build dependencies
with cwd(osp.join(samples_dir, 'pep621_nodynamic')):
assert buildapi.get_requires_for_build_wheel() == []
assert buildapi.get_requires_for_build_editable() == []
assert buildapi.get_requires_for_build_sdist() == []

def test_get_build_requires_import():
Expand All @@ -39,6 +41,7 @@ def test_get_build_requires_import():
expected = ["numpy >=1.16.0"]
with cwd(osp.join(samples_dir, 'constructed_version')):
assert buildapi.get_requires_for_build_wheel() == expected
assert buildapi.get_requires_for_build_editable() == expected
assert buildapi.get_requires_for_build_sdist() == expected

def test_build_wheel():
Expand All @@ -47,6 +50,9 @@ def test_build_wheel():
assert filename.endswith('.whl'), filename
assert_isfile(osp.join(td, filename))
assert zipfile.is_zipfile(osp.join(td, filename))
with zipfile.ZipFile(osp.join(td, filename)) as zip:
assert "module1.py" in zip.namelist()
assert "module1.pth" not in zip.namelist()

def test_build_wheel_pep621():
with TemporaryDirectory() as td, cwd(osp.join(samples_dir, 'pep621')):
Expand All @@ -55,6 +61,16 @@ def test_build_wheel_pep621():
assert_isfile(osp.join(td, filename))
assert zipfile.is_zipfile(osp.join(td, filename))

def test_build_editable():
with TemporaryDirectory() as td, cwd(osp.join(samples_dir,'pep517')):
filename = buildapi.build_editable(td)
assert filename.endswith('.whl'), filename
assert_isfile(osp.join(td, filename))
assert zipfile.is_zipfile(osp.join(td, filename))
with zipfile.ZipFile(osp.join(td, filename)) as zip:
assert "module1.py" not in zip.namelist()
assert "module1.pth" in zip.namelist()

def test_build_sdist():
with TemporaryDirectory() as td, cwd(osp.join(samples_dir,'pep517')):
filename = buildapi.build_sdist(td)
Expand All @@ -68,3 +84,10 @@ def test_prepare_metadata_for_build_wheel():
assert dirname.endswith('.dist-info'), dirname
assert_isdir(osp.join(td, dirname))
assert_isfile(osp.join(td, dirname, 'METADATA'))

def test_prepare_metadata_for_build_editable():
with TemporaryDirectory() as td, cwd(osp.join(samples_dir,'pep517')):
dirname = buildapi.prepare_metadata_for_build_editable(td)
assert dirname.endswith('.dist-info'), dirname
assert_isdir(osp.join(td, dirname))
assert_isfile(osp.join(td, dirname, 'METADATA'))
15 changes: 11 additions & 4 deletions flit_core/flit_core/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ def copy_module(self):
rel_path = osp.relpath(full_path, source_dir)
self._add_file(full_path, rel_path)

def add_pth(self):
with self._write_to_zip(self.module.name + ".pth") as f:
f.write(str(self.module.source_dir))

def write_metadata(self):
log.info('Writing metadata files')

Expand Down Expand Up @@ -173,22 +177,25 @@ def write_record(self):
# RECORD itself is recorded with no hash or size
f.write(self.dist_info + '/RECORD,,\n')

def build(self):
def build(self, editable=False):
try:
self.copy_module()
if editable:
self.add_pth()
else:
self.copy_module()
self.write_metadata()
self.write_record()
finally:
self.wheel_zip.close()

def make_wheel_in(ini_path, wheel_directory):
def make_wheel_in(ini_path, wheel_directory, editable=False):
# We don't know the final filename until metadata is loaded, so write to
# a temporary_file, and rename it afterwards.
(fd, temp_path) = tempfile.mkstemp(suffix='.whl', dir=str(wheel_directory))
try:
with io.open(fd, 'w+b') as fp:
wb = WheelBuilder.from_ini_path(ini_path, fp)
wb.build()
wb.build(editable)

wheel_path = wheel_directory / wb.wheel_filename
os.replace(temp_path, str(wheel_path))
Expand Down
45 changes: 45 additions & 0 deletions tests/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,33 @@ def test_wheel_module(copy_sample):
make_wheel_in(td / 'pyproject.toml', td)
assert_isfile(td / 'module1-0.1-py2.py3-none-any.whl')

def test_editable_wheel_module(copy_sample):
td = copy_sample('module1_toml')
make_wheel_in(td / 'pyproject.toml', td, editable=True)
whl_file = td / 'module1-0.1-py2.py3-none-any.whl'
assert_isfile(whl_file)
with unpack(whl_file) as unpacked:
pth_path = Path(unpacked, 'module1.pth')
assert_isfile(pth_path)
assert pth_path.read_text() == str(td)
assert_isdir(Path(unpacked, 'module1-0.1.dist-info'))

def test_wheel_package(copy_sample):
td = copy_sample('package1')
make_wheel_in(td / 'pyproject.toml', td)
assert_isfile(td / 'package1-0.1-py2.py3-none-any.whl')

def test_editable_wheel_package(copy_sample):
td = copy_sample('package1')
make_wheel_in(td / 'pyproject.toml', td, editable=True)
whl_file = td / 'package1-0.1-py2.py3-none-any.whl'
assert_isfile(whl_file)
with unpack(whl_file) as unpacked:
pth_path = Path(unpacked, 'package1.pth')
assert_isfile(pth_path)
assert pth_path.read_text() == str(td)
assert_isdir(Path(unpacked, 'package1-0.1.dist-info'))

def test_wheel_src_module(copy_sample):
td = copy_sample('module3')
make_wheel_in(td / 'pyproject.toml', td)
Expand All @@ -41,6 +63,17 @@ def test_wheel_src_module(copy_sample):
assert_isdir(Path(unpacked, 'module3-0.1.dist-info'))
assert_isfile(Path(unpacked, 'module3-0.1.dist-info', 'LICENSE'))

def test_editable_wheel_src_module(copy_sample):
td = copy_sample('module3')
make_wheel_in(td / 'pyproject.toml', td, editable=True)
whl_file = td / 'module3-0.1-py2.py3-none-any.whl'
assert_isfile(whl_file)
with unpack(whl_file) as unpacked:
pth_path = Path(unpacked, 'module3.pth')
assert_isfile(pth_path)
assert pth_path.read_text() == str(td / "src")
assert_isdir(Path(unpacked, 'module3-0.1.dist-info'))

def test_wheel_src_package(copy_sample):
td = copy_sample('package2')
make_wheel_in(td / 'pyproject.toml', td)
Expand All @@ -51,6 +84,18 @@ def test_wheel_src_package(copy_sample):
print(os.listdir(unpacked))
assert_isfile(Path(unpacked, 'package2', '__init__.py'))

def test_editable_wheel_src_package(copy_sample):
td = copy_sample('package2')
make_wheel_in(td / 'pyproject.toml', td, editable=True)
whl_file = td / 'package2-0.1-py2.py3-none-any.whl'
assert_isfile(whl_file)
with unpack(whl_file) as unpacked:
pth_path = Path(unpacked, 'package2.pth')
assert_isfile(pth_path)
assert pth_path.read_text() == str(td / "src")
assert_isdir(Path(unpacked, 'package2-0.1.dist-info'))


def test_dist_name(copy_sample):
td = copy_sample('altdistname')
make_wheel_in(td / 'pyproject.toml', td)
Expand Down

0 comments on commit 01e64e9

Please sign in to comment.