@@ -442,4 +442,146 @@ \subsubsection{ Что проверить руками}
442442pip list
443443python -c "import requests; print(requests.__file__)"
444444deactivate
445+ \end {lstlisting }
446+
447+ \subsection { pyproject.toml vs requirements.txt vs setup.py }
448+ \subsubsection { setup.py (legacy) }
449+
450+ \textbf {Исторический способ. Исполняемый Python-файл. }
451+ \ begin{lstlisting}
452+ from setuptools import setup, find_packages
453+
454+ setup(
455+ name="myproject",
456+ version="0.1.0",
457+ packages=find_packages(),
458+ install_requires=["requests>=2.31"],
459+ )
460+ \end {lstlisting }
461+
462+ \textbf {Проблемы: }
463+ \begin {itemize }
464+ \item Исполняемый код при установке — небезопасно.
465+ \item Нельзя прочитать метаданные без запуска.
466+ \item Дублирование с setup.cfg.
467+ \end {itemize }
468+
469+ \textbf {Статус: } deprecated, но ещё встречается в legacy-проектах.
470+
471+ \subsubsection {requirements.txt }
472+
473+ \textbf {Простой список зависимостей. }
474+ \ begin{lstlisting}
475+ requests==2.31.0
476+ httpx>=0.27,<1
477+ pydantic~=2.6
478+ \end {lstlisting }
479+
480+ \textbf {Плюсы: }
481+ \begin {itemize }
482+ \item Просто.
483+ \item Понятно.
484+ \item Работает везде.
485+ \end {itemize }
486+
487+ \textbf {Минусы: }
488+ \begin {itemize }
489+ \item Нет метаданных проекта (имя, версия, entry points).
490+ \item Нет разделения на prod/dev (обычно делают requirements-dev.txt).
491+ \item Нет lock-файла (нужен pip-tools или pip freeze).
492+ \end {itemize }
493+
494+ \textbf {Когда использовать: }
495+ \begin {itemize }
496+ \item Простые проекты.
497+ \item Legacy.
498+ \item Docker-образы (иногда).
499+ \end {itemize}
500+
501+ \subsubsection { pyproject.toml (современный стандарт) }
502+ \textbf {PEP 518 / PEP 621. }
503+
504+ \textbf {Единый файл конфигурации проекта. }
505+ \ begin{lstlisting}
506+ [build-system]
507+ requires = ["setuptools>=68", "wheel"]
508+ build-backend = "setuptools.build_meta"
509+
510+ [project]
511+ name = "myproject"
512+ version = "0.1.0"
513+ description = "My project"
514+ readme = "README.md"
515+ requires-python = ">=3.11"
516+ license = {text = "MIT"}
517+ authors = [{name = "Ivan", email = "ivan@example.com"}]
518+ dependencies = [
519+ "requests>=2.31",
520+ "pydantic>=2.6",
521+ ]
522+
523+ [project.optional-dependencies]
524+ dev = [
525+ "pytest>=8.0",
526+ "ruff>=0.4",
527+ "mypy>=1.10",
528+ ]
529+
530+ [project.scripts]
531+ myproject = "myproject.cli:main"
532+
533+ [tool.ruff]
534+ line-length = 100
535+
536+ [tool.mypy]
537+ strict = true
538+
539+ [tool.pytest.ini_options]
540+ testpaths = ["tests"]
541+ \end {lstlisting }
542+
543+ \textbf {Плюсы: }
544+ \begin {itemize }
545+ \item Единое место для метаданных и настроек инструментов.
546+ \item Декларативный.
547+ \item Совместим с pip, uv, poetry, hatch, pdm.
548+ \item Lock-файлы (uv.lock, poetry.lock) дополняют.
549+ \end {itemize }
550+ \textbf {Минусы: }
551+ \begin {itemize }
552+ \item Сложнее для новичка.
553+ \item Разные бэкенды (setuptools, hatchling, flit, poetry-core).
554+ \end {itemize }
555+ \begin {warningbox2 }
556+ \textbf {Когда использовать: } всегда в новых проектах.
557+ \end {warningbox2 }
558+ \subsubsection {Сравнение }
559+ \begin {table }[h]
560+ \centering
561+ \begin {tabular }{|l|l|l|}
562+ \hline
563+ \textbf {Файл } & \textbf {Назначение } & textbf{Статус}\\
564+ \hline
565+ setup.py & сборка/установка & legacy\\
566+ requirements.txt & список зависимостей & актуален для простых случаев\\
567+ pyproject.toml & всё: метаданные, зависимости, настройки & современный стандарт\\
568+ uv.lock / poetry.lock & точные версии всех зависимостей & обязателен для воспроизводимости\\
569+ \hline
570+ \end {tabular }
571+ \caption {Сравнение}
572+ \label {tab:differents }
573+ \end {table }
574+ \subsubsection {Что проверить руками }
575+ \ begin{lstlisting}
576+ mkdir /tmp/pyproj && cd /tmp/pyproj
577+ cat > pyproject.toml <<'EOF'
578+ [project]
579+ name = "demo"
580+ version = "0.1.0"
581+ requires-python = ">=3.11"
582+ dependencies = ["requests"]
583+ EOF
584+
585+ python3 -m pip install -e .
586+ python3 -c "import demo" # если есть пакет
445587\end {lstlisting }
0 commit comments