API reference
pendle
Typed Python client for the Pendle Finance v2 API.
PendleAPIError
Bases: PendleError
Raised when the Pendle API returns an error response.
The Pendle API signals errors with a non-2xx HTTP status and a JSON body of
the shape {"message", "error", "statusCode"} (e.g.
400 "Invalid receiver address" or 404 "Not Found").
Attributes:
| Name | Type | Description |
|---|---|---|
message |
The API's |
|
error |
The API's short |
|
status_code |
The HTTP status code of the response. |
Example::
from pendle import PendleClient, PendleAPIError
with PendleClient() as client:
try:
client.get_market(1, "0xnot-a-market")
except PendleAPIError as exc:
print(exc.status_code, exc.message) # 404 'Not Found'
PendleError
Bases: Exception
Base class for all errors raised by this library.
Catch this to handle any failure originating from pendle (currently just
:class:PendleAPIError). Network-level failures from the underlying
httpx client propagate as httpx exceptions and are not wrapped.
AsyncPendleClient
Bases: _BaseClient
Asynchronous counterpart of :class:PendleClient.
Exposes the same endpoints as coroutines, backed by httpx.AsyncClient.
Use it as an async context manager so the connection pool is closed for you;
otherwise call :meth:aclose.
Example::
import asyncio
from pendle import AsyncPendleClient
async def main():
async with AsyncPendleClient() as client:
markets = await client.get_markets(1, limit=5)
print(markets.total)
asyncio.run(main())
__init__(base_url=DEFAULT_BASE_URL, *, timeout=30.0, client=None)
Create an asynchronous client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str
|
Pendle Core API base URL. Defaults to the public endpoint
(:data: |
DEFAULT_BASE_URL
|
timeout
|
float
|
Per-request timeout in seconds, applied when this client
creates its own |
30.0
|
client
|
Optional[AsyncClient]
|
An existing |
None
|
aclose()
async
Close the underlying async HTTP client.
No-op when an external httpx.AsyncClient was injected via the
constructor (the caller owns that client's lifecycle).
__aenter__()
async
Enter the async runtime context and return this client.
__aexit__(exc_type, exc, tb)
async
Exit the async runtime context, closing the client via :meth:aclose.
get_markets(chain_id, *, limit=None, skip=None)
async
Fetch the (paginated) list of markets on a chain.
Async equivalent of :meth:PendleClient.get_markets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
limit
|
Optional[int]
|
Page size. Omit to use the API default. |
None
|
skip
|
Optional[int]
|
Number of markets to skip (offset pagination). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
MarketsResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API returns an error. |
get_market(chain_id, address)
async
Fetch detail for a single market.
Async equivalent of :meth:PendleClient.get_market.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
address
|
str
|
Market (LP) contract address. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
Market
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the market is unknown or the address is malformed. |
get_active_markets(chain_id)
async
Fetch the chain's active markets with liquidity and APY metrics.
Async equivalent of :meth:PendleClient.get_active_markets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
Returns:
| Name | Type | Description |
|---|---|---|
An |
ActiveMarketsResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API returns an error. |
get_assets(chain_id)
async
Fetch metadata for every asset Pendle knows about on a chain.
Async equivalent of :meth:PendleClient.get_assets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
Returns:
| Type | Description |
|---|---|
List[Asset]
|
A list of :class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API returns an error. |
get_historical_data(chain_id, address, *, time_frame='day', timestamp_start=None, timestamp_end=None)
async
Fetch a market's APY/TVL time series.
Async equivalent of :meth:PendleClient.get_historical_data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
address
|
str
|
Market (LP) contract address. |
required |
time_frame
|
str
|
|
'day'
|
timestamp_start
|
Optional[str]
|
ISO-8601 start of the range (optional). |
None
|
timestamp_end
|
Optional[str]
|
ISO-8601 end of the range (optional). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
HistoricalDataResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API returns an error. |
convert(chain_id, *, receiver, slippage, inputs, outputs, enable_aggregator=None, aggregators=None, redeem_rewards=None, use_limit_order=None, need_scale=None, additional_data=None, extra=None)
async
Build calldata for any Pendle action via the universal convert endpoint.
Async equivalent of :meth:PendleClient.convert; see that method for
full argument and return documentation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
receiver
|
str
|
Address that receives the output. |
required |
slippage
|
float
|
Max slippage fraction in |
required |
inputs
|
List[Dict[str, str]]
|
Input tokens as |
required |
outputs
|
List[str]
|
Output token addresses. |
required |
enable_aggregator
|
Optional[bool]
|
Allow an external swap aggregator. |
None
|
aggregators
|
Optional[List[str]]
|
Restrict to these aggregator names. |
None
|
redeem_rewards
|
Optional[bool]
|
Also redeem accrued rewards. |
None
|
use_limit_order
|
Optional[bool]
|
Use the limit-order book (API default |
None
|
need_scale
|
Optional[bool]
|
Set |
None
|
additional_data
|
Optional[str]
|
Comma-separated extra fields, e.g. |
None
|
extra
|
Optional[Dict[str, Any]]
|
Additional raw body fields, merged last. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
swap(chain_id, *, token_in, amount_in, token_out, receiver, slippage, **kwargs)
async
Build calldata to swap amount_in of token_in into token_out.
Async equivalent of :meth:PendleClient.swap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
token_in
|
str
|
Address of the token you are spending. |
required |
amount_in
|
str
|
Amount of |
required |
token_out
|
str
|
Address of the token you want to receive. |
required |
receiver
|
str
|
Address that receives |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
add_liquidity(chain_id, *, market, token_in, amount_in, receiver, slippage, **kwargs)
async
Build calldata to add liquidity to market with token_in.
Async equivalent of :meth:PendleClient.add_liquidity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
market
|
str
|
Market (LP) contract address — the LP token you receive. |
required |
token_in
|
str
|
Address of the token you are depositing. |
required |
amount_in
|
str
|
Amount of |
required |
receiver
|
str
|
Address that receives the LP token. |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
remove_liquidity(chain_id, *, market, amount_in, token_out, receiver, slippage, **kwargs)
async
Build calldata to remove liquidity from market into token_out.
Async equivalent of :meth:PendleClient.remove_liquidity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
market
|
str
|
Market (LP) contract address — the LP token you burn. |
required |
amount_in
|
str
|
Amount of LP token to remove, in wei (decimal string). |
required |
token_out
|
str
|
Address of the token you want to receive. |
required |
receiver
|
str
|
Address that receives |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
mint_py(chain_id, *, token_in, amount_in, pt, yt, receiver, slippage, **kwargs)
async
Build calldata to mint PT + YT from token_in.
Async equivalent of :meth:PendleClient.mint_py.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
token_in
|
str
|
Address of the token you are depositing (SY or underlying). |
required |
amount_in
|
str
|
Amount of |
required |
pt
|
str
|
Principal-token address to receive. |
required |
yt
|
str
|
Yield-token address to receive. |
required |
receiver
|
str
|
Address that receives the PT and YT. |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
redeem_py(chain_id, *, pt, yt, amount_in, token_out, receiver, slippage, **kwargs)
async
Build calldata to redeem PT + YT back into token_out.
Async equivalent of :meth:PendleClient.redeem_py.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
pt
|
str
|
Principal-token address to redeem. |
required |
yt
|
str
|
Yield-token address to redeem. |
required |
amount_in
|
str
|
Amount of each of PT and YT to redeem, in wei. |
required |
token_out
|
str
|
Address of the token you want to receive. |
required |
receiver
|
str
|
Address that receives |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
PendleClient
Bases: _BaseClient
Synchronous client for the Pendle Finance v2 API.
Wraps the public, keyless endpoints: market/asset data, APY history, and the
universal convert calldata endpoint (with ergonomic swap /
add_liquidity / remove_liquidity / mint_py / redeem_py
wrappers). Every method raises :class:PendleAPIError on an API error.
Use it as a context manager so the underlying httpx connection pool is
closed for you; otherwise call :meth:close when done.
Example::
from pendle import PendleClient
from pendle.constants import ChainId
with PendleClient() as client:
markets = client.get_active_markets(ChainId.ETHEREUM)
for m in markets.markets[:5]:
print(m.name, m.details.implied_apy)
__init__(base_url=DEFAULT_BASE_URL, *, timeout=30.0, client=None)
Create a synchronous client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str
|
Pendle Core API base URL. Defaults to the public endpoint
(:data: |
DEFAULT_BASE_URL
|
timeout
|
float
|
Per-request timeout in seconds, applied when this client
creates its own |
30.0
|
client
|
Optional[Client]
|
An existing |
None
|
close()
Close the underlying HTTP client.
No-op when an external httpx.Client was injected via the constructor
(the caller owns that client's lifecycle).
__enter__()
Enter the runtime context and return this client.
__exit__(exc_type, exc, tb)
Exit the runtime context, closing the client via :meth:close.
get_markets(chain_id, *, limit=None, skip=None)
Fetch the (paginated) list of markets on a chain.
Calls GET /v1/{chainId}/markets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (an |
required |
limit
|
Optional[int]
|
Page size. Omit to use the API default. |
None
|
skip
|
Optional[int]
|
Number of markets to skip (offset pagination). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
MarketsResponse
|
class: |
MarketsResponse
|
page of :class: |
|
MarketsResponse
|
SY and LP token legs). |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API returns an error. |
get_market(chain_id, address)
Fetch detail for a single market.
Calls GET /v1/{chainId}/markets/{address}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
address
|
str
|
Market (LP) contract address. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
Market
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the market is unknown or the address is malformed. |
get_active_markets(chain_id)
Fetch the chain's active markets with liquidity and APY metrics.
Calls GET /v1/{chainId}/markets/active.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
Returns:
| Name | Type | Description |
|---|---|---|
An |
ActiveMarketsResponse
|
class: |
ActiveMarketsResponse
|
APY and liquidity under |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API returns an error. |
get_assets(chain_id)
Fetch metadata for every asset Pendle knows about on a chain.
Calls GET /v1/{chainId}/assets/all (which returns a bare array).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
Returns:
| Type | Description |
|---|---|
List[Asset]
|
A list of :class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API returns an error. |
get_historical_data(chain_id, address, *, time_frame='day', timestamp_start=None, timestamp_end=None)
Fetch a market's APY/TVL time series.
Calls GET /v3/{chainId}/markets/{address}/historical-data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
address
|
str
|
Market (LP) contract address. |
required |
time_frame
|
str
|
Sample granularity: |
'day'
|
timestamp_start
|
Optional[str]
|
ISO-8601 start of the range (optional). |
None
|
timestamp_end
|
Optional[str]
|
ISO-8601 end of the range (optional). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
HistoricalDataResponse
|
class: |
HistoricalDataResponse
|
class: |
|
HistoricalDataResponse
|
APY and TVL). |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API returns an error. |
convert(chain_id, *, receiver, slippage, inputs, outputs, enable_aggregator=None, aggregators=None, redeem_rewards=None, use_limit_order=None, need_scale=None, additional_data=None, extra=None)
Build calldata for any Pendle action via the universal convert endpoint.
Calls POST /v3/sdk/{chainId}/convert. Pendle infers the action
(swap, add/remove-liquidity, mint/redeem PY, etc.) from the kinds of the
inputs and outputs tokens. For common actions prefer the
higher-level :meth:swap, :meth:add_liquidity,
:meth:remove_liquidity, :meth:mint_py and :meth:redeem_py wrappers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
receiver
|
str
|
Address that receives the output (must be a valid address;
the API rejects placeholders such as |
required |
slippage
|
float
|
Max slippage as a fraction in |
required |
inputs
|
List[Dict[str, str]]
|
Input tokens as |
required |
outputs
|
List[str]
|
Output token addresses (the asset(s) you want to receive). |
required |
enable_aggregator
|
Optional[bool]
|
Allow an external swap aggregator for tokens that can't be natively converted. |
None
|
aggregators
|
Optional[List[str]]
|
Restrict to these aggregator names (see
|
None
|
redeem_rewards
|
Optional[bool]
|
Also redeem accrued rewards (for redeem actions). |
None
|
use_limit_order
|
Optional[bool]
|
Use the limit-order book when converting (API
default is |
None
|
need_scale
|
Optional[bool]
|
Set |
None
|
additional_data
|
Optional[str]
|
Comma-separated extra fields to compute, e.g.
|
None
|
extra
|
Optional[Dict[str, Any]]
|
Additional raw body fields, merged last (escape hatch). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
ConvertResponse
|
|
|
ConvertResponse
|
calldata performs the action. |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request (bad token pair, invalid receiver, etc.). |
Example
Swap 1 SY for PT on Ethereum::
resp = client.convert(
1,
receiver="0xYourAddress",
slippage=0.01,
inputs=[{"token": SY, "amount": "1000000000000000000"}],
outputs=[PT],
)
tx = resp.routes[0].tx # sign & broadcast
print(resp.action) # "swap"
swap(chain_id, *, token_in, amount_in, token_out, receiver, slippage, **kwargs)
Build calldata to swap amount_in of token_in into token_out.
Thin wrapper over :meth:convert with a single input and output (e.g.
token -> PT, PT -> token, token -> YT). Extra keyword args are forwarded
to :meth:convert (e.g. enable_aggregator=True).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
token_in
|
str
|
Address of the token you are spending. |
required |
amount_in
|
str
|
Amount of |
required |
token_out
|
str
|
Address of the token you want to receive. |
required |
receiver
|
str
|
Address that receives |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
add_liquidity(chain_id, *, market, token_in, amount_in, receiver, slippage, **kwargs)
Build calldata to add liquidity to market with token_in.
Thin wrapper over :meth:convert whose output is the market (LP) token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
market
|
str
|
Market (LP) contract address — the LP token you receive. |
required |
token_in
|
str
|
Address of the token you are depositing. |
required |
amount_in
|
str
|
Amount of |
required |
receiver
|
str
|
Address that receives the LP token. |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
remove_liquidity(chain_id, *, market, amount_in, token_out, receiver, slippage, **kwargs)
Build calldata to remove liquidity from market into token_out.
Thin wrapper over :meth:convert whose input is the market (LP) token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
market
|
str
|
Market (LP) contract address — the LP token you burn. |
required |
amount_in
|
str
|
Amount of LP token to remove, in wei (decimal string). |
required |
token_out
|
str
|
Address of the token you want to receive. |
required |
receiver
|
str
|
Address that receives |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
mint_py(chain_id, *, token_in, amount_in, pt, yt, receiver, slippage, **kwargs)
Build calldata to mint PT + YT from token_in.
Thin wrapper over :meth:convert whose outputs are the PT and YT.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
token_in
|
str
|
Address of the token you are depositing (SY or underlying). |
required |
amount_in
|
str
|
Amount of |
required |
pt
|
str
|
Principal-token address to receive. |
required |
yt
|
str
|
Yield-token address to receive. |
required |
receiver
|
str
|
Address that receives the PT and YT. |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
redeem_py(chain_id, *, pt, yt, amount_in, token_out, receiver, slippage, **kwargs)
Build calldata to redeem PT + YT back into token_out.
Thin wrapper over :meth:convert whose inputs are equal amounts of PT
and YT.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain_id
|
int
|
Chain id (int or |
required |
pt
|
str
|
Principal-token address to redeem. |
required |
yt
|
str
|
Yield-token address to redeem. |
required |
amount_in
|
str
|
Amount of each of PT and YT to redeem, in wei. |
required |
token_out
|
str
|
Address of the token you want to receive (SY or underlying). |
required |
receiver
|
str
|
Address that receives |
required |
slippage
|
float
|
Max slippage fraction in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ConvertResponse
|
class: |
Raises:
| Type | Description |
|---|---|
PendleAPIError
|
If the API rejects the request. |
ActiveMarket
Bases: _Model
An entry from GET /v1/{chainId}/markets/active.
Unlike :class:Market, the pt/yt/sy fields here are composite
id strings ('<chainId>-<address>'), not nested token objects, and the
APY/liquidity figures live under :attr:details.
ActiveMarketsResponse
Bases: _Model
Response of GET /v1/{chainId}/markets/active.
Asset
Bases: _Model
Asset metadata from GET /v1/{chainId}/assets/all (a bare array of these).
ConvertResponse
Bases: _Model
Response of POST /v3/sdk/{chainId}/convert.
Pendle infers the :attr:action (swap, add-liquidity,
remove-liquidity, mint-py, redeem-py, etc.) from the input and
output token kinds, and returns the calldata as one or more
:attr:routes, plus the ERC-20 :attr:required_approvals you must grant
before broadcasting.
Example::
resp = client.swap(
chain_id=1, token_in="0x...sy", token_out="0x...pt",
amount_in="1000000000000000000", receiver="0xYou", slippage=0.01,
)
for approval in resp.required_approvals:
... # approve approval.token for approval.amount
for route in resp.routes:
... # sign & broadcast route.tx
ConvertRoute
Bases: _Model
One executed route of a convert: its tx, outputs, and economics.
A convert may decompose into multiple routes; each carries its own
:attr:tx to broadcast in order.
HistoricalDataPoint
Bases: _Model
One time-series sample of a market's APYs and TVL.
HistoricalDataResponse
Bases: _Model
Response of GET /v3/{chainId}/markets/{address}/historical-data.
Market
Bases: _Model
A Pendle market from GET /v1/{chainId}/markets (and /markets/{address}).
Bundles the four token legs of a Pendle market: the principal token
(:attr:pt), yield token (:attr:yt), standardized-yield wrapper
(:attr:sy), and the LP token (:attr:lp).
MarketsResponse
Bases: _Model
Paginated response of GET /v1/{chainId}/markets.
Token
Bases: _Model
A Pendle token leg (PT / YT / SY / LP), as embedded in a market.
The base_type discriminates the kind: "PT", "YT", "SY",
"PENDLE_LP", or "GENERIC" for plain assets.
TokenAmount
Bases: _Model
A token address paired with an amount in wei (decimal string).
Transaction
Bases: _Model
An unsigned EVM transaction to broadcast.
value is only present when the input is the chain's native token; it is
None otherwise.