Ursache für "QML-Dateien greifen nicht" (Verfahrensgebiet #50): get_plugin_root() nutzte Path(__file__).resolve(), was Junctions zum echten Zielverzeichnis auflöst. link_qgis_profile.py verknüpft die Klone im QGIS-Profil per Junction unter ihrem Paketnamen (sn_verfahrensgebiet, sn_plan41, ...) - .resolve() sprang dabei zurück zum Workspace-Root, wo die Klone unter ihrem Repo-Namen (Plugin_SN_*) liegen. Alle Aufrufer von get_plugin_root() (Stilpruefer, ly_style_wrapper.apply_style, LayerLoader.apply_style, Datenschreiber, sn_plan41 vln_api_logic/tab_a_logic) suchten dadurch am falschen Ort. .absolute() statt .resolve(): __file__ liefert beim Import über die Junction bereits den korrekten, unaufgelösten Pfad - nichts, was aufgelöst werden müsste. Für echte ZIP-/Repository-Installationen (kein Symlink im Plugin- Ordner) ändert sich nichts, da dort nichts aufzulösen ist. Test test_get_plugin_root_folgt_keiner_verzeichnisverknuepfung legt eine echte Verzeichnisverknüpfung an (Symlink, unter Windows via Junction wie link_qgis_profile.py) und zeigt den Fehler vor dem Fix rot, danach grün. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
113 lines
2.7 KiB
Python
113 lines
2.7 KiB
Python
"""
|
||
sn_basis/functions/sys_wrapper.py – System- und Pfad-Abstraktion
|
||
"""
|
||
|
||
from pathlib import Path
|
||
from typing import Union
|
||
import sys
|
||
|
||
from sn_basis.functions.os_wrapper import is_absolute_path, basename
|
||
|
||
_PathLike = Union[str, Path]
|
||
|
||
|
||
# ---------------------------------------------------------
|
||
# Plugin Root
|
||
# ---------------------------------------------------------
|
||
|
||
def get_plugin_root() -> Path:
|
||
"""
|
||
Liefert das Basisverzeichnis des Plugins.
|
||
|
||
Löst bewusst keine Symlinks/Junctions auf (``.absolute()`` statt
|
||
``.resolve()``): ``link_qgis_profile.py`` verknüpft die Klone im
|
||
QGIS-Profil per Junction unter ihrem Paketnamen. Würde hier aufgelöst,
|
||
landete man beim Workspace-Root (wo die Klone unter ihrem Repo-Namen
|
||
liegen) statt beim QGIS-Plugin-Ordner – Assets von Fachplugins wären dann
|
||
nicht mehr auffindbar (Verfahrensgebiet #50).
|
||
"""
|
||
return Path(__file__).absolute().parents[2]
|
||
|
||
|
||
# ---------------------------------------------------------
|
||
# Pfad-Utilities
|
||
# ---------------------------------------------------------
|
||
|
||
def join_path(*parts: _PathLike) -> Path:
|
||
"""
|
||
Verbindet Pfadbestandteile OS-sicher.
|
||
"""
|
||
path = Path(parts[0])
|
||
for part in parts[1:]:
|
||
path /= part
|
||
return path
|
||
|
||
|
||
def file_exists(path: _PathLike) -> bool:
|
||
"""
|
||
Prüft, ob eine Datei existiert.
|
||
"""
|
||
try:
|
||
return Path(path).exists()
|
||
except Exception:
|
||
return False
|
||
|
||
|
||
def ensure_dir(path: _PathLike) -> Path:
|
||
"""
|
||
Stellt sicher, dass ein Verzeichnis existiert.
|
||
"""
|
||
p = Path(path)
|
||
p.mkdir(parents=True, exist_ok=True)
|
||
return p
|
||
|
||
|
||
# ---------------------------------------------------------
|
||
# Datei-IO
|
||
# ---------------------------------------------------------
|
||
|
||
def read_text(path: _PathLike, encoding: str = "utf-8") -> str:
|
||
"""
|
||
Liest eine Textdatei.
|
||
"""
|
||
try:
|
||
return Path(path).read_text(encoding=encoding)
|
||
except Exception:
|
||
return ""
|
||
|
||
|
||
def write_text(
|
||
path: _PathLike,
|
||
content: str,
|
||
encoding: str = "utf-8",
|
||
) -> bool:
|
||
"""
|
||
Schreibt eine Textdatei.
|
||
"""
|
||
try:
|
||
Path(path).write_text(content, encoding=encoding)
|
||
return True
|
||
except Exception:
|
||
return False
|
||
|
||
|
||
|
||
def add_to_sys_path(path: Union[str, Path]) -> None:
|
||
"""
|
||
Fügt einen Pfad zu sys.path hinzu, falls er noch nicht enthalten ist.
|
||
"""
|
||
p = str(path)
|
||
if p not in sys.path:
|
||
sys.path.insert(0, p)
|
||
def getattr_safe(obj, attr, default=None):
|
||
"""
|
||
Sicherer Zugriff auf ein Attribut.
|
||
|
||
Gibt das Attribut zurück, wenn es existiert,
|
||
ansonsten den Default-Wert (None, wenn nicht angegeben).
|
||
"""
|
||
try:
|
||
return getattr(obj, attr)
|
||
except Exception:
|
||
return default
|