From 4bd10e4ee6aadabc78c87c04ea64a845704208ae Mon Sep 17 00:00:00 2001 From: Jacob Callahan Date: Fri, 16 Aug 2024 18:43:56 -0400 Subject: [PATCH] Update PyO3 to 0.22 This commit bumps the pyo3 dependency up one minor version. In order to do that, some changes were made, namely adding function signatures to anything with optional arguments. For more information about the version bump see this link: https://pyo3.rs/main/migration#from-021-to-022 fixes #10 --- .github/workflows/build_and_test.yml | 3 +- .github/workflows/release.yml | 3 +- Cargo.toml | 4 +-- src/connection.rs | 48 ++++++++++++++++------------ src/lib.rs | 4 +-- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 0495421..e14ace1 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -48,7 +48,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: [x86_64, aarch64, armv7, s390x, ppc64le] + # s390x currently has issues with gcc + target: [x86_64, aarch64, armv7, ppc64le] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f3ac991..6530cb5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: [x86_64, aarch64, armv7, s390x, ppc64le] + # s390x currently has issues with gcc + target: [x86_64, aarch64, armv7, ppc64le] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/Cargo.toml b/Cargo.toml index ce37e79..201c614 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hussh" -version = "0.1.5" +version = "0.1.6" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -10,7 +10,7 @@ crate-type = ["cdylib"] [dependencies] openssl = { version = "0.10", features = ["vendored"] } -pyo3 = "0.21.0" +pyo3 = "0.22" # ssh2 = "0.9" # temporary until ssh2#312 makes it into a release. probably 0.9.5 ssh2 = { git = "https://github.com/alexcrichton/ssh2-rs", branch = "master" } diff --git a/src/connection.rs b/src/connection.rs index 2883421..f311ceb 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -226,15 +226,13 @@ impl Connection { #[pymethods] impl Connection { #[new] - #[pyo3( - text_signature = "(host, /, port=22, username='root', password=None, private_key=None, timeout=0)" - )] + #[pyo3(signature = (host, port=22, username="root", password=None, private_key=None, timeout=0))] fn new( - host: String, + host: &str, port: Option, - username: Option, - password: Option, - private_key: Option, + username: Option<&str>, + password: Option<&str>, + private_key: Option<&str>, timeout: Option, ) -> PyResult { // if port isn't set, use the default ssh port 22 @@ -252,29 +250,29 @@ impl Connection { .handshake() .map_err(|e| PyErr::new::(format!("{}", e)))?; // if username isn't set, try using root - let username = username.unwrap_or("root".to_string()); - let password = password.unwrap_or("".to_string()); - let private_key = private_key.unwrap_or("".to_string()); + let username = username.unwrap_or("root"); + let password = password.unwrap_or(""); + let private_key = private_key.unwrap_or(""); // if private_key is set, use it to authenticate if !private_key.is_empty() { // if a password is set, use it to decrypt the private key if !password.is_empty() { session - .userauth_pubkey_file(&username, None, Path::new(&private_key), Some(&password)) + .userauth_pubkey_file(username, None, Path::new(private_key), Some(password)) .map_err(|e| PyErr::new::(format!("{}", e)))?; } else { // otherwise, try using the private key without a passphrase session - .userauth_pubkey_file(&username, None, Path::new(&private_key), None) + .userauth_pubkey_file(username, None, Path::new(private_key), None) .map_err(|e| PyErr::new::(format!("{}", e)))?; } } else if !password.is_empty() { session - .userauth_password(&username, &password) + .userauth_password(username, password) .map_err(|e| PyErr::new::(format!("{}", e)))?; } else { // if password isn't set, try using the default ssh-agent - if session.userauth_agent(&username).is_err() { + if session.userauth_agent(username).is_err() { return Err(PyErr::new::( "Failed to authenticate with ssh-agent", )); @@ -283,10 +281,10 @@ impl Connection { Ok(Connection { session, port, - host, - username, - password, - private_key, + host: host.to_string(), + username: username.to_string(), + password: password.to_string(), + private_key: private_key.to_string(), timeout, sftp_conn: None, }) @@ -304,6 +302,7 @@ impl Connection { /// Reads a file over SCP and returns the contents. /// If `local_path` is provided, the file is saved to the local system. /// Otherwise, the contents of the file are returned as a string. + #[pyo3(signature = (remote_path, local_path=None))] fn scp_read(&self, remote_path: String, local_path: Option) -> PyResult { let (mut remote_file, stat) = self.session.scp_recv(Path::new(&remote_path)).unwrap(); match local_path { @@ -384,6 +383,7 @@ impl Connection { /// Reads a file over SFTP and returns the contents. /// If `local_path` is provided, the file is saved to the local system. /// Otherwise, the contents of the file are returned as a string. + #[pyo3(signature = (remote_path, local_path=None))] fn sftp_read(&mut self, remote_path: String, local_path: Option) -> PyResult { let mut remote_file = BufReader::new(self.sftp().open(Path::new(&remote_path)).unwrap()); match local_path { @@ -411,6 +411,7 @@ impl Connection { /// Writes a file over SFTP. /// If `remote_path` is not provided, the local file is written to the same path on the remote system. + #[pyo3(signature = (local_path, remote_path=None))] fn sftp_write(&mut self, local_path: String, remote_path: Option) -> PyResult<()> { let mut local_file = std::fs::File::open(&local_path).unwrap(); let remote_path = remote_path.unwrap_or_else(|| local_path.clone()); @@ -438,6 +439,7 @@ impl Connection { } // Copy a file from this connection to another connection + #[pyo3(signature = (source_path, dest_conn, dest_path=None))] fn remote_copy( &self, source_path: String, @@ -493,6 +495,7 @@ impl Connection { /// shell.send("pwd") /// print(shell.result.stdout) /// ``` + #[pyo3(signature = (pty=None))] fn shell(&self, pty: Option) -> PyResult { let mut channel = self.session.channel_session().unwrap(); if let Some(pty) = pty { @@ -517,7 +520,7 @@ pub struct ChannelWrapper { #[pyclass] #[derive(Clone)] -struct InteractiveShell { +pub struct InteractiveShell { channel: ChannelWrapper, pty: bool, #[pyo3(get)] @@ -545,6 +548,7 @@ impl InteractiveShell { /// Sends a command to the shell. /// If you don't want to add a newline at the end of the command, set `add_newline` to `false`. + #[pyo3(signature = (data, add_newline=None))] fn send(&mut self, data: String, add_newline: Option) -> PyResult<()> { let add_newline = add_newline.unwrap_or(true); let data = if add_newline && !data.ends_with('\n') { @@ -566,6 +570,7 @@ impl InteractiveShell { slf } + #[pyo3(signature = (_exc_type=None, _exc_value=None, _traceback=None))] fn __exit__( &mut self, _exc_type: Option<&Bound<'_, PyAny>>, @@ -601,7 +606,7 @@ impl InteractiveShell { /// * `__enter__`: Prepares the `FileTailer` for use in a `with` statement. /// * `__exit__`: Cleans up after the `FileTailer` is used in a `with` statement. #[pyclass] -struct FileTailer { +pub struct FileTailer { sftp_conn: ssh2::Sftp, #[pyo3(get)] remote_file: String, @@ -615,6 +620,7 @@ struct FileTailer { #[pymethods] impl FileTailer { #[new] + #[pyo3(signature = (conn, remote_file, init_pos=None))] fn new(conn: &Connection, remote_file: String, init_pos: Option) -> FileTailer { FileTailer { sftp_conn: conn.session.sftp().unwrap(), @@ -640,6 +646,7 @@ impl FileTailer { } // Read the contents of the remote file from a given position + #[pyo3(signature = (from_pos=None))] fn read(&mut self, from_pos: Option) -> String { let from_pos = from_pos.unwrap_or(self.last_pos); let mut remote_file = @@ -658,6 +665,7 @@ impl FileTailer { Ok(slf) } + #[pyo3(signature = (_exc_type=None, _exc_value=None, _traceback=None))] fn __exit__( &mut self, _exc_type: Option<&Bound<'_, PyAny>>, diff --git a/src/lib.rs b/src/lib.rs index c102524..82c4697 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,8 @@ mod connection; fn hussh(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; // Add the Connection class m.add_class::()?; - // m.add_class::()?; - // m.add_class::()?; + m.add_class::()?; + m.add_class::()?; m.add( "AuthenticationError", _py.get_type_bound::(),