diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e302cb43..e16c8ab1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,11 +24,11 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/tox-dev/pyproject-fmt - rev: v2.11.1 + rev: v2.16.2 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.24.1 + rev: v0.25 hooks: - id: validate-pyproject - repo: https://github.com/sphinx-contrib/sphinx-lint @@ -37,14 +37,14 @@ repos: - id: sphinx-lint types: [rst] - repo: https://github.com/pycqa/isort - rev: 7.0.0 + rev: 8.0.1 hooks: - id: isort additional_dependencies: ["toml"] entry: isort --profile=black name: isort (python) - repo: https://github.com/psf/black-pre-commit-mirror - rev: 25.12.0 + rev: 26.1.0 hooks: - id: black - repo: https://github.com/tonybaloney/perflint diff --git a/README.rst b/README.rst index 798eeeca..e145a575 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ Python4DataScience ================== -.. _badges: +.. _badges Status ------ @@ -29,7 +29,7 @@ Status :alt: Mastodon :target: https://mastodon.social/@Python4DataScience -.. _first-steps: +.. _first-steps Überblick --------- @@ -125,7 +125,7 @@ Installation Das PDF findet ihr anschließend in ``docs/_build/latex/jupytertutorial.pdf``. -.. _follow-us: +.. _follow-us Folge uns --------- diff --git a/docs/conf.py b/docs/conf.py index 504f0942..14cb00bb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,7 +18,6 @@ import os import re - # Set canonical URL for the sitemap html_baseurl = "https://python4data.science/de/latest/" @@ -33,7 +32,6 @@ import os import re - project = "Python für Data Science" author = "Veit Schiele" copyright = f"2019–2025, {author}" diff --git a/docs/data-processing/apis/fastapi/example.rst b/docs/data-processing/apis/fastapi/example.rst index 1e40aac5..4253af3b 100644 --- a/docs/data-processing/apis/fastapi/example.rst +++ b/docs/data-processing/apis/fastapi/example.rst @@ -16,7 +16,6 @@ Erstellt die Datei :file:`main.py` mit diesem Inhalt: from fastapi import FastAPI - app = FastAPI() @@ -81,7 +80,6 @@ zu erhalten: from fastapi import FastAPI - app = FastAPI() diff --git a/docs/data-processing/apis/grpc/accounts_pb2.py b/docs/data-processing/apis/grpc/accounts_pb2.py index fbe1589d..bf7c2ec9 100644 --- a/docs/data-processing/apis/grpc/accounts_pb2.py +++ b/docs/data-processing/apis/grpc/accounts_pb2.py @@ -6,12 +6,12 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: accounts.proto """Generated protocol buffer code.""" + from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database - # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() diff --git a/docs/data-processing/apis/grpc/accounts_pb2_grpc.py b/docs/data-processing/apis/grpc/accounts_pb2_grpc.py index c6c2f83d..b3787a52 100644 --- a/docs/data-processing/apis/grpc/accounts_pb2_grpc.py +++ b/docs/data-processing/apis/grpc/accounts_pb2_grpc.py @@ -4,6 +4,7 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" + import accounts_pb2 as accounts__pb2 import grpc diff --git a/docs/data-processing/postgresql/db-api.rst b/docs/data-processing/postgresql/db-api.rst index 60245b10..8c508f5a 100644 --- a/docs/data-processing/postgresql/db-api.rst +++ b/docs/data-processing/postgresql/db-api.rst @@ -82,12 +82,10 @@ Cursor .. code-block:: python cursor = conn.cursor() - cursor.execute( - """ + cursor.execute(""" SELECT column1, column2 FROM tableA - """ - ) + """) for column1, column2 in cursor.fetchall(): print(column1, column2) diff --git a/docs/data-processing/postgresql/sqlalchemy.rst b/docs/data-processing/postgresql/sqlalchemy.rst index 29264c8c..0d381042 100644 --- a/docs/data-processing/postgresql/sqlalchemy.rst +++ b/docs/data-processing/postgresql/sqlalchemy.rst @@ -44,7 +44,6 @@ Datenbankverbindung from sqlalchemy import create_engine - engine = create_engine("postgresql:///example", echo=True) Datenmodell @@ -56,7 +55,6 @@ Datenmodell from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship - Base = declarative_base() diff --git a/docs/data-processing/serialisation-formats/json/index.rst b/docs/data-processing/serialisation-formats/json/index.rst index d3e9ad3f..3efc63f2 100644 --- a/docs/data-processing/serialisation-formats/json/index.rst +++ b/docs/data-processing/serialisation-formats/json/index.rst @@ -245,6 +245,26 @@ JSON-Tools .. image:: https://raster.shields.io/github/license/stefankoegl/python-json-patch :alt: Lizenz +`jsonata-python `_ + `JSONata `_ ist eine + leichtgewichtige Abfrage- und Transformationssprache für JSON-Daten, + inspiriert von XPath. + + .. image:: https://raster.shields.io/github/stars/rayokota/jsonata-python + :alt: Stars + :target: https://github.com/rayokota/jsonata-python + + .. image:: https://raster.shields.io/github/contributors/rayokota/jsonata-python + :alt: Contributors + :target: https://github.com/rayokota/jsonata-python/graphs/contributors + + .. image:: https://raster.shields.io/github/commit-activity/y/rayokota/jsonata-python + :alt: Commit activity + :target: https://github.com/rayokota/jsonata-python/graphs/commit-activity + + .. image:: https://raster.shields.io/github/license/rayokota/jsonata-python + :alt: Lizenz + .. _`standard`: https://www.json.org/json-en.html .. _`JSON_Checker`: http://www.json.org/JSON_checker/ .. _`JSON Schema Proposal`: https://json-schema.org diff --git a/docs/data-processing/serialisation-formats/pyproject.toml b/docs/data-processing/serialisation-formats/pyproject.toml index 2d6e0964..f527be25 100644 --- a/docs/data-processing/serialisation-formats/pyproject.toml +++ b/docs/data-processing/serialisation-formats/pyproject.toml @@ -14,6 +14,5 @@ lines_between_types = 1 multi_line_output = 3 not_skip = "__init__.py" use_parentheses = true - known_first_party = "jupyter-tutorial" known_third_party = [ "mpi4py", "numpy", "requests" ] diff --git a/docs/data-processing/serialisation-formats/toml/index.rst b/docs/data-processing/serialisation-formats/toml/index.rst index 01d7d5a1..2f198f4c 100644 --- a/docs/data-processing/serialisation-formats/toml/index.rst +++ b/docs/data-processing/serialisation-formats/toml/index.rst @@ -66,7 +66,6 @@ Beispiel import toml - config = toml.load("pyproject.toml") .. seealso:: diff --git a/docs/data-processing/serialisation-formats/toml/pyproject.toml b/docs/data-processing/serialisation-formats/toml/pyproject.toml index 732e8efc..be663057 100644 --- a/docs/data-processing/serialisation-formats/toml/pyproject.toml +++ b/docs/data-processing/serialisation-formats/toml/pyproject.toml @@ -14,6 +14,5 @@ lines_between_types = 1 multi_line_output = 3 not_skip = "__init__.py" use_parentheses = true - known_first_party = [ "MY_FIRST_MODULE", "MY_SECOND_MODULE" ] known_third_party = [ "mpi4py", "numpy", "requests" ] diff --git a/docs/performance/index.rst b/docs/performance/index.rst index e55d3122..3b047856 100644 --- a/docs/performance/index.rst +++ b/docs/performance/index.rst @@ -23,6 +23,10 @@ zu kümmern. `_, in Computer Programming as an Art (1974) +.. seealso:: + * `Speed up your data science and scientific computing code + `_ + k-Means-Beispiel ---------------- @@ -51,7 +55,6 @@ Beispieldaten können wir uns erstellen mit: from sklearn.datasets import make_blobs - points, labels_true = make_blobs( n_samples=1000, centers=3, random_state=0, cluster_std=0.60 ) @@ -67,8 +70,16 @@ Performance-Messungen Wenn ihr erst einmal mit eurem Code gearbeitet habt, kann es nützlich sein, die Effizienz genauer zu untersuchen. Hierfür kann :abbr:`z. B. (zum Beispiel)` -`cProfile `_, -:doc:`ipython-profiler` oder :doc:`scalene` genutzt werden. +:doc:`cProfile `, :doc:`ipython-profiler`, :doc:`scalene`, :doc:`tprof` +oder :doc:`memray` genutzt werden. Bisher führe ich meist die folgenden Schritte +aus: + +#. Ich profilierte das gesamte Programm mit :doc:`cProfile ` oder + `py-spy `_, um langsame Funktionen zu + finden. +#. Anschließend optimiertee ich eine langsame Funktion. +#. Schließlich erstellte ich ein neues Profil und filterte das Ergebnis meiner + optimierten Version heraus um die Ergebnisse vergleichen zu können. .. versionadded:: Python3.15 Mit :pep:`799` wird ein spezielles Profiling-Modul zur Verfügung stehen, das @@ -76,9 +87,8 @@ Effizienz genauer zu untersuchen. Hierfür kann :abbr:`z. B. (zum Beispiel)` Namespace organisiert. Dieses Modul enthält: :mod:`profiling.tracing` - deterministische Funktionsaufrufverfolgung, die aus `cProfile - `_ - verschoben wurde. + deterministische Funktionsaufrufverfolgung, die aus :doc:`cProfile + ` verschoben wurde. :mod:`profiling.sampling` der neue statistische Sampling-Profiler :doc:`tachyon`. @@ -96,8 +106,11 @@ Effizienz genauer zu untersuchen. Hierfür kann :abbr:`z. B. (zum Beispiel)` :titlesonly: :maxdepth: 0 + tracing ipython-profiler.ipynb scalene.ipynb + tprof + memray tachyon Suche nach bestehenden Implementierungen @@ -114,7 +127,6 @@ k-Means-Algorithmus gibt es sogar gleich zwei Implementierungen: from sklearn.cluster import KMeans - KMeans(10).fit_predict(points) * `dask_ml.cluster.KMeans @@ -124,7 +136,6 @@ k-Means-Algorithmus gibt es sogar gleich zwei Implementierungen: from dask_ml.cluster import KMeans - KMeans(10).fit(points).predict(points) Gegen diese bestehenden Lösungen könnte bestenfalls sprechen, dass sie einen @@ -293,6 +304,11 @@ wissenschaftlichen Python- und NumPy-Code in schnellen Maschinencode Numba benötigt allerdings `LLVM `_ und einige Python-Konstrukte werden nicht unterstützt. +.. seealso:: + * `Speeding up NumPy with parallelism + by Itamar + Turner-Trauring`_ + Aufgabenplaner -------------- diff --git a/docs/performance/memray-flamegraph.png b/docs/performance/memray-flamegraph.png new file mode 100644 index 00000000..abe56453 Binary files /dev/null and b/docs/performance/memray-flamegraph.png differ diff --git a/docs/performance/memray.rst b/docs/performance/memray.rst new file mode 100644 index 00000000..7b1d44d6 --- /dev/null +++ b/docs/performance/memray.rst @@ -0,0 +1,97 @@ +.. SPDX-FileCopyrightText: 2026 Veit Schiele +.. +.. SPDX-License-Identifier: BSD-3-Clause + +Memray +====== + +Die Speichernutzung ist in Python-Projekten nur schwer zu kontrollieren, da die +Sprache nicht explizit deutlich macht, wo Speicher zugewiesen wird, Modulimporte +können den Verbrauch erheblich steigern, und es ist nur allzu leicht, eine +Datenstruktur zu erstellen, die versehentlich unbegrenzt wächst. +Data-Science-Projekte sind besonders anfällig für hohen Speicherverbrauch, da +sie meist viele große Abhängigkeiten wie :doc:`/workspace/numpy/index` +importieren, selbst wenn diese nur an wenigen Stellen verwendet werden. + +`Memray `_ hilft euch, die Speichernutzung +eures Programms zu verstehen, wobei nachverfolgt wird, wo während der +Programmausführung Speicher zugewiesen und freigegeben wird. Diese Daten können +dann auf verschiedene Weise dargestellt werden, :abbr:`u. a. (uter anderem)` +werden in `Flame Graphs `_ die +`Stacktraces `_ in einem Diagramm +zusammengefasst, wobei die Balkenbreite die Größe der Speicherzuweisung +darstellt. + +Mit ``memray run`` kann jeder Python-Befehl profiliert werden. Für die meisten +Projekte empfiehlt sich, zunächst mit ``check`` die Funktion zu profilieren, die +euer Projekt lädt. Damit wird der Mindestaufwand überprüft, der zum Starten +eurer Anwendung erforderlich ist, :abbr:`z.B. (zum Beispiel)`: + +.. code-block:: console + + $ uv run memray run src/items/__init__.py check + Writing profile results into src/items/memray-__init__.py.72633.bin + [memray] Successfully generated profile results. + + You can now generate reports from the stored allocation records. + Some example commands to generate reports: + + /Users/veit/items/.venv/bin/python3 -m memray flamegraph src/items/memray-__init__.py.72633.bin + +Der Befehl gibt die Meldung ``Successfully generated profile results.`` aus und +erstellt eine Datei :samp:`{PROCESS-ID}.bin`-Datei. Den *Flame Graph* können wir +dann erstellen mit: + +.. code-block:: console + + $ uv run python -m memray flamegraph src/items/memray-__init__.py.72633.bin + Wrote src/items/memray-flamegraph-__init__.py.72633.html + +.. tip:: + In vielen Konsolen könnt ihr die beiden Befehle zusammenfassen mit ``&&``: + + .. code-block:: console + + $ uv run memray run src/items/__init__.py check && uv run python -m memray flamegraph src/items/memray-__init__.py.72633.bin + +Das Ergebnis ist folgende HTML-Datei: + +.. figure:: memray-flamegraph.png + :alt: memray flamegraph report + + memray flamegraph report + +Der Kopfbereich der Seite enthält einige Steuerelemente, :abbr: `u.a. (unter anderem)` zu + +*Memory Graph* + Anzeige des Speicherplatzes eines Prozesses im Arbeitsspeicher (`Resident + set size `_) und des + `dynamischen Speichers + `_ (Heap Memory) über + die Zeit +*Stats* + Speicherstatistiken, in diesem Fall + + .. code-block:: text + + Command line: /Users/veit/items/.venv/bin/memray run src/items/api.py check + Start time: Sun Feb 08 2026 12:12:27 GMT+0100 (Central European Standard Time) + End time: Sun Feb 08 2026 12:12:27 GMT+0100 (Central European Standard Time) + Duration: 0:00:00.068000 + Total number of allocations: 11142 + Total number of frames seen: 0 + Peak memory usage: 4.6 MB + Python allocator: pymalloc + +Darunter befindet sich der *Flame-Graph* als Eiszapfendiagramm mit den +Speicherzuweisungen über die Zeit, wobei der letzte Aufruf ganz unten steht. Die +Grafik zeigt die zu einem bestimmten Zeitpunkt ausgeführte Codezeile an wobei +die Breite proportional zur zugewiesenen Speichermenge ist; bewegt ihr die Maus +darüber, seht ihr weitere Details wie Dateiname, Zeilennummer, zugewiesener +Speicher und Anzahl der Zuweisungen. + +.. tip:: + Mit :ref:`python-basics:pytest_memray` gibt es auch ein Plugin für + :doc:`python-basics:test/pytest/index`, mit dem ihr überprüfen könnt, ob + von euch festgelegte Obergrenzen für den Speicherverbrauch und Speicherlecks + eingehalten werden. diff --git a/docs/performance/tprof.rst b/docs/performance/tprof.rst new file mode 100644 index 00000000..b22d1b94 --- /dev/null +++ b/docs/performance/tprof.rst @@ -0,0 +1,71 @@ +.. SPDX-FileCopyrightText: 2026 Veit Schiele +.. +.. SPDX-License-Identifier: BSD-3-Clause + +``tprof`` +========= + +`tprof `_ misst ab Python 3.12 die Zeit, +die beim Ausführen eines Moduls in bestimmten Funktionen verbracht wird. Im +Gegensatz zu anderen Profilern verfolgt es nur die angegebenen Funktionen mit +:mod:`sys.monitoring`, wodurch man sich das Filtern sparen kann. + +``tprof`` unterstützt die Verwendung als Befehlszeilenprogramm und mit einer +Python-Schnittstelle: + +:samp:`uv run tprof -t {MODULE}:{FUNCTION} (-m {MODULE} | {PATH/TO/SCRIPT})` + Angenommen, ihr habt festgestellt, dass die Erstellung von + :class:`pathlib.Path`-Objekten im :mod:`main`-Modul euren Code verlangsamt. + So könnt ihr dies mit ``tprof`` messen: + + .. code-block:: console + + $ uv run tprof -t pathlib:Path.open -m main + 🎯 tprof results: + function calls total mean ± σ min … max + pathlib:Path.open() 1 93μs 93μs 93μs … 93μs + + Mit der ``-x``-Option könnt ihr auch zwei Funktionen miteinander + vergleichen: + + .. code-block:: console + + $ uv run tprof -x -t old -m main -t new -m main + 🎯 tprof results: + function calls total mean ± σ min … max delta + main:old() 1 41μs 41μs 41μs … 41μs - + main:new() 1 20μs 20μs 20μs … 20μs -50.67% + +``tprof(*targets, label: str | None = None, compare: bool = False)`` + verwendet diesen Code als :doc:`Kontextmanager + ` in eurem Code, um ein Profil in einem + bestimmten Block zu erstellen. Der Bericht wird jedes Mal ausgegeben, + wenn der Block durchlaufen wurde. + + ``*targets`` + sind aufrufbare Elemente zum Profiling oder Referenzen zu Elementen, die + mit :func:`pkgutil.resolve_name` aufgelöst werden. + ``label`` + ist eine optionale Zeichenfolge, die als Kopfzeile dem Bericht + hinzugefügt werden kann. + ``compare`` + auf ``True`` gesetzt, wird der Vergleichsmodus aktiviert. + + Beispiel: + + .. code-block:: Python + + from pathlib import Path + + from tprof import tprof + + with tprof(Path.open): + p = Path("docs", "save-data", "myfile.txt") + f = p.open() + + .. code-block:: console + + $ uv run python main.py + 🎯 tprof results: + function calls total mean ± σ min … max + pathlib:Path.open() 1 82μs 82μs 82μs … 82μs diff --git a/docs/performance/tracing.rst b/docs/performance/tracing.rst new file mode 100644 index 00000000..5a1187ba --- /dev/null +++ b/docs/performance/tracing.rst @@ -0,0 +1,48 @@ +.. SPDX-FileCopyrightText: 2026 Veit Schiele +.. +.. SPDX-License-Identifier: BSD-3-Clause + +cProfile/profiling.tracing +========================== + +Üblicherweise wird in der Kommandozeile mit `cProfile +`_ oder ab +Python 3.15 mit :mod:`profiling.tracing` ein Profil erstellt, das anschließend +dessen Profilstatistiken anzeigt. Dies kann jedoch schnell sehr mühsam sein, +insbesondere beim Lesen umfangreicher Profile oder beim Sortieren der Daten. +Flexibler ist, die Profildaten stattdessen in einer Datei zu speichern, die dann +mit dem :mod:`pstats`-Modul gelesen werden kann: + +#. :samp:`uv run python -m cProfile -o {PROFILE} ({SCRIPT} | {-m {MODULE})` + führt `cProfile + `_ zum + Profilerstellung eures Script oder eures Moduls aus und speichert die + Ergebnisse in einer Datei, die durch die Option ``-o`` angegeben wird. + +#. :samp:`uv run python -m (cProfile | profiling.tracing) -o profile ({SCRIPT} | + -m {MODULE}) <<< $'sort cumtime\nstats 100' | less` übergibt die folgenden + beiden Befehle an das :mod:`pstats`-Modul, wobei die ``$``-Syntax verwendet + wird. + + ``sort cumtime`` + sortiert die Ausgabe nach kumulativer Zeit, beginnend mit der größten. + + Um nach anderen Metriken zu sortieren, könnt ihr ``cumtime`` einfach + durch einen Wert aus :meth:`pstats.Stats.sort_stats` ersetzen. + + ``stats 100`` + zeigt die ersten 100 Zeilen des Profils an. + + Die Ausgabe wird an ``less`` übergeben, sodass ihr euch die Ergebnisse + anschauen könnt. Drückt :kbd:`q`, um den Vorgang zu beenden, wenn ihr fertig + seid. + +#. Vor und nach der Optimierung lassen sich einfach vergleichen, :abbr:`z. B. + (zum Beispiel)` mit: + + .. code-block:: console + + $ uv run python -m cProfile -o before.profile main.py + $ git switch -c main_optimisation + ... + $ uv run python -m cProfile -o after.profile main.py diff --git a/docs/productive/git/advanced/exceltocsv.py b/docs/productive/git/advanced/exceltocsv.py index a6235830..1972f47b 100644 --- a/docs/productive/git/advanced/exceltocsv.py +++ b/docs/productive/git/advanced/exceltocsv.py @@ -8,7 +8,6 @@ import pandas as pd - for sheet_name in pd.ExcelFile(sys.argv[1]).sheet_names: output = StringIO() print("Sheet: %s" % sheet_name) diff --git a/docs/productive/git/advanced/internals.rst b/docs/productive/git/advanced/internals.rst index 12765ec6..8cdd5cb9 100644 --- a/docs/productive/git/advanced/internals.rst +++ b/docs/productive/git/advanced/internals.rst @@ -2,21 +2,100 @@ .. .. SPDX-License-Identifier: BSD-3-Clause -Git's Datenbank-Interna ------------------------ +Git-Interna +=========== + +Bisher haben wir uns angeschaut, wie ihr mit Git die unterschiedlichen Zustände +eures Codes verwalten könnt. Hier wollen wir euch nun zeigen, welche +:ref:`Daten- ` und :ref:`Speichermodelle ` +Git zugrundeliegen. + +.. _git-data-model: + +Datenmodell +----------- + +Ihr werdet Git besser nutzen können, wenn ihr das Datenmodell verstanden habt. +Dabei verwaltet Git vier Arten von Daten: + +Objekte +~~~~~~~ + +.. include:: ../glossary.rst + :start-after: start-object + :end-before: end-object + +Commit +:::::: + +.. include:: ../glossary.rst + :start-after: start-commit + :end-before: end-commit + +Tree +:::: + +.. include:: ../glossary.rst + :start-after: start-tree + :end-before: end-tree + +Blob +:::: + +.. include:: ../glossary.rst + :start-after: start-blob + :end-before: end-blob + +Tag +::: + +.. include:: ../glossary.rst + :start-after: start-tag + :end-before: end-tag + +Referenzen +~~~~~~~~~~ + +.. include:: ../glossary.rst + :start-after: start-refs + :end-before: end-refs + +Index +~~~~~ + +.. include:: ../glossary.rst + :start-after: start-index + :end-before: end-index + +Reflog +~~~~~~ + +.. include:: ../glossary.rst + :start-after: start-reflog + :end-before: end-reflog + +.. _git-storage-model: + +Speichermodell +-------------- .. seealso:: - * `Commits are snapshots, not diffs - `_ - * Git’s database internals - - * `Part I: packed object store - `_ - * `Part II: commit history queries - `_ - * `Part III: file history queries - `_ - * `Part IV: distributed synchronization - `_ - * `Part V: scalability - `_ + Git’s database internals + + * `Part I: packed object store + `_ + * `Part II: commit history queries + `_ + * `Part III: file history queries + `_ + * `Part IV: distributed synchronization + `_ + * `Part V: scalability + `_ + +Packfiles +~~~~~~~~~ + +.. include:: ../glossary.rst + :start-after: start-packfile + :end-before: end-packfile diff --git a/docs/productive/git/branch.rst b/docs/productive/git/branch.rst index a3200970..2a1285ed 100644 --- a/docs/productive/git/branch.rst +++ b/docs/productive/git/branch.rst @@ -337,6 +337,8 @@ Zweige löschen ``-D`` statt ``-d`` erzwingt die Löschung. +.. _remote-branches: + Entfernte Zweige ---------------- diff --git a/docs/productive/git/glossary.rst b/docs/productive/git/glossary.rst index 19740a58..c0a732fc 100644 --- a/docs/productive/git/glossary.rst +++ b/docs/productive/git/glossary.rst @@ -7,27 +7,82 @@ Git-Glossar .. glossary:: + Blob + + .. _start-blob + + Ein Blob-Objekt enthält den Inhalt einer Datei. + + Bei jedem :term:`Commit` speichert Git den gesamten Inhalt jeder Datei, + den ihr geändert habt, als Blob. Wenn ihr beispielsweise einen Commit + habt, der zwei Dateien in einem Repository ändert, erstellt dieser + Commit zwei neue Blobs, sodass Commits selbst in sehr großen + Repositories relativ wenig Speicherplatz beanspruchen. + + .. _end-blob + Branch Zweig - Ein Zweig ist eine Entwicklungslinie. Der letzte Commit auf einem Zweig - wird als Spitze des Zweiges bezeichnet, der durch einen ``head`` - referenziert wird und der sich weiterbewegt, wenn weitere Entwicklungen - auf dem Zweig vorgenommen werden. Ein einzelnes Git-Repository kann eine - beliebige Anzahl von Zweigen haben, aber ihr :term:`Working Tree` ist - nur mit einem von ihnen verbunden – dem *aktuellen* oder - *ausgecheckten* Zweig – und :term:`HEAD` zeigt auf diesen Zweig. + Ein Zweig ist eine Entwicklungslinie. Der letzte :term:`Commit` auf + einem Zweig wird als Spitze des Zweiges bezeichnet, der durch einen + :term:`HEAD` referenziert wird und der sich weiterbewegt, wenn weitere + Entwicklungen auf dem Zweig vorgenommen werden. Ein einzelnes + Git-Repository kann eine beliebige Anzahl von Zweigen haben, aber ihr + :term:`Working Tree` ist nur mit einem von ihnen verbunden – dem + *aktuellen* oder *ausgecheckten* Zweig – und :term:`HEAD` zeigt auf + diesen Zweig. Cache Veraltet für :term:`Index`. Clone Klon - Lokale Version eines Repository einschließlich aller Commits und - Branches. + Lokale Version eines Repository einschließlich aller :term:`Commits + ` und :term:`Branches `. Commit - Ein Snapshot des gesamten Git-Repository, komprimiert in einem `SHA - `_. + + .. _start-commit + + Ein Commit ist ein Snapshot des gesamten Git-Repository, der durch einen + `SHA `_-Wert + eindeutig identifiziert werden kann und mindestens die folgenden + Angaben enthält: + + * Verzeichnisstruktur aller Dateien dieser Version des Repositorys und + Inhalt jeder Datei, gespeichert als :term:`Tree`-ID des obersten + Verzeichnisses des Commits. + * ID(s) des oder der übergeordneten Commits. Der erste Commit eines + Repository hat keine übergeordneten Commits, reguläre Commits haben + einen übergeordneten Commit, Merge-Commits haben zwei oder mehr + übergeordnete Commits. + * Autor*in und Zeitpunkt, zu dem der Commit erstellt wurde. + * Committer und Zeitpunkt, zu dem der Commit committet wurde. + * Commit-Nachricht + + Beispiel: + + .. code-block:: console + + $ git cat-file -p main + tree 47cc0283b10bd5e4e8a0d61537d13bba3bfad916 + parent 63825a43e213ef8a7904a8994976ac86284d32bd + author veit 1770370977 +0100 + committer veit 1770370977 +0100 + + :memo: Add links to Python speed + + Wie alle anderen Objekte können auch Commits nach ihrer Erstellung nicht + mehr geändert werden. Wenn ihr also einen Commit mit ``git commit + --amend`` ändern wollt, wird tatsächlich ein neuer Commit mit demselben + Parent erstellt. Und auch wenn ihr euch einen Commit mit ``git show`` + anzeigen lasst, so wird das Diff zu diesem Zeitpunkt erst berechnet. + + .. seealso:: + * `Commits are snapshots, not diffs + `_ + + .. _end-commit Fork Kopie eines Repository auf :term:`GitHub` oder :term:`GitLab`, das einem @@ -56,21 +111,62 @@ Git-Glossar ``HEAD`` Der ``HEAD``-Zeiger repräsentiert euer aktuelles Arbeitsverzeichnis und - kann mit ``git switch`` in verschiedene Zweige, Tags oder Commits - verschoben werden. + kann mit ``git switch`` in verschiedene :term:`Zweige `, + :doc:`Tags ` oder :term:`Commits ` verschoben werden. Index - Eine Sammlung von Dateien mit Statusinformationen, deren Inhalt als - Objekte gespeichert wird. Der Index ist eine gespeicherte Version eures - :term:`Working Tree`. + Staging Area + + .. _start-index + + Liste von Dateien und deren Inhalten, die als :term:`Blob` gespeichert + sind. Mit ``git add`` könnt ihr Dateien zum Index hinzufügen oder den + Inhalt einer Datei im Index aktualisieren. + + Im Gegensatz zu einem :term:`Tree` ist der Index eine flache Liste von + Dateien. Wenn ihr committet, konvertiert Git die Liste der Dateien im + Index in einen Verzeichnisbaum und verwendet diesen Baum für den neuen + Commit. Jeder Indexeintrag hat vier Felder: + + #. Einer der folgenden vier Dateitypen: + + * reguläre Datei + * ausführbare Datei + * symbolischer Link + * gitlink (für Submodule) + + #. Blob-ID der Datei oder Commit-ID des Submoduls + #. Staging-Nummer, normalerweise ``0``. Bei einen Merge-Konflikt kann es + jedoch auch mehrere Versionen desselben Dateinamens im Index geben. + #. Dateipfad + + .. _end-index Merge-Request Ort zum Vergleichen und Diskutieren der in einem Branch eingeführten Änderungen mit Bewertungen, Kommentaren, Tests :abbr:`etc. (et cetera)`; .. seealso:: - * :doc:`advanced/gitlab/merge-requests`. - * :ref:`Merge- oder Pull-Requests `. + * :doc:`advanced/gitlab/merge-requests` + * :ref:`Merge- oder Pull-Requests ` + + Objekt + + .. _start-object + + Alle :term:`Commits `, :term:`Trees `, :term:`Blobs + ` und :term:`Tags ` in einem Git-Repository werden als + Git-Objekte gespeichert, die sich nach ihrer Erstellung nie mehr ändern + und eine eindeutige ID haben, :abbr:`z. B. (zum Beispiel)` + ``3a5c279ea2f5d18498b61c229571d2449305a0``. :abbr:`D. h. (Das heißt)`, + dass ihr mit der ID eines Objekts jederzeit dessen Inhalt + wiederherstellen könnt, solange das Objekt nicht gelöscht wurde. + + .. seealso:: + * `Git Internals - Git Objects + `_ + + .. _end-object ``origin`` Das übliche Upstream-Repository. Die meisten Projekte haben mindestens @@ -79,10 +175,231 @@ Git-Glossar Zweige mit dem Namen :samp:`origin/{NAME_OF_UPSTREAM_BRANCH}` geholt, die ihr mit ``git branch -r`` sehen könnt. + Packfile + + .. _start-packfile + + Das Format, in dem Git Objekte auf der Festplatte speichert, wird als + *loose*-Objektformat bezeichnet. Um Platz zu sparen packt Git + gelegentlich jedoch mehrere dieser Objekte in eine einzige Binärdatei, + die als Packfile bezeichnet wird, um Platz zu sparen und effizienter + arbeiten zu können. Ihr könnt das Packen auch manuell mit ``git push`` + oder ``git gc`` ausführen. Dadurch werden in :file:`.git/objects/` die + meisten eurer Objekte gelöscht und ein neues Dateipaar erstellt: + + .. code-block:: console + + $ find .git/objects -type f + .git/objects/pack/pack-e9282cda3898f806f7bd108a3675c9e4d236915c.pack + .git/objects/pack/pack-e9282cda3898f806f7bd108a3675c9e4d236915c.idx + + :file:`*.pack` + enthält den Inhalt aller Objekte, die aus eurem Dateisystem entfernt + wurden. + :file:`.idx` + enthält die Offsets dieser Packdatei, sodass schnell zu einem + bestimmten Objekt gespringen werden kann. + + :abbr:`Ggf. (Gegebenenfalls)` verbleibende Objekte sind :term:`Blobs + `, auf die kein Commit verweist, :abbr:`sog. (sogenannte)` + *dangling references*, :abbr:`z. B. (zum Beispiel)` Dateien im + Arbeitsverzeichnis, die nie zu einem Commit hinzugefügt wurden. + + Wenn Git Objekte packt, sucht es nach Dateien mit ähnlichen Namen und + Größen und speichert nur die Deltas von einer Version der Datei zur + nächsten. Mit ``git verify-pack`` könnt ihr euch das Packfile ansehen + und erkennen, wie Git Speicherplatz sparte: + + .. code-block:: console + + $ git verify-pack -v .git/objects/pack/pack-e9282cda3898f806f7bd108a3675c9e4d236915c.pack + ... + dd1827ebf73b22d9f5828eec005eda4d79520f57 blob 147 140 389838 + 0a66f9a9ab72e3a99994803de8337f523b1b93d0 blob 31 43 389978 1 dd1827ebf73b22d9f5828eec005eda4d79520f57 + ... + .git/objects/pack/pack-e9282cda3898f806f7bd108a3675c9e4d236915c.pack: ok + + * :term:`Blob` ``0a66f9a`` verweist auf den nachfolgenden Blob + ``dd1827e``. + * Die dritte Spalte gibt die Größe des Objekts im Packfile an, sodass + ihr sehen könnt, dass ``dd1827e`` 147 Bytes einnimmt, während + ``0a66f9a`` nur 31 Bytes einnimmt. + * Die aktuelle Datei wird also unverändert gespeichert, während die + ursprüngliche Version als Delta gespeichert ist. Dies erlaubt einen + schnelleren Zugriff auf die jeweils neueste Version einer Datei. + * Die allgemeine Syntax von ``git verify-pack -v`` ist: + + :samp:`{OBJECT-ID} {TYPE} {SIZE} {SIZE-IN-PACKFILE} {OFFSET-IN-PACKFILE} [{DEPTH} {BASE-ID}]` + + .. seealso:: + * `Git Internals - Packfiles + `_ + * `git verify-pack `_ + + .. _end-packfile + + Referenz + + .. _start-refs + + Referenzen sind eine Möglichkeit, Commits einen Namen zu geben, der + einfacher, zu merken ist, :abbr:`z. B. (zum Beispiel)` für :doc:`Zweige + `, :doc:`Tags `, + :ref:`remote-branches` :abbr:`u.s.w. (und so weiter)` Git verwendet + häufig ``ref`` als Abkürzung für solche Referenzen. Die wichtigsten + Referenzen sind: + + :samp:`.git/refs/heads/{BRANCHNAME}` + Ein Branch bezieht sich auf die ID des neuesten Commits auf diesem + Branch. Um die Historie der :term:`Commits ` auf einem + :term:`Branch` abzurufen, beginnt Git bei der Commit-ID, auf die der + Branch verweist, und sieht sich dann die übergeordneten Commits an. + Referenzen können sich beziehen auf + + * eine Objekt-ID, in der Regel eine Commit-ID + * eine andere, *symbolische* Referenz + + :samp:`.git/refs/tags/{TAGNAME}` + Ein Tag bezieht sich auf eine Commit-ID, eine Tag-Objekt-ID oder + eine andere Objekt-ID. + + ``.git/HEAD`` + :term:`HEAD` ist der Ort, an dem Git euren aktuellen :term:`Branch` + speichert. ``HEAD`` kann entweder + + * eine symbolische Referenz auf euren aktuellen Branch sein, + :abbr:`z.B. (zum Beispiel)` ``ref: refs/heads/main``. + * eine direkte Referenz auf eine Commit-ID wenn es keinen aktuellen + Branch gibt, also in einem *detached HEAD state*. + + :samp:`.git/refs/remotes/{REMOTE}/{BRANCHNAME}` + Ein :ref:`Remote-Tracking-Branch ` bezieht sich auf + eine Commit-ID. Mit ``git fetch`` könnt ihr diese :abbr:`ggf. + (gegebenenfalls)` aktualisieren und wenn ``git status`` ``Your + branch is up to date with 'origin/main'`` ausgibt, bezieht es sich + darauf. + + ``refs/remotes/{REMOTE}/HEAD`` ist eine symbolische Referenz auf den + Standard-Zweig des Remote-Repositories. + + .. seealso:: + * `Git Internals - Git References + `_ + + .. _end-refs: + + Reflog + + .. _start-reflog + + Jedes Mal, wenn ein :term:`Branch`, ein :ref:`Remote-Tracking-Branch + ` oder :term:`HEAD` aktualisiert wird, aktualisiert Git + ein Protokoll namens *Reflog* für diese Referenz, :abbr:`z.B. (zum Beispiel)` in :file:`.git/logs/refs/heads/main`: + + .. code-block:: console + + 0000000000000000000000000000000000000000 492e16edcf9cdb3371492be59735e517a17cc86c veit 1739549686 +0100 clone: from github.com:cusyio/Python4DataScience-de.git + 492e16edcf9cdb3371492be59735e517a17cc86c c40bfa2a238e824b619f760494ce5ce0769851c3 veit 1739549907 +0100 commit: Update git docs + c40bfa2a238e824b619f760494ce5ce0769851c3 fa39661bb7fa93b420870845cb174529e8d62552 veit 1739549971 +0100 rebase (finish): refs/heads/main onto b7214df753ecbd01acd90d8f3dcd359e02441249 + ... + + Jeder Eintrag des Reflog enthält: + + * Commit-ID + * Commit-ID des nachfolgenden Commits + * Autor*in + * E-Mail-Adresse + * Zeitstempel, zu dem die Änderung vorgenommen wurde + * Protokollmeldung, :abbr:`z. B. (zum Beispiel)`: + + * :samp:`clone: from {REMOTE-URL}` + * :samp:`commit: {COMMIT-MESSAGE}` + * :samp:`rebase (finish): refs/heads/main onto {BASIC-COMMIT-ID}` + + Reflogs protokollieren Änderungen, die in eurem lokalen Repository + vorgenommen wurden. Sie werden jedoch nicht im :term:`Remote Repository` + geteilt. + + .. seealso:: + * :ref:`reflog` + + .. _end-reflog + Remote Repository Gemeinsames Repository, :abbr:`z.B. (zum Beispiel)` auf :term:`GitLab`, zum Austausch von Änderungen in einem Team. + Tag-Objekt + + .. _start-tag + + Tag-Objekte enthalten mindestens die folgenden Felder: + + * ID des Objekts, auf das es verweist + * Typ des Objekts, auf das es verweist + * Tag-Nachricht + * Tagger und Tag-Datum + + Beispiel: + + .. code-block:: console + + $ git cat-file -p 24.3.0 + object aa366cc9af3497544338482f82bdeb21f1dd3c21 + type commit + tag 24.3.0 + tagger Veit Schiele 1732086922 +0100 + + .. _end-tag + + Tree + + .. _start-tree + + Darstellung eines Verzeichnisses in Git und kann Dateien oder andere + Bäume (also Unterverzeichnisse) enthalten. Für jedes Element im Baum + listet er Folgendes auf: + + * Dateiname + * Dateityp: + + * normale Datei + * ausführbare Datei + * symbolischer Link + * Verzeichnis + * Gitlink (für Submodule) + + * Objekt-ID mit dem Inhalt der Datei, des Verzeichnisses oder des + gitlinks + + Beispiel: + + .. code-block:: console + + $ git cat-file -p main^{tree} + 040000 tree 2f59a223f7dc767f4776e77762d208fa72bfd343 .dvc + 040000 tree 75833fd33271db55b6f1c96915f60f98a60b51a0 .github + 100644 blob 36d2dc5a5228cbf65b8cfe913565c9be49db1a3d .gitignore + ... + $ git cat-file -p 2f59a223f7dc767f4776e77762d208fa72bfd343 + 100644 blob 669784da1fe0818e9abb795f73b7faf393832f2e .gitignore + 100644 blob 0a66f9a9ab72e3a99994803de8337f523b1b93d0 config + $ git cat-file -p 36d2dc5a5228cbf65b8cfe913565c9be49db1a3d + # SPDX-FileCopyrightText: 2019 Veit Schiele + # + # SPDX-License-Identifier: BSD-3-Clause + ... + + .. hint:: + Die erste Spalte eines Baum-Eintrags orientiert sich grob an den + `Unix-Dateirechten + `_, tatsächlich + können mit Git jedoch keine Unix-Dateirechte verwaltet werden. Hierzu + sind Erweiterungen, wie :abbr:`z.B. (zum Beispiel)` + :doc:`/productive/git/advanced/etckeeper` erforderlich. + + .. _end-tree + Trunk-Based Development TBD Git-Workflow mit kurzlebigen Themenzweigen, die schnell zum einem diff --git a/docs/productive/licensing.rst b/docs/productive/licensing.rst index 13c7cc4e..cf64040e 100644 --- a/docs/productive/licensing.rst +++ b/docs/productive/licensing.rst @@ -262,6 +262,9 @@ fehlen: * Alek Tarkowski, Open Future in Zusammenarbeit mit der Open Source Initiative: `Data Governance in Open Source AI `_ + * Andreas Liesenfeld, Mark Dingemanse: `Rethinking open source generative AI: + open-washing and the EU AI Act + `_ Datenbanken ~~~~~~~~~~~ diff --git a/docs/productive/security.rst b/docs/productive/security.rst index 0ee1459a..ec176418 100644 --- a/docs/productive/security.rst +++ b/docs/productive/security.rst @@ -97,9 +97,9 @@ Gibt es ein Sicherheitskonzept für das Projekt? Risiko: Mittel -Idealerweise sollte mit dem Projekt eine Datei :file:`SECURITY.md` :abbr:`o.ä. -(oder ähnliches)` veröffentlicht worden sein. Diese Datei sollte Informationen -enthalten, +Idealerweise sollte mit dem Projekt eine :ref:`python-basics:security`-Datei +:abbr:`o.ä. (oder ähnliches)` veröffentlicht worden sein. Diese Datei sollte +Informationen enthalten, * wie eine Sicherheitslücke gemeldet werden kann ohne dass sie öffentlich sichtbar wird, diff --git a/fastapi/main.py b/fastapi/main.py index b2e7e624..7aa41f3d 100644 --- a/fastapi/main.py +++ b/fastapi/main.py @@ -8,7 +8,6 @@ from fastapi import FastAPI - app = FastAPI() diff --git a/pyproject.toml b/pyproject.toml index 7f659f75..c97e8e66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,8 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", ] -dependencies = [ ] - +dependencies = [] urls."Bug Tracker" = "https://github.com/cusyio/Python4DataScience/issues" urls."Homepage" = "https://github.com/cusyio/Python4DataScience/" @@ -52,7 +51,7 @@ docs = [ ] [tool.setuptools] -packages = [ ] +packages = [] [tool.black] line-length = 79 @@ -66,7 +65,6 @@ lines_between_types = 1 multi_line_output = 3 not_skip = "__init__.py" use_parentheses = true - known_first_party = "Python4DataScience" known_third_party = [ "Cython", @@ -84,5 +82,8 @@ known_third_party = [ ] [tool.codespell] -skip = "*.csv, *.html, *.pdf, *.rst, *.ipynb, ./docs/_build/*, */books.json, */books.txt, ./styles/*, ./Python4DataScience.egg-info/*" +skip = """\ + *.csv, *.html, *.pdf, *.rst, *.ipynb, ./docs/_build/*, */books.json, */books.txt, ./styles/*, \ + ./Python4DataScience.egg-info/*\ + """ ignore-words-list = "comit"