From fe4342304a78d1eba15dc3b0807c8f7aee2faa35 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Mon, 19 Aug 2024 19:21:03 +0100 Subject: [PATCH 1/3] Add an exclude patttern for wheels Allows files to be included in the sdist but not installed. Useful for established projects that have tests as a subdirectory of the package directory. --- flit_core/flit_core/common.py | 33 +++++++++++++++++++++++++++++++++ flit_core/flit_core/config.py | 13 ++++++++++++- flit_core/flit_core/sdist.py | 35 ++--------------------------------- flit_core/flit_core/wheel.py | 10 +++++++--- 4 files changed, 54 insertions(+), 37 deletions(-) diff --git a/flit_core/flit_core/common.py b/flit_core/flit_core/common.py index 8bcda3fb..cca7150e 100644 --- a/flit_core/flit_core/common.py +++ b/flit_core/flit_core/common.py @@ -1,8 +1,10 @@ import ast from contextlib import contextmanager +from glob import glob import hashlib import logging import os +import os.path as osp import sys from pathlib import Path @@ -12,6 +14,37 @@ from .versionno import normalise_version + +class FilePatterns: + """Manage a set of file inclusion/exclusion patterns relative to basedir""" + def __init__(self, patterns, basedir): + self.basedir = basedir + + self.dirs = set() + self.files = set() + + for pattern in patterns: + for path in sorted(glob(osp.join(basedir, pattern), recursive=True)): + rel = osp.relpath(path, basedir) + if osp.isdir(path): + self.dirs.add(rel) + else: + self.files.add(rel) + + def match_file(self, rel_path): + if rel_path in self.files: + return True + + return any(rel_path.startswith(d + os.sep) for d in self.dirs) + + def match_dir(self, rel_path): + if rel_path in self.dirs: + return True + + # Check if it's a subdirectory of any directory in the list + return any(rel_path.startswith(d + os.sep) for d in self.dirs) + + class Module(object): """This represents the module/package that we are going to distribute """ diff --git a/flit_core/flit_core/config.py b/flit_core/flit_core/config.py index 12929561..24a2ca41 100644 --- a/flit_core/flit_core/config.py +++ b/flit_core/flit_core/config.py @@ -129,7 +129,7 @@ def prep_toml_config(d, path): ) unknown_sections = set(dtool) - { - 'metadata', 'module', 'scripts', 'entrypoints', 'sdist', 'external-data' + 'metadata', 'module', 'scripts', 'entrypoints', 'sdist', 'wheel', 'external-data' } unknown_sections = [s for s in unknown_sections if not s.lower().startswith('x-')] if unknown_sections: @@ -155,6 +155,17 @@ def prep_toml_config(d, path): exclude, 'exclude' ) + if 'wheel' in dtool: + unknown_keys = set(dtool['wheel']) - {'exclude'} + if unknown_keys: + raise ConfigError( + "Unknown keys in [tool.flit.wheel]:" + ", ".join(unknown_keys) + ) + + loaded_cfg.wheel_exclude_patterns = _check_glob_patterns( + dtool['wheel'].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" diff --git a/flit_core/flit_core/sdist.py b/flit_core/flit_core/sdist.py index b2d512bd..f067f0e5 100644 --- a/flit_core/flit_core/sdist.py +++ b/flit_core/flit_core/sdist.py @@ -1,6 +1,5 @@ from collections import defaultdict from copy import copy -from glob import glob from gzip import GzipFile import io import logging @@ -34,36 +33,6 @@ def clean_tarinfo(ti, mtime=None): return ti -class FilePatterns: - """Manage a set of file inclusion/exclusion patterns relative to basedir""" - def __init__(self, patterns, basedir): - self.basedir = basedir - - self.dirs = set() - self.files = set() - - for pattern in patterns: - for path in sorted(glob(osp.join(basedir, pattern), recursive=True)): - rel = osp.relpath(path, basedir) - if osp.isdir(path): - self.dirs.add(rel) - else: - self.files.add(rel) - - def match_file(self, rel_path): - if rel_path in self.files: - return True - - return any(rel_path.startswith(d + os.sep) for d in self.dirs) - - def match_dir(self, rel_path): - if rel_path in self.dirs: - return True - - # Check if it's a subdirectory of any directory in the list - return any(rel_path.startswith(d + os.sep) for d in self.dirs) - - class SdistBuilder: """Builds a minimal sdist @@ -80,8 +49,8 @@ def __init__(self, module, metadata, cfgdir, reqs_by_extra, entrypoints, 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)) + self.includes = common.FilePatterns(include_patterns, str(cfgdir)) + self.excludes = common.FilePatterns(exclude_patterns, str(cfgdir)) @classmethod def from_ini_path(cls, ini_path: Path): diff --git a/flit_core/flit_core/wheel.py b/flit_core/flit_core/wheel.py index 66b0ac29..4ae05b13 100644 --- a/flit_core/flit_core/wheel.py +++ b/flit_core/flit_core/wheel.py @@ -61,7 +61,8 @@ def zip_timestamp_from_env() -> Optional[tuple]: class WheelBuilder: def __init__( - self, directory, module, metadata, entrypoints, target_fp, data_directory + self, directory, module, metadata, entrypoints, target_fp, data_directory, + exclude_patterns=(), ): """Build a wheel from a module/package """ @@ -70,6 +71,7 @@ def __init__( self.metadata = metadata self.entrypoints = entrypoints self.data_directory = data_directory + self.excludes = common.FilePatterns(exclude_patterns, str(directory)) self.records = [] self.source_time_stamp = zip_timestamp_from_env() @@ -87,7 +89,8 @@ def from_ini_path(cls, ini_path, target_fp): module = common.Module(ini_info.module, directory) metadata = common.make_metadata(module, ini_info) return cls( - directory, module, metadata, entrypoints, target_fp, ini_info.data_directory + directory, module, metadata, entrypoints, target_fp, ini_info.data_directory, + ini_info.wheel_exclude_patterns, ) @property @@ -162,7 +165,8 @@ def copy_module(self): for full_path in self.module.iter_files(): rel_path = osp.relpath(full_path, source_dir) - self._add_file(full_path, rel_path) + if not self.excludes.match_file(rel_path): + self._add_file(full_path, rel_path) def add_pth(self): with self._write_to_zip(self.module.name + ".pth") as f: From a9fc3442d0e234a1479ec0f0a7530c7add63be99 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Mon, 19 Aug 2024 19:21:03 +0100 Subject: [PATCH 2/3] Stop installing flit_core tests --- flit_core/pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flit_core/pyproject.toml b/flit_core/pyproject.toml index affb6d0a..c3d12a18 100644 --- a/flit_core/pyproject.toml +++ b/flit_core/pyproject.toml @@ -25,3 +25,6 @@ Source = "https://github.com/pypa/flit" [tool.flit.sdist] include = ["bootstrap_install.py", "build_dists.py"] + +[tool.flit.wheel] +exclude = ["flit_core/tests"] From b758159d85b63ce833b0fb09a7bcc48bfc3984e8 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Mon, 26 Aug 2024 19:28:04 +0100 Subject: [PATCH 3/3] Add wheel_exclude_patterns to LoadedConfig --- flit_core/flit_core/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/flit_core/flit_core/config.py b/flit_core/flit_core/config.py index 24a2ca41..641bb690 100644 --- a/flit_core/flit_core/config.py +++ b/flit_core/flit_core/config.py @@ -266,6 +266,7 @@ def __init__(self): self.referenced_files = [] self.sdist_include_patterns = [] self.sdist_exclude_patterns = [] + self.wheel_exclude_patterns = [] self.dynamic_metadata = [] self.data_directory = None