diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..b26d4442ea1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# Top-most EditorConfig file +root = true + +[*] +# Unix-style newlines with a newline ending every file +end_of_line = lf +insert_final_newline = true +charset = utf-8 + +# Four-space indentation +indent_size = 4 +indent_style = space + +trim_trailing_whitespace = false + +[*.yml] +# Two-space indentation +indent_size = 2 +indent_style = space diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000000..ec083d68034 --- /dev/null +++ b/.flake8 @@ -0,0 +1,5 @@ +[flake8] +ignore = W293,E301,E271,E265,W291,E722,E302,C901,E225,E128,E122,E226,E231 +max-line-length = 160 +exclude = tests/* +max-complexity = 10 diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000000..d5be139ad02 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,21 @@ +# When making commits that are strictly formatting/style changes, add the +# commit hash here, so git blame can ignore the change. See docs for more +# details: +# https://git-scm.com/docs/git-config#Documentation/git-config.txt-blameignoreRevsFile +# +# +# You should be able to execute either +# ./tools/configure-git-blame-ignore-revs.bat or +# ./tools/configure-git-blame-ignore-revs.sh +# +# Example entries: +# +# # initial black-format +# # rename something internal +6e748726282d1acb9a4f9f264ee679c474c4b8f5 # Apply pygrade --36plus on IPython/core/tests/test_inputtransformer.py. +0233e65d8086d0ec34acb8685b7a5411633f0899 # apply pyupgrade to IPython/extensions/tests/test_autoreload.py +a6a7e4dd7e51b892147895006d3a2a6c34b79ae6 # apply black to IPython/extensions/tests/test_autoreload.py +c5ca5a8f25432dfd6b9eccbbe446a8348bf37cfa # apply pyupgrade to IPython/extensions/autoreload.py +50624b84ccdece781750f5eb635a9efbf2fe30d6 # apply black to IPython/extensions/autoreload.py +b7aaa47412b96379198705955004930c57f9d74a # apply pyupgrade to IPython/extensions/autoreload.py +9c7476a88af3e567426b412f1b3c778401d8f6aa # apply black to IPython/extensions/autoreload.py diff --git a/.gitattributes b/.gitattributes index 8b5b26e3e96..56783b63081 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,5 @@ IPython/.git_commit_info.ini export-subst * text=auto +*.py diff=python +*.js diff=javascript +*.html diff=html diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000000..2a6d4877c68 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,16 @@ +--- +name: Bug report / Question / Feature +about: Anything related to IPython itsel +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..d1fed9f3d5f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + groups: + actions: + patterns: + - "*" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000000..a9ca3457f98 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,45 @@ +name: Build docs + +on: [push, pull_request] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: 3.x + cache: pip + cache-dependency-path: | + docs/requirements.txt + pyproject.toml + - name: Install uv + uses: astral-sh/setup-uv@v7 + - name: Install Graphviz + run: | + sudo apt-get update + sudo apt-get install graphviz + - name: Install Python dependencies + run: | + uv pip install --system setuptools coverage rstvalidator + uv pip install --system -r docs/requirements.txt + - name: Build docs + run: | + python -m rstvalidator long_description.rst + python tools/fixup_whats_new_pr.py + make -C docs/ html SPHINXOPTS="-W" \ + PYTHON="coverage run -a" \ + SPHINXBUILD="coverage run -a -m sphinx.cmd.build" + - name: Generate coverage xml + run: | + coverage combine `find . -name .coverage\*` && coverage xml + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + with: + name: Docs diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml new file mode 100644 index 00000000000..a8a03502917 --- /dev/null +++ b/.github/workflows/downstream.yml @@ -0,0 +1,99 @@ +name: Run Downstream tests + +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - '**.rst' + pull_request: + paths-ignore: + - 'docs/**' + - '**.md' + - '**.rst' + # Run weekly on Monday at 1:23 UTC + schedule: + - cron: '23 1 * * 1' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: ${{ matrix.os }} + # Disable scheduled CI runs on forks + if: github.event_name != 'schedule' || github.repository_owner == 'ipython' + strategy: + matrix: + os: [ubuntu-latest] + python-version: ["3.13"] + include: + - os: macos-14 + python-version: "3.13" + + steps: + - uses: actions/checkout@v6 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + - name: Update Python installer + run: | + python -m pip install --upgrade pip setuptools wheel + - name: Install ipykernel + run: | + cd .. + git clone https://github.com/ipython/ipykernel + cd ipykernel + pip install -e .[test] + cd .. + - name: Install and update Python dependencies + run: | + python -m pip install --upgrade -e file://$PWD#egg=ipython[test] + # we must install IPython after ipykernel to get the right versions. + python -m pip install --upgrade --upgrade-strategy eager flaky ipyparallel + - name: pytest ipykernel + env: + COLUMNS: 120 + run: | + cd ../ipykernel + pytest + - name: Install sagemath-repl + run: | + # Sept 2024, sage has been failing for a while, + # Skipping. + # cd .. + # git clone --depth 1 https://github.com/sagemath/sage + # cd sage + # # We cloned it for the tests, but for simplicity we install the + # # wheels from PyPI. + # # (Avoid 10.3b6 because of https://github.com/sagemath/sage/pull/37178) + # pip install --pre sagemath-repl sagemath-environment + # # Install optionals that make more tests pass + # pip install pillow + # pip install --pre sagemath-categories + # cd .. + - name: Test sagemath-repl + run: | + # cd ../sage/ + # # From https://github.com/sagemath/sage/blob/develop/pkgs/sagemath-repl/tox.ini + # sage-runtests -p --environment=sage.all__sagemath_repl --baseline-stats-path=pkgs/sagemath-repl/known-test-failures.json --initial --optional=sage src/sage/repl src/sage/doctest src/sage/misc/sage_input.py src/sage/misc/sage_eval.py + - name: Install pyflyby + run: | + cd .. + git clone https://github.com/deshaw/pyflyby + cd pyflyby + pip install meson-python meson ninja pybind11>=2.10.4 setuptools-scm + pip install setuptools wheel # needed for epydoc + pip install --no-build-isolation -ve .[test] + pip install 'pytest<=8' + cd .. + - name: Test pyflyby (IPython integration only) + run: | + cd ../pyflyby + pytest tests/test_interactive.py diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 00000000000..ff7bc347974 --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,40 @@ +name: Run MyPy + +on: + push: + branches: [ main, 7.x] + pull_request: + branches: [ main, 7.x] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.14"] + + steps: + - uses: actions/checkout@v6 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + cache: pip + - name: Install uv + uses: astral-sh/setup-uv@v7 + - name: Install dependencies + run: | + uv pip install --system mypy pyflakes flake8 types-decorator '.[all]' + - name: Lint with mypy + run: | + set -e + mypy IPython + - name: Lint with pyflakes + run: | + set -e + flake8 IPython/core/magics/script.py + flake8 IPython/core/magics/packaging.py diff --git a/.github/workflows/nightly-wheel-build.yml b/.github/workflows/nightly-wheel-build.yml new file mode 100644 index 00000000000..28e41ca2f9b --- /dev/null +++ b/.github/workflows/nightly-wheel-build.yml @@ -0,0 +1,36 @@ +name: Nightly Wheel builder +on: + workflow_dispatch: + schedule: + # this cron is ran every Sunday at midnight UTC + - cron: '0 0 * * 0' + +jobs: + upload_anaconda: + name: Upload to Anaconda + runs-on: ubuntu-latest + # The artifacts cannot be uploaded on PRs, also disable scheduled CI runs on forks + if: github.event_name != 'pull_request' && (github.event_name != 'schedule' || github.repository_owner == 'ipython') + + steps: + - uses: actions/checkout@v6 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.14" + cache: pip + cache-dependency-path: | + pyproject.toml + - name: Install uv + uses: astral-sh/setup-uv@v7 + - name: Try building with Python build + if: runner.os != 'Windows' # setup.py does not support sdist on Windows + run: | + uv pip install --system build + python -m build + + - name: Upload wheel + uses: scientific-python/upload-nightly-action@main + with: + artifacts_path: dist + anaconda_nightly_upload_token: ${{secrets.UPLOAD_TOKEN}} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000000..b8cd0ceafc5 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,79 @@ +name: Build and Publish IPython + +on: + push: + tags: + - '*' + workflow_dispatch: + +jobs: + build-and-publish: + name: Build and Publish to PyPI + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/ipython + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + + steps: + - uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.14" + cache: pip + cache-dependency-path: | + pyproject.toml + + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + python -m pip install build + + - name: Build distribution + run: python -m build + + - name: Verify built version matches tag + if: startsWith(github.ref, 'refs/tags/') + run: | + TAG_NAME=${GITHUB_REF#refs/tags/} + echo "Tag name: $TAG_NAME" + + # Check dist folder filenames + echo "Built distribution files:" + ls -la dist/ + + # Install the built wheel + python -m pip install dist/*.whl + + # Get IPython version + IPYTHON_VERSION=$(ipython --version) + echo "Installed IPython version: $IPYTHON_VERSION" + + # Compare versions (allow only X.Y.Z) + if [[ "$TAG_NAME" != "$IPYTHON_VERSION" ]]; then + echo "Error: Tag ($TAG_NAME) does not match built IPython version ($IPYTHON_VERSION)" + exit 1 + fi + + echo "Version check passed! Tag matches built version." + + - name: Publish distribution to PyPI + if: startsWith(github.ref, 'refs/tags/') + uses: pypa/gh-action-pypi-publish@v1.13.0 + + - name: Send Zulip notification + if: startsWith(github.ref, 'refs/tags/') + uses: zulip/github-actions-zulip/send-message@v1 + with: + api-key: ${{ secrets.ZULIP_API_KEY }} + email: ${{ secrets.ZULIP_EMAIL }} + organization-url: ${{ vars.ZULIP_ORGANIZATION_URL }} + to: 'Releases' + type: 'stream' + topic: 'IPython' + content: | + IPython ${{ github.ref_name }} was just released on PyPI! 🎉 + https://pypi.org/project/ipython/${{ github.ref_name }}/ diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml new file mode 100644 index 00000000000..9be2d870fb0 --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1,43 @@ +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +name: Python package + +permissions: + contents: read + +on: + push: + branches: [ main, 7.x, 8.x ] + pull_request: + branches: [ main, 7.x, 8.x ] + +jobs: + formatting: + + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: 3.x + cache: pip + - name: Install uv + uses: astral-sh/setup-uv@v7 + - name: Install dependencies + run: | + # when changing the versions please update CONTRIBUTING.md too + uv pip install --system darker==2.1.1 black==24.10.0 + - name: Lint with darker + run: | + # disabling darker for now, I can't get it to format the same locally and on CI. + # darker -r 60625f241f298b5039cb2debc365db38aa7bb522 --check --diff . || ( + # echo "Changes need auto-formatting. Run:" + # echo " darker -r 60625f241f298b5039cb2debc365db38aa7bb522 ." + # echo "then commit and push changes to fix." + # exit 1 + # ) diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml new file mode 100644 index 00000000000..efbc9dd7beb --- /dev/null +++ b/.github/workflows/ruff.yml @@ -0,0 +1,35 @@ +name: Run Ruff + +on: + push: + branches: [ main, 7.x, 8.x] + pull_request: + branches: [ main, 7.x, 8.x] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.x"] + + steps: + - uses: actions/checkout@v6 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + cache: pip + - name: Install uv + uses: astral-sh/setup-uv@v7 + - name: Install dependencies + run: | + uv pip install --system ruff + - name: Lint with ruff + run: | + set -e + ruff check . diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000000..6a3ef2f2e7a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,143 @@ +name: Run tests + +on: + push: + branches: + - main + - '*.x' + pull_request: + # Run weekly on Monday at 1:23 UTC + schedule: + - cron: '23 1 * * 1' + workflow_dispatch: + + +jobs: + test: + runs-on: ${{ matrix.os }} + timeout-minutes: 15 + # Disable scheduled CI runs on forks + if: github.event_name != 'schedule' || github.repository_owner == 'ipython' + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + python-version: ["3.12", "3.13", "3.14"] + deps: [test_extra] + # Test all on ubuntu, test ends on macos + include: + - os: macos-latest + python-version: "3.12" + deps: test_extra + # free threaded, not with all dependencies + - os: ubuntu-latest + python-version: "3.14t" + deps: test + # Tests latest development Python version + - os: ubuntu-latest + python-version: "3.15-dev" + deps: test + - os: ubuntu-latest + python-version: "3.12" + deps: test_extra + want-latest-entry-point-code: true + + steps: + - uses: actions/checkout@v6 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: | + pyproject.toml + - name: Install uv + uses: astral-sh/setup-uv@v7 + - name: Install latex + if: runner.os == 'Linux' && matrix.deps == 'test_extra' + run: echo "disable latex for now, issues in mirros" #sudo apt-get -yq -o Acquire::Retries=3 --no-install-suggests --no-install-recommends install texlive dvipng + - name: Install and update Python dependencies (binary only) + if: ${{ ! contains( matrix.python-version, 'dev' ) }} + run: | + uv pip install --system setuptools wheel build + uv pip install --system -e .[${{ matrix.deps }}] + uv pip install --system check-manifest pytest-cov pytest + - name: Install and update Python dependencies (dev?) + if: ${{ contains( matrix.python-version, 'dev' ) }} + run: | + uv pip install --system --prerelease=allow setuptools wheel build + uv pip install --system --prerelease=allow --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple -e .[${{ matrix.deps }}] + uv pip install --system --prerelease=allow --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple check-manifest pytest-cov + - name: Try building with Python build + if: runner.os != 'Windows' # setup.py does not support sdist on Windows + run: | + python -m build + shasum -a 256 dist/* + - name: Check manifest + if: runner.os != 'Windows' # setup.py does not support sdist on Windows + run: check-manifest + + - name: Install entry point compatible code (TEMPORARY, April 2024) + if: matrix.want-latest-entry-point-code + run: | + uv pip list --system + # Not installing matplotlib's entry point code as building matplotlib from source is complex. + # Rely upon matplotlib to test all the latest entry point branches together. + uv pip install --system git+https://github.com/ipython/matplotlib-inline.git@main + uv pip list --system + + - name: pytest + env: + COLUMNS: 120 + run: | + pytest --color=yes -raXxs ${{ startsWith(matrix.python-version, 'pypy') && ' ' || '--cov --cov-report=xml' }} --maxfail=15 + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + name: Test + files: /home/runner/work/ipython/ipython/coverage.xml + + oldest-deps: + # pro-actively check backward compatibility + runs-on: ${{ matrix.os }} + timeout-minutes: 15 + # Disable scheduled CI runs on forks + if: github.event_name != 'schedule' || github.repository_owner == 'ipython' + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + # include windows because of platform-specific direct dependencies + - windows-latest + + steps: + - uses: actions/checkout@v6 + - name: Set up uv with Python 3.12 + uses: astral-sh/setup-uv@v7 + with: + python-version: '3.12' + enable-cache: true + activate-environment: true + prune-cache: false + cache-dependency-glob: | + pyproject.toml + + - name: Install Python dependencies (oldest supported versions) + run: uv pip install --resolution=lowest-direct -e .[test] + + - name: Try building with uv build + if: runner.os != 'Windows' # setup.py does not support sdist on Windows + run: | + uv build + shasum -a 256 dist/* + + - name: Check manifest + if: runner.os != 'Windows' # setup.py does not support sdist on Windows + run: uvx check-manifest + + - name: pytest + env: + COLUMNS: 120 + run: pytest --color=yes -raXxs diff --git a/.github/workflows/zulip.yaml b/.github/workflows/zulip.yaml new file mode 100644 index 00000000000..13097f5c2eb --- /dev/null +++ b/.github/workflows/zulip.yaml @@ -0,0 +1,29 @@ +name: Post message to Zulip + +on: + workflow_dispatch: + inputs: + message: + description: 'Message to post to Zulip' + required: false + default: 'Test Auto release notification of IPython from GitHub action' + type: string + +jobs: + post-message: + name: Post Message to Zulip + runs-on: ubuntu-latest + + steps: + + - name: Send Zulip notification + uses: zulip/github-actions-zulip/send-message@v1 + with: + api-key: ${{ secrets.ORG_ZULIP_API_KEY }} + email: ${{ secrets.ORG_ZULIP_EMAIL }} + organization-url: ${{ secrets.ORG_ZULIP_ORGANIZATION_URL }} + to: 'Releases' + type: 'stream' + topic: 'IPython' + content: | + ${{ inputs.message }} diff --git a/.gitignore b/.gitignore index 6221076cfb1..270eb98a3e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,41 @@ +MANIFEST build -./dist -docs/dist -docs/build -docs/_build +dist +_build +docs/man/*.gz docs/source/api/generated +docs/source/config/options +docs/source/config/shortcuts/*.csv +docs/source/config/shortcuts/table.tsv +docs/source/savefig +docs/source/interactive/magics-generated.txt docs/gh-pages +jupyter_notebook/notebook/static/mathjax +jupyter_notebook/static/style/*.map *.py[co] -build +__pycache__ *.egg-info *~ *.bak +.ipynb_checkpoints +.tox +.DS_Store +\#*# +.#* +.cache +.coverage +*.swp +.pytest_cache +.python-version +.venv*/ +venv*/ +.mypy_cache/ + +# jetbrains ide stuff +*.iml +.idea/ + +# vscode ide stuff +*.code-workspace +.history +.vscode diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000000..ab05ba24ba2 --- /dev/null +++ b/.mailmap @@ -0,0 +1,174 @@ +A. J. Holyoake ajholyoake +Alok Singh Alok Singh <8325708+alok@users.noreply.github.com> +Aaron Culich Aaron Culich +Aron Ahmadia ahmadia +Arthur Svistunov <18216480+madbird1304@users.noreply.github.com> +Arthur Svistunov <18216480+madbird1304@users.noreply.github.com> +Adam Hackbarth +Benjamin Ragan-Kelley +Benjamin Ragan-Kelley Min RK +Benjamin Ragan-Kelley MinRK +Barry Wark Barry Wark +Ben Edwards Ben Edwards +Bradley M. Froehle Bradley M. Froehle +Bradley M. Froehle Bradley Froehle +Brandon Parsons Brandon Parsons +Brian E. Granger Brian Granger +Brian E. Granger Brian Granger <> +Brian E. Granger bgranger <> +Brian E. Granger bgranger +Blazej Michalik <6691643+MrMino@users.noreply.github.com> +Blazej Michalik +Christoph Gohlke cgohlke +Cyrille Rossant rossant +Damián Avila damianavila +Damián Avila damianavila +Damon Allen damontallen +Darren Dale darren.dale <> +Darren Dale Darren Dale <> +Dav Clark Dav Clark <> +Dav Clark Dav Clark +David Hirschfeld dhirschfeld +David P. Sanders David P. Sanders +David Warde-Farley David Warde-Farley <> +Dan Green-Leipciger +Doug Blank Doug Blank +Eugene Van den Bulke Eugene Van den Bulke +Evan Patterson +Evan Patterson +Evan Patterson +Evan Patterson +Evan Patterson epatters +Evan Patterson epatters +Ernie French Ernie French +Ernie French ernie french +Ernie French ernop +Fernando Perez +Fernando Perez Fernando Perez +Fernando Perez fperez <> +Fernando Perez fptest <> +Fernando Perez fptest1 <> +Fernando Perez Fernando Perez +Fernando Perez Fernando Perez <> +Fernando Perez Fernando Perez +Frank Murphy Frank Murphy +Gabriel Becker gmbecker +Gael Varoquaux gael.varoquaux <> +Gael Varoquaux gvaroquaux +Gael Varoquaux Gael Varoquaux <> +Ingolf Becker watercrossing +Jake Vanderplas Jake Vanderplas +Jakob Gager jakobgager +Jakob Gager jakobgager +Jakob Gager jakobgager +Jason Grout +Jason Grout +Jason Gors jason gors +Jason Gors jgors +Jens Hedegaard Nielsen Jens Hedegaard Nielsen +Jens Hedegaard Nielsen Jens H Nielsen +Jens Hedegaard Nielsen Jens H. Nielsen +Jez Ng Jez Ng +Jonathan Frederic Jonathan Frederic +Jonathan Frederic Jonathan Frederic +Jonathan Frederic Jonathan Frederic +Jonathan Frederic jon +Jonathan Frederic U-Jon-PC\Jon +Jonathan March Jonathan March +Jean Cruypenynck Jean Cruypenynck +Jonathan March jdmarch +Jörgen Stenarson Jörgen Stenarson +Jörgen Stenarson Jorgen Stenarson +Jörgen Stenarson Jorgen Stenarson <> +Jörgen Stenarson jstenar +Jörgen Stenarson jstenar <> +Jörgen Stenarson Jörgen Stenarson +Juergen Hasch juhasch +Juergen Hasch juhasch +Julia Evans Julia Evans +Kester Tong KesterTong +Kyle Kelley Kyle Kelley +Kyle Kelley rgbkrk +kd2718 +Kory Donati kory donati +Kory Donati Kory Donati +Kory Donati koryd +Laurent Dufréchou +Laurent Dufréchou +Laurent Dufréchou laurent dufrechou <> +Laurent Dufréchou laurent.dufrechou <> +Laurent Dufréchou Laurent Dufrechou <> +Laurent Dufréchou laurent.dufrechou@gmail.com <> +Laurent Dufréchou ldufrechou +Luciana da Costa Marques luciana +Lorena Pantano Lorena +Luis Pedro Coelho Luis Pedro Coelho +Marc Molla marcmolla +Martín Gaitán Martín Gaitán +Matthias Bussonnier Matthias BUSSONNIER +Matthias Bussonnier Bussonnier Matthias +Matthias Bussonnier Matthias BUSSONNIER +Matthias Bussonnier Matthias Bussonnier +Matthias Bussonnier Matthias Bussonnier +Michael Droettboom Michael Droettboom +Nicholas Bollweg Nicholas Bollweg (Nick) +Nicolas Rougier +Nikolay Koldunov Nikolay Koldunov +Omar Andrés Zapata Mesa Omar Andres Zapata Mesa +Omar Andrés Zapata Mesa Omar Andres Zapata Mesa +Pankaj Pandey Pankaj Pandey +Pascal Schetelat pascal-schetelat +Paul Ivanov Paul Ivanov +Paul Ivanov Paul Ivanov +Pauli Virtanen Pauli Virtanen <> +Pauli Virtanen Pauli Virtanen +Pierre Gerold Pierre Gerold +Pietro Berkes Pietro Berkes +Piti Ongmongkolkul piti118 +Prabhu Ramachandran Prabhu Ramachandran <> +Puneeth Chaganti Puneeth Chaganti +Robert Kern rkern <> +Robert Kern Robert Kern +Robert Kern Robert Kern +Robert Kern Robert Kern <> +Robert Marchman Robert Marchman +Satrajit Ghosh Satrajit Ghosh +Satrajit Ghosh Satrajit Ghosh +Scott Sanderson Scott Sanderson +smithj1 smithj1 +smithj1 smithj1 +Sang Min Park Sang Min Park +Steven Johnson stevenJohnson +Steven Silvester blink1073 +S. Weber s8weber +Stefan van der Walt Stefan van der Walt +Silvia Vinyes Silvia +Silvia Vinyes silviav12 +Srinivas Reddy Thatiparthy Srinivas Reddy Thatiparthy +Sylvain Corlay +Sylvain Corlay sylvain.corlay +Samuel Gaist +Richard Shadrach +Juan Luis Cano Rodríguez +Tamir Bahar Tamir Bahar +Ted Drain TD22057 +Théophile Studer Théophile Studer +Thomas A Caswell Thomas A Caswell +Thomas Kluyver Thomas +Thomas Kluyver Thomas Kluyver +Thomas Spura Thomas Spura +Timo Paulssen timo +vds vds2212 +vds vds +Ville M. Vainio +Ville M. Vainio ville +Ville M. Vainio ville +Ville M. Vainio vivainio <> +Ville M. Vainio Ville M. Vainio +Ville M. Vainio Ville M. Vainio +Walter Doerwald walter.doerwald <> +Walter Doerwald Walter Doerwald <> +Wieland Hoffmann Wieland Hoffmann +W. Trevor King W. Trevor King +Yoval P. y-p + diff --git a/.meeseeksdev.yml b/.meeseeksdev.yml new file mode 100644 index 00000000000..b52022dde07 --- /dev/null +++ b/.meeseeksdev.yml @@ -0,0 +1,22 @@ +users: + LucianaMarques: + can: + - tag +special: + everyone: + can: + - say + - tag + - untag + - close + config: + tag: + only: + - good first issue + - async/await + - backported + - help wanted + - documentation + - notebook + - tab-completion + - windows diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000000..61e986075d6 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,16 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + +- repo: https://github.com/akaihola/darker + rev: 1.7.2 + hooks: + - id: darker + additional_dependencies: [isort, mypy, flake8] diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000000..4ab594e9d2a --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,18 @@ +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "3.14" + apt_packages: + - graphviz + +sphinx: + configuration: docs/source/conf.py + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: docs/requirements.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..f51a821b07e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,117 @@ +## Triaging Issues + +On the IPython repository, we strive to trust users and give them responsibility. +By using one of our bots, any user can close issues or add/remove +labels by mentioning the bot and asking it to do things on your behalf. + +To close an issue (or PR), even if you did not create it, use the following: + +> @meeseeksdev close + +This command can be in the middle of another comment, but must start on its +own line. + +To add labels to an issue, ask the bot to `tag` with a comma-separated list of +tags to add: + +> @meeseeksdev tag windows, documentation + +Only already pre-created tags can be added. So far, the list is limited to: +`async/await`, `backported`, `help wanted`, `documentation`, `notebook`, +`tab-completion`, `windows` + +To remove a label, use the `untag` command: + +> @meeseeksdev untag windows, documentation + +We'll be adding additional capabilities for the bot and will share them here +when they are ready to be used. + +## Opening an Issue + +When opening a new Issue, please take the following steps: + +1. Search GitHub and/or Google for your issue to avoid duplicate reports. + Keyword searches for your error messages are most helpful. +2. If possible, try updating to main and reproducing your issue, + because we may have already fixed it. +3. Try to include a minimal reproducible test case. +4. Include relevant system information. Start with the output of: + + python -c "import IPython; print(IPython.sys_info())" + + And include any relevant package versions, depending on the issue, such as + matplotlib, numpy, Qt, Qt bindings (PyQt/PySide), tornado, web browser, etc. + +## Pull Requests + +Some guidelines on contributing to IPython: + +* All work is submitted via Pull Requests. +* Pull Requests can be submitted as soon as there is code worth discussing. + Pull Requests track the branch, so you can continue to work after the PR is submitted. + Review and discussion can begin well before the work is complete, + and the more discussion the better. + The worst case is that the PR is closed. +* Pull Requests should generally be made against main +* Pull Requests should be tested, if feasible: + - bugfixes should include regression tests. + - new behavior should at least get minimal exercise. +* New features and backwards-incompatible changes should be documented by adding + a new file to the [pr](docs/source/whatsnew/pr) directory, see [the README.md + there](docs/source/whatsnew/pr/README.md) for details. +* Don't make 'cleanup' pull requests just to change code style. + We don't follow any style guide strictly, and we consider formatting changes + unnecessary noise. + If you're making functional changes, you can clean up the specific pieces of + code you're working on. + +[GitHub Actions](https://github.com/ipython/ipython/actions/workflows/test.yml) does +a pretty good job testing IPython and Pull Requests, +but it may make sense to manually perform tests, +particularly for PRs that affect `IPython.parallel` or Windows. + +For more detailed information, see our [GitHub Workflow](https://github.com/ipython/ipython/wiki/Dev:-GitHub-workflow). + +## Running Tests + +All the tests can be run by using +```shell +pytest +``` + +All the tests for a single module (for example **test_alias**) can be run by using the fully qualified path to the module. +```shell +pytest IPython/core/tests/test_alias.py +``` + +Only a single test (for example **test_alias_lifecycle**) within a single file can be run by adding the specific test after a `::` at the end: +```shell +pytest IPython/core/tests/test_alias.py::test_alias_lifecycle +``` + +## Code style + +* Before committing, run `darker -r 60625f241f298b5039cb2debc365db38aa7bb522 ` to apply selective `black` formatting on modified regions using [darker](https://github.com/akaihola/darker)==1.5.1 and black==22.10.0 +* As described in the pull requests section, please avoid excessive formatting changes; if a formatting-only commit is necessary, consider adding its hash to [`.git-blame-ignore-revs`](https://github.com/ipython/ipython/blob/main/.git-blame-ignore-revs) file. + +## Documentation + +Sphinx documentation can be built locally using standard sphinx `make` commands. To build HTML documentation from the root of the project, execute: + +```shell +pip install -r docs/requirements.txt # only needed once +make -C docs/ html SPHINXOPTS="-W" +``` + +To force update of the API documentation, precede the `make` command with: + +```shell +python3 docs/autogen_api.py +``` + +Similarly, to force-update the configuration, run: + +```shell +python3 docs/autogen_config.py +``` diff --git a/COPYING.rst b/COPYING.rst new file mode 100644 index 00000000000..e5c79ef38f0 --- /dev/null +++ b/COPYING.rst @@ -0,0 +1,41 @@ +============================= + The IPython licensing terms +============================= + +IPython is licensed under the terms of the Modified BSD License (also known as +New or Revised or 3-Clause BSD). See the LICENSE file. + + +About the IPython Development Team +---------------------------------- + +Fernando Perez began IPython in 2001 based on code from Janko Hauser + and Nathaniel Gray . Fernando is still +the project lead. + +The IPython Development Team is the set of all contributors to the IPython +project. This includes all of the IPython subprojects. + +The core team that coordinates development on GitHub can be found here: +https://github.com/ipython/. + +Our Copyright Policy +-------------------- + +IPython uses a shared copyright model. Each contributor maintains copyright +over their contributions to IPython. But, it is important to note that these +contributions are typically only changes to the repositories. Thus, the IPython +source code, in its entirety is not the copyright of any single person or +institution. Instead, it is the collective copyright of the entire IPython +Development Team. If individual contributors want to maintain a record of what +changes/contributions they have specific copyright on, they should indicate +their copyright in the commit message of the change, when they commit the +change to one of the IPython repositories. + +With this in mind, the following banner should be used in any source code file +to indicate the copyright and license terms: + +:: + + # Copyright (c) IPython Development Team. + # Distributed under the terms of the Modified BSD License. diff --git a/COPYING.txt b/COPYING.txt deleted file mode 100644 index 64205fe4853..00000000000 --- a/COPYING.txt +++ /dev/null @@ -1,85 +0,0 @@ -============================= - The IPython licensing terms -============================= - -IPython is licensed under the terms of the Modified BSD License (also known as -New or Revised BSD), as follows: - -Copyright (c) 2008-2010, IPython Development Team -Copyright (c) 2001-2007, Fernando Perez. -Copyright (c) 2001, Janko Hauser -Copyright (c) 2001, Nathaniel Gray - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -Neither the name of the IPython Development Team nor the names of its -contributors may be used to endorse or promote products derived from this -software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -About the IPython Development Team ----------------------------------- - -Fernando Perez began IPython in 2001 based on code from Janko Hauser - and Nathaniel Gray . Fernando is still -the project lead. - -The IPython Development Team is the set of all contributors to the IPython -project. This includes all of the IPython subprojects. A full list with -details is kept in the documentation directory, in the file -``about/credits.txt``. - -The core team that coordinates development on GitHub can be found here: -http://github.com/ipython. As of late 2010, it consists of: - -* Brian E. Granger -* Jonathan March -* Evan Patterson -* Fernando Perez -* Min Ragan-Kelley -* Robert Kern - - -Our Copyright Policy --------------------- - -IPython uses a shared copyright model. Each contributor maintains copyright -over their contributions to IPython. But, it is important to note that these -contributions are typically only changes to the repositories. Thus, the IPython -source code, in its entirety is not the copyright of any single person or -institution. Instead, it is the collective copyright of the entire IPython -Development Team. If individual contributors want to maintain a record of what -changes/contributions they have specific copyright on, they should indicate -their copyright in the commit message of the change, when they commit the -change to one of the IPython repositories. - -With this in mind, the following banner should be used in any source code file -to indicate the copyright and license terms: - -#----------------------------------------------------------------------------- -# Copyright (c) 2010, IPython Development Team. -# -# Distributed under the terms of the Modified BSD License. -# -# The full license is in the file COPYING.txt, distributed with this software. -#----------------------------------------------------------------------------- diff --git a/IPython/.git_commit_info.ini b/IPython/.git_commit_info.ini deleted file mode 100644 index 19c2a55c94c..00000000000 --- a/IPython/.git_commit_info.ini +++ /dev/null @@ -1,9 +0,0 @@ -# This is an ini file that may contain information about the code state -[commit hash] - -# The line below may contain a valid hash if it has been substituted during -# 'git archive' -archive_subst_hash=$Format:%h$ - -# This line may be modified by the install process -install_hash= diff --git a/IPython/__init__.py b/IPython/__init__.py index f49c9dd0760..d239b32280a 100644 --- a/IPython/__init__.py +++ b/IPython/__init__.py @@ -1,11 +1,11 @@ -# encoding: utf-8 +# PYTHON_ARGCOMPLETE_OK """ -IPython. +IPython: tools for interactive and parallel computing in Python. -IPython is a set of tools for interactive and exploratory computing in Python. +https://ipython.org """ #----------------------------------------------------------------------------- -# Copyright (c) 2008-2010, IPython Development Team. +# Copyright (c) 2008-2011, IPython Development Team. # Copyright (c) 2001-2007, Fernando Perez # Copyright (c) 2001, Janko Hauser # Copyright (c) 2001, Nathaniel Gray @@ -18,41 +18,127 @@ #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- -from __future__ import absolute_import -import os import sys +import warnings #----------------------------------------------------------------------------- # Setup everything #----------------------------------------------------------------------------- # Don't forget to also update setup.py when this changes! -if sys.version[0:3] < '2.6': - raise ImportError('Python Version 2.6 or above is required for IPython.') +if sys.version_info < (3, 12): + raise ImportError( + """ +IPython 9.x supports Python 3.12 and above, following SPEC0 +IPython 8.31+ supports Python 3.11 and above, following SPEC0 +IPython 8.19+ supports Python 3.10 and above, following SPEC0. +IPython 8.13+ supports Python 3.9 and above, following NEP 29. +When using Python 2.7, please install IPython 5.x LTS Long Term Support version. +Python 3.3 and 3.4 were supported up to IPython 6.x. +Python 3.5 was supported with IPython 7.0 to 7.9. +Python 3.6 was supported with IPython up to 7.16. +Python 3.7 was still supported with the 7.x branch. +See IPython `README.rst` file for more information: -# Make it easy to import extensions - they are always directly on pythonpath. -# Therefore, non-IPython modules can be added to extensions directory. -# This should probably be in ipapp.py. -sys.path.append(os.path.join(os.path.dirname(__file__), "extensions")) + https://github.com/ipython/ipython/blob/main/README.rst + +""" + ) #----------------------------------------------------------------------------- # Setup the top level names #----------------------------------------------------------------------------- -from .config.loader import Config +from .core.getipython import get_ipython from .core import release from .core.application import Application -from .frontend.terminal.embed import embed -from .core.error import TryNext +from .terminal.embed import embed + from .core.interactiveshell import InteractiveShell -from .testing import test from .utils.sysinfo import sys_info +from .utils.frame import extract_module_locals + +__all__ = ["start_ipython", "embed", "embed_kernel"] # Release data -__author__ = '' -for author, email in release.authors.itervalues(): - __author__ += author + ' <' + email + '>\n' +__author__ = '%s <%s>' % (release.author, release.author_email) __license__ = release.license __version__ = release.version +version_info = release.version_info +# list of CVEs that should have been patched in this release. +# this is informational and should not be relied upon. +__patched_cves__ = {"CVE-2022-21699", "CVE-2023-24816"} + + +def embed_kernel(module=None, local_ns=None, **kwargs): + """Embed and start an IPython kernel in a given scope. + + If you don't want the kernel to initialize the namespace + from the scope of the surrounding function, + and/or you want to load full IPython configuration, + you probably want `IPython.start_kernel()` instead. + + This is a deprecated alias for `ipykernel.embed.embed_kernel()`, + to be removed in the future. + You should import directly from `ipykernel.embed`; this wrapper + fails anyway if you don't have `ipykernel` package installed. + + Parameters + ---------- + module : types.ModuleType, optional + The module to load into IPython globals (default: caller) + local_ns : dict, optional + The namespace to load into IPython user namespace (default: caller) + **kwargs : various, optional + Further keyword args are relayed to the IPKernelApp constructor, + such as `config`, a traitlets :class:`Config` object (see :ref:`configure_start_ipython`), + allowing configuration of the kernel. Will only have an effect + on the first embed_kernel call for a given process. + """ + + warnings.warn( + "import embed_kernel from ipykernel.embed directly (since 2013)." + " Importing from IPython will be removed in the future", + DeprecationWarning, + stacklevel=2, + ) + + (caller_module, caller_locals) = extract_module_locals(1) + if module is None: + module = caller_module + if local_ns is None: + local_ns = dict(**caller_locals) + + # Only import .zmq when we really need it + from ipykernel.embed import embed_kernel as real_embed_kernel + real_embed_kernel(module=module, local_ns=local_ns, **kwargs) + +def start_ipython(argv=None, **kwargs): + """Launch a normal IPython instance (as opposed to embedded) + + `IPython.embed()` puts a shell in a particular calling scope, + such as a function or method for debugging purposes, + which is often not desirable. + + `start_ipython()` does full, regular IPython initialization, + including loading startup files, configuration, etc. + much of which is skipped by `embed()`. + + This is a public API method, and will survive implementation changes. + + Parameters + ---------- + argv : list or None, optional + If unspecified or None, IPython will parse command-line options from sys.argv. + To prevent any command-line parsing, pass an empty list: `argv=[]`. + user_ns : dict, optional + specify this dictionary to initialize the IPython user namespace with particular values. + **kwargs : various, optional + Any other kwargs will be passed to the Application constructor, + such as `config`, a traitlets :class:`Config` object (see :ref:`configure_start_ipython`), + allowing configuration of the instance (see :ref:`terminal_options`). + """ + from IPython.terminal.ipapp import launch_new_instance + return launch_new_instance(argv=argv, **kwargs) diff --git a/IPython/__main__.py b/IPython/__main__.py new file mode 100644 index 00000000000..9eabd50e74a --- /dev/null +++ b/IPython/__main__.py @@ -0,0 +1,14 @@ +# PYTHON_ARGCOMPLETE_OK +# encoding: utf-8 +"""Terminal-based IPython entry point.""" +# ----------------------------------------------------------------------------- +# Copyright (c) 2012, IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +# ----------------------------------------------------------------------------- + +from IPython import start_ipython + +start_ipython() diff --git a/IPython/config/__init__.py b/IPython/config/__init__.py deleted file mode 100644 index 876b4f330d0..00000000000 --- a/IPython/config/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# encoding: utf-8 - -__docformat__ = "restructuredtext en" - -#------------------------------------------------------------------------------- -# Copyright (C) 2008 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# Imports -#------------------------------------------------------------------------------- \ No newline at end of file diff --git a/IPython/config/configurable.py b/IPython/config/configurable.py deleted file mode 100755 index ed8fc2a921a..00000000000 --- a/IPython/config/configurable.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -""" -A base class for objects that are configurable. - -Authors: - -* Brian Granger -* Fernando Perez -""" - -#----------------------------------------------------------------------------- -# Copyright (C) 2008-2010 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from copy import deepcopy -import datetime -from weakref import WeakValueDictionary - -from IPython.utils.importstring import import_item -from loader import Config -from IPython.utils.traitlets import HasTraits, Instance - - -#----------------------------------------------------------------------------- -# Helper classes for Configurables -#----------------------------------------------------------------------------- - - -class ConfigurableError(Exception): - pass - - -#----------------------------------------------------------------------------- -# Configurable implementation -#----------------------------------------------------------------------------- - - -class Configurable(HasTraits): - - config = Instance(Config,(),{}) - created = None - - def __init__(self, **kwargs): - """Create a conigurable given a config config. - - Parameters - ---------- - config : Config - If this is empty, default values are used. If config is a - :class:`Config` instance, it will be used to configure the - instance. - - Notes - ----- - Subclasses of Configurable must call the :meth:`__init__` method of - :class:`Configurable` *before* doing anything else and using - :func:`super`:: - - class MyConfigurable(Configurable): - def __init__(self, config=None): - super(MyConfigurable, self).__init__(config) - # Then any other code you need to finish initialization. - - This ensures that instances will be configured properly. - """ - config = kwargs.pop('config', None) - if config is not None: - # We used to deepcopy, but for now we are trying to just save - # by reference. This *could* have side effects as all components - # will share config. In fact, I did find such a side effect in - # _config_changed below. If a config attribute value was a mutable type - # all instances of a component were getting the same copy, effectively - # making that a class attribute. - # self.config = deepcopy(config) - self.config = config - # This should go second so individual keyword arguments override - # the values in config. - super(Configurable, self).__init__(**kwargs) - self.created = datetime.datetime.now() - - #------------------------------------------------------------------------- - # Static trait notifiations - #------------------------------------------------------------------------- - - def _config_changed(self, name, old, new): - """Update all the class traits having ``config=True`` as metadata. - - For any class trait with a ``config`` metadata attribute that is - ``True``, we update the trait with the value of the corresponding - config entry. - """ - # Get all traits with a config metadata entry that is True - traits = self.traits(config=True) - - # We auto-load config section for this class as well as any parent - # classes that are Configurable subclasses. This starts with Configurable - # and works down the mro loading the config for each section. - section_names = [cls.__name__ for cls in \ - reversed(self.__class__.__mro__) if - issubclass(cls, Configurable) and issubclass(self.__class__, cls)] - - for sname in section_names: - # Don't do a blind getattr as that would cause the config to - # dynamically create the section with name self.__class__.__name__. - if new._has_section(sname): - my_config = new[sname] - for k, v in traits.iteritems(): - # Don't allow traitlets with config=True to start with - # uppercase. Otherwise, they are confused with Config - # subsections. But, developers shouldn't have uppercase - # attributes anyways! (PEP 6) - if k[0].upper()==k[0] and not k.startswith('_'): - raise ConfigurableError('Configurable traitlets with ' - 'config=True must start with a lowercase so they are ' - 'not confused with Config subsections: %s.%s' % \ - (self.__class__.__name__, k)) - try: - # Here we grab the value from the config - # If k has the naming convention of a config - # section, it will be auto created. - config_value = my_config[k] - except KeyError: - pass - else: - # print "Setting %s.%s from %s.%s=%r" % \ - # (self.__class__.__name__,k,sname,k,config_value) - # We have to do a deepcopy here if we don't deepcopy the entire - # config object. If we don't, a mutable config_value will be - # shared by all instances, effectively making it a class attribute. - setattr(self, k, deepcopy(config_value)) - diff --git a/IPython/config/default/ipcluster_config.py b/IPython/config/default/ipcluster_config.py deleted file mode 100644 index 5c2b43184ab..00000000000 --- a/IPython/config/default/ipcluster_config.py +++ /dev/null @@ -1,241 +0,0 @@ -import os - -c = get_config() - -#----------------------------------------------------------------------------- -# Select which launchers to use -#----------------------------------------------------------------------------- - -# This allows you to control what method is used to start the controller -# and engines. The following methods are currently supported: -# - Start as a regular process on localhost. -# - Start using mpiexec. -# - Start using the Windows HPC Server 2008 scheduler -# - Start using PBS/SGE -# - Start using SSH - - -# The selected launchers can be configured below. - -# Options are: -# - LocalControllerLauncher -# - MPIExecControllerLauncher -# - PBSControllerLauncher -# - SGEControllerLauncher -# - WindowsHPCControllerLauncher -# c.Global.controller_launcher = 'IPython.parallel.apps.launcher.LocalControllerLauncher' -# c.Global.controller_launcher = 'IPython.parallel.apps.launcher.PBSControllerLauncher' - -# Options are: -# - LocalEngineSetLauncher -# - MPIExecEngineSetLauncher -# - PBSEngineSetLauncher -# - SGEEngineSetLauncher -# - WindowsHPCEngineSetLauncher -# c.Global.engine_launcher = 'IPython.parallel.apps.launcher.LocalEngineSetLauncher' - -#----------------------------------------------------------------------------- -# Global configuration -#----------------------------------------------------------------------------- - -# The default number of engines that will be started. This is overridden by -# the -n command line option: "ipcluster start -n 4" -# c.Global.n = 2 - -# Log to a file in cluster_dir/log, otherwise just log to sys.stdout. -# c.Global.log_to_file = False - -# Remove old logs from cluster_dir/log before starting. -# c.Global.clean_logs = True - -# The working directory for the process. The application will use os.chdir -# to change to this directory before starting. -# c.Global.work_dir = os.getcwd() - - -#----------------------------------------------------------------------------- -# Local process launchers -#----------------------------------------------------------------------------- - -# The command line arguments to call the controller with. -# c.LocalControllerLauncher.controller_args = \ -# ['--log-to-file','--log-level', '40'] - -# The working directory for the controller -# c.LocalEngineSetLauncher.work_dir = u'' - -# Command line argument passed to the engines. -# c.LocalEngineSetLauncher.engine_args = ['--log-to-file','--log-level', '40'] - -#----------------------------------------------------------------------------- -# MPIExec launchers -#----------------------------------------------------------------------------- - -# The mpiexec/mpirun command to use in both the controller and engines. -# c.MPIExecLauncher.mpi_cmd = ['mpiexec'] - -# Additional arguments to pass to the actual mpiexec command. -# c.MPIExecLauncher.mpi_args = [] - -# The mpiexec/mpirun command and args can be overridden if they should be different -# for controller and engines. -# c.MPIExecControllerLauncher.mpi_cmd = ['mpiexec'] -# c.MPIExecControllerLauncher.mpi_args = [] -# c.MPIExecEngineSetLauncher.mpi_cmd = ['mpiexec'] -# c.MPIExecEngineSetLauncher.mpi_args = [] - -# The command line argument to call the controller with. -# c.MPIExecControllerLauncher.controller_args = \ -# ['--log-to-file','--log-level', '40'] - -# Command line argument passed to the engines. -# c.MPIExecEngineSetLauncher.engine_args = ['--log-to-file','--log-level', '40'] - -# The default number of engines to start if not given elsewhere. -# c.MPIExecEngineSetLauncher.n = 1 - -#----------------------------------------------------------------------------- -# SSH launchers -#----------------------------------------------------------------------------- - -# ipclusterz can be used to launch controller and engines remotely via ssh. -# Note that currently ipclusterz does not do any file distribution, so if -# machines are not on a shared filesystem, config and json files must be -# distributed. For this reason, the reuse_files defaults to True on an -# ssh-launched Controller. This flag can be overridded by the program_args -# attribute of c.SSHControllerLauncher. - -# set the ssh cmd for launching remote commands. The default is ['ssh'] -# c.SSHLauncher.ssh_cmd = ['ssh'] - -# set the ssh cmd for launching remote commands. The default is ['ssh'] -# c.SSHLauncher.ssh_args = ['tt'] - -# Set the user and hostname for the controller -# c.SSHControllerLauncher.hostname = 'controller.example.com' -# c.SSHControllerLauncher.user = os.environ.get('USER','username') - -# Set the arguments to be passed to ipcontrollerz -# note that remotely launched ipcontrollerz will not get the contents of -# the local ipcontrollerz_config.py unless it resides on the *remote host* -# in the location specified by the --cluster_dir argument. -# c.SSHControllerLauncher.program_args = ['-r', '-ip', '0.0.0.0', '--cluster_dir', '/path/to/cd'] - -# Set the default args passed to ipenginez for SSH launched engines -# c.SSHEngineSetLauncher.engine_args = ['--mpi', 'mpi4py'] - -# SSH engines are launched as a dict of locations/n-engines. -# if a value is a tuple instead of an int, it is assumed to be of the form -# (n, [args]), setting the arguments to passed to ipenginez on `host`. -# otherwise, c.SSHEngineSetLauncher.engine_args will be used as the default. - -# In this case, there will be 3 engines at my.example.com, and -# 2 at you@ipython.scipy.org with a special json connector location. -# c.SSHEngineSetLauncher.engines = {'my.example.com' : 3, -# 'you@ipython.scipy.org' : (2, ['-f', '/path/to/ipcontroller-engine.json']} -# } - -#----------------------------------------------------------------------------- -# Unix batch (PBS) schedulers launchers -#----------------------------------------------------------------------------- - -# SGE and PBS are very similar. All configurables in this section called 'PBS*' -# also exist as 'SGE*'. - -# The command line program to use to submit a PBS job. -# c.PBSLauncher.submit_command = ['qsub'] - -# The command line program to use to delete a PBS job. -# c.PBSLauncher.delete_command = ['qdel'] - -# The PBS queue in which the job should run -# c.PBSLauncher.queue = 'myqueue' - -# A regular expression that takes the output of qsub and find the job id. -# c.PBSLauncher.job_id_regexp = r'\d+' - -# If for some reason the Controller and Engines have different options above, they -# can be set as c.PBSControllerLauncher.