Source code for xcookie.builders.pyproject

import toml
import ubelt as ub


[docs] def build_pyproject(self): """ Returns: str: templated code """ # data = toml.loads((self.template_dpath / 'pyproject.toml').read_text()) # print('data = {}'.format(ub.urepr(data, nl=5))) pyproj_config = ub.AutoDict() use_setup_py = self.config.get('use_setup_py', True) pyproject_settings = self.config._load_xcookie_pyproject_settings() if pyproject_settings is None: pyproject_settings = {} # {'tool': {}} if 'binpy' in self.config['tags']: pyproj_config['build-system']['requires'] = [ 'setuptools>=41.0.1', # setuptools_scm[toml] # "wheel", 'scikit-build>=0.11.1', 'numpy', 'ninja>=1.10.2', 'cmake>=3.21.2', 'cython>=0.29.24', ] supported_cp_version = [] for pyver in self.config['supported_python_versions']: supported_cp_version.append('cp' + pyver.replace('.', '')) wheel_build_patterns = [] for cpver in supported_cp_version: wheel_build_patterns.append(cpver + '-*') test_extras = ['tests-strict', 'runtime-strict'] if 'cv2' in self.config['tags']: test_extras += ['headless-strict'] pyproj_config['tool']['cibuildwheel'].update( { 'build': ' '.join(wheel_build_patterns), 'build-frontend': 'build', # 'skip': "pp* cp27-* cp34-* cp35-* cp36-* *-musllinux_*", 'skip': 'pp* *-musllinux_*', 'build-verbosity': 1, # 'test-requires': ["-r requirements/tests.txt"], 'test-extras': test_extras, 'test-command': 'python {project}/run_tests.py', } ) if True: cibw = pyproj_config['tool']['cibuildwheel'] req_commands = { 'linux': [ 'yum install epel-release lz4 lz4-devel -y', ], 'windows': [ 'choco install lz4 -y', ], 'macos': [ 'brew install lz4', ], } for plat in req_commands.keys(): cmd = ' && '.join(req_commands[plat]) cibw[plat]['before-all'] = cmd else: pyproj_config['build-system']['requires'] = [ 'setuptools>=41.0.1', # setuptools_scm[toml] # "wheel>=0.37.1", ] pyproj_config['build-system']['build-backend'] = 'setuptools.build_meta' WITH_PYTEST_INI = 1 if WITH_PYTEST_INI: xdoctest_style = self.config['xdoctest_style'] pytest_ini_opts = pyproj_config['tool']['pytest']['ini_options'] pytest_ini_opts['addopts'] = ( f'-p no:doctest --xdoctest --xdoctest-style={xdoctest_style} --ignore-glob=setup.py --ignore-glob=dev --ignore-glob=docs' ) pytest_ini_opts['norecursedirs'] = ( '.git ignore build __pycache__ dev _skbuild docs' ) pytest_ini_opts['filterwarnings'] = [ 'default', 'ignore:.*No cfgstr given in Cacher constructor or call.*:Warning', 'ignore:.*Define the __nice__ method for.*:Warning', 'ignore:.*private pytest class or function.*:Warning', ] WITH_COVERAGE = 1 if WITH_COVERAGE: pyproj_config['tool']['coverage'].update( toml.loads( ub.codeblock( """ [run] branch = true [report] exclude_lines =[ "pragma: no cover", ".* # pragma: no cover", ".* # nocover", "def __repr__", "raise AssertionError", "raise NotImplementedError", "if 0:", "if trace is not None", "verbose = .*", "^ *raise", "^ *pass *$", "if _debug:", "if __name__ == .__main__.:", ".*if six.PY2:" ] omit=[ "{REPO_NAME}/__main__.py", "*/setup.py" ] """ ).format(REPO_NAME=self.repo_name) ) ) pyproj_config['tool']['mypy']['ignore_missing_imports'] = True WITH_XCOOKIE = 1 if WITH_XCOOKIE: options_to_save = [ 'tags', 'mod_name', 'repo_name', 'pkg_name', 'rel_mod_parent_dpath', 'os', 'min_python', 'version', 'url', 'author', 'author_email', 'description', 'license', 'dev_status', 'typed', 'remote_host', 'remote_group', 'use_setup_py', ] config_to_save = ub.dict_subset(self.config, options_to_save) pyproj_config['tool']['xcookie'].update(config_to_save) if not use_setup_py: project_block = pyproj_config['project'] project_block['name'] = self.config['pkg_name'] project_block['description'] = self.config['description'] project_block['requires-python'] = f'>={self.config["min_python"]}' project_block['dynamic'] = [ 'version', 'dependencies', 'optional-dependencies', ] authors = self.config['author'] author_emails = self.config['author_email'] author_entries = [] if authors: if not isinstance(authors, (list, tuple)): authors = [authors] if not isinstance(author_emails, (list, tuple)): author_emails = [author_emails] if author_emails else [] for idx, name in enumerate(authors): entry = {'name': name} if idx < len(author_emails) and author_emails[idx]: entry['email'] = author_emails[idx] elif isinstance(author_emails, str) and idx == 0: entry['email'] = author_emails author_entries.append(entry) if author_entries: project_block['authors'] = author_entries project_block['classifiers'] = self._project_classifiers() if self.config['license']: project_block['license'] = {'text': self.config['license']} if self.config['url']: project_block['urls'] = {'Homepage': str(self.config['url'])} if self.config['tags']: project_block['keywords'] = sorted( {tag for tag in self.config['tags'] if tag} ) setuptools_block = pyproj_config['tool']['setuptools'] setuptools_block['include-package-data'] = True setuptools_block['packages']['find']['where'] = [ self.config['rel_mod_parent_dpath'] ] setuptools_block['packages']['find']['include'] = [ f'{self.config["mod_name"]}*' ] if self.config['rel_mod_parent_dpath'] != '.': setuptools_block['package-dir'] = { '': self.config['rel_mod_parent_dpath'] } package_data = setuptools_block['package-data'] package_data['*'] = ['requirements/*.txt'] if self.config['typed']: package_data[self.mod_name] = ['py.typed', '*.pyi'] for key, value in pyproject_settings.get('package_data', {}).items(): normalized_key = '*' if key == '' else key package_data[normalized_key] = value setuptools_dynamic = setuptools_block['dynamic'] setuptools_dynamic['version'] = { 'attr': f'{self.config["mod_name"]}.__version__' } setuptools_dynamic['readme'] = { 'file': ['README.rst'], 'content-type': 'text/x-rst', } setuptools_dynamic['dependencies'] = { 'file': ['requirements/runtime.txt'] } extras = ['tests', 'optional', 'docs'] if 'cv2' in self.tags: extras.extend(['headless', 'graphics']) if 'postgresql' in self.tags: extras.append('postgresql') optional_dynamic = {} for name in extras: optional_dynamic[name] = {'file': [f'requirements/{name}.txt']} setuptools_dynamic['optional-dependencies'] = optional_dynamic entry_points = pyproject_settings.get('entry_points', {}) console_scripts = entry_points.get('console_scripts', []) if console_scripts: scripts = {} for item in console_scripts: name, _, target = item.partition('=') scripts[name.strip()] = target.strip() project_block['scripts'] = scripts extra_entry_points = { k: v for k, v in entry_points.items() if k != 'console_scripts' } if extra_entry_points: ep_table = {} for group, entries in extra_entry_points.items(): group_entries = {} for item in entries: name, _, target = item.partition('=') group_entries[name.strip()] = target.strip() ep_table[group] = group_entries project_block['entry-points'] = ep_table pyproj_config['build-system'].setdefault( 'build-backend', 'setuptools.build_meta' ) try: # fix GitURL issue pyproj_config['tool']['xcookie']['url'] = str( pyproj_config['tool']['xcookie']['url'] ) except KeyError: ... text = toml.dumps(pyproj_config) return text