Upgrade from 2.x¶
3.0.0 is a breaking release: it removes the old ways instead of keeping them next to the new ones. This page lists what to change in code written for 2.x, by topic. The release history has every change with the reason for it.
A good way to upgrade:
Require Python 3.11 or newer, and
s3pathlib>=3.0.0,<4.0.0.Change the imports (section 1) and the clients (section 2); most code then runs.
Run your tests with
-W error::DeprecationWarning, to find the code that 4.0.0 will break (section 3).Read the other sections for the behavior that changed.
If you use Claude Code, copy the s3pathlib-upgrade-to-3 folder into the .claude/skills/ folder of your project and run /s3pathlib-upgrade-to-3: it scans your code and notebooks for 2.x usage, rewrites the renames, and walks you through the behavior changes.
1. Imports¶
Import every public name from s3pathlib.api. The old top level import raises an ImportError that says what to write instead:
[1]:
try:
from s3pathlib import S3Path
except ImportError as e:
print(e)
'from s3pathlib import S3Path' was removed in 3.0.0; use 'from s3pathlib.api import S3Path'
[2]:
from s3pathlib.api import S3Path
2.x |
3.x |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
removed |
Python 3.9 / 3.10 |
Python 3.11 or newer |
|
no longer dependencies: add them to your own if you use them |
2. Clients¶
The bsm argument is now s3_client, and it takes a boto3 S3 client only. The global context is now s3_context, and it only holds the default S3 client.
[3]:
p = S3Path("my-bucket", "file.txt")
try:
p.read_text(bsm=None)
except TypeError as e:
print(e)
ReadAndWriteAPIMixin.read_text() got an unexpected keyword argument 'bsm'
2.x |
3.x |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
removed: keep your own session and clients |
|
|
See Clients and Errors.
3. Paths¶
Join onto a folder. A path without a trailing / is a file, and a file has no sub path. Joining onto a file, and relative_to with a file as the base, still work in 3.x but emit a DeprecationWarning, and raise S3PathIsNotFolderError in 4.0.0. The most common case is a chain, where the middle part has no /:
[4]:
import warnings
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
try:
S3Path("my-bucket") / "folder" / "file.txt"
except DeprecationWarning:
print("deprecated: joins onto the file 'folder'")
deprecated: joins onto the file 'folder'
Any of these is right:
[5]:
S3Path("my-bucket") / "folder/" / "file.txt"
[5]:
S3Path('s3://my-bucket/folder/file.txt')
[6]:
S3Path("my-bucket").joinpath("folder", "file.txt")
[6]:
S3Path('s3://my-bucket/folder/file.txt')
2.x |
3.x |
|---|---|
|
|
|
|
|
|
|
raises |
|
raises |
|
raises |
|
a folder comes right before its content, like |
|
|
|
|
|
removed (S3 Select is closed to new customers) |
|
raises |
See Path Manipulation.
4. Metadata¶
A path’s metadata is a snapshot of one object version, taken by the call that produced the path; see Metadata and Tags.
2.x |
3.x |
|---|---|
|
they only fill an empty snapshot; call |
changing the dict of |
they return a copy |
a listed old version loaded its missing metadata from the latest version |
it loads them from its own version |
|
removed: copy the object onto itself with |
|
it returns |
5. Read, write and open¶
2.x |
3.x |
|---|---|
|
|
|
|
|
needs |
|
raises |
|
returns the new |
|
raises |
6. List¶
2.x |
3.x |
|---|---|
|
raises |
|
gives them in S3 key order, mixed |
|
raises |
a key such as |
raises |
|
each entry once, in S3 order |
|
|
7. Copy, move and delete¶
2.x |
3.x |
|---|---|
|
returns the new |
|
|
|
raises |
|
copies every key, markers included |
|
returns a new |
|
raises |
|
deletes this exact key only |
|
|
|
|
See Copy, Move and Delete and Versioning.
8. Sync¶
2.x |
3.x |
|---|---|
|
|
|
|
|
raises |
|
every |
See Sync.
9. Errors¶
2.x |
3.x |
|---|---|
|
|
|
|
|
|
|
|
|
|
Every exception of s3pathlib now inherits from exc.S3PathlibError. See Clients and Errors.
10. Helpers¶
2.x |
3.x |
|---|---|
|
|
|
|
|
|
|
removed |
tests that subclass |
|