def migrate_scripts(self): if "scripts" not in self._pipenv: return for name, cmd in self._pipenv["scripts"].items(): if "scripts" not in self._pyproject["tool"]["poetry"]: self._pyproject["tool"]["poetry"]["scripts"] = table() self._pyproject["tool"]["poetry"]["scripts"].add(name, cmd)
def from_string(cls, string): document = tomlkit.loads(string) # tomlkit's setdefault is broken, see sdipater/tomlkit#49 for each in "virtualenv", "bundle": if each not in document: document[each] = tomlkit.table() _check_for_duplicated_links(document["virtualenv"].values()) return cls(contents=document)
def _add_config_values_to_toml_object(toml_obj: TOMLContainer, data: typing.Dict[str, typing.Union[dict, ConfigValue]]): for key_name, key_data in data.items(): if isinstance(key_data, dict): table = tomlkit.table() _add_config_values_to_toml_object(table, key_data) toml_obj[key_name] = table else: key_data.add_to_toml_obj(toml_obj, _NOT_SET)
def test_uses_pyproject_if_tbump_toml_is_missing(test_data_path: Path, tmp_path: Path) -> None: expected_file = tbump.config.get_config_file(test_data_path) parsed_config = expected_file.get_parsed() tools_config = tomlkit.table() tools_config.add("tbump", parsed_config) pyproject_config = tomlkit.table() pyproject_config.add("tool", tools_config) to_write = tomlkit.dumps(pyproject_config) pyproject_toml = tmp_path / "pyproject.toml" pyproject_toml.write_text(to_write) actual_file = tbump.config.get_config_file(tmp_path) assert actual_file.get_config() == expected_file.get_config()
def generate_poetry_content(self, original: PyProjectTOML | None = None) -> str: template = POETRY_DEFAULT content = loads(template) poetry_content = content["tool"]["poetry"] poetry_content["name"] = self._project poetry_content["version"] = self._version poetry_content["description"] = self._description poetry_content["authors"].append(self._author) if self._license: poetry_content["license"] = self._license else: poetry_content.remove("license") poetry_content["readme"] = f"README.{self._readme_format}" packages = self.get_package_include() if packages: poetry_content["packages"].append(packages) else: poetry_content.remove("packages") poetry_content["dependencies"]["python"] = self._python for dep_name, dep_constraint in self._dependencies.items(): poetry_content["dependencies"][dep_name] = dep_constraint if self._dev_dependencies: for dep_name, dep_constraint in self._dev_dependencies.items(): poetry_content["group"]["dev"]["dependencies"][ dep_name] = dep_constraint else: del poetry_content["group"] # Add build system build_system = table() build_system_version = "" if BUILD_SYSTEM_MIN_VERSION is not None: build_system_version = ">=" + BUILD_SYSTEM_MIN_VERSION if BUILD_SYSTEM_MAX_VERSION is not None: if build_system_version: build_system_version += "," build_system_version += "<" + BUILD_SYSTEM_MAX_VERSION build_system.add("requires", ["poetry-core" + build_system_version]) build_system.add("build-backend", "poetry.core.masonry.api") content.add("build-system", build_system) content = dumps(content) if original and original.file.exists(): content = dumps(original.data) + "\n" + content return content
def _add_entrypoints(section, entrypoints): # drop old console_scripts if 'scripts' in section: scripts = {e.name for e in entrypoints if e.group == 'console_scripts'} for script_name in section['scripts']: if script_name not in scripts: del section['scripts'][script_name] # add console_scripts for entrypoint in entrypoints: if entrypoint.group != 'console_scripts': continue if 'scripts' not in section: section['scripts'] = tomlkit.table() if entrypoint.extras: content = tomlkit.inline_table() content['callable'] = entrypoint.path content['extras'] = entrypoint.extras else: content = entrypoint.path section['scripts'][entrypoint.name] = content # drop old plugins if 'plugins' in section: groups = defaultdict(set) for entrypoint in entrypoints: if entrypoint.group != 'console_scripts': groups[entrypoint.group].add(entrypoint.name) for group_name, group_content in dict(section['plugins']): if group_name not in groups: del section['plugins'][group_name] continue for script_name in group_content: if script_name not in groups[group_name]: del section['plugins'][group_name][script_name] # add plugins for entrypoint in entrypoints: if entrypoint.group == 'console_scripts': continue if 'plugins' not in section: section['plugins'] = tomlkit.table() if entrypoint.group not in section['plugins']: section['plugins'][entrypoint.group] = tomlkit.table() section['plugins'][entrypoint.group][entrypoint.name] = entrypoint.path
def do_import( project: Project, filename: str, format: Optional[str] = None, options: Optional[Namespace] = None, ) -> None: """Import project metadata from given file. :param project: the project instance :param filename: the file name :param format: the file format, or guess if not given. :param options: other options parsed to the CLI. """ if not format: for key in FORMATS: if FORMATS[key].check_fingerprint(project, filename): break else: raise PdmUsageError("Can't derive the file format automatically, " "please specify it via '-f/--format' option.") else: key = format if options is None: options = Namespace(dev=False, section=None) project_data, settings = FORMATS[key].convert(project, filename, options) pyproject = project.pyproject or tomlkit.document() if "tool" not in pyproject or "pdm" not in pyproject["tool"]: setdefault(pyproject, "tool", {})["pdm"] = tomlkit.table() pyproject["tool"]["pdm"].update(settings) if "project" not in pyproject: pyproject.add("project", tomlkit.table()) pyproject["project"].add(tomlkit.comment("PEP 621 project metadata")) pyproject["project"].add( tomlkit.comment("See https://www.python.org/dev/peps/pep-0621/")) pyproject["project"].update(project_data) pyproject["build-system"] = { "requires": ["pdm-pep517"], "build-backend": "pdm.pep517.api", } project.pyproject = pyproject project.write_pyproject()
def dump(self, configs, path): doc = tomlkit.document() root_comment = getattr(configs, '__doc__', '') def add_comment(sec, comment): for line in textwrap.wrap(comment.strip()): sec.add(tomlkit.comment(line)) def add_value(sec, k, v): is_none = v is None if is_none: sec.add(tomlkit.comment(f'{k} = # Uncomment to use')) else: sec.add(k, v) return not is_none if root_comment: add_comment(doc, root_comment.strip()) doc.add(tomlkit.nl()) for p, value, prop in configs.get_prop_paths(): section = doc key = p if '.' in p: parts = p.split('.') key = parts[-1] for part in parts[:-1]: section = section[part] if isinstance(value, Nestable): # Just add a table for those. table = tomlkit.table() section.add(key, table) if prop.comment is not None: add_comment(table, prop.comment) table.add(tomlkit.nl()) else: if prop.comment is not None: if len(prop.comment) > 40: # Only short comments are inlined. section.add(tomlkit.nl()) add_comment(section, prop.comment) add_value(section, key, value) else: good = add_value(section, key, value) if good: if isinstance(value, bool): item = section.item(key) else: item = section[key] item.comment(prop.comment) else: add_value(section, key, value) with open(path, 'w') as file: file.write(tomlkit.dumps(doc))
def source_to_table(source: Source) -> Table: from tomlkit import nl from tomlkit import table source_table: Table = table() for key, value in source.to_dict().items(): source_table.add(key, value) source_table.add(nl()) return source_table
def _get_pipfile_section(self, develop, insert=True): name = "dev-packages" if develop else "packages" try: section = self.pipfile[name] except KeyError: section = plette.models.PackageCollection(tomlkit.table()) if insert: self.pipfile[name] = section return section
def test_basic(self): t = table() t.append('name', 'mypackage') t.append('version', '1.2.3') packageName, packageVersion = self.__lock2PyprojectConverter.convert(t) self.assertEqual('mypackage', packageName) self.assertEqual('1.2.3', packageVersion)
def create(self, name: str = None): if self.config_path: logger.error("Config file already initialized: {config}", config=self.config_path) return _name = name or os.path.basename(os.getcwd()) config_root = os.path.join(os.getcwd(), name or "") self.config_path = os.path.join(config_root, "pyproject.toml") if os.path.exists(self.config_path): logger.error("Config file already exists at: {config}", config=self.config_path) return logger.info("Creating project: {path}", path=config_root) if not os.path.exists(config_root): os.mkdir(config_root) project_conf = document() poetry_meta = table() poetry_meta.add("name", _name) poetry_meta.add("version", "0.0.1") poetry_meta.add("description", "Just an opinionated photo stream site") project_conf.add("tool.poetry", poetry_meta) poetry_deps = table() poetry_deps.add("python", "^3.8") poetry_deps.add(__title__, "*") project_conf.add("tool.poetry.dependencies", poetry_deps) build_sys = table() build_sys.add("requires", ["poetry-core>=1.0.0"]) build_sys.add("build-backend", "poetry.masonry.api") project_conf.add("build-system", build_sys) meta = table() meta.add("name", _name) meta.add("author", "John Smith") meta.add("author_bio", "Just a photographer") project_conf.add("tool.humber.meta", meta) with open(self.config_path, "w", encoding="utf-8") as f: f.write(project_conf.as_string()) logger.info("Created new config: {conf}", conf=self.config_path)
def create_config_file(config: Config) -> None: doc = tomlkit.document() doc.add("theme", config.theme) sitemeta = tomlkit.table() sitemeta.add("title", config.sitemeta.title) sitemeta.add("author", config.sitemeta.author) sitemeta.add("language_code", config.sitemeta.language_code) sitemeta.add("year_of_publication", config.sitemeta.year_of_publication) doc.add("sitemeta", sitemeta) write_file("config.toml", doc.as_string())
def update_pyproject_version(self, new_version: str,) -> None: """ Update the version in the pyproject.toml file """ version = safe_version(new_version) pyproject_toml = tomlkit.parse(self.pyproject_toml_path.read_text()) if 'tool' not in pyproject_toml: tool_table = tomlkit.table() pyproject_toml['tool'] = tool_table if 'poetry' not in pyproject_toml['tool']: poetry_table = tomlkit.table() pyproject_toml['tool'].add('poetry', poetry_table) pyproject_toml['tool']['poetry']['version'] = version self.pyproject_toml_path.write_text(tomlkit.dumps(pyproject_toml))
def reorder_source_keys(data): # type: ignore sources = data["source"] # type: sources_type for i, entry in enumerate(sources): table = tomlkit.table() # type: Mapping table["name"] = entry["name"] table["url"] = entry["url"] table["verify_ssl"] = entry["verify_ssl"] data["source"][i] = table return data
def dumps(self, reqs, project: RootDependency, content=None) -> str: doc = tomlkit.parse(content) if content else tomlkit.document() doc['package'] = [self._format_req(req=req) for req in reqs] # add extras extras = defaultdict(list) for req in reqs: if req.is_main: for extra in req.main_envs: extras[extra].append(req.name) if req.is_dev: for extra in req.dev_envs: extras[extra].append(req.name) if extras: doc['extras'] = dict(extras) # add repositories sources = tomlkit.aot() if not project.dependencies: project.attach_dependencies([req.dep for req in reqs]) for repo in project.warehouses: if isinstance(repo, WarehouseLocalRepo): continue source = tomlkit.table() source['name'] = repo.name source['url'] = repo.pretty_url sources.append(source) if sources: doc['source'] = sources doc['metadata'] = { # sha256 of tool.poetry section from pyproject.toml # 'content-hash': ..., # 'platform': '*', 'python-versions': str(project.python), } doc['metadata']['hashes'] = tomlkit.table() for req in reqs: doc['metadata']['hashes'][req.name] = list(req.hashes or []) return tomlkit.dumps(doc)
def dict_to_toml(d): import tomlkit toml = tomlkit.document() toml.add(tomlkit.comment("Autogenertod by anysnake")) for key, sub_d in d.items(): table = tomlkit.table() for k, v in sub_d.items(): table.add(k, v) toml.add(key, table) return toml
def defaults(commented): table = tomlkit.table() table['model_kwargs'] = collect_kwarg_defaults(PauliNet.from_hf, DEEPQMC_MAPPING) table['train_kwargs'] = collect_kwarg_defaults(train, DEEPQMC_MAPPING) table['evaluate_kwargs'] = collect_kwarg_defaults(evaluate, DEEPQMC_MAPPING) lines = tomlkit.dumps(table).split('\n') if commented: lines = ['# ' + l if ' = ' in l and l[0] != '#' else l for l in lines] click.echo('\n'.join(lines), nl=False)
def reorder_source_keys(data): # type: ignore sources = data["source"] # type: sources_type for i, entry in enumerate(sources): table = tomlkit.table() # type: Mapping source_entry = PipfileLoader.populate_source(entry.copy()) table["name"] = source_entry["name"] table["url"] = source_entry["url"] table["verify_ssl"] = source_entry["verify_ssl"] data["source"][i] = table return data
def test_git(self): t = table() t.append('name', 'mypackage') t.append('version', '1.2.3') tr = table() tr.append('reference', '0e2068c02f72b9d3092ff8343aab72cd606fc983') tr.append('type', 'git') tr.append('url', 'https://github.com/bricksflow/dbx-deploy.git') t.append('source', tr) packageName, packageDefinition = self.__lock2PyprojectConverter.convert( t) it = inline_table() it.append('git', 'https://github.com/bricksflow/dbx-deploy.git') it.append('rev', '0e2068c02f72b9d3092ff8343aab72cd606fc983') self.assertEqual('mypackage', packageName) self.assertEqual(it, packageDefinition)
def _make_env(from_format, from_path, to_format, to_path): table = tomlkit.table() table['from'] = tomlkit.inline_table() table['from']['format'] = from_format table['from']['path'] = from_path table['to'] = tomlkit.inline_table() table['to']['format'] = to_format table['to']['path'] = to_path return table
def _make_env(from_format: str, from_path: str, to_format: str, to_path: str) -> Table: table = tomlkit.table() table['from'] = tomlkit.inline_table() table['from']['format'] = from_format table['from']['path'] = from_path table['to'] = tomlkit.inline_table() table['to']['format'] = to_format table['to']['path'] = to_path return table
def generate_poetry_content(self) -> TOMLDocument: template = POETRY_DEFAULT content: dict[str, Any] = loads(template) poetry_content = content["tool"]["poetry"] poetry_content["name"] = self._project poetry_content["version"] = self._version poetry_content["description"] = self._description poetry_content["authors"].append(self._author) if self._license: poetry_content["license"] = self._license else: poetry_content.remove("license") poetry_content["readme"] = f"README.{self._readme_format}" packages = self.get_package_include() if packages: poetry_content["packages"].append(packages) else: poetry_content.remove("packages") poetry_content["dependencies"]["python"] = self._python for dep_name, dep_constraint in self._dependencies.items(): poetry_content["dependencies"][dep_name] = dep_constraint if self._dev_dependencies: for dep_name, dep_constraint in self._dev_dependencies.items(): poetry_content["group"]["dev"]["dependencies"][ dep_name] = dep_constraint else: del poetry_content["group"] # Add build system build_system = table() build_system_version = "" if BUILD_SYSTEM_MIN_VERSION is not None: build_system_version = ">=" + BUILD_SYSTEM_MIN_VERSION if BUILD_SYSTEM_MAX_VERSION is not None: if build_system_version: build_system_version += "," build_system_version += "<" + BUILD_SYSTEM_MAX_VERSION build_system.add("requires", ["poetry-core" + build_system_version]) build_system.add("build-backend", "poetry.core.masonry.api") assert isinstance(content, TOMLDocument) content.add("build-system", build_system) return content
def _format_req(self, req): result = tomlkit.table() for name, value in req: if name in self.fields: if isinstance(value, tuple): value = list(value) result[name] = value result['category'] = 'dev' if req.is_dev else 'main' if 'version' not in result: result['version'] = '*' result['version'] = result['version'].lstrip('=') if req.markers: result['marker'] = req.markers # add link if req.link and (req.git or isinstance(req.link, DirLink)): result['source'] = tomlkit.table() if req.git: result['source']['type'] = 'git' elif isinstance(req.link, DirLink): result['source']['type'] = 'directory' result['source']['url'] = req.link.short if req.rev: result['source']['reference'] = req.rev elif isinstance(req.dep.repo, WarehouseBaseRepo): repo = req.dep.repo.repos[0] result['source'] = tomlkit.table() result['source']['type'] = 'legacy' result['source']['url'] = repo.pretty_url result['source']['reference'] = repo.name # add dependencies deps = req.dep.dependencies if deps: result['dependencies'] = tomlkit.table() for dep in deps: result['dependencies'][dep.raw_name] = str( dep.constraint) or '*' return result
def create_test(test): '''Create conversion test table.''' conversion_test = tomlkit.table() float64 = Float64(test) mantissa = float64.mantissa() exponent = float64.exponent() conversion_test.add('UID', '') conversion_test.add('str', test) conversion_test.add('hex', float64.to_hex()) conversion_test.add('int', '{}*2^{}'.format(mantissa, exponent)) return conversion_test
def add_property(self, key, value): # type: (str, Any) -> None with self.secure() as config: keys = key.split(".") for i, key in enumerate(keys): if key not in config and i < len(keys) - 1: config[key] = table() if i == len(keys) - 1: config[key] = value break config = config[key]
def generate(template: settings_template, *, table: bool = False) -> document_or_table: """Generates a TOML document or table from a provided settings template""" document = tomlkit.table() if table else tomlkit.TOMLDocument() for item in template: match item: case Option(): document.add(item.key, item.value) case tomlkit.api.Comment() | tomlkit.api.Whitespace(): document.add(item) case _: raise TypeError('Template can only contain Option, Comment and Whitespace items') return document
def migrate_pyproject(project: Project): """Migrate the legacy pyproject format to PEP 621""" if project.pyproject and "project" in project.pyproject: pyproject = project.pyproject settings = {} updated_fields = [] for field in ("includes", "excludes", "build", "package-dir"): if field in pyproject["project"]: updated_fields.append(field) settings[field] = pyproject["project"][field] del pyproject["project"][field] if "dev-dependencies" in pyproject["project"]: if pyproject["project"]["dev-dependencies"]: settings["dev-dependencies"] = { "dev": pyproject["project"]["dev-dependencies"] } del pyproject["project"]["dev-dependencies"] updated_fields.append("dev-dependencies") if updated_fields: if "tool" not in pyproject or "pdm" not in pyproject["tool"]: setdefault(pyproject, "tool", {})["pdm"] = tomlkit.table() pyproject["tool"]["pdm"].update(settings) project.pyproject = pyproject project.write_pyproject() project.core.ui.echo( f"{termui.yellow('[AUTO-MIGRATION]')} These fields are moved from " f"[project] to [tool.pdm] table: {updated_fields}", err=True, ) return if not project.pyproject_file.exists() or not FORMATS["legacy"].check_fingerprint( project, project.pyproject_file ): return project.core.ui.echo( f"{termui.yellow('[AUTO-MIGRATION]')} Legacy pdm 0.x metadata detected, " "migrating to PEP 621...", err=True, ) do_import(project, project.pyproject_file, "legacy") project.core.ui.echo( termui.green("pyproject.toml") + termui.yellow( " has been migrated to PEP 621 successfully. " "Now you can safely delete the legacy metadata under [tool.pdm] table." ), err=True, )
def do_init( project: Project, name: str = "", version: str = "", license: str = "MIT", author: str = "", email: str = "", python_requires: str = "", ) -> None: """Bootstrap the project and create a pyproject.toml""" data = { "tool": { "pdm": { "name": name, "version": version, "description": "", "author": f"{author} <{email}>", "license": license, "homepage": "", "dependencies": tomlkit.table(), "dev-dependencies": tomlkit.table(), } }, "build-system": { "requires": ["pdm"], "build-backend": "pdm.builders.api" }, } if python_requires and python_requires != "*": get_specifier(python_requires) data["tool"]["pdm"]["python_requires"] = python_requires if not project.pyproject: project._pyproject = data else: project._pyproject.setdefault("tool", {})["pdm"] = data["tool"]["pdm"] project._pyproject["build-system"] = data["build-system"] project.write_pyproject() project.environment.write_site_py()
def format_lockfile(mapping, fetched_dependencies, summary_collection): """Format lock file from a dict of resolved candidates, a mapping of dependencies and a collection of package summaries. """ packages = tomlkit.aot() file_hashes = tomlkit.table() for k, v in sorted(mapping.items()): base = tomlkit.table() base.update(v.as_lockfile_entry()) base.add("summary", summary_collection[strip_extras(k)[0]]) deps = tomlkit.table() for r in fetched_dependencies[k].values(): name, req = r.as_req_dict() if getattr(req, "items", None) is not None: deps.add(name, make_inline_table(req)) else: deps.add(name, req) if len(deps) > 0: base.add("dependencies", deps) packages.append(base) if v.hashes: key = f"{k} {v.version}" array = tomlkit.array() array.multiline(True) for filename, hash_value in v.hashes.items(): inline = make_inline_table({ "file": filename, "hash": hash_value }) array.append(inline) if array: file_hashes.add(key, array) doc = tomlkit.document() doc.add("package", packages) metadata = tomlkit.table() metadata.add("files", file_hashes) doc.add("metadata", metadata) return doc
def add_property(self, key, value): keys = key.split(".") config = self._content for i, key in enumerate(keys): if key not in config and i < len(keys) - 1: config[key] = table() if i == len(keys) - 1: config[key] = value break config = config[key] self.dump()