Skip to content

Commit

Permalink
Move python deps in setup.py + add install-pydeps-test|dev make t…
Browse files Browse the repository at this point in the history
…argets (#651)

Add ``make install-pydeps-test`` and ``make install-pydeps-dev`` targets. They can be used to install dependencies meant for running tests and for local development. They can also be installed via ``pip install .[test]`` and ``pip install .[dev]``.

Also move python deps from Makefile into setup.py.
  • Loading branch information
giampaolo authored Oct 20, 2024
1 parent d90cc93 commit 67b1b9e
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Install pydeps ${{ matrix.os }}
if: matrix.os != 'windows-latest'
run: |
make setup-dev-env
make install-pydeps-test
- name: Tests
run: |
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ include scripts/ftpbench
include scripts/internal/check_broken_links.py
include scripts/internal/generate_manifest.py
include scripts/internal/git_pre_commit.py
include scripts/internal/install_pip.py
include scripts/internal/print_announce.py
include scripts/internal/purge_installation.py
include scripts/internal/winmake.py
Expand Down
73 changes: 20 additions & 53 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,24 @@
# To run a specific test:
# $ make test ARGS="-v -s pyftpdlib/test/test_functional.py::TestIPv6MixedEnvironment::test_port_v4"

# Configurable
PYTHON = python3
ARGS =

# mandatory deps for running tests
PYDEPS = \
psutil \
pyopenssl \
pytest \
pytest-xdist \
setuptools
# dev deps
ifndef GITHUB_ACTIONS
PYDEPS += \
black \
check-manifest \
coverage \
pylint \
pytest-cov \
pytest-xdist \
rstcheck \
ruff \
teyit \
toml-sort \
twine
endif

# In not in a virtualenv, add --user options for install commands.
INSTALL_OPTS = `$(PYTHON) -c "import sys; print('' if hasattr(sys, 'real_prefix') else '--user')"`
SETUP_INSTALL_ARGS = `$(PYTHON) -c \
"import sys; print('' if hasattr(sys, 'real_prefix') or hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix else '--user')"`
TEST_PREFIX = PYTHONWARNINGS=always
PYTEST_ARGS = -v -s --tb=short
NUM_WORKERS = `$(PYTHON) -c "import os; print(os.cpu_count() or 1)"`
PIP_INSTALL_ARGS = --trusted-host files.pythonhosted.org --trusted-host pypi.org --upgrade

# if make is invoked with no arg, default to `make help`
.DEFAULT_GOAL := help

# install git hook
_ := $(shell mkdir -p .git/hooks/ && ln -sf ../../scripts/internal/git_pre_commit.py .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit)

# ===================================================================
# Install
# ===================================================================
Expand Down Expand Up @@ -75,37 +58,25 @@ clean: ## Remove all build files.
install: ## Install this package.
# make sure setuptools is installed (needed for 'develop' / edit mode)
$(PYTHON) -c "import setuptools"
$(PYTHON) setup.py develop $(INSTALL_OPTS)
$(PYTHON) setup.py develop $(SETUP_INSTALL_ARGS)

uninstall: ## Uninstall this package.
cd ..; $(PYTHON) -m pip uninstall -y -v pyftpdlib || true
$(PYTHON) scripts/internal/purge_installation.py

install-pip: ## Install pip (no-op if already installed).
@$(PYTHON) -c \
"import sys, ssl, os, pkgutil, tempfile, atexit; \
from urllib.request import urlopen; \
sys.exit(0) if pkgutil.find_loader('pip') else None; \
exec(pyexc); \
ctx = ssl._create_unverified_context() if hasattr(ssl, '_create_unverified_context') else None; \
url = 'https://bootstrap.pypa.io/get-pip.py'; \
kw = dict(context=ctx) if ctx else {}; \
req = urlopen(url, **kw); \
data = req.read(); \
f = tempfile.NamedTemporaryFile(suffix='.py'); \
atexit.register(f.close); \
f.write(data); \
f.flush(); \
print('downloaded %s' % f.name); \
code = os.system('%s %s --user --upgrade' % (sys.executable, f.name)); \
f.close(); \
sys.exit(code);"

setup-dev-env: ## Install GIT hooks, pip, test deps (also upgrades them).
$(PYTHON) scripts/internal/install_pip.py

install-pydeps-test: ## Install python deps necessary to run unit tests.
${MAKE} install-pip
$(PYTHON) -m pip install $(PIP_INSTALL_ARGS) pip # upgrade pip to latest version
$(PYTHON) -m pip install $(PIP_INSTALL_ARGS) `$(PYTHON) -c "import setup; print(' '.join(setup.TEST_DEPS))"`

install-pydeps-dev: ## Install python deps meant for local development.
${MAKE} install-git-hooks
${MAKE} install-pip
$(PYTHON) -m pip install $(INSTALL_OPTS) --upgrade pip setuptools
$(PYTHON) -m pip install $(INSTALL_OPTS) --upgrade $(PYDEPS)
$(PYTHON) -m pip install $(PIP_INSTALL_ARGS) pip # upgrade pip to latest version
$(PYTHON) -m pip install $(PIP_INSTALL_ARGS) `$(PYTHON) -c "import setup; print(' '.join(setup.TEST_DEPS + setup.DEV_DEPS))"`

# ===================================================================
# Tests
Expand Down Expand Up @@ -157,7 +128,7 @@ black: ## Python files linting (via black)
@git ls-files '*.py' | xargs $(PYTHON) -m black --check --safe

ruff: ## Run ruff linter.
@git ls-files '*.py' | xargs $(PYTHON) -m ruff check --no-cache --output-format=concise
@git ls-files '*.py' | xargs $(PYTHON) -m ruff check --output-format=concise

_pylint: ## Python pylint (not mandatory, just run it from time to time)
@git ls-files '*.py' | xargs $(PYTHON) -m pylint --rcfile=pyproject.toml --jobs=${NUM_WORKERS}
Expand All @@ -182,19 +153,15 @@ fix-black:
git ls-files '*.py' | xargs $(PYTHON) -m black

fix-ruff:
@git ls-files '*.py' | xargs $(PYTHON) -m ruff check --no-cache --fix $(ARGS)
@git ls-files '*.py' | xargs $(PYTHON) -m ruff check --fix --output-format=concise $(ARGS)

fix-toml: ## Fix pyproject.toml
@git ls-files '*.toml' | xargs toml-sort

fix-unittests: ## Fix unittest idioms.
@git ls-files '*test_*.py' | xargs $(PYTHON) -m teyit --show-stats

fix-all: ## Run all code fixers.
${MAKE} fix-black
${MAKE} fix-ruff
${MAKE} fix-toml
${MAKE} fix-unittests

# ===================================================================
# Distribution
Expand Down
58 changes: 58 additions & 0 deletions scripts/internal/install_pip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env python3

# Copyright (C) 2007 Giampaolo Rodola' <g.rodola@gmail.com>.
# Use of this source code is governed by MIT license that can be
# found in the LICENSE file.

import sys


try:
import pip # noqa: F401
except ImportError:
pass
else:
print("pip already installed")
sys.exit(0)

import os
import ssl
import tempfile


PY3 = sys.version_info[0] >= 3
if PY3:
from urllib.request import urlopen

URL = "https://bootstrap.pypa.io/get-pip.py"

else:
from urllib2 import urlopen

URL = "https://bootstrap.pypa.io/pip/2.7/get-pip.py"


def main():
ssl_context = (
ssl._create_unverified_context()
if hasattr(ssl, "_create_unverified_context")
else None
)
with tempfile.NamedTemporaryFile(suffix=".py") as f:
print("downloading %s into %s" % (URL, f.name))
kwargs = dict(context=ssl_context) if ssl_context else {}
req = urlopen(URL, **kwargs)
data = req.read()
req.close()

f.write(data)
f.flush()
print("download finished, installing pip")

code = os.system("%s %s --user --upgrade" % (sys.executable, f.name))

sys.exit(code)


if __name__ == "__main__":
main()
Loading

0 comments on commit 67b1b9e

Please sign in to comment.