From 7dfb38b859531b5cfde6cccd34f897360f785527 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sun, 2 Jan 2022 13:01:20 +0000 Subject: [PATCH 01/21] Lowercase distribution name in wheel filename and .dist-info folder name --- flit_core/flit_core/common.py | 2 +- tests/samples/altdistname/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flit_core/flit_core/common.py b/flit_core/flit_core/common.py index f1f378f5..dd009f52 100644 --- a/flit_core/flit_core/common.py +++ b/flit_core/flit_core/common.py @@ -407,7 +407,7 @@ def normalize_dist_name(name: str, version: str) -> str: See https://packaging.python.org/specifications/binary-distribution-format/#escaping-and-unicode """ - normalized_name = re.sub(r'[-_.]+', '_', name, flags=re.UNICODE) + normalized_name = re.sub(r'[-_.]+', '_', name, flags=re.UNICODE).lower() assert check_version(version) == version assert '-' not in version, 'Normalized versions can’t have dashes' return '{}-{}'.format(normalized_name, version) diff --git a/tests/samples/altdistname/pyproject.toml b/tests/samples/altdistname/pyproject.toml index 00caf94c..c2d08cad 100644 --- a/tests/samples/altdistname/pyproject.toml +++ b/tests/samples/altdistname/pyproject.toml @@ -7,5 +7,5 @@ module = "package1" author = "Sir Robin" author-email = "robin@camelot.uk" home-page = "http://github.com/sirrobin/package1" -dist-name = "package-dist1" +dist-name = "package-Dist1" From 291e928c264c611c399116e878179cac352f8667 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sun, 2 Jan 2022 13:31:35 +0000 Subject: [PATCH 02/21] Use newer importlib APIs when loading module for docstring & __version__ --- flit_core/flit_core/common.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/flit_core/flit_core/common.py b/flit_core/flit_core/common.py index f1f378f5..6d1a64ff 100644 --- a/flit_core/flit_core/common.py +++ b/flit_core/flit_core/common.py @@ -163,10 +163,13 @@ def get_docstring_and_version_via_import(target): _import_i += 1 log.debug("Loading module %s", target.file) - from importlib.machinery import SourceFileLoader - sl = SourceFileLoader('flit_core.dummy.import%d' % _import_i, str(target.file)) + from importlib.util import spec_from_file_location, module_from_spec + mod_name = 'flit_core.dummy.import%d' % _import_i + spec = spec_from_file_location(mod_name, target.file) with _module_load_ctx(): - m = sl.load_module() + m = module_from_spec(spec) + spec.loader.exec_module(m) + docstring = m.__dict__.get('__doc__', None) version = m.__dict__.get('__version__', None) return docstring, version From 811d9099a440da93ffa2c003861775b0178e4086 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sun, 2 Jan 2022 15:20:41 +0000 Subject: [PATCH 03/21] CI: Add Python 3.10, move Windows tests to GH actions (#500) --- .github/workflows/test.yml | 5 +++-- appveyor.yml | 16 ---------------- tests/test_install.py | 2 ++ tox.ini | 3 ++- 4 files changed, 7 insertions(+), 19 deletions(-) delete mode 100644 appveyor.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 565a68ce..16e902a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,10 +4,11 @@ on: [push, pull_request] jobs: test: - runs-on: ubuntu-latest + runs-on: ${{ matrix.platform }} strategy: matrix: - python-version: [ 3.6, 3.7, 3.8, 3.9, ] + platform: ["ubuntu-latest", "windows-latest"] + python-version: [ "3.6", "3.7", "3.8", "3.9", "3.10" ] steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 08ef1a6c..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,16 +0,0 @@ -environment: - matrix: - - TOXENV: "py37" - TOX_APPVEYOR_X64: "1" - - TOXENV: "py36" - TOX_APPVEYOR_X64: "0" - -# The Python version here doesn't matter (except that the commands have the same), -# as Tox will set up an environment using the Python specified above. -install: - - py -3.7 -m pip install tox tox-appveyor - -test_script: - - py -3.7 -m tox - -build: off diff --git a/tests/test_install.py b/tests/test_install.py index 77a90076..94ad3825 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -167,6 +167,8 @@ def test_symlink_module_pep621(self): ) def test_symlink_module_in_src(self): + if os.name == 'nt': + raise SkipTest("symlink") oldcwd = os.getcwd() os.chdir(samples_dir / 'packageinsrc') try: diff --git a/tox.ini b/tox.ini index 71bc8867..e1689d66 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{39,38,37,36},bootstrap +envlist = py{310,39,38,37,36},bootstrap skip_missing_interpreters = true [gh-actions] @@ -8,6 +8,7 @@ python = 3.7: py37 3.8: py38, bootstrap 3.9: py39 + 3.10: py310 [testenv] deps = From d1e50e6381a8ac0990fe46f3c74e710c3b14f93c Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Mon, 3 Jan 2022 11:23:10 +0000 Subject: [PATCH 04/21] Help for --setup-py: don't say it's the default --- flit/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/flit/__init__.py b/flit/__init__.py index 8af9b34b..57f689ea 100644 --- a/flit/__init__.py +++ b/flit/__init__.py @@ -82,12 +82,11 @@ def main(argv=None): parser_build.add_argument('--setup-py', action='store_true', help=("Generate a setup.py file in the sdist. " "The sdist will work with older tools that predate PEP 517. " - "This is the default for now, but will change in a future version." ) ) parser_build.add_argument('--no-setup-py', action='store_true', - help=("Don't generate a setup.py file in the sdist. " + help=("Don't generate a setup.py file in the sdist. This is the default. " "The sdist will only work with tools that support PEP 517, " "but the wheel will still be usable by any compatible tool." ) From c404ea36f883ba6101581d943844d2986ec2bf28 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 15 Jan 2022 15:20:39 +0000 Subject: [PATCH 05/21] Add support for external data directory --- flit/install.py | 13 +++++++++++++ flit_core/flit_core/common.py | 17 +++++++++++++++++ flit_core/flit_core/config.py | 26 ++++++++++++++++++++++++-- flit_core/flit_core/sdist.py | 9 ++++++--- flit_core/flit_core/wheel.py | 19 ++++++++++++++++--- 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/flit/install.py b/flit/install.py index fe095d65..3ea9a4bf 100644 --- a/flit/install.py +++ b/flit/install.py @@ -196,6 +196,17 @@ def install_scripts(self, script_defs, scripts_dir): self.installed_files.append(cmd_file) + def install_data_dir(self, target_data_dir): + for src_path in common.walk_data_dir(self.ini_info.data_directory): + rel_path = os.path.relpath(src_path, self.ini_info.data_directory) + dst_path = os.path.join(target_data_dir, rel_path) + os.makedirs(os.path.dirname(dst_path), exist_ok=True) + if self.symlink: + os.symlink(os.path.realpath(src_path), dst_path) + else: + shutil.copy2(src_path, dst_path) + self.installed_files.append(dst_path) + def _record_installed_directory(self, path): for dirpath, dirnames, files in os.walk(path): for f in files: @@ -332,6 +343,8 @@ def install_directly(self): scripts = self.ini_info.entrypoints.get('console_scripts', {}) self.install_scripts(scripts, dirs['scripts']) + self.install_data_dir(dirs['data']) + self.write_dist_info(dirs['purelib']) def install_with_pip(self): diff --git a/flit_core/flit_core/common.py b/flit_core/flit_core/common.py index f1f378f5..039d903f 100644 --- a/flit_core/flit_core/common.py +++ b/flit_core/flit_core/common.py @@ -416,3 +416,20 @@ def normalize_dist_name(name: str, version: str) -> str: def dist_info_name(distribution, version): """Get the correct name of the .dist-info folder""" return normalize_dist_name(distribution, version) + '.dist-info' + + +def walk_data_dir(data_directory): + """Iterate over the files in the given data directory. + + Yields absolute paths - caller may want to make them relative. + Excludes any __pycache__ subdirectories. + """ + if data_directory is None: + return + + for dirpath, dirs, files in os.walk(data_directory): + for file in sorted(files): + full_path = os.path.join(dirpath, file) + yield full_path + + dirs[:] = [d for d in sorted(dirs) if d != '__pycache__'] diff --git a/flit_core/flit_core/config.py b/flit_core/flit_core/config.py index b0b6ddbd..ade14b8d 100644 --- a/flit_core/flit_core/config.py +++ b/flit_core/flit_core/config.py @@ -120,7 +120,7 @@ def prep_toml_config(d, path): ) unknown_sections = set(dtool) - { - 'metadata', 'module', 'scripts', 'entrypoints', 'sdist' + 'metadata', 'module', 'scripts', 'entrypoints', 'sdist', 'external-data' } unknown_sections = [s for s in unknown_sections if not s.lower().startswith('x-')] if unknown_sections: @@ -142,6 +142,27 @@ def prep_toml_config(d, path): dtool['sdist'].get('exclude', []), 'exclude' ) + data_dir = dtool.get('external-data', {}).get('directory', None) + if data_dir is not None: + toml_key = "tool.flit.external-data.directory" + if not isinstance(data_dir, str): + raise ConfigError(f"{toml_key} must be a string") + + normp = osp.normpath(data_dir) + if osp.isabs(normp): + raise ConfigError(f"{toml_key} cannot be an absolute path") + if normp.startswith('..' + os.sep): + raise ConfigError( + f"{toml_key} cannot point outside the directory containing pyproject.toml" + ) + if normp == '.': + raise ConfigError( + f"{toml_key} cannot refer to the directory containing pyproject.toml" + ) + loaded_cfg.data_directory = path.parent / data_dir + if not loaded_cfg.data_directory.is_dir(): + raise ConfigError(f"{toml_key} must refer to a directory") + return loaded_cfg def flatten_entrypoints(ep): @@ -207,7 +228,7 @@ def _check_glob_patterns(pats, clude): raise ConfigError( '{} pattern {!r} is an absolute path'.format(clude, p) ) - if osp.normpath(p).startswith('..' + os.sep): + if normp.startswith('..' + os.sep): raise ConfigError( '{} pattern {!r} points out of the directory containing pyproject.toml' .format(clude, p) @@ -227,6 +248,7 @@ def __init__(self): self.sdist_include_patterns = [] self.sdist_exclude_patterns = [] self.dynamic_metadata = [] + self.data_directory = None def add_scripts(self, scripts_dict): if scripts_dict: diff --git a/flit_core/flit_core/sdist.py b/flit_core/flit_core/sdist.py index 80ccf25d..cb72ea1d 100644 --- a/flit_core/flit_core/sdist.py +++ b/flit_core/flit_core/sdist.py @@ -72,13 +72,14 @@ class SdistBuilder: which is what should normally be published to PyPI. """ def __init__(self, module, metadata, cfgdir, reqs_by_extra, entrypoints, - extra_files, include_patterns=(), exclude_patterns=()): + extra_files, data_directory, include_patterns=(), exclude_patterns=()): self.module = module self.metadata = metadata self.cfgdir = cfgdir self.reqs_by_extra = reqs_by_extra self.entrypoints = entrypoints self.extra_files = extra_files + self.data_directory = data_directory self.includes = FilePatterns(include_patterns, str(cfgdir)) self.excludes = FilePatterns(exclude_patterns, str(cfgdir)) @@ -93,8 +94,8 @@ def from_ini_path(cls, ini_path: Path): extra_files = [ini_path.name] + ini_info.referenced_files return cls( module, metadata, srcdir, ini_info.reqs_by_extra, - ini_info.entrypoints, extra_files, ini_info.sdist_include_patterns, - ini_info.sdist_exclude_patterns, + ini_info.entrypoints, extra_files, ini_info.data_directory, + ini_info.sdist_include_patterns, ini_info.sdist_exclude_patterns, ) def prep_entry_points(self): @@ -115,6 +116,8 @@ def select_files(self): cfgdir_s = str(self.cfgdir) return [ osp.relpath(p, cfgdir_s) for p in self.module.iter_files() + ] + [ + osp.relpath(p, cfgdir_s) for p in common.walk_data_dir(self.data_directory) ] + self.extra_files def apply_includes_excludes(self, files): diff --git a/flit_core/flit_core/wheel.py b/flit_core/flit_core/wheel.py index 8c87451e..d921f7cc 100644 --- a/flit_core/flit_core/wheel.py +++ b/flit_core/flit_core/wheel.py @@ -57,13 +57,16 @@ def zip_timestamp_from_env() -> Optional[tuple]: class WheelBuilder: - def __init__(self, directory, module, metadata, entrypoints, target_fp): + def __init__( + self, directory, module, metadata, entrypoints, target_fp, data_directory + ): """Build a wheel from a module/package """ self.directory = directory self.module = module self.metadata = metadata self.entrypoints = entrypoints + self.data_directory = data_directory self.records = [] self.source_time_stamp = zip_timestamp_from_env() @@ -74,14 +77,15 @@ def __init__(self, directory, module, metadata, entrypoints, target_fp): @classmethod def from_ini_path(cls, ini_path, target_fp): - # Local import so bootstrapping doesn't try to load toml from .config import read_flit_config directory = ini_path.parent ini_info = read_flit_config(ini_path) entrypoints = ini_info.entrypoints module = common.Module(ini_info.module, directory) metadata = common.make_metadata(module, ini_info) - return cls(directory, module, metadata, entrypoints, target_fp) + return cls( + directory, module, metadata, entrypoints, target_fp, ini_info.data_directory + ) @property def dist_info(self): @@ -160,6 +164,14 @@ def add_pth(self): with self._write_to_zip(self.module.name + ".pth") as f: f.write(str(self.module.source_dir.resolve())) + def add_data_directory(self): + dir_in_whl = '{}.data/data/'.format( + common.normalize_dist_name(self.metadata.name, self.metadata.version) + ) + for full_path in common.walk_data_dir(self.data_directory): + rel_path = os.path.relpath(full_path, self.data_directory) + self._add_file(full_path, dir_in_whl + rel_path) + def write_metadata(self): log.info('Writing metadata files') @@ -193,6 +205,7 @@ def build(self, editable=False): self.add_pth() else: self.copy_module() + self.add_data_directory() self.write_metadata() self.write_record() finally: From 6215968310216bc311b53943bbe3ece3f3254069 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 15 Jan 2022 15:21:33 +0000 Subject: [PATCH 06/21] Tests for external data directory --- .../tests/samples/with_data_dir/LICENSE | 1 + .../tests/samples/with_data_dir/README.rst | 1 + .../with_data_dir/data/share/man/man1/foo.1 | 1 + .../tests/samples/with_data_dir/module1.py | 3 ++ .../samples/with_data_dir/pyproject.toml | 26 ++++++++++++++++ flit_core/flit_core/tests/test_sdist.py | 9 ++++++ flit_core/flit_core/tests/test_wheel.py | 7 +++++ tests/test_install.py | 31 ++++++++++++++++--- 8 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 flit_core/flit_core/tests/samples/with_data_dir/LICENSE create mode 100644 flit_core/flit_core/tests/samples/with_data_dir/README.rst create mode 100644 flit_core/flit_core/tests/samples/with_data_dir/data/share/man/man1/foo.1 create mode 100644 flit_core/flit_core/tests/samples/with_data_dir/module1.py create mode 100644 flit_core/flit_core/tests/samples/with_data_dir/pyproject.toml diff --git a/flit_core/flit_core/tests/samples/with_data_dir/LICENSE b/flit_core/flit_core/tests/samples/with_data_dir/LICENSE new file mode 100644 index 00000000..7f5c1948 --- /dev/null +++ b/flit_core/flit_core/tests/samples/with_data_dir/LICENSE @@ -0,0 +1 @@ +This file should be added to wheels diff --git a/flit_core/flit_core/tests/samples/with_data_dir/README.rst b/flit_core/flit_core/tests/samples/with_data_dir/README.rst new file mode 100644 index 00000000..ef7b7c19 --- /dev/null +++ b/flit_core/flit_core/tests/samples/with_data_dir/README.rst @@ -0,0 +1 @@ +This contains a nön-ascii character diff --git a/flit_core/flit_core/tests/samples/with_data_dir/data/share/man/man1/foo.1 b/flit_core/flit_core/tests/samples/with_data_dir/data/share/man/man1/foo.1 new file mode 100644 index 00000000..c12128d8 --- /dev/null +++ b/flit_core/flit_core/tests/samples/with_data_dir/data/share/man/man1/foo.1 @@ -0,0 +1 @@ +Example data file diff --git a/flit_core/flit_core/tests/samples/with_data_dir/module1.py b/flit_core/flit_core/tests/samples/with_data_dir/module1.py new file mode 100644 index 00000000..87f0370d --- /dev/null +++ b/flit_core/flit_core/tests/samples/with_data_dir/module1.py @@ -0,0 +1,3 @@ +"""Example module""" + +__version__ = '0.1' diff --git a/flit_core/flit_core/tests/samples/with_data_dir/pyproject.toml b/flit_core/flit_core/tests/samples/with_data_dir/pyproject.toml new file mode 100644 index 00000000..84d165e3 --- /dev/null +++ b/flit_core/flit_core/tests/samples/with_data_dir/pyproject.toml @@ -0,0 +1,26 @@ +[build-system] +requires = ["flit_core >=3.2,<4"] +build-backend = "flit_core.buildapi" + +[project] +name = "module1" +authors = [ + {name = "Sir Röbin", email = "robin@camelot.uk"} +] +readme = "README.rst" +license = {file = "LICENSE"} +requires-python = ">=3.7" +dependencies = [ + "requests >= 2.18", + "docutils", +] +dynamic = [ + "version", + "description", +] + +[project.scripts] +foo = "module1:main" + +[tool.flit.external-data] +directory = "data" diff --git a/flit_core/flit_core/tests/test_sdist.py b/flit_core/flit_core/tests/test_sdist.py index ca29c4e9..a513758e 100644 --- a/flit_core/flit_core/tests/test_sdist.py +++ b/flit_core/flit_core/tests/test_sdist.py @@ -49,3 +49,12 @@ def test_include_exclude(): assert osp.join('doc', 'test.rst') in files assert osp.join('doc', 'test.txt') not in files assert osp.join('doc', 'subdir', 'test.txt') in files + + +def test_data_dir(): + builder = sdist.SdistBuilder.from_ini_path( + samples_dir / 'with_data_dir' / 'pyproject.toml' + ) + files = builder.apply_includes_excludes(builder.select_files()) + + assert osp.join('data', 'share', 'man', 'man1', 'foo.1') in files diff --git a/flit_core/flit_core/tests/test_wheel.py b/flit_core/flit_core/tests/test_wheel.py index 9bb38fb2..51d6def7 100644 --- a/flit_core/flit_core/tests/test_wheel.py +++ b/flit_core/flit_core/tests/test_wheel.py @@ -29,3 +29,10 @@ def test_zero_timestamp(tmp_path, monkeypatch): # Minimum value for zip timestamps is 1980-1-1 with ZipFile(info.file, 'r') as zf: assert zf.getinfo('module1a.py').date_time == (1980, 1, 1, 0, 0, 0) + + +def test_data_dir(tmp_path): + info = make_wheel_in(samples_dir / 'with_data_dir' / 'pyproject.toml', tmp_path) + assert_isfile(info.file) + with ZipFile(info.file, 'r') as zf: + assert 'module1-0.1.data/data/share/man/man1/foo.1' in zf.namelist() diff --git a/tests/test_install.py b/tests/test_install.py index 94ad3825..70007e85 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -21,11 +21,13 @@ class InstallTests(TestCase): def setUp(self): td = tempfile.TemporaryDirectory() - scripts_dir = os.path.join(td.name, 'scripts') - purelib_dir = os.path.join(td.name, 'site-packages') self.addCleanup(td.cleanup) self.get_dirs_patch = patch('flit.install.get_dirs', - return_value={'scripts': scripts_dir, 'purelib': purelib_dir}) + return_value={ + 'scripts': os.path.join(td.name, 'scripts'), + 'purelib': os.path.join(td.name, 'site-packages'), + 'data': os.path.join(td.name, 'data'), + }) self.get_dirs_patch.start() self.tmpdir = pathlib.Path(td.name) @@ -246,11 +248,13 @@ def test_symlink_other_python(self): # Called by Installer._get_dirs() : script2 = ("#!{python}\n" "import json, sys\n" - "json.dump({{'purelib': {purelib!r}, 'scripts': {scripts!r} }}, " + "json.dump({{'purelib': {purelib!r}, 'scripts': {scripts!r}, 'data': {data!r} }}, " "sys.stdout)" ).format(python=sys.executable, purelib=str(self.tmpdir / 'site-packages2'), - scripts=str(self.tmpdir / 'scripts2')) + scripts=str(self.tmpdir / 'scripts2'), + data=str(self.tmpdir / 'data'), + ) with MockCommand('mock_python', content=script1): ins = Installer.from_ini_path(samples_dir / 'package1' / 'pyproject.toml', python='mock_python', @@ -288,6 +292,23 @@ def test_extras_error(self): Installer.from_ini_path(samples_dir / 'requires-requests.toml', user=False, deps='none', extras='dev') + def test_install_data_dir(self): + Installer.from_ini_path( + core_samples_dir / 'with_data_dir' / 'pyproject.toml', + ).install_directly() + assert_isfile(self.tmpdir / 'site-packages' / 'module1.py') + assert_isfile(self.tmpdir / 'data' / 'share' / 'man' / 'man1' / 'foo.1') + + def test_symlink_data_dir(self): + Installer.from_ini_path( + core_samples_dir / 'with_data_dir' / 'pyproject.toml', symlink=True + ).install_directly() + assert_isfile(self.tmpdir / 'site-packages' / 'module1.py') + assert_islink( + self.tmpdir / 'data' / 'share' / 'man' / 'man1' / 'foo.1', + to=core_samples_dir / 'with_data_dir' / 'data' / 'share' / 'man' / 'man1' / 'foo.1' + ) + @pytest.mark.parametrize(('deps', 'extras', 'installed'), [ ('none', [], set()), ('develop', [], {'pytest ;', 'toml ;'}), From 23efb36d7d6ea33c2ea0916ffa816e7e9db01562 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 15 Jan 2022 15:54:34 +0000 Subject: [PATCH 07/21] Document external data files --- doc/pyproject_toml.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/pyproject_toml.rst b/doc/pyproject_toml.rst index 6ef305ab..c88d328d 100644 --- a/doc/pyproject_toml.rst +++ b/doc/pyproject_toml.rst @@ -417,4 +417,35 @@ These paths: Exclusions have priority over inclusions. +External data section +--------------------- + +Data files which your code will use should go inside the Python package folder. +Flit will package these with no special configuration. + +However, sometimes it's useful to package external files for system integration, +such as man pages or files defining a Jupyter extension. To do this, arrange +the files within a directory such as ``data``, next to your ``pyproject.toml`` +file, and add a section like this: + +.. code-block:: toml + + [tool.flit.external-data] + directory = "data" + +Paths within this directory are typically installed to corresponding paths under +a prefix (such as a virtualenv directory). E.g. you might save a man page for a +script as ``(data)/share/man/man1/foo.1``. + +Whether these files are detected by the systems they're meant to integrate with +depends on how your package is installed and how those systems are configured. +For instance, installing in a virtualenv usually doesn't affect anything outside +that environment. Don't rely on these files being picked up unless you have +close control of how the package will be installed. + +.. note:: + + For users coming from setuptools: external data corresponds to setuptools' + ``data_files`` parameter, although setuptools offers more flexibility. + .. _environment marker: https://www.python.org/dev/peps/pep-0508/#environment-markers From c68295c766d9ed2dec267e8666a3f0b6b35aa95c Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 15 Jan 2022 15:58:55 +0000 Subject: [PATCH 08/21] Skip symlink test on Windows --- tests/test_install.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_install.py b/tests/test_install.py index 70007e85..b4e9068e 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -300,6 +300,8 @@ def test_install_data_dir(self): assert_isfile(self.tmpdir / 'data' / 'share' / 'man' / 'man1' / 'foo.1') def test_symlink_data_dir(self): + if os.name == 'nt': + raise SkipTest("symlink") Installer.from_ini_path( core_samples_dir / 'with_data_dir' / 'pyproject.toml', symlink=True ).install_directly() From 38a5aa714a3a9b9d2871a644d330c6d34fa087a3 Mon Sep 17 00:00:00 2001 From: BubuOT <97530794+BubuOT@users.noreply.github.com> Date: Thu, 20 Jan 2022 12:49:25 +0100 Subject: [PATCH 09/21] docs: mention flit-core sdist behaviour Ref: https://github.com/pypa/flit/issues/513#issuecomment-1017407065 --- doc/pyproject_toml.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/pyproject_toml.rst b/doc/pyproject_toml.rst index 6ef305ab..13296d8f 100644 --- a/doc/pyproject_toml.rst +++ b/doc/pyproject_toml.rst @@ -417,4 +417,13 @@ These paths: Exclusions have priority over inclusions. +.. note:: + + If you are not using :ref:`build_cmd` but ``flit_core`` via another build + frontend Flit doesn't doesn't check the VCS for files to include but instead + builds a 'minimal' sdist (which includes the files necessary to build a wheel). + You'll have to adaopt your inclusion/exclusion rules to achieve the same result + as you'd get with :ref:`build_cmd`. + + .. _environment marker: https://www.python.org/dev/peps/pep-0508/#environment-markers From da5fc0afbf6cf8ba522444413eaf4abac6a7eb01 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Thu, 20 Jan 2022 19:29:24 +0000 Subject: [PATCH 10/21] Spelling and punctuation fixes --- doc/pyproject_toml.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/pyproject_toml.rst b/doc/pyproject_toml.rst index 13296d8f..4e1392ef 100644 --- a/doc/pyproject_toml.rst +++ b/doc/pyproject_toml.rst @@ -420,9 +420,9 @@ Exclusions have priority over inclusions. .. note:: If you are not using :ref:`build_cmd` but ``flit_core`` via another build - frontend Flit doesn't doesn't check the VCS for files to include but instead + frontend, Flit doesn't doesn't check the VCS for files to include but instead builds a 'minimal' sdist (which includes the files necessary to build a wheel). - You'll have to adaopt your inclusion/exclusion rules to achieve the same result + You'll have to adapt your inclusion/exclusion rules to achieve the same result as you'd get with :ref:`build_cmd`. From e3a9500ebf3c5905511efee376008d009f80c147 Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Sat, 15 Jan 2022 18:15:05 -0700 Subject: [PATCH 11/21] Add bootstrap script/wheel module for flit_core --- flit_core/bootstrap.py | 87 ++++++++++++++++++++++++++++++++++++ flit_core/flit_core/wheel.py | 39 ++++++++++++++++ flit_core/pyproject.toml | 3 ++ 3 files changed, 129 insertions(+) create mode 100644 flit_core/bootstrap.py diff --git a/flit_core/bootstrap.py b/flit_core/bootstrap.py new file mode 100644 index 00000000..830a127f --- /dev/null +++ b/flit_core/bootstrap.py @@ -0,0 +1,87 @@ +"""Install flit_core without using any other tools. + +Normally, you would install flit_core with pip like any other Python package. +This script is meant to help with 'bootstrapping' other packaging +systems, where you may need flit_core to build other packaging tools. + +Pass a path to the site-packages directory or equivalent where the package +should be placed. If omitted, this defaults to the site-packages directory +of the Python running the script. +""" +import argparse +import sys +import sysconfig +from pathlib import Path +from tempfile import TemporaryDirectory +from zipfile import ZipFile + +from flit_core.wheel import add_wheel_arguments, build_flit_wheel + +srcdir = Path(__file__).parent.resolve() + +def extract_wheel(whl_path, dest): + print("Installing to", dest.resolve()) + with ZipFile(whl_path) as zf: + zf.extractall(dest) + +def add_install_arguments(parser): + parser.add_argument( + '--wheeldir', + '-w', + type=str, + help=f'wheel dist directory (defaults to {srcdir.joinpath("dist").resolve()})', + ) + purelib = Path(sysconfig.get_path('purelib')) + parser.add_argument( + '--installdir', + '-i', + type=Path, + default=purelib, + help=f'installdir directory (defaults to {purelib.resolve()}', + ) + return parser + +def get_dist_wheel(wheeldir): + wheel_path = Path(wheeldir) if wheeldir is not None else srcdir.joinpath('dist') + wheel_glob = wheel_path.glob('flit_core-*.whl') + return next(wheel_glob, None) + +def build(args): + print("Building wheel") + outdir = srcdir.joinpath('dist') if args.outdir is None else Path(args.outdir) + whl_fname = build_flit_wheel(srcdir, outdir) + print("Wheel built", outdir.joinpath(whl_fname).resolve()) + +def install(args): + dist_wheel = get_dist_wheel(args.wheeldir) + + # User asked to install wheel but none was found + if dist_wheel is None and args.wheeldir is not None: + print(f"No wheel found in {Path(args.wheeldir).resolve()}") + sys.exit(1) + + if dist_wheel is not None: + print("Installing from wheel", dist_wheel.resolve()) + # Extract the prebuilt wheel + extract_wheel(dist_wheel, args.installdir) + else: + # No prebuilt wheel found, build in temp dir + with TemporaryDirectory(prefix='flit_core-bootstrap-') as td: + whl_fname = build_flit_wheel(srcdir, Path(td)) + whl_path = Path(td).joinpath(whl_fname) + extract_wheel(whl_path, args.installdir) + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers() + + build_parser = subparsers.add_parser('build') + build_parser = add_wheel_arguments(build_parser, srcdir) + build_parser.set_defaults(func=build) + + install_parser = subparsers.add_parser('install') + install_parser = add_install_arguments(install_parser) + install_parser.set_defaults(func=install) + + args = parser.parse_args() + args.func(args) diff --git a/flit_core/flit_core/wheel.py b/flit_core/flit_core/wheel.py index 8c87451e..d9f83a83 100644 --- a/flit_core/flit_core/wheel.py +++ b/flit_core/flit_core/wheel.py @@ -1,3 +1,4 @@ +import argparse from base64 import urlsafe_b64encode import contextlib from datetime import datetime @@ -8,6 +9,7 @@ import os.path as osp import stat import tempfile +from pathlib import Path from types import SimpleNamespace from typing import Optional import zipfile @@ -215,3 +217,40 @@ def make_wheel_in(ini_path, wheel_directory, editable=False): log.info("Built wheel: %s", wheel_path) return SimpleNamespace(builder=wb, file=wheel_path) + +def add_wheel_arguments(parser, srcdir=None): + if srcdir is None: + srcdir = Path.cwd() + parser.add_argument( + '--srcdir', + '-s', + type=Path, + default=Path.cwd(), + help='source directory (defaults to current directory)', + ) + + parser.add_argument( + '--outdir', + '-o', + type=Path, + default=srcdir.joinpath('dist'), + help=f'output directory (defaults to {srcdir.joinpath("dist").resolve()})', + ) + return parser + +def build_flit_wheel(srcdir, outdir): + """Builds a wheel, places it in outdir""" + pyproj_toml = Path(srcdir).joinpath('pyproject.toml') + outdir.mkdir(parents=True, exist_ok=True) + info = make_wheel_in(pyproj_toml, Path(outdir)) + return info.file.name + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser = add_wheel_arguments(parser) + args = parser.parse_args() + srcdir = Path.cwd() if args.srcdir is None else Path(args.srcdir) + outdir = args.outdir + print("Building wheel") + whl_fname = build_flit_wheel(srcdir, outdir) + print("Wheel built", outdir.joinpath(whl_fname).resolve()) diff --git a/flit_core/pyproject.toml b/flit_core/pyproject.toml index ca3f46b2..03771248 100644 --- a/flit_core/pyproject.toml +++ b/flit_core/pyproject.toml @@ -19,3 +19,6 @@ dynamic = ["version"] [project.urls] Source = "https://github.com/pypa/flit" + +[tool.flit.sdist] +include = ["bootstrap.py"] From cfac2b923b992d4c07b8e71cb029ed97126e2c31 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Wed, 16 Feb 2022 11:53:50 +0000 Subject: [PATCH 12/21] Simplify bootstrap code --- flit_core/bootstrap.py | 74 +++++++----------------------------- flit_core/flit_core/wheel.py | 46 +++++++++------------- 2 files changed, 32 insertions(+), 88 deletions(-) diff --git a/flit_core/bootstrap.py b/flit_core/bootstrap.py index 830a127f..2c6c3d80 100644 --- a/flit_core/bootstrap.py +++ b/flit_core/bootstrap.py @@ -3,85 +3,39 @@ Normally, you would install flit_core with pip like any other Python package. This script is meant to help with 'bootstrapping' other packaging systems, where you may need flit_core to build other packaging tools. - -Pass a path to the site-packages directory or equivalent where the package -should be placed. If omitted, this defaults to the site-packages directory -of the Python running the script. """ import argparse import sys import sysconfig from pathlib import Path -from tempfile import TemporaryDirectory from zipfile import ZipFile -from flit_core.wheel import add_wheel_arguments, build_flit_wheel - -srcdir = Path(__file__).parent.resolve() - def extract_wheel(whl_path, dest): - print("Installing to", dest.resolve()) + print("Installing to", dest) with ZipFile(whl_path) as zf: zf.extractall(dest) -def add_install_arguments(parser): +if __name__ == "__main__": + parser = argparse.ArgumentParser() parser.add_argument( - '--wheeldir', - '-w', - type=str, - help=f'wheel dist directory (defaults to {srcdir.joinpath("dist").resolve()})', + 'wheel', + type=Path, + help=f'flit_core wheel to install (.whl file)', ) - purelib = Path(sysconfig.get_path('purelib')) + purelib = Path(sysconfig.get_path('purelib')).resolve() parser.add_argument( '--installdir', '-i', type=Path, default=purelib, - help=f'installdir directory (defaults to {purelib.resolve()}', + help=f'installdir directory (defaults to {purelib})', ) - return parser - -def get_dist_wheel(wheeldir): - wheel_path = Path(wheeldir) if wheeldir is not None else srcdir.joinpath('dist') - wheel_glob = wheel_path.glob('flit_core-*.whl') - return next(wheel_glob, None) - -def build(args): - print("Building wheel") - outdir = srcdir.joinpath('dist') if args.outdir is None else Path(args.outdir) - whl_fname = build_flit_wheel(srcdir, outdir) - print("Wheel built", outdir.joinpath(whl_fname).resolve()) -def install(args): - dist_wheel = get_dist_wheel(args.wheeldir) - - # User asked to install wheel but none was found - if dist_wheel is None and args.wheeldir is not None: - print(f"No wheel found in {Path(args.wheeldir).resolve()}") - sys.exit(1) - - if dist_wheel is not None: - print("Installing from wheel", dist_wheel.resolve()) - # Extract the prebuilt wheel - extract_wheel(dist_wheel, args.installdir) - else: - # No prebuilt wheel found, build in temp dir - with TemporaryDirectory(prefix='flit_core-bootstrap-') as td: - whl_fname = build_flit_wheel(srcdir, Path(td)) - whl_path = Path(td).joinpath(whl_fname) - extract_wheel(whl_path, args.installdir) - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers() - - build_parser = subparsers.add_parser('build') - build_parser = add_wheel_arguments(build_parser, srcdir) - build_parser.set_defaults(func=build) + args = parser.parse_args() - install_parser = subparsers.add_parser('install') - install_parser = add_install_arguments(install_parser) - install_parser.set_defaults(func=install) + if not args.wheel.name.startswith('flit_core-'): + sys.exit("Use this script only for flit_core wheels") + if not args.installdir.is_dir(): + sys.exit(f"{args.installdir} is not a directory") - args = parser.parse_args() - args.func(args) + extract_wheel(args.wheel, args.installdir) diff --git a/flit_core/flit_core/wheel.py b/flit_core/flit_core/wheel.py index d9f83a83..df228ecd 100644 --- a/flit_core/flit_core/wheel.py +++ b/flit_core/flit_core/wheel.py @@ -218,39 +218,29 @@ def make_wheel_in(ini_path, wheel_directory, editable=False): log.info("Built wheel: %s", wheel_path) return SimpleNamespace(builder=wb, file=wheel_path) -def add_wheel_arguments(parser, srcdir=None): - if srcdir is None: - srcdir = Path.cwd() - parser.add_argument( - '--srcdir', - '-s', - type=Path, - default=Path.cwd(), - help='source directory (defaults to current directory)', - ) +def main(): + parser = argparse.ArgumentParser() parser.add_argument( - '--outdir', - '-o', + 'srcdir', type=Path, - default=srcdir.joinpath('dist'), - help=f'output directory (defaults to {srcdir.joinpath("dist").resolve()})', + nargs='?', + default=Path.cwd(), + help='source directory (defaults to current directory)', ) - return parser -def build_flit_wheel(srcdir, outdir): - """Builds a wheel, places it in outdir""" - pyproj_toml = Path(srcdir).joinpath('pyproject.toml') + parser.add_argument( + '--outdir', + '-o', + help='output directory (defaults to {srcdir}/dist)', + ) + args = parser.parse_args() + outdir = args.srcdir / 'dist' if args.outdir is None else Path(args.outdir) + print("Building wheel from", args.srcdir) + pyproj_toml = args.srcdir / 'pyproject.toml' outdir.mkdir(parents=True, exist_ok=True) - info = make_wheel_in(pyproj_toml, Path(outdir)) - return info.file.name + info = make_wheel_in(pyproj_toml, outdir) + print("Wheel built", outdir / info.file.name) if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser = add_wheel_arguments(parser) - args = parser.parse_args() - srcdir = Path.cwd() if args.srcdir is None else Path(args.srcdir) - outdir = args.outdir - print("Building wheel") - whl_fname = build_flit_wheel(srcdir, outdir) - print("Wheel built", outdir.joinpath(whl_fname).resolve()) + main() From 9a403a8c891a8defa96af348a297debcd2966d30 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Wed, 16 Feb 2022 11:58:04 +0000 Subject: [PATCH 13/21] Rename script to bootstrap_install.py --- flit_core/{bootstrap.py => bootstrap_install.py} | 7 +++++++ flit_core/pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) rename flit_core/{bootstrap.py => bootstrap_install.py} (82%) diff --git a/flit_core/bootstrap.py b/flit_core/bootstrap_install.py similarity index 82% rename from flit_core/bootstrap.py rename to flit_core/bootstrap_install.py index 2c6c3d80..e04a007e 100644 --- a/flit_core/bootstrap.py +++ b/flit_core/bootstrap_install.py @@ -3,6 +3,13 @@ Normally, you would install flit_core with pip like any other Python package. This script is meant to help with 'bootstrapping' other packaging systems, where you may need flit_core to build other packaging tools. + +Use 'python -m flit_core.wheel' to make a wheel, then: + + python bootstrap_install.py flit_core-3.6.0-py3-none-any.whl + +To install for something other than the Python running the script, pass a +site-packages or equivalent directory with the --installdir option. """ import argparse import sys diff --git a/flit_core/pyproject.toml b/flit_core/pyproject.toml index 03771248..3652f9a3 100644 --- a/flit_core/pyproject.toml +++ b/flit_core/pyproject.toml @@ -21,4 +21,4 @@ dynamic = ["version"] Source = "https://github.com/pypa/flit" [tool.flit.sdist] -include = ["bootstrap.py"] +include = ["bootstrap_install.py", "build_dists.py"] From 17df326a26b2b6466e8b8aa4789e5d8e22579757 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Wed, 16 Feb 2022 12:03:45 +0000 Subject: [PATCH 14/21] Add test for python -m flit_core.wheel --- flit_core/flit_core/tests/test_wheel.py | 11 ++++++++++- flit_core/flit_core/wheel.py | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/flit_core/flit_core/tests/test_wheel.py b/flit_core/flit_core/tests/test_wheel.py index 9bb38fb2..882ae66a 100644 --- a/flit_core/flit_core/tests/test_wheel.py +++ b/flit_core/flit_core/tests/test_wheel.py @@ -3,7 +3,7 @@ from testpath import assert_isfile -from flit_core.wheel import make_wheel_in +from flit_core.wheel import make_wheel_in, main samples_dir = Path(__file__).parent / 'samples' @@ -29,3 +29,12 @@ def test_zero_timestamp(tmp_path, monkeypatch): # Minimum value for zip timestamps is 1980-1-1 with ZipFile(info.file, 'r') as zf: assert zf.getinfo('module1a.py').date_time == (1980, 1, 1, 0, 0, 0) + + +def test_main(tmp_path): + main(['--outdir', str(tmp_path), str(samples_dir / 'pep621')]) + wheels = list(tmp_path.glob('*.whl')) + assert len(wheels) == 1 + # Minimum value for zip timestamps is 1980-1-1 + with ZipFile(wheels[0], 'r') as zf: + assert 'module1a.py' in zf.namelist() diff --git a/flit_core/flit_core/wheel.py b/flit_core/flit_core/wheel.py index df228ecd..8c3150ab 100644 --- a/flit_core/flit_core/wheel.py +++ b/flit_core/flit_core/wheel.py @@ -219,7 +219,7 @@ def make_wheel_in(ini_path, wheel_directory, editable=False): return SimpleNamespace(builder=wb, file=wheel_path) -def main(): +def main(argv=None): parser = argparse.ArgumentParser() parser.add_argument( 'srcdir', @@ -234,7 +234,7 @@ def main(): '-o', help='output directory (defaults to {srcdir}/dist)', ) - args = parser.parse_args() + args = parser.parse_args(argv) outdir = args.srcdir / 'dist' if args.outdir is None else Path(args.outdir) print("Building wheel from", args.srcdir) pyproj_toml = args.srcdir / 'pyproject.toml' From 6b5d64439bb299fc4875b7a7179c1fb613320800 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Thu, 17 Feb 2022 15:35:03 +0000 Subject: [PATCH 15/21] Update bootstrapping doc --- doc/bootstrap.rst | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/doc/bootstrap.rst b/doc/bootstrap.rst index 02da8945..19d7d923 100644 --- a/doc/bootstrap.rst +++ b/doc/bootstrap.rst @@ -13,24 +13,29 @@ from source? The key piece is ``flit_core``. This is a package which can build itself using nothing except Python and the standard library. From an unpacked source archive, -you can run ``python build_dists.py``, of which the crucial part is:: +you can make a wheel by running:: - from flit_core import buildapi - whl_fname = buildapi.build_wheel('dist/') - print(os.path.join('dist', whl_fname)) + python -m flit_core.wheel -This produces a ``.whl`` wheel file, which you can unzip into your -``site-packages`` folder (or equivalent) to make ``flit_core`` available for -building other packages. (You could also just copy ``flit_core`` from the -source directory, but without the ``.dist-info`` folder, tools like pip won't -know that it's installed.) +And then you can install this wheel with the ``bootstrap_install.py`` script +included in the sdist (or by unzipping it to the correct directory):: + + # Install to site-packages for this Python: + python bootstrap_install.py dist/flit_core-*.whl + + # Install somewhere else: + python bootstrap_install.py --installdir /path/to/site-packages dist/flit_core-*.whl As of version 3.6, flit_core bundles the ``tomli`` TOML parser, to avoid a dependency cycle. If you need to unbundle it, you will need to special-case installing flit_core and/or tomli to get around that cycle. -I recommend that you get the `build `_ and -`installer `_ packages (and their -dependencies) installed as the goal of the bootstrapping phase. These tools -together can be used to install any other Python packages: ``build`` to create -wheels and ``installer`` to install them. +After ``flit_core``, I recommend that you get `installer +`_ set up. You can use +``python -m flit_core.wheel`` again to make a wheel, and then use installer +itself (from the source directory) to install it. + +After that, you probably want to get `build `_ +and its dependencies installed as the goal of the bootstrapping phase. You can +then use ``build`` to create wheels of any other Python packages, and +``installer`` to install them. From ede1253e302fd5fbaa21bbbb4d85fc4c65900000 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Thu, 17 Feb 2022 16:06:35 +0000 Subject: [PATCH 16/21] Improve docs around external data --- doc/pyproject_toml.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/pyproject_toml.rst b/doc/pyproject_toml.rst index 88fee376..8c56bdcf 100644 --- a/doc/pyproject_toml.rst +++ b/doc/pyproject_toml.rst @@ -428,6 +428,8 @@ Exclusions have priority over inclusions. External data section --------------------- +.. versionadded:: 3.7 + Data files which your code will use should go inside the Python package folder. Flit will package these with no special configuration. @@ -451,6 +453,11 @@ For instance, installing in a virtualenv usually doesn't affect anything outside that environment. Don't rely on these files being picked up unless you have close control of how the package will be installed. +If you install a package with ``flit install --symlink``, a symlink is made +for each file in the external data directory. Otherwise (including development +installs with ``pip install -e``), these files are copied to their destination, +so changes here won't take effect until you reinstall the package. + .. note:: For users coming from setuptools: external data corresponds to setuptools' From 84d266045b3353a948e9a666e397567e0cf6c32a Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Feb 2022 11:14:25 -0600 Subject: [PATCH 17/21] Add Concurrency Limit in CI --- .github/workflows/test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 16e902a1..f7ac0f6c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,6 +2,13 @@ name: Test on: [push, pull_request] +concurrency: + group: >- + ${{ github.workflow }}- + ${{ github.ref_type }}- + ${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + jobs: test: runs-on: ${{ matrix.platform }} From 8360b643ca679f3f470a95353708b4e347037d8b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 18 Feb 2022 13:23:39 -0600 Subject: [PATCH 18/21] ignore push events on other branchs --- .github/workflows/test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f7ac0f6c..5fa946ba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,10 @@ name: Test -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: concurrency: group: >- From 08ac42dd0c3223f9eecbefcdcc2e4b4b5d55708a Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Mon, 21 Feb 2022 18:46:33 +0000 Subject: [PATCH 19/21] Reword docstring for walk_data_dir about output format --- flit_core/flit_core/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flit_core/flit_core/common.py b/flit_core/flit_core/common.py index c039f332..edf95d87 100644 --- a/flit_core/flit_core/common.py +++ b/flit_core/flit_core/common.py @@ -421,8 +421,8 @@ def dist_info_name(distribution, version): def walk_data_dir(data_directory): """Iterate over the files in the given data directory. - Yields absolute paths - caller may want to make them relative. - Excludes any __pycache__ subdirectories. + Yields paths prefixed with data_directory - caller may want to make them + relative to that. Excludes any __pycache__ subdirectories. """ if data_directory is None: return From fed7a7e371df2299e341fb60d517f257be38ceb4 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Mon, 21 Feb 2022 19:04:56 +0000 Subject: [PATCH 20/21] Release notes for 3.7 --- doc/history.rst | 15 +++++++++++++++ doc/pyproject_toml.rst | 2 ++ 2 files changed, 17 insertions(+) diff --git a/doc/history.rst b/doc/history.rst index e3e6a126..343cd163 100644 --- a/doc/history.rst +++ b/doc/history.rst @@ -1,6 +1,21 @@ Release history =============== +Version 3.7 +----------- + +- Support for :ref:`external data files ` such + as man pages or Jupyter extension support files (:ghpull:`510`). +- Project names are now lowercase in wheel filenames and ``.dist-info`` folder + names, in line with the specifications (:ghpull:`498`). +- Improved support for :doc:`bootstrapping ` a Python environment, + e.g. for downstream packagers (:ghpull:`511`). ``flit_core.wheel`` is usable + with ``python -m`` to create wheels before the `build `_ + tool is available, and ``flit_core`` sdists also include a script to install + itself from a wheel before `installer `_ + is available. +- Use newer importlib APIs, fixing some deprecation warnings (:ghpull:`499`). + Version 3.6 ----------- diff --git a/doc/pyproject_toml.rst b/doc/pyproject_toml.rst index 8c56bdcf..388e41eb 100644 --- a/doc/pyproject_toml.rst +++ b/doc/pyproject_toml.rst @@ -425,6 +425,8 @@ Exclusions have priority over inclusions. You'll have to adapt your inclusion/exclusion rules to achieve the same result as you'd get with :ref:`build_cmd`. +.. _pyproject_toml_external_data: + External data section --------------------- From bdafdfec7158ba3774a47f7ed3d03645854a0540 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Tue, 22 Feb 2022 11:16:24 +0000 Subject: [PATCH 21/21] =?UTF-8?q?Bump=20version:=203.6.0=20=E2=86=92=203.7?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- doc/conf.py | 2 +- flit/__init__.py | 2 +- flit_core/flit_core/__init__.py | 2 +- pyproject.toml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index f8280ed8..3fb51ecf 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.6.0 +current_version = 3.7.0 commit = True tag = False diff --git a/doc/conf.py b/doc/conf.py index 2837ce50..364334dc 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -57,7 +57,7 @@ # built documents. # # The short X.Y version. -version = '3.6.0' +version = '3.7.0' # The full version, including alpha/beta/rc tags. release = version #+ '.1' diff --git a/flit/__init__.py b/flit/__init__.py index 57f689ea..24b23553 100644 --- a/flit/__init__.py +++ b/flit/__init__.py @@ -12,7 +12,7 @@ from .config import ConfigError from .log import enable_colourful_output -__version__ = '3.6.0' +__version__ = '3.7.0' log = logging.getLogger(__name__) diff --git a/flit_core/flit_core/__init__.py b/flit_core/flit_core/__init__.py index 0314577d..c227699a 100644 --- a/flit_core/flit_core/__init__.py +++ b/flit_core/flit_core/__init__.py @@ -4,4 +4,4 @@ All the convenient development features live in the main 'flit' package. """ -__version__ = '3.6.0' +__version__ = '3.7.0' diff --git a/pyproject.toml b/pyproject.toml index 64d14150..cb56b5c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["flit_core >=3.6.0,<4"] +requires = ["flit_core >=3.7.0,<4"] build-backend = "flit_core.buildapi" [project] @@ -8,7 +8,7 @@ authors = [ {name = "Thomas Kluyver", email = "thomas@kluyver.me.uk"}, ] dependencies = [ - "flit_core >=3.6.0", + "flit_core >=3.7.0", "requests", "docutils", "tomli",