Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI Tests
name: Tests

# Controls when the workflow will run
on:
Expand All @@ -21,6 +21,7 @@ jobs:
- "3.11"
- "3.12"
- "3.13"
- "3.14"

steps:
- uses: actions/checkout@v5
Expand Down
9 changes: 1 addition & 8 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,5 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v3
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- run: pip install mkdocs-material
- run: pip install -r ./docs/requirements.txt
- run: mkdocs gh-deploy --force
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![tests_badge](https://github.com/Jtachan/PyBackport/actions/workflows/CI.yml/badge.svg)
[![PyPI Version](https://img.shields.io/pypi/v/PyBackport)](https://pypi.org/project/PyBackport/)
[![Python Version](https://img.shields.io/badge/python-3.8+-blue)](https://www.python.org/downloads/)
[![Python Version](https://img.shields.io/badge/python-3.8%20|%203.9%20|%203.10%20|%203.11-blue)](https://www.python.org/downloads/)
[![MIT License](https://img.shields.io/github/license/Jtachan/PyBackport)](https://github.com/Jtachan/PyBackport/blob/master/LICENSE)
[![PyPI Downloads](https://img.shields.io/pypi/dm/PyBackport)](https://pypi.org/project/PyBackport/)
[![Docs](https://img.shields.io/badge/Read_the_docs-blue)](https://Jtachan.github.io/PyBackport/)
Expand Down
58 changes: 1 addition & 57 deletions docs/builtins.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,3 @@
# PyBackport: Builtins

`py_back` allows using the `builtins` module just as the original.
However, they must be imported and initialized by converting the instance:

```pycon
# Python version lower than 3.9
>>> from py_back.builtins import str

>>> my_string = str("Hello world!")
>>> print(my_string.removesuffix("!"))
Hello world
```

## str

### [_str_.**removeprefix**(prefix, /)](https://docs.python.org/3/library/stdtypes.html#str.removeprefix)

If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string:

```pycon
from py_back.builtins import str

>>> str('TestHook').removeprefix('Test')
'Hook'

>>> str('BaseTestCase').removeprefix('Test')
'BaseTestCase'
```

> Backported from python 3.9.

### [_str_.**removesuffix**(suffix, /)](https://docs.python.org/3/library/stdtypes.html#str.removesuffix)

If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string:

```pycon
from py_back.builtins import str

>>> str('MiscTests').removesuffix('Tests')
'Misc'

>>> str('TmpDirMixin').removesuffix('Tests')
'TmpDirMixin'
```

## dict

### [d | other](https://docs.python.org/3/library/stdtypes.html#typesmapping:~:text=values()%0AFalse-,d%20%7C%20other,-Create%20a%20new)

Create a new dictionary with the merged keys and values of d and other, which must both be dictionaries. The values of other take priority when d and other share keys.

> Backported from python 3.9

### [d |= other](https://docs.python.org/3/library/stdtypes.html#typesmapping:~:text=in%20version%203.9.-,d%20%7C%3D%20other,-Update%20the%20dictionary)

Update the dictionary d with keys and values from other, which may be either a [mapping](https://docs.python.org/3/glossary.html#term-mapping) or an [iterable](https://docs.python.org/3/glossary.html#term-iterable) of key/value pairs. The values of other take priority when d and other share keys.

> Backported from python 3.9
::: py_back.builtins
71 changes: 1 addition & 70 deletions docs/enum.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,3 @@
# PyBackport: Enumerations

`py_back` allows using the `enum` module just as the original, with the only difference at the import.

```python
from py_back import enum


class Number(enum.IntEnum):
"""Enumeration using the original 'IntEnum' call"""
ONE = enum.auto()
TWO = 2


class Animal(enum.StrEnum):
"""Supported original 'StrEnum' for python versions < 3.11"""
CAT = enum.auto()
DOG = "dog"
```

---

## [_enum._**IntEnum**](https://docs.python.org/3/library/enum.html#enum.IntEnum)

> Backported from version 3.11: `str()` and `format()`

_IntEnum_ is the same as _Enum_, but its members are also integers and can be used anywhere that an integer can be used.

> **Note:** [`__str__()`](https://docs.python.org/3/reference/datamodel.html#object.__str__) is now `int.__str__()` to better support the replacement of existing constants use-case.
[`__format__()`](https://docs.python.org/3/reference/datamodel.html#object.__format__) was already `int.__format__()` for that same reason.

## [_enum._**StrEnum**](https://docs.python.org/3.11/library/enum.html#enum.StrEnum)

> Backported from version 3.11

_StrEnum_ is the same as [_Enum_](https://docs.python.org/3.12/library/enum.html#enum.Enum), but its members are also strings and can be used in most of the same places that a string can be used.

```pycon
>>> from py_back import enum
>>> class Animal(enum.StrEnum):
... CAT = enum.auto()
... DOG = "dog"
...
>>> Animal.CAT
cat
>>> Animal.DOG.title()
'Dog'
>>> Animal.CAT == "cat"
True
>>> Animal.CAT + Animal.DOG
'catdog'
>>> " and ".join(list(Animals))
'cat and dog'
```

**Note**: Using [`auto`](https://docs.python.org/3.12/library/enum.html#enum.auto) results in the lower-cased member name as the value.

## [_enum._**IntFlag**](https://docs.python.org/3/library/enum.html#enum.IntFlag)

> Backported from version 3.11: `str()` and `format()`

IntFlag is the same as Flag, but its members are also integers and can be used anywhere that an integer can be used.

> **None:** [`__str__()`](https://docs.python.org/3/reference/datamodel.html#object.__str__) is now `int.__str__()` to better support the replacement of existing constants use-case.
[`__format__()`](https://docs.python.org/3/reference/datamodel.html#object.__format__) was already `int.__format__()` for that same reason.

## [_enum._**ReprEnum**](https://docs.python.org/3/library/enum.html#enum.ReprEnum)

> Backported from version 3.11

_ReprEnum_ uses the repr() of Enum, but the str() of the mixed-in data type.
The class is used for any builtin type enum.
::: py_back.enum
6 changes: 1 addition & 5 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
_Python Backport_ main goal is to backport functionalities from newer python releases.
It allows using its modules just as the original ones, with the only difference at the import.

Any backported (or experimental) functionality can be imported with the module `py_back`.
Any backported functionality can be imported with the module `py_back`.

```python
from py_back import enum
Expand Down Expand Up @@ -46,7 +46,3 @@ Alternatively, any pip-install-git command can be called over the repository.
```commandline
pip install git+https://github.com/Jtachan/PyBackport.git
```

---
## Modules index
- [enum](enum.md)
3 changes: 3 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mkdocs-material
mkdocstrings-python
ruff
41 changes: 36 additions & 5 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ nav:
- Enum: "enum.md"

theme:
name: material
name: readthedocs
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
Expand Down Expand Up @@ -45,7 +45,38 @@ markdown_extensions:
permalink: true
plugins:
- search

extra:
version:
provider: mike
- autorefs
- mkdocstrings:
handlers:
python: # https://mkdocstrings.github.io/python/usage/
options:
# General options
show_bases: true
show_source: false
# Headings
heading_level: 2
parameter_headings: true
show_root_heading: true
show_root_full_path: true
show_root_members_full_path: false
show_category_heading: false
# Members
inherited_members: false
members_order: source
# filters:
# - "!^_.*$"
group_by_category: true
show_submodules: true
# Docstrings
docstring_style: numpy
docstring_section_style: table
merge_init_into_class: true
# Signatures
annotations_path: source
line_length: 88
modernize_annotations: true
overloads_only: true
show_signature: true
show_signature_annotations: true
separate_signature: true
show_overloads: true
15 changes: 13 additions & 2 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
output-format = "concise"
line-length = 120
line-length = 88

[format]
docstring-code-format = true
Expand Down Expand Up @@ -49,11 +49,22 @@ ignore = [
"PLR0917", # too-many-positional-arguments
"PLC1901", # compare-to-empty-string
"PLR2004", # magic-value-comparison
"RUF067", # non empty init module
]

[lint.per-file-ignores]
"tests/*" = [
"A004","PLC0415",
"A004", # Shadowing builtins name
]
"src/**/builtins/*" = [
"A001", # Builtin variable shadowing
"A004", # Shadowing a Python builtin through import
"N801", # Invalid class name (not CamelCase)
]
"src/**/__init__.py" = [
"F401", # Imported but unused (false positive)
"F403", # Unable to detect undefined names wiht `from ... import *`
"F405", # Unable to detect (un)defined names due to `from ... import *`
]

[lint.flake8-annotations]
Expand Down
15 changes: 13 additions & 2 deletions src/py_back/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
"""Python package to port functionalities from newer python versions back to older ones."""
"""Backporting functionalities from newer python versions back to older ones.

__version__ = "0.3.0-1"
The software was created by Jtachan and with MIT license.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""

__version__ = "0.3.1"
36 changes: 23 additions & 13 deletions src/py_back/builtins/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
"""Module to backport 'builtins' classes depending on the system python."""
"""Module to backport 'builtins' classes depending on the system python.

`py_back` allows using the `builtins` module just as the original.

```pycon
# Python version lower than 3.9
>>> from py_back.builtins import str
>>> my_string = str("Hello world!")
>>> print(my_string.removesuffix("!"))
Hello world
```

!!! Note
Python builtins don't require to be imported, but the backported builtins do not
follow this rule. This results in the inconvenience that backported instances must
be defined with the constructor provided by `py_back`, even if they interact with
other not backported builtins.
"""

import sys
import warnings
from builtins import * # noqa: F403

__all__ = [name for name in dir() if not name.startswith("_")]
__all__ = ["dict", "str"]

from builtins import *

if sys.version_info >= (3, 9):
warnings.warn(
"Importing from the standard builtins library: dict, str\n"
"Consider 'from builtins import ...' instead of 'from py_back.builtins "
"import ...'",
stacklevel=2,
)
else:
from ._back_builtins import dict, str # noqa: F401, A004
if sys.version_info < (3, 9):
from ._back_builtins import dict, str
Loading