diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58e86f7d..5ebdd9bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,9 @@ permissions: contents: write packages: write +env: + MATURIN_VERSION: ${{ vars.MATURIN_VERSION }} + jobs: style: name: style @@ -220,7 +223,7 @@ jobs: with: maturin-version: ${{ env.MATURIN_VERSION }} target: ${{ matrix.platform.target }} - args: --release --out dist ${{ matrix.build_type.maturin_args }} --features ${{ matrix.platform.allocator || '' }} + args: --release --out dist ${{ matrix.platform.target != 'aarch64' && matrix.build_type.maturin_args || '' }} --features ${{ matrix.platform.allocator || '' }} sccache: "false" - name: Upload wheels uses: actions/upload-artifact@v7 diff --git a/python/wreq/http1.py b/python/wreq/http1.py index 402527c2..b860436f 100644 --- a/python/wreq/http1.py +++ b/python/wreq/http1.py @@ -66,3 +66,9 @@ def __init__(self, **kwargs: Unpack[Params]) -> None: Crate a new Http1Options instance. """ ... + + def __str__(self) -> str: + """ + Return a string representation of the type. + """ + ... diff --git a/python/wreq/http2.py b/python/wreq/http2.py index 2917410d..ed1398c4 100644 --- a/python/wreq/http2.py +++ b/python/wreq/http2.py @@ -123,6 +123,12 @@ def __init__(self, src: int) -> None: """ ... + def __str__(self) -> str: + """ + Return a string representation of the type. + """ + ... + @final class StreamDependency: @@ -149,6 +155,12 @@ def __init__( """ ... + def __str__(self) -> str: + """ + Return a string representation of the type. + """ + ... + @final class Priority: @@ -172,6 +184,12 @@ def __init__(self, stream_id: StreamId, dependency: StreamDependency) -> None: """ ... + def __str__(self) -> str: + """ + Return a string representation of the type. + """ + ... + @final class Priorities: @@ -191,6 +209,12 @@ def __init__(self, *priority: Priority) -> None: """ ... + def __str__(self) -> str: + """ + Return a string representation of the type. + """ + ... + @final class PseudoOrder: @@ -209,6 +233,12 @@ def __init__(self, *pseudo_id: PseudoId) -> None: """ ... + def __str__(self) -> str: + """ + Return a string representation of the type. + """ + ... + @final class SettingsOrder: @@ -228,6 +258,12 @@ def __init__(self, *setting_id: SettingId) -> None: """ ... + def __str__(self) -> str: + """ + Return a string representation of the type. + """ + ... + class Params(TypedDict): """ @@ -359,3 +395,9 @@ def __init__(self, **kwargs: Unpack[Params]) -> None: Create a new Http2Options instance. """ ... + + def __str__(self) -> str: + """ + Return a string representation of the type. + """ + ... \ No newline at end of file diff --git a/src/client.rs b/src/client.rs index 8f52e751..4d96cb0f 100644 --- a/src/client.rs +++ b/src/client.rs @@ -7,7 +7,6 @@ mod param; mod query; use std::{ - fmt, net::{IpAddr, Ipv4Addr, Ipv6Addr}, sync::Arc, time::Duration, @@ -55,11 +54,7 @@ impl SocketAddr { } } -impl fmt::Display for SocketAddr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} +define_display!(SocketAddr); /// A builder for `Client`. #[derive(Default)] diff --git a/src/client/resp/http.rs b/src/client/resp/http.rs index 4c79b1a1..c5dbcda5 100644 --- a/src/client/resp/http.rs +++ b/src/client/resp/http.rs @@ -181,7 +181,7 @@ impl Response { .extensions() .get::() .map_or_else(Vec::new, |history| { - history.into_iter().cloned().map(History::from).collect() + history.into_iter().cloned().map(History).collect() }) }) } diff --git a/src/client/resp/ws.rs b/src/client/resp/ws.rs index 0e98ce93..cf4a4394 100644 --- a/src/client/resp/ws.rs +++ b/src/client/resp/ws.rs @@ -56,7 +56,7 @@ impl WebSocket { pub async fn new(response: WebSocketResponse) -> wreq::Result { let (version, status, remote_addr, local_addr, headers) = ( Version::from_ffi(response.version()), - StatusCode::from(response.status()), + StatusCode(response.status()), response.remote_addr().map(SocketAddr), response.local_addr().map(SocketAddr), HeaderMap(response.headers().clone()), diff --git a/src/client/resp/ws/msg.rs b/src/client/resp/ws/msg.rs index 68837fd6..44b2e47d 100644 --- a/src/client/resp/ws/msg.rs +++ b/src/client/resp/ws/msg.rs @@ -7,7 +7,7 @@ //! //! The `Message` type is used for sending and receiving WebSocket messages in a unified way. -use std::fmt::{self, Debug}; +use std::fmt::Debug; use bytes::Bytes; use pyo3::{ @@ -173,9 +173,4 @@ impl Message { } } -impl fmt::Display for Message { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} +define_display!(Message); diff --git a/src/cookie.rs b/src/cookie.rs index fc1c7716..78f109bf 100644 --- a/src/cookie.rs +++ b/src/cookie.rs @@ -1,4 +1,4 @@ -use std::{fmt, sync::Arc, time::SystemTime}; +use std::{sync::Arc, time::SystemTime}; use bytes::Bytes; use cookie::{Cookie as RawCookie, Expiration, ParseError, time::Duration}; @@ -181,11 +181,7 @@ impl Cookie { } } -impl fmt::Display for Cookie { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} +define_display!(Cookie); // ===== impl Cookies ===== diff --git a/src/header.rs b/src/header.rs index 7de7848b..eda7b961 100644 --- a/src/header.rs +++ b/src/header.rs @@ -1,5 +1,3 @@ -use std::fmt; - use bytes::Bytes; use pyo3::{ prelude::*, @@ -234,11 +232,7 @@ impl HeaderMap { } } -impl fmt::Display for HeaderMap { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} +define_display!(HeaderMap); impl FromPyObject<'_, '_> for HeaderMap { type Error = PyErr; @@ -347,11 +341,7 @@ impl OrigHeaderMap { } } -impl fmt::Display for OrigHeaderMap { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} +define_display!(OrigHeaderMap); impl FromPyObject<'_, '_> for OrigHeaderMap { type Error = PyErr; diff --git a/src/http.rs b/src/http.rs index bf0c8527..c9cabb23 100644 --- a/src/http.rs +++ b/src/http.rs @@ -1,5 +1,3 @@ -use std::fmt; - use pyo3::{class::basic::CompareOp, prelude::*}; define_enum!( @@ -88,14 +86,4 @@ impl StatusCode { } } -impl From for StatusCode { - fn from(status: wreq::StatusCode) -> Self { - Self(status) - } -} - -impl fmt::Display for StatusCode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} +define_display!(StatusCode); diff --git a/src/http1.rs b/src/http1.rs index 07114963..cc51e8cd 100644 --- a/src/http1.rs +++ b/src/http1.rs @@ -33,7 +33,7 @@ struct Builder { /// These options allow you to customize the behavior of HTTP/1 connections, /// such as enabling support for HTTP/0.9 responses, header case preservation, etc. #[derive(Clone)] -#[pyclass(frozen, from_py_object)] +#[pyclass(frozen, str, from_py_object)] pub struct Http1Options(pub wreq::http1::Http1Options); // ===== impl Builder ===== @@ -106,3 +106,5 @@ impl Http1Options { }) } } + +define_display!(Http1Options); diff --git a/src/http2.rs b/src/http2.rs index 7b943394..c9918fa6 100644 --- a/src/http2.rs +++ b/src/http2.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use std::{fmt::Debug, time::Duration}; use pyo3::prelude::*; @@ -50,7 +50,7 @@ define_enum!( /// /// [Section 5.1.1]: https://tools.ietf.org/html/rfc7540#section-5.1.1 #[derive(Clone)] -#[pyclass(frozen, from_py_object)] +#[pyclass(frozen, str, from_py_object)] pub struct StreamId(wreq::http2::StreamId); /// Represents a stream dependency in HTTP/2 priority frames. @@ -66,7 +66,7 @@ pub struct StreamId(wreq::http2::StreamId); /// can depend on another stream. This creates a priority hierarchy that helps /// determine the relative order in which streams should be processed. #[derive(Clone)] -#[pyclass(frozen, from_py_object)] +#[pyclass(frozen, str, from_py_object)] pub struct StreamDependency(wreq::http2::StreamDependency); /// The PRIORITY frame (type=0x2) specifies the sender-advised priority @@ -74,7 +74,7 @@ pub struct StreamDependency(wreq::http2::StreamDependency); /// including idle or closed streams. /// [Section 5.3]: #[derive(Clone)] -#[pyclass(frozen, from_py_object)] +#[pyclass(frozen, str, from_py_object)] pub struct Priority(wreq::http2::Priority); /// A collection of HTTP/2 PRIORITY frames. @@ -85,7 +85,7 @@ pub struct Priority(wreq::http2::Priority); /// sending multiple PRIORITY frames at once during connection setup or /// stream reprioritization. #[derive(Clone)] -#[pyclass(frozen, from_py_object)] +#[pyclass(frozen, str, from_py_object)] pub struct Priorities(wreq::http2::Priorities); /// Represents the order of HTTP/2 pseudo-header fields in a header block. @@ -95,7 +95,7 @@ pub struct Priorities(wreq::http2::Priorities); /// significant according to the HTTP/2 specification, and this type ensures that the correct order /// is preserved and that no duplicates are present. #[derive(Clone)] -#[pyclass(frozen, from_py_object)] +#[pyclass(frozen, str, from_py_object)] pub struct PseudoOrder(wreq::http2::PseudoOrder); /// Represents the order of settings in a SETTINGS frame. @@ -105,7 +105,7 @@ pub struct PseudoOrder(wreq::http2::PseudoOrder); /// or interoperability. `SettingsOrder` ensures that the specified order is preserved and that no /// duplicate settings are present. #[derive(Clone)] -#[pyclass(frozen, from_py_object)] +#[pyclass(frozen, str, from_py_object)] pub struct SettingsOrder(wreq::http2::SettingsOrder); /// A builder for [`Http2Options`]. @@ -183,7 +183,7 @@ struct Builder { /// This struct defines various parameters to fine-tune the behavior of an HTTP/2 connection, /// including stream management, window sizes, frame limits, and header config. #[derive(Clone)] -#[pyclass(frozen, from_py_object)] +#[pyclass(frozen, str, from_py_object)] pub struct Http2Options(pub wreq::http2::Http2Options); // ===== impl StreamId ===== @@ -206,6 +206,8 @@ impl StreamId { } } +define_display!(StreamId); + // ===== impl StreamDependency ===== #[pymethods] @@ -222,6 +224,8 @@ impl StreamDependency { } } +define_display!(StreamDependency); + // ===== impl Priority ===== #[pymethods] @@ -234,6 +238,8 @@ impl Priority { } } +define_display!(Priority); + // ===== impl Priorities ===== #[pymethods] @@ -250,6 +256,8 @@ impl Priorities { } } +define_display!(Priorities); + // ===== impl PseudoOrder ===== #[pymethods] @@ -266,6 +274,8 @@ impl PseudoOrder { } } +define_display!(PseudoOrder); + // ===== impl SettingsOrder ===== #[pymethods] @@ -282,6 +292,8 @@ impl SettingsOrder { } } +define_display!(SettingsOrder); + // ===== impl Builder ===== impl FromPyObject<'_, '_> for Builder { @@ -449,3 +461,5 @@ impl Http2Options { }) } } + +define_display!(Http2Options); diff --git a/src/macros.rs b/src/macros.rs index 0b205a30..f7a36410 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,3 +1,11 @@ +macro_rules! extract_option { + ($ob:expr, $params:expr, $field:ident) => { + if let Ok(value) = $ob.get_item(pyo3::intern!($ob.py(), stringify!($field))) { + $params.$field = value.extract()?; + } + }; +} + macro_rules! apply_option { (set_if_some, $builder:expr, $option:expr, $method:ident) => { if let Some(value) = $option.take() { @@ -117,10 +125,13 @@ macro_rules! define_enum { }; } -macro_rules! extract_option { - ($ob:expr, $params:expr, $field:ident) => { - if let Ok(value) = $ob.get_item(pyo3::intern!($ob.py(), stringify!($field))) { - $params.$field = value.extract()?; +macro_rules! define_display { + ($typed:ident) => { + impl std::fmt::Display for $typed { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Debug::fmt(&self.0, f) + } } }; } diff --git a/src/proxy.rs b/src/proxy.rs index f5a20051..1023d445 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -1,6 +1,3 @@ -use core::fmt; -use std::fmt::Debug; - use bytes::Bytes; use pyo3::{prelude::*, pybacked::PyBackedStr}; use wreq::header::HeaderValue; @@ -96,11 +93,7 @@ impl Proxy { } } -impl fmt::Display for Proxy { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} +define_display!(Proxy); fn create_proxy<'py>( py: Python<'py>, diff --git a/src/redirect.rs b/src/redirect.rs index 4ce8ab3b..9476b87c 100644 --- a/src/redirect.rs +++ b/src/redirect.rs @@ -1,7 +1,4 @@ -use std::{ - fmt::{self, Debug, Display}, - sync::Arc, -}; +use std::{fmt::Display, sync::Arc}; use pyo3::prelude::*; @@ -45,7 +42,7 @@ enum ActionKind { /// An entry in the redirect history. #[pyclass(subclass, str, frozen)] -pub struct History(wreq::redirect::HistoryEntry); +pub struct History(pub wreq::redirect::HistoryEntry); #[pymethods] impl History { @@ -129,11 +126,7 @@ impl Policy { } } -impl Display for Policy { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } -} +define_display!(Policy); // ===== impl Attempt ===== @@ -203,14 +196,4 @@ impl Display for Action { // ===== impl History ===== -impl From for History { - fn from(history: wreq::redirect::HistoryEntry) -> Self { - History(history) - } -} - -impl fmt::Display for History { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} +define_display!(History);