def __init__(self, path: Union[str, Path]) -> None: from poetry.core.toml import TOMLFile self._file = TOMLFile(path=path) self._data: Optional["TOMLDocument"] = None self._build_system: Optional["BuildSystem"] = None self._poetry_config: Optional["TOMLDocument"] = None
def temporary_project_directory( path, toml_patch=None ): # type: (Path, Optional[Dict[str, Any]]) -> ContextManager[str] """ Context manager that takes a project source directory, copies content to a temporary directory, patches the `pyproject.toml` using the provided patch, or using the default patch if one is not given. The default path replaces `build-system` section in order to use the working copy of poetry-core as the backend. Once the context, exists, the temporary directory is cleaned up. :param path: Source project root directory to copy from. :param toml_patch: Patch to use for the pyproject.toml, defaults to build system patching. :return: A temporary copy """ assert (path / "pyproject.toml").exists() with tempfile.TemporaryDirectory(prefix="poetry-core-pep517") as tmp: dst = Path(tmp) / path.name shutil.copytree(str(path), dst) toml = TOMLFile(str(dst / "pyproject.toml")) data = toml.read() data.update(toml_patch or __toml_build_backend_patch__) toml.write(data) yield str(dst)
def test_validate_fails(): complete = TOMLFile(fixtures_dir / "complete.toml") content = complete.read()["tool"]["poetry"] content["this key is not in the schema"] = "" expected = ("Additional properties are not allowed " "('this key is not in the schema' was unexpected)") assert Factory.validate(content) == {"errors": [expected], "warnings": []}
def test_strict_validation_success_on_multiple_readme_files() -> None: with_readme_files = TOMLFile(fixtures_dir / "with_readme_files" / "pyproject.toml") doc: dict[str, Any] = with_readme_files.read() content = doc["tool"]["poetry"] assert Factory.validate(content, strict=True) == { "errors": [], "warnings": [] }
def create(cls, reload: bool = False) -> Config: global _default_config if _default_config is None or reload: _default_config = cls() # Load global config config_file = TOMLFile(CONFIG_DIR / "config.toml") if config_file.exists(): logger.debug("Loading configuration file %s", config_file.path) _default_config.merge(config_file.read()) _default_config.set_config_source(FileConfigSource(config_file)) # Load global auth config auth_config_file = TOMLFile(CONFIG_DIR / "auth.toml") if auth_config_file.exists(): logger.debug("Loading configuration file %s", auth_config_file.path) _default_config.merge(auth_config_file.read()) _default_config.set_auth_config_source( FileConfigSource(auth_config_file)) return _default_config
def test_strict_validation_fails_on_readme_files_with_unmatching_types( ) -> None: with_readme_files = TOMLFile(fixtures_dir / "with_readme_files" / "pyproject.toml") doc: dict[str, Any] = with_readme_files.read() content = doc["tool"]["poetry"] content["readme"][0] = "README.md" assert Factory.validate(content, strict=True) == { "errors": [ "Declared README files must be of same type: found text/markdown," " text/x-rst" ], "warnings": [], }
def test_pyproject_toml_invalid() -> None: toml = TOMLFile(FIXTURE_DIR / "complete_invalid.toml").read() content = toml["tool"]["poetry"] assert Factory.validate(content) == { "errors": ["[source.0] 'url' is a required property"], "warnings": [], }
def test_pyproject_toml_file_invalid(pyproject_toml: Path) -> None: with pyproject_toml.open(mode="a") as f: f.write("<<<<<<<<<<<") with pytest.raises(PoetryCoreException) as excval: _ = TOMLFile(pyproject_toml).read() assert f"Invalid TOML file {pyproject_toml.as_posix()}" in str(excval.value)
def test_pyproject_toml_file_invalid(pyproject_toml): with pyproject_toml.open(mode="a") as f: f.write(decode("<<<<<<<<<<<")) with pytest.raises(PoetryCoreException) as excval: _ = TOMLFile(pyproject_toml).read() assert "Invalid TOML file {}".format(pyproject_toml.as_posix()) in str( excval.value)
def test_old_pyproject_toml_file_deprecation( pyproject_toml: Path, build_system_section: str, poetry_section: str ) -> None: from poetry.core.utils.toml_file import TomlFile with pytest.warns(DeprecationWarning): file = TomlFile(pyproject_toml) data = file.read() assert data == TOMLFile(pyproject_toml).read()
class PyProjectTOML: def __init__(self, path: str | Path) -> None: from poetry.core.toml import TOMLFile self._file = TOMLFile(path=path) self._data: TOMLDocument | None = None self._build_system: BuildSystem | None = None @property def file(self) -> TOMLFile: return self._file @property def data(self) -> TOMLDocument: from tomlkit.toml_document import TOMLDocument if self._data is None: if not self._file.exists(): self._data = TOMLDocument() else: self._data = self._file.read() return self._data @property def build_system(self) -> BuildSystem: from poetry.core.pyproject.tables import BuildSystem if self._build_system is None: build_backend = None requires = None if not self._file.exists(): build_backend = "poetry.core.masonry.api" requires = ["poetry-core"] container = self.data.get("build-system", {}) self._build_system = BuildSystem( build_backend=container.get("build-backend", build_backend), requires=container.get("requires", requires), ) return self._build_system @property def poetry_config(self) -> Container: from tomlkit.exceptions import NonExistentKey try: return cast(Container, self.data["tool"]["poetry"]) except NonExistentKey as e: from poetry.core.pyproject.exceptions import PyProjectException raise PyProjectException( f"[tool.poetry] section not found in {self._file}" ) from e def is_poetry_project(self) -> bool: from poetry.core.pyproject.exceptions import PyProjectException if self.file.exists(): try: _ = self.poetry_config return True except PyProjectException: pass return False def __getattr__(self, item: str) -> Any: return getattr(self.data, item) def save(self) -> None: from tomlkit.container import Container data = self.data if self._build_system is not None: if "build-system" not in data: data["build-system"] = Container() build_system = cast(Container, data["build-system"]) build_system["requires"] = self._build_system.requires build_system["build-backend"] = self._build_system.build_backend self.file.write(data=data) def reload(self) -> None: self._data = None self._build_system = None
def test_pyproject_toml_valid() -> None: toml = TOMLFile(FIXTURE_DIR / "complete_valid.toml").read() content = toml["tool"]["poetry"] assert Factory.validate(content) == {"errors": [], "warnings": []}
def test_validate(): complete = TOMLFile(fixtures_dir / "complete.toml") content = complete.read()["tool"]["poetry"] assert Factory.validate(content) == {"errors": [], "warnings": []}
def __init__(self, path): # type: (Union[str, Path]) -> None self._file = TOMLFile(path=path) self._data = None # type: Optional[TOMLDocument] self._build_system = None # type: Optional[BuildSystem] self._poetry_config = None # type: Optional[TOMLDocument]
class PyProjectTOML: def __init__(self, path): # type: (Union[str, Path]) -> None self._file = TOMLFile(path=path) self._data = None # type: Optional[TOMLDocument] self._build_system = None # type: Optional[BuildSystem] self._poetry_config = None # type: Optional[TOMLDocument] @property def file(self): # type: () -> TOMLFile return self._file @property def data(self): # type: () -> TOMLDocument if self._data is None: if not self._file.exists(): self._data = TOMLDocument() else: self._data = self._file.read() return self._data @property def build_system(self): # type: () -> BuildSystem if self._build_system is None: build_backend = None requires = None if not self._file.exists(): build_backend = "poetry.core.masonry.api" requires = ["poetry-core"] container = self.data.get("build-system", {}) self._build_system = BuildSystem( build_backend=container.get("build-backend", build_backend), requires=container.get("requires", requires), ) return self._build_system @property def poetry_config(self): # type: () -> Optional[TOMLDocument] if self._poetry_config is None: self._poetry_config = self.data.get("tool", {}).get("poetry") if self._poetry_config is None: raise PyProjectException( "[tool.poetry] section not found in {}".format(self._file)) return self._poetry_config def is_poetry_project(self): # type: () -> bool if self.file.exists(): try: _ = self.poetry_config return True except PyProjectException: pass return False def __getattr__(self, item): # type: (str) -> Any return getattr(self.data, item) def save(self): # type: () -> None data = self.data if self._poetry_config is not None: data["tool"]["poetry"] = self._poetry_config if self._build_system is not None: if "build-system" not in data: data["build-system"] = Container() data["build-system"]["requires"] = self._build_system.requires data["build-system"][ "build-backend"] = self._build_system.build_backend self.file.write(data=data) def reload(self): # type: () -> None self._data = None self._build_system = None self._poetry_config = None
def test_pyproject_toml_file_getattr(tmp_path: Path, pyproject_toml: Path) -> None: file = TOMLFile(pyproject_toml) assert file.parent == tmp_path
def __init__(self, path: str | Path) -> None: from poetry.core.toml import TOMLFile self._file = TOMLFile(path=path) self._data: TOMLDocument | None = None self._build_system: BuildSystem | None = None
def test_validate() -> None: complete = TOMLFile(fixtures_dir / "complete.toml") doc: dict[str, Any] = complete.read() content = doc["tool"]["poetry"] assert Factory.validate(content) == {"errors": [], "warnings": []}