summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml91
-rw-r--r--.codecov.yml3
-rw-r--r--.coveragerc5
-rw-r--r--.flake89
-rw-r--r--.github/FUNDING.yml3
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml88
-rw-r--r--README.rst193
-rw-r--r--dev-requirements.txt12
-rw-r--r--paramiko/_version.py2
-rw-r--r--paramiko/sftp_client.py17
-rw-r--r--pytest.ini10
-rw-r--r--setup.cfg20
-rw-r--r--setup.py28
-rw-r--r--sites/shared_conf.py2
-rw-r--r--sites/www/changelog.rst20
-rw-r--r--sites/www/contact.rst6
-rw-r--r--sites/www/index.rst23
-rw-r--r--tasks.py38
-rw-r--r--tests/test_client.py5
-rw-r--r--tests/test_gssapi.py7
-rw-r--r--tests/test_sftp.py28
22 files changed, 293 insertions, 319 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 00000000..6b622057
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,91 @@
+version: 2.1
+
+
+orbs:
+ orb: invocations/orb@1.0.4
+
+
+jobs:
+ sdist-test-suite:
+ executor:
+ name: orb/default
+ version: "3.6"
+ steps:
+ - orb/setup
+ - run: inv release.build --no-wheel --directory .
+ - run: |
+ cd dist
+ tar xzvf *.tar.gz
+ rm -v *.tar.gz
+ cd paramiko-*
+ pip install -e .
+ inv -e test
+ - orb/debug
+
+ kerberos:
+ executor:
+ name: orb/default
+ version: "3.6"
+ steps:
+ - orb/setup
+ # Required to actually see all of universe/multiverse :(
+ - run: sudo apt update
+ # System reqs to install/build gssapi c-ext & friends (who only
+ # appear to offer wheels for Windows)
+ - run: sudo apt install -y libkrb5-dev krb5-admin-server krb5-kdc
+ # Our gssapi-supporting flavor, eg gssapi, pyasn1 etc
+ - run: pip install -e '.[gssapi]'
+ # Test-only deps for Kerberos (if they are importable it triggers
+ # running the kerberos tests instead of skipping them)
+ - run: pip install k5test
+ # Do the thing, win the points!
+ - run: inv test
+ - orb/debug
+
+
+workflows:
+ main:
+ jobs:
+ # The basics
+ - orb/lint:
+ name: Lint
+ - orb/format:
+ name: Style check
+ # Main test run, w/ coverage, and latest-supported cryptography
+ - orb/coverage:
+ name: Test 3.6 (w/ coverage, latest crypto)
+ # Non-coverage runs w/ other crypto versions.
+ # (Phrased as 2-dimensional matrix but 3.6 only for now to save credits)
+ - orb/test:
+ name: Test << matrix.version >> w/ << matrix.pip-overrides >>
+ matrix:
+ parameters:
+ version: ["3.6"]
+ # TODO: I don't see a nicer way to do this that doesn't require
+ # making the orb know too much about its client code...
+ pip-overrides: ["cryptography==2.5", "cryptography==3.4"]
+ # Kerberos tests. Currently broken :(
+ #- kerberos:
+ # name: Test 3.6 w/ Kerberos support
+ # # No point testing k5 if base tests already fail
+ # requires: ["Test 3.6 (w/ coverage, latest crypto)"]
+ - orb/test-release:
+ name: Release test
+ # Ensure test suite is included in sdist & functions appropriately
+ - sdist-test-suite:
+ name: Test within sdist
+ requires:
+ - "Test 3.6 (w/ coverage, latest crypto)"
+ - "Release test"
+ # Test other interpreters if main passed
+ - orb/test:
+ name: Test << matrix.version >>
+ requires: ["Test 3.6 (w/ coverage, latest crypto)"]
+ matrix:
+ parameters:
+ version: ["3.7", "3.8", "3.9"]
+ # Test doc building if main test suite passed (no real reason to spend
+ # all those credits if the main tests would also fail...)
+ - orb/docs:
+ name: "Docs"
+ requires: ["Test 3.6 (w/ coverage, latest crypto)"]
diff --git a/.codecov.yml b/.codecov.yml
new file mode 100644
index 00000000..41ab9cc4
--- /dev/null
+++ b/.codecov.yml
@@ -0,0 +1,3 @@
+comment: false
+coverage:
+ precision: 0
diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 00000000..47b6f4c3
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,5 @@
+[run]
+branch = True
+include =
+ paramiko/*
+ tests/*
diff --git a/.flake8 b/.flake8
new file mode 100644
index 00000000..1317fd52
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,9 @@
+[flake8]
+exclude = sites,.git,build,dist,demos
+# NOTE: W503, E203 are concessions to black 18.0b5 and could be reinstated
+# later if fixed on that end.
+# NOTE: E722 seems to only have started popping up on move to flake8 3.6.0 from
+# 2.4.0. Not sure why, bare excepts have been a (regrettable) thing forever...
+ignore = E124,E125,E128,E261,E301,E302,E303,E402,E721,W503,E203,E722
+max-line-length = 79
+
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..30ce38c8
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+# These are supported funding model platforms
+
+tidelift: "pypi/paramiko"
diff --git a/.gitignore b/.gitignore
index 89a9eee0..c6a6c494 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@ _build
.coverage
.cache
.idea
+coverage.xml
+htmlcov
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 58a3ac42..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,88 +0,0 @@
-dist: xenial
-language: python
-sudo: false
-cache:
- directories:
- - $HOME/.cache/pip
-python:
- - "2.7"
- - "3.4"
- - "3.5"
- - "3.6"
- - "3.7"
- - "3.8"
- - "pypy"
- - "pypy3"
-matrix:
- # Explicitly test against our oldest supported cryptography.io, in addition
- # to whatever the latest default is.
- include:
- - python: 2.7
- env: "OLDEST_CRYPTO=2.5"
- - python: 3.7
- env: "OLDEST_CRYPTO=2.5"
- - python: 2.7
- env: "USE_K5TEST=yes"
- - python: 3.7
- env: "USE_K5TEST=yes"
-install:
- # Ensure modern pip/etc to avoid some issues w/ older worker environs
- - pip install pip==9.0.1 setuptools==36.6.0
- # Grab a specific version of Cryptography if desired. Doing this before other
- # installations ensures we don't have to do any downgrading/overriding.
- - |
- if [[ -n "$OLDEST_CRYPTO" ]]; then
- pip install "cryptography==${OLDEST_CRYPTO}"
- fi
- # Self-install for setup.py-driven deps (plus additional
- # safe-enough-for-all-matrix-cells optional deps)
- # TODO: additional matrices or test steps to test all the entrypoints
- - pip install -e ".[ed25519,invoke]"
- # Dev (doc/test running) requirements
- # TODO: use poetry + whatever contexty-type stuff it has, should be more than
- # just prod/dev split. Also apply to the above re: extras_require.
- - pip install codecov # For codecov specifically
- - pip install -r dev-requirements.txt
- - |
- if [[ -n "$USE_K5TEST" ]]; then
- # we need a few commands and libraries
- # Debian/Ubuntu package: commands used by package k5test
- # libkrb5-dev: krb5-config
- # krb5-kdc: kdb5_util, krb5kdc
- # krb5-admin-server: kadmin.local, kprop, kadmind
- # krb5-user: kinit, klist
- #
- # krb5-multidev: required to build gssapi
- sudo apt-get -y install libkrb5-dev krb5-admin-server \
- krb5-kdc krb5-user krb5-multidev && \
- pip install k5test gssapi pyasn1
- fi
- # In case of problems uncomment the following to get the krb environment
- # - |
- # if [[ -n "$USE_K5TEST" ]]; then
- # python -c 'from tests.util import k5shell; k5shell()' env | sort
- # fi
-script:
- # Fast syntax check failures for more rapid feedback to submitters
- # (Travis-oriented metatask that version checks Python, installs, runs.)
- - inv travis.blacken
- # I have this in my git pre-push hook, but contributors probably don't
- - flake8
- # All (including slow) tests, w/ coverage!
- - inv coverage
- # Ensure documentation builds, both sites, maxxed nitpicking
- - inv sites
- # Sanity check ability to build sdist
- - python setup.py sdist
- # And ability to run tests from within the result
- - cd dist && tar xzvf *.tar.gz && rm *.tar.gz && cd paramiko-* && ls -l && pip install -e . && inv test
-notifications:
- irc:
- channels: "irc.freenode.org#paramiko"
- template:
- - "%{repository}@%{branch}: %{message} (%{build_url})"
- on_success: change
- on_failure: change
- email: false
-after_success:
- - codecov
diff --git a/README.rst b/README.rst
index 5fb2f77f..f99090d3 100644
--- a/README.rst
+++ b/README.rst
@@ -1,145 +1,48 @@
-========
-Paramiko
-========
-
-.. Continuous integration and code coverage badges
-
-.. image:: https://travis-ci.org/paramiko/paramiko.svg?branch=master
- :target: https://travis-ci.org/paramiko/paramiko
-.. image:: https://codecov.io/gh/paramiko/paramiko/branch/master/graph/badge.svg
- :target: https://codecov.io/gh/paramiko/paramiko
-
-:Paramiko: Python SSH module
-:Copyright: Copyright (c) 2009 Robey Pointer <robeypointer@gmail.com>
-:Copyright: Copyright (c) 2020 Jeff Forcier <jeff@bitprophet.org>
-:License: `LGPL <https://www.gnu.org/copyleft/lesser.html>`_
-:Homepage: http://www.paramiko.org/
-:API docs: http://docs.paramiko.org
-:Development: https://github.com/paramiko/paramiko
-
-
-What
-----
-
-"Paramiko" is a combination of the Esperanto words for "paranoid" and
-"friend". It's a module for Python 2.7/3.4+ that implements the SSH2 protocol
-for secure (encrypted and authenticated) connections to remote machines. Unlike
-SSL (aka TLS), SSH2 protocol does not require hierarchical certificates signed
-by a powerful central authority. You may know SSH2 as the protocol that
-replaced Telnet and rsh for secure access to remote shells, but the protocol
-also includes the ability to open arbitrary channels to remote services across
-the encrypted tunnel (this is how SFTP works, for example).
-
-It is written entirely in Python (though it depends on third-party C wrappers
-for low level crypto; these are often available precompiled) and is released
-under the GNU Lesser General Public License (`LGPL
-<https://www.gnu.org/copyleft/lesser.html>`_).
-
-The package and its API is fairly well documented in the ``docs`` folder that
-should have come with this repository.
-
-
-Installation
-------------
-
-For most users, the recommended method to install is via pip::
-
- pip install paramiko
-
-For more detailed instructions, see the `Installing
-<http://www.paramiko.org/installing.html>`_ page on the main Paramiko website.
-
-
-Portability Issues
-------------------
-
-Paramiko primarily supports POSIX platforms with standard OpenSSH
-implementations, and is most frequently tested on Linux and OS X. Windows is
-supported as well, though it may not be as straightforward.
-
-Bugs & Support
---------------
-
-:Bug Reports: `Github <https://github.com/paramiko/paramiko/issues/>`_
-:Mailing List: ``paramiko@librelist.com`` (see the `LibreList website
- <http://librelist.com/>`_ for usage details).
-:IRC: ``#paramiko`` on Freenode
-
-
-Kerberos Support
-----------------
-
-Paramiko ships with optional Kerberos/GSSAPI support; for info on the extra
-dependencies for this, see the `GSS-API section
-<http://www.paramiko.org/installing.html#gssapi>`_
-on the main Paramiko website.
-
-
-Demo
-----
-
-Several demo scripts come with Paramiko to demonstrate how to use it.
-Probably the simplest demo is this::
-
- import base64
- import paramiko
- key = paramiko.RSAKey(data=base64.b64decode(b'AAA...'))
- client = paramiko.SSHClient()
- client.get_host_keys().add('ssh.example.com', 'ssh-rsa', key)
- client.connect('ssh.example.com', username='strongbad', password='thecheat')
- stdin, stdout, stderr = client.exec_command('ls')
- for line in stdout:
- print('... ' + line.strip('\n'))
- client.close()
-
-This prints out the results of executing ``ls`` on a remote server. The host
-key ``b'AAA...'`` should of course be replaced by the actual base64 encoding of the
-host key. If you skip host key verification, the connection is not secure!
-
-The following example scripts (in demos/) get progressively more detailed:
-
-:demo_simple.py:
- Calls invoke_shell() and emulates a terminal/TTY through which you can
- execute commands interactively on a remote server. Think of it as a
- poor man's SSH command-line client.
-
-:demo.py:
- Same as demo_simple.py, but allows you to authenticate using a private
- key, attempts to use an SSH agent if present, and uses the long form of
- some of the API calls.
-
-:forward.py:
- Command-line script to set up port-forwarding across an SSH transport.
-
-:demo_sftp.py:
- Opens an SFTP session and does a few simple file operations.
-
-:demo_server.py:
- An SSH server that listens on port 2200 and accepts a login for
- 'robey' (password 'foo'), and pretends to be a BBS. Meant to be a
- very simple demo of writing an SSH server.
-
-:demo_keygen.py:
- A key generator similar to OpenSSH ``ssh-keygen(1)`` program with
- Paramiko keys generation and progress functions.
-
-Use
----
-
-The demo scripts are probably the best example of how to use this package.
-Also a lot of documentation is generated by Sphinx autodoc, in the
-doc/ folder.
-
-There are also unit tests here::
-
- $ pip install -r dev-requirements.txt
- $ pytest
-
-Which will verify that most of the core components are working correctly.
-
-To test Kerberos/GSSAPI, you need a Kerberos environment. On UNIX you can
-use the package k5test to setup a Kerberos environment on the fly::
-
- $ pip install -r dev-requirements.txt
- $ pip install k5test gssapi pyasn1
- $ pytest
+|version| |python| |license| |ci| |coverage|
+
+.. |version| image:: https://img.shields.io/pypi/v/paramiko
+ :target: https://pypi.org/project/paramiko/
+ :alt: PyPI - Package Version
+.. |python| image:: https://img.shields.io/pypi/pyversions/paramiko
+ :target: https://pypi.org/project/paramiko/
+ :alt: PyPI - Python Version
+.. |license| image:: https://img.shields.io/pypi/l/paramiko
+ :target: https://github.com/paramiko/paramiko/blob/main/LICENSE
+ :alt: PyPI - License
+.. |ci| image:: https://img.shields.io/circleci/build/github/paramiko/paramiko/main
+ :target: https://app.circleci.com/pipelines/github/paramiko/paramiko
+ :alt: CircleCI
+.. |coverage| image:: https://img.shields.io/codecov/c/gh/paramiko/paramiko
+ :target: https://app.codecov.io/gh/paramiko/paramiko
+ :alt: Codecov
+
+Welcome to Paramiko!
+====================
+
+Paramiko is a pure-Python [#]_ (2.7, 3.4+) implementation of the SSHv2 protocol
+[#]_, providing both client and server functionality. It provides the
+foundation for the high-level SSH library `Fabric <https://fabfile.org>`_,
+which is what we recommend you use for common client use-cases such as running
+remote shell commands or transferring files.
+
+Direct use of Paramiko itself is only intended for users who need
+advanced/low-level primitives or want to run an in-Python sshd.
+
+For installation information, changelogs, FAQs and similar, please visit `our
+main project website <https://paramiko.org>`_; for API details, see `the
+versioned docs <https://docs.paramiko.org>`_. Additionally, the project
+maintainer keeps a `roadmap <http://bitprophet.org/projects#roadmap>`_ on his
+personal site.
+
+.. [#]
+ Paramiko relies on `cryptography <https://cryptography.io>`_ for crypto
+ functionality, which makes use of C and Rust extensions but has many
+ precompiled options available. See `our installation page
+ <https://www.paramiko.org/installing.html>`_ for details.
+
+.. [#]
+ SSH is defined in :rfc-reference:`4251`, :rfc-reference:`4252`,
+ :rfc-reference:`4253` and :rfc-reference:`4254`. The primary working
+ implementation of the protocol is the `OpenSSH project
+ <http://openssh.org>`_. Paramiko implements a large portion of the SSH
+ feature set, but there are occasional gaps.
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 56f53ad9..aa2f8d49 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,6 +1,6 @@
# Invocations for common project tasks
-invoke>=1.0,<2.0
-invocations>=1.2.0,<2.0
+invoke==1.6.0
+invocations==2.3.0
pytest==4.4.2
pytest-relaxed==1.1.5
# pytest-xdist for test dir watching and the inv guard task
@@ -8,16 +8,16 @@ pytest-xdist==1.28.0
mock==2.0.0
# Linting!
flake8==3.8.3
+# Formatting!
+black==18.6b4
# Coverage!
coverage==4.5.4
-codecov==1.6.3
+codecov==2.1.11
# Documentation tools
sphinx>=1.4,<1.7
alabaster==0.7.12
releases>=1.5,<2.0
# Release tools
semantic_version>=2.4,<2.5
-wheel==0.24
-twine==1.11.0
# Self
--e .
+-e ".[ed2559,invoke]"
diff --git a/paramiko/_version.py b/paramiko/_version.py
index 8b3ae0e7..07aff82b 100644
--- a/paramiko/_version.py
+++ b/paramiko/_version.py
@@ -1,2 +1,2 @@
-__version_info__ = (2, 7, 2)
+__version_info__ = (2, 8, 0)
__version__ = ".".join(map(str, __version_info__))
diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py
index 93190d85..6294fb48 100644
--- a/paramiko/sftp_client.py
+++ b/paramiko/sftp_client.py
@@ -758,7 +758,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager):
with open(localpath, "rb") as fl:
return self.putfo(fl, remotepath, file_size, callback, confirm)
- def getfo(self, remotepath, fl, callback=None):
+ def getfo(self, remotepath, fl, callback=None, prefetch=True):
"""
Copy a remote file (``remotepath``) from the SFTP server and write to
an open file or file-like object, ``fl``. Any exception raised by
@@ -771,18 +771,23 @@ class SFTPClient(BaseSFTP, ClosingContextManager):
:param callable callback:
optional callback function (form: ``func(int, int)``) that accepts
the bytes transferred so far and the total bytes to be transferred
+ :param bool prefetch:
+ controls whether prefetching is performed (default: True)
:return: the `number <int>` of bytes written to the opened file object
.. versionadded:: 1.10
+ .. versionchanged:: 2.8
+ Added the ``prefetch`` keyword argument.
"""
file_size = self.stat(remotepath).st_size
with self.open(remotepath, "rb") as fr:
- fr.prefetch(file_size)
+ if prefetch:
+ fr.prefetch(file_size)
return self._transfer_with_callback(
reader=fr, writer=fl, file_size=file_size, callback=callback
)
- def get(self, remotepath, localpath, callback=None):
+ def get(self, remotepath, localpath, callback=None, prefetch=True):
"""
Copy a remote file (``remotepath``) from the SFTP server to the local
host as ``localpath``. Any exception raised by operations will be
@@ -793,13 +798,17 @@ class SFTPClient(BaseSFTP, ClosingContextManager):
:param callable callback:
optional callback function (form: ``func(int, int)``) that accepts
the bytes transferred so far and the total bytes to be transferred
+ :param bool prefetch:
+ controls whether prefetching is performed (default: True)
.. versionadded:: 1.4
.. versionchanged:: 1.7.4
Added the ``callback`` param
+ .. versionchanged:: 2.8
+ Added the ``prefetch`` keyword argument.
"""
with open(localpath, "wb") as fl:
- size = self.getfo(remotepath, fl, callback)
+ size = self.getfo(remotepath, fl, callback, prefetch)
s = os.stat(localpath)
if s.st_size != size:
raise IOError(
diff --git a/pytest.ini b/pytest.ini
new file mode 100644
index 00000000..be207cd8
--- /dev/null
+++ b/pytest.ini
@@ -0,0 +1,10 @@
+[pytest]
+# We use pytest-relaxed just for its utils at the moment, so disable it at the
+# plugin level until we adapt test organization to really use it.
+addopts = -p no:relaxed
+# Loop on failure
+looponfailroots = tests paramiko
+# Ignore some warnings we cannot easily handle.
+filterwarnings =
+ ignore::DeprecationWarning:pkg_resources
+ ignore::cryptography.utils.CryptographyDeprecationWarning
diff --git a/setup.cfg b/setup.cfg
index 44d029c4..59b47d60 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -6,23 +6,3 @@ license_file = LICENSE
[coverage:run]
omit = paramiko/_winapi.py
-
-[flake8]
-exclude = sites,.git,build,dist,demos
-# NOTE: W503, E203 are concessions to black 18.0b5 and could be reinstated
-# later if fixed on that end.
-# NOTE: E722 seems to only have started popping up on move to flake8 3.6.0 from
-# 2.4.0. Not sure why, bare excepts have been a (regrettable) thing forever...
-ignore = E124,E125,E128,E261,E301,E302,E303,E402,E721,W503,E203,E722
-max-line-length = 79
-
-[tool:pytest]
-# We use pytest-relaxed just for its utils at the moment, so disable it at the
-# plugin level until we adapt test organization to really use it.
-addopts = -p no:relaxed
-# Loop on failure
-looponfailroots = tests paramiko
-# Ignore some warnings we cannot easily handle.
-filterwarnings =
- ignore::DeprecationWarning:pkg_resources
- ignore::cryptography.utils.CryptographyDeprecationWarning
diff --git a/setup.py b/setup.py
index d439fd03..56997532 100644
--- a/setup.py
+++ b/setup.py
@@ -24,16 +24,7 @@ if sys.platform == "darwin":
setup_helper.install_custom_make_tarball()
-longdesc = """
-This is a library for making SSH2 connections (client or server).
-Emphasis is on using SSH2 as an alternative to SSL for making secure
-connections between python scripts. All major ciphers and hash methods
-are supported. SFTP client and server mode are both supported too.
-
-To install the development version, ``pip install -e
-git+https://github.com/paramiko/paramiko/#egg=paramiko``.
-"""
-
+long_description = open("README.rst").read()
# Version info -- read without importing
_locals = {}
@@ -61,10 +52,17 @@ setup(
name="paramiko",
version=version,
description="SSH2 protocol library",
- long_description=longdesc,
+ long_description=long_description,
author="Jeff Forcier",
author_email="jeff@bitprophet.org",
- url="https://github.com/paramiko/paramiko/",
+ url="https://paramiko.org",
+ project_urls={
+ "Docs": "https://docs.paramiko.org",
+ "Source": "https://github.com/paramiko/paramiko",
+ "Issues": "https://github.com/paramiko/paramiko/issues",
+ "Changelog": "https://www.paramiko.org/changelog.html",
+ "CI": "https://app.circleci.com/pipelines/github/paramiko/paramiko",
+ },
packages=["paramiko"],
license="LGPL",
platforms="Posix; MacOS X; Windows",
@@ -85,9 +83,13 @@ setup(
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
],
# TODO 3.0: remove bcrypt, pynacl and update installation docs noting that
- # use of the extras_require(s) is now required for those
+ # use of the extras_require ("paramiko[ed2559]") is now required for those
+ # TODO 3.0: alternately, given how prevalent ed25519 is now, and how we use
+ # invoke for (increasing) subproc stuff, consider making the default flavor
+ # "full" and adding a "minimal" or similar that is just-crypto?
install_requires=["bcrypt>=3.1.3", "cryptography>=2.5", "pynacl>=1.0.1"],
extras_require=extras_require,
)
diff --git a/sites/shared_conf.py b/sites/shared_conf.py
index 7bb503ce..c406054c 100644
--- a/sites/shared_conf.py
+++ b/sites/shared_conf.py
@@ -13,7 +13,7 @@ html_theme_options = {
"github_user": "paramiko",
"github_repo": "paramiko",
"analytics_id": "UA-18486793-2",
- "travis_button": True,
+ "travis_button": False,
"tidelift_url": "https://tidelift.com/subscription/pkg/pypi-paramiko?utm_source=pypi-paramiko&utm_medium=referral&utm_campaign=docs",
}
html_sidebars = {
diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst
index 7c20e434..49b41f41 100644
--- a/sites/www/changelog.rst
+++ b/sites/www/changelog.rst
@@ -2,12 +2,28 @@
Changelog
=========
-- :bug:`1462` (via :issue:`1882`) Newer server-side key exchange algorithms not
- intended to use SHA1 (``diffie-hellman-group14-sha256``,
+- :release:`2.8.0 <2021-10-09>`
+- :support:`-` Administrivia overhaul, including but not limited to:
+
+ - Migrate CI to CircleCI
+ - Primary dev branch is now ``main`` (renamed)
+ - Many README edits for clarity, modernization etc; including a bunch more
+ (and consistent) status badges & unification with main project site index
+ - PyPI page much more fleshed out (long_description is now filled in with the
+ README; sidebar links expanded; etc)
+ - flake8, pytest configs split out of setup.cfg into their own files
+ - Invoke/invocations (used by maintainers/contributors) upgraded to modern
+ versions
+
+- :bug:`1462 major` (via :issue:`1882`) Newer server-side key exchange
+ algorithms not intended to use SHA1 (``diffie-hellman-group14-sha256``,
``diffie-hellman-group16-sha512``) were incorrectly using SHA1 after all, due
to a bug causing them to ignore the ``hash_algo`` class attribute. This has
been corrected. Big thanks to ``@miverson`` for the report and to Benno Rice
for the patch.
+- :feature:`1846` Add a ``prefetch`` keyword argument to `SFTPClient.get <paramiko.sftp_client.SFTPClient.get>`/`SFTPClient.getfo <paramiko.sftp_client.SFTPClient.getfo>`
+ so users who need to skip SFTP prefetching are able to conditionally turn it
+ off. Thanks to Github user ``@h3ll0r`` for the PR.
- :release:`2.7.2 <2020-08-30>`
- :support:`- backported` Update our CI to catch issues with sdist generation,
installation and testing.
diff --git a/sites/www/contact.rst b/sites/www/contact.rst
index dafc1bd4..202815f8 100644
--- a/sites/www/contact.rst
+++ b/sites/www/contact.rst
@@ -5,6 +5,8 @@ Contact
You can get in touch with the developer & user community in any of the
following ways:
-* IRC: ``#paramiko`` on Freenode
-* This website - a blog section is forthcoming.
* Submit contributions on Github - see the :doc:`contributing` page.
+* Follow ``@bitprophet`` on Twitter, though it's not a dedicated account and
+ mostly just retweets funny pictures.
+* Subscribe to the ``paramiko`` category on the developer's blog:
+ http://bitprophet.org/categories/paramiko/
diff --git a/sites/www/index.rst b/sites/www/index.rst
index 26961f24..9c3bb3aa 100644
--- a/sites/www/index.rst
+++ b/sites/www/index.rst
@@ -1,18 +1,4 @@
-Welcome to Paramiko!
-====================
-
-Paramiko is a Python (2.7, 3.4+) implementation of the SSHv2 protocol [#]_,
-providing both client and server functionality. While it leverages a Python C
-extension for low level cryptography (`Cryptography
-<https://cryptography.io>`_), Paramiko itself is a pure Python interface around
-SSH networking concepts.
-
-This website covers project information for Paramiko such as the changelog,
-contribution guidelines, development roadmap, news/blog, and so forth. Detailed
-usage and API documentation can be found at our code documentation site,
-`docs.paramiko.org <http://docs.paramiko.org>`_.
-
-Please see the sidebar to the left to begin.
+.. include:: ../../README.rst
.. toctree::
:hidden:
@@ -25,10 +11,3 @@ Please see the sidebar to the left to begin.
contact
-.. rubric:: Footnotes
-
-.. [#]
- SSH is defined in :rfc:`4251`, :rfc:`4252`, :rfc:`4253` and :rfc:`4254`. The
- primary working implementation of the protocol is the `OpenSSH project
- <http://openssh.org>`_. Paramiko implements a large portion of the SSH
- feature set, but there are occasional gaps.
diff --git a/tasks.py b/tasks.py
index 3d2fdf65..2e105297 100644
--- a/tasks.py
+++ b/tasks.py
@@ -3,7 +3,6 @@ from os.path import join
from shutil import rmtree, copytree
from invoke import Collection, task
-from invocations import travis
from invocations.checks import blacken
from invocations.docs import docs, www, sites
from invocations.packaging.release import ns as release_coll, publish
@@ -60,7 +59,7 @@ def test(
# Leverage how pytest can be run as 'python -m pytest', and then how
# coverage can be told to run things in that manner instead of
# expecting a literal .py file.
- runner = "coverage run --source=paramiko -m pytest"
+ runner = "coverage run -m pytest"
# Strip SSH_AUTH_SOCK from parent env to avoid pollution by interactive
# users.
# TODO: once pytest coverage plugin works, see if there's a pytest-native
@@ -75,11 +74,15 @@ def test(
@task
-def coverage(ctx, opts=""):
+def coverage(ctx, opts="", codecov=False):
"""
Execute all tests (normal and slow) with coverage enabled.
"""
- return test(ctx, coverage=True, include_slow=True, opts=opts)
+ test(ctx, coverage=True, include_slow=True, opts=opts)
+ # Cribbed from invocations.pytest.coverage for now
+ if codecov:
+ ctx.run("coverage xml")
+ ctx.run("codecov")
@task
@@ -94,8 +97,12 @@ def guard(ctx, opts=""):
# Until we stop bundling docs w/ releases. Need to discover use cases first.
# TODO: would be nice to tie this into our own version of build() too, but
# still have publish() use that build()...really need to try out classes!
+# TODO 3.0: I'd like to just axe the 'built docs in sdist', none of my other
+# projects do it.
@task
-def release(ctx, sdist=True, wheel=True, sign=True, dry_run=False, index=None):
+def publish_(
+ ctx, sdist=True, wheel=True, sign=True, dry_run=False, index=None
+):
"""
Wraps invocations.packaging.publish to add baked-in docs folder.
"""
@@ -110,17 +117,22 @@ def release(ctx, sdist=True, wheel=True, sign=True, dry_run=False, index=None):
publish(
ctx, sdist=sdist, wheel=wheel, sign=sign, dry_run=dry_run, index=index
)
- # Remind
- print(
- "\n\nDon't forget to update RTD's versions page for new minor "
- "releases!"
- )
+
+
+# Also have to hack up the newly enhanced all_() so it uses our publish
+@task(name="all", default=True)
+def all_(c, dry_run=False):
+ release_coll["prepare"](c, dry_run=dry_run)
+ publish_(c, dry_run=dry_run)
+ release_coll["push"](c, dry_run=dry_run)
+ release_coll["tidelift"](c, dry_run=dry_run)
# TODO: "replace one task with another" needs a better public API, this is
# using unpublished internals & skips all the stuff add_task() does re:
# aliasing, defaults etc.
-release_coll.tasks["publish"] = release
+release_coll.tasks["publish"] = publish_
+release_coll.tasks["all"] = all_
ns = Collection(
test,
@@ -131,7 +143,6 @@ ns = Collection(
www,
sites,
count_errors,
- travis,
blacken,
)
ns.configure(
@@ -145,7 +156,6 @@ ns.configure(
"changelog_file": join(
www.configuration()["sphinx"]["source"], "changelog.rst"
),
- },
- "travis": {"black": {"version": "18.6b4"}},
+ }
}
)
diff --git a/tests/test_client.py b/tests/test_client.py
index 60ad310c..f14aac23 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -421,7 +421,10 @@ class SSHClientTest(ClientTest):
# force a collection to see whether the SSHClient object is deallocated
# 2 GCs are needed on PyPy, time is needed for Python 3
- time.sleep(0.3)
+ # TODO: this still fails randomly under CircleCI under Python 3.7, 3.8
+ # at the very least. bumped sleep 0.3->1.0s but the underlying
+ # functionality should get reevaluated once we drop Python 2.
+ time.sleep(1)
gc.collect()
gc.collect()
diff --git a/tests/test_gssapi.py b/tests/test_gssapi.py
index 308caa93..acdc7c82 100644
--- a/tests/test_gssapi.py
+++ b/tests/test_gssapi.py
@@ -26,6 +26,13 @@ import socket
from .util import needs_gssapi, KerberosTestCase, update_env
+#
+# NOTE: KerberosTestCase skips all tests if it was unable to import k5test
+# third-party library. That's the primary trigger for whether this module
+# effectively gets run or not. See tests/util.py for other triggers (a set of
+# env vars a human might have defined).
+#
+
@needs_gssapi
class GSSAPITest(KerberosTestCase):
diff --git a/tests/test_sftp.py b/tests/test_sftp.py
index e4e18e5a..a98a46c6 100644
--- a/tests/test_sftp.py
+++ b/tests/test_sftp.py
@@ -554,6 +554,34 @@ class TestSFTP(object):
os.unlink(localname)
sftp.unlink(sftp.FOLDER + "/bunny.txt")
+ def test_get_without_prefetch(self, sftp):
+ """
+ Create a 4MB file. Verify that pull works without prefetching
+ using a lager file.
+ """
+
+ sftp_filename = sftp.FOLDER + "/dummy_file"
+ num_chars = 1024 * 1024 * 4
+
+ fd, localname = mkstemp()
+ os.close(fd)
+
+ with open(localname, "wb") as f:
+ f.write(b"0" * num_chars)
+
+ sftp.put(localname, sftp_filename)
+
+ os.unlink(localname)
+ fd, localname = mkstemp()
+ os.close(fd)
+
+ sftp.get(sftp_filename, localname, prefetch=False)
+
+ assert os.stat(localname).st_size == num_chars
+
+ os.unlink(localname)
+ sftp.unlink(sftp_filename)
+
def test_check(self, sftp):
"""
verify that file.check() works against our own server.