typediter


Nametypediter JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryType-safe versions of Python's builtin iterables
upload_time2024-08-16 17:42:48
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseMIT License Copyright (c) 2024 Didier Martin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 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.
keywords type safe type-safe type-hints type-checking typed iterable iterables list tuple set frozenset
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # TypedIter
**The Type-Safe Versions of Python Built-in Iterables** 

![](https://img.shields.io/badge/Python->=_3.11-royalblue)
![](https://img.shields.io/badge/License-MIT-seagreen)


This package aims to provide type-safe versions of some python built-in iterables ( `list`, `tuple`, `set`, `frozenset` ), those can be used exactly in the same way as their built-in equivalents, except that a type of item is provided at instance creation (`i_type`), and breaking that type restriction will raise a custom `TypeRestrictionError`.
(The type-checking is executed at runtime.)




## Two Flavours of Type Safety

For each built-in iterable, this package provides 2 type-safe versions.

| Built-in class | Light version       | Complete version |
| -------------- | ------------------- | ---------------- |
| `list`         | `TypedList_lt`      | `TypedList`      |
| `tuple`        | `TypedTuple_lt`     | `TypedTuple`     |
| `set`          | `TypedSet_lt`       | `TypedSet`       |
| `frozenset`    | `TypedFrozenset_lt` | `TypedFrozenset` |

**Note:** The 'complete' versions inherits from their 'light' version equivalents. 

### Light

The "light" version (*class name ending in* **_lt**) 
only ensures the type safety of the current instance.

- Mutating methods that could insert incompatible items are overridden, they perform type checks, and will fail instead of inserting an incompatible item.
- Non-Mutating methods are all handled by the built-in class the typed iterable is based on.
So for example, a `TypedList_lt` addition, is not type-checked, and will return a built-in `list`. 
The only exception being the `copy()` method, which is overridden to return a new instance of the current typed iterable class.

The aim is to provide type safety for the current instance only, 
while avoiding slowing down operations that don't directly affect it.
This makes those operations faster, and more permissive,
but their results are downgraded to built-in iterables.



### Complete

The "complete" version ensures the type safety of the current instance, and type safety of new instances generated from it.

- Mutating methods that could insert incompatible items are overridden, they perform type checks, and will fail instead of inserting an incompatible item.
- Non-Mutating methods that used to return an instance of the same class are overridden to return an instance of the current typed iterable, for example, `list` addition returns a new `list`, so `TypedList` addition returns a new `TypedList`.
So those operations will perform type checks and fail instead of inserting an incompatible item in the operation result.

The aim is to be coherent with the built-in iterables the classes are based on. 
The downside is that it makes those operations heavier and less permissive.




## Installation

```SHELL
pip install typediter
```




## Instance Creation

```PYTHON
from typediter import (
    TypedList,
    TypedSet,
)

# Creating a list that allows only int items
# -> Any iterable can be used as initialisation value
int_list = TypedList( (1, 2, 3), i_type=int )

# Creating an empty set that allows only str items
# -> Without initialisation value, we create an empty iterable
str_set = TypedSet( i_type=str )
```

- *If one of the given items isn't an instance of the expected `i_type` the initialisation will fail with `TypeRestrictionError`.*
- *If a non-iterable initial value is given, the initialisation will fail with `IterableExpectedError`.*
- *If `i_type` is not an instance of `type`, the initialisation will fail with an `InvalidTypeRestrictionError`.*
- *For `set`/`frozenset` based classes, if `i_type` is not a hashable type, the initialisation will fail with an `InvalidTypeRestrictionError`.*




## Operations

All operations and methods defined in the built-in version are supported, and can be used in the same way.



### Mutating Operations

For both 'light' and 'complete' versions, any operation directly modifying the instance, that could insert an incompatible item is type-checked.

```PYTHON
from typediter import (
    TypedList,
    TypedSet,
)

# Creating type-restricted iterables
int_list = TypedList( (1, 2, 3), i_type=int )
int_set = TypedSet( (1, 2, 3), i_type=int )

# Same operations and methods as the built-in equivalent
int_list.append( 4 )
int_list[2] = 42
print( int_list ) # -> List[int]:[1, 2, 42, 4]

int_set.add( 4 )
int_set.update({ 5, 6 })
print( int_set ) # -> Set[int]:{1, 2, 3, 4, 5, 6}
```

- *Trying to insert an incompatible item will fail with `TypeRestrictionError`.*
- *Type-checked operations expecting an iterable, but called with something else, will fail with `IterableExpectedError`.*
- *Exceptions that are usually raised for a given operation (such as `TypeError`) can still be raised by the underlying built-in class.*



### Non-mutating operations: Light *vs* Complete versions

Operations that return a new instance and don't directly affect the current instance are handled differently between the 'light' and 'complete' versions of typed iterables:

- **light versions:** all non-mutating operations are handled by the base built-in iterable (*except `copy()` which is overridden to return a new instance of the current typed iterable class*).
- **complete versions:** non-mutating operations that return a new instance of the same class are overridden to return a new instance of the current typed iterable (for example, `list` addition returns a new `list`, so `TypedList` addition returns a new `TypedList`)

```PYTHON
# Importing both 'complete' and 'light' versions of typed list
from typediter import TypedList_lt, TypedList

# Creating instances
light_str_list = TypedList_lt( ('A', 'B', 'C'), i_type=str )
complete_str_list = TypedList( ('A', 'B', 'C'), i_type=str )

# Operation handled by the light version:
# (Not type-restricted, returns a new built-in list)
light_result = light_str_list + [ 1, 2, 3 ]
type( light_result ) # -> list

# Operation handled by the complete version:
# (Type-restricted, returns a new typed iterable)
complete_result = complete_str_list + [ 'D', 'E', 'F' ]
type( complete_result ) # -> TypedList

complete_result = complete_str_list + [ 1, 2, 3 ] # -> Fails with TypeRestrictionError
```
**for both versions:**
- *Type-checked operations expecting an iterable, but called with something else, will fail with `IterableExpectedError`.*
- *Exceptions that are usually raised for a given operation (such as `TypeError`) can still be raised by the underlying built-in class.*

**for the complete version:**
- *Trying to insert an incompatible item in the resulting instance will fail with `TypeRestrictionError`.*
- *Order matters in operations using operators ( + - ^ | ...), the first object has priority to handle the operation, if the 'complete' typed iterable is not first, the operation will be handled by the other object and type safety isn't enforced, for example: `[1,2,3]+complete_str_list` will return a built-in list and will not fail.*
- *Operations are type-restricted only if the operation is about to introduce an incompatible item in the result, operations that cannot introduce an item of the wrong type in the result aren't checked at all (like `set` `difference()` method).*




## Utility Functions

All utility functions can be imported from `typediter.utils`

```PYTHON
from typediter.utils import get_converter_func
```


### `get_converter_func( typed_iterable_cls, *, i_type )`

Returns a function converting an iterable to an instance of the given typed iterable class, restricted to the specified type (`i_type`).

**Remark:** if we create a converter for something else than a typed iterable class, or with an invalid `i_type`, it will only fail when trying to convert a value, not when creating the converter.

```PYTHON
from typediter import TypedList
from typediter.utils import get_converter_func

# Getting a function converting an iterable to a TypedList[str]
to_str_list = get_converter_func( TypedList, i_type=str )

# Converting an iterable to a typed list
str_list = to_str_list( ['A', 'B', 'C'] )

type( str_list ) # -> TypedList
```

- *The converter getter function is only meant to be used with typed iterable classes.*
- *If the iterable we are trying to convert, contains items that are not instances of `i_type`, the conversion will fail with `TypeRestrictionError`.*
- *If the value being converted is not an iterable, the conversion will fail with `IterableExpectedError`.*
- *If `i_type` is not an instance of `type`, the conversion will fail with an `InvalidTypeRestrictionError`.*
- *When converting to `set`/`frozenset` based classes, if `i_type` is not a hashable type, the conversion will fail with an `InvalidTypeRestrictionError`.*



### `get_typesafe_tuple_converter_func( i_type )`

Returns a function converting an iterable to a built-in `tuple`, restricted to the specified type (`i_type`).

**Remark:** if we create a converter with an invalid `i_type`, it will only fail when trying to convert a value, not when creating the converter.

```PYTHON
from typediter.utils import get_typesafe_tuple_converter_func

# Getting the converter functions
to_str_builtin_tuple = get_typesafe_tuple_converter_func( str )

# Converting iterables to type-safe tuple
str_builtin_tuple = to_str_builtin_tuple( ['A', 'B', 'C'] )

type( str_builtin_tuple ) # -> tuple
```

- *If the iterable we are trying to convert, contains items that are not instances of `i_type`, the conversion will fail with `TypeRestrictionError`.*
- *If the value being converted is not an iterable, the conversion will fail with `IterableExpectedError`.*
- *If `i_type` is not an instance of `type`, the conversion will fail with an `InvalidTypeRestrictionError`.*



### `get_typesafe_frozenset_converter_func( i_type )`

Returns a function converting an iterable to a built-in `frozenset`, restricted to the specified type (`i_type`).

**Remark:** if we create a converter with an invalid `i_type`, it will only fail when trying to convert a value, not when creating the converter.

```PYTHON
from typediter.utils import get_typesafe_frozenset_converter_func

# Getting the converter functions
to_str_builtin_frozenset = get_typesafe_frozenset_converter_func( str )

# Converting iterables to type-safe frozenset
str_builtin_frozenset = to_str_builtin_frozenset( ['A', 'B', 'C'] )

type( str_builtin_frozenset ) # -> frozenset
```

- *If the iterable we are trying to convert, contains items that are not instances of `i_type`, the conversion will fail with `TypeRestrictionError`.*
- *If the value being converted is not an iterable, the conversion will fail with `IterableExpectedError`.*
- *If `i_type` is not an instance of `type` or if it's not a hashable type, the conversion will fail with an `InvalidTypeRestrictionError`.*



### `filter_items( items, *, i_type )`

Function taking an iterable and a type, and returning a tuple containing only the items that are instances of that type.

```PYTHON
from typediter.utils import filter_items

filtered_items = filter_items( [1, 'A', 2, 'B'], i_type=int )

print( filtered_items ) # -> ( 1, 2 )
```



### `is_typediter_instance( obj )`

Function returning True if the given argument is an instance of a typed iterable

```PYTHON
from typediter import TypedList, TypedTuple
from typediter.utils import is_typediter_instance

# Creating typed iterable instances
str_list = TypedList( ('A', 'B', 'C'), i_type=str )
str_tuple = TypedTuple( ('A', 'B', 'C'), i_type=str )

is_typediter_instance( str_list ) # -> True
is_typediter_instance( str_tuple ) # -> True

is_typediter_instance( TypedList ) # -> False
is_typediter_instance( ['A', 'B', 'C'] ) # -> False
```



### `is_typediter_subclass( cls )`

Function returning True if the given argument is a typed iterable class

```PYTHON
from typediter import TypedList, TypedTuple
from typediter.utils import is_typediter_subclass

is_typediter_subclass( TypedList ) # -> True
is_typediter_subclass( TypedTuple ) # -> True

is_typediter_subclass( list ) # -> False
```




## Custom Exceptions

All exceptions can be imported from `typediter.exceptions`.

```PYTHON
from typediter.exceptions import TypeRestrictionError
```



### `TypeRestrictionError`
Inherits from `Exception`

Exception raised to prevent operations from breaking type restriction.



### `OperationError` 
Inherits from `Exception`

Base exception for errors related to mishandled type-checked operations.



### `InvalidTypeRestrictionError` 
Inherits from `OperationError`

Exception raised if the type restriction (`i_type`) is invalid.

Either because it's not a type, 
or because the type restriction is applied to a `set`/`frozenset` based class
and the provided `i_type` is not hashable.



### `IterableExpectedError` 
Inherits from `OperationError`

Exception raised when a type-checked operation expecting an iterable instance receives something else.




## Type hinting utils

Some utility types are made available for type hinting and can be imported from `typediter.types`

```PYTHON
from typediter.types import TypedIterable_T

foo: TypedIterable_T = ...
bar: TypedIterable_T[str] = ...
```

### `TypedIterable_T`

Any instance of a typed iterable class:
- `TypedList_lt` / `TypedList`
- `TypedTuple_lt` / `TypedTuple`
- `TypedSet_lt` / `TypedSet`
- `TypedFrozenset_lt` / `TypedFrozenset`



### `MutableTypedIterable_T`

An instance of a mutable typed iterable class:
- `TypedList_lt` / `TypedList`
- `TypedSet_lt` / `TypedSet`



### `FrozenTypedIterable_T`

An instance of an immutable typed iterable class:
- `TypedTuple_lt` / `TypedTuple`
- `TypedFrozenset_lt` / `TypedFrozenset`



## Tests

This package was tested with python **3.11.2**, **3.11.9** and **3.12.5**, on Debian 12.

It won't work with any version below **3.11**.

### Running Tests

- Download the repo
- `cd` to the root package directory
- run following command

```SHELL
python -m unittest tests
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "typediter",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": "type safe, type-safe, type-hints, type-checking, typed, iterable, iterables, list, tuple, set, frozenset",
    "author": null,
    "author_email": "Didier Martin <didier.martin.dev@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/27/eb/903d89045a638821ffd2c245f2d082c02e4e0adfdd931a733dfc6d28c872/typediter-1.0.0.tar.gz",
    "platform": null,
    "description": "# TypedIter\n**The Type-Safe Versions of Python Built-in Iterables** \n\n![](https://img.shields.io/badge/Python->=_3.11-royalblue)\n![](https://img.shields.io/badge/License-MIT-seagreen)\n\n\nThis package aims to provide type-safe versions of some python built-in iterables ( `list`, `tuple`, `set`, `frozenset` ), those can be used exactly in the same way as their built-in equivalents, except that a type of item is provided at instance creation (`i_type`), and breaking that type restriction will raise a custom `TypeRestrictionError`.\n(The type-checking is executed at runtime.)\n\n\n\n\n## Two Flavours of Type Safety\n\nFor each built-in iterable, this package provides 2 type-safe versions.\n\n| Built-in class | Light version       | Complete version |\n| -------------- | ------------------- | ---------------- |\n| `list`         | `TypedList_lt`      | `TypedList`      |\n| `tuple`        | `TypedTuple_lt`     | `TypedTuple`     |\n| `set`          | `TypedSet_lt`       | `TypedSet`       |\n| `frozenset`    | `TypedFrozenset_lt` | `TypedFrozenset` |\n\n**Note:** The 'complete' versions inherits from their 'light' version equivalents. \n\n### Light\n\nThe \"light\" version (*class name ending in* **_lt**) \nonly ensures the type safety of the current instance.\n\n- Mutating methods that could insert incompatible items are overridden, they perform type checks, and will fail instead of inserting an incompatible item.\n- Non-Mutating methods are all handled by the built-in class the typed iterable is based on.\nSo for example, a `TypedList_lt` addition, is not type-checked, and will return a built-in `list`. \nThe only exception being the `copy()` method, which is overridden to return a new instance of the current typed iterable class.\n\nThe aim is to provide type safety for the current instance only, \nwhile avoiding slowing down operations that don't directly affect it.\nThis makes those operations faster, and more permissive,\nbut their results are downgraded to built-in iterables.\n\n\n\n### Complete\n\nThe \"complete\" version ensures the type safety of the current instance, and type safety of new instances generated from it.\n\n- Mutating methods that could insert incompatible items are overridden, they perform type checks, and will fail instead of inserting an incompatible item.\n- Non-Mutating methods that used to return an instance of the same class are overridden to return an instance of the current typed iterable, for example, `list` addition returns a new `list`, so `TypedList` addition returns a new `TypedList`.\nSo those operations will perform type checks and fail instead of inserting an incompatible item in the operation result.\n\nThe aim is to be coherent with the built-in iterables the classes are based on. \nThe downside is that it makes those operations heavier and less permissive.\n\n\n\n\n## Installation\n\n```SHELL\npip install typediter\n```\n\n\n\n\n## Instance Creation\n\n```PYTHON\nfrom typediter import (\n    TypedList,\n    TypedSet,\n)\n\n#\u00a0Creating a list that allows only int items\n#\u00a0-> Any iterable can be used as initialisation value\nint_list = TypedList( (1, 2, 3), i_type=int )\n\n#\u00a0Creating an empty set that allows only str items\n# -> Without initialisation value, we create an empty iterable\nstr_set = TypedSet( i_type=str )\n```\n\n- *If one of the given items isn't an instance of the expected `i_type` the initialisation will fail with `TypeRestrictionError`.*\n- *If a non-iterable initial value is given, the initialisation will fail with `IterableExpectedError`.*\n- *If `i_type` is not an instance of `type`, the initialisation will fail with an `InvalidTypeRestrictionError`.*\n- *For `set`/`frozenset` based classes, if `i_type` is not a hashable type, the initialisation will fail with an `InvalidTypeRestrictionError`.*\n\n\n\n\n## Operations\n\nAll operations and methods defined in the built-in version are supported, and can be used in the same way.\n\n\n\n### Mutating Operations\n\nFor both 'light' and 'complete' versions, any operation directly modifying the instance, that could insert an incompatible item is type-checked.\n\n```PYTHON\nfrom typediter import (\n    TypedList,\n    TypedSet,\n)\n\n#\u00a0Creating type-restricted iterables\nint_list = TypedList( (1, 2, 3), i_type=int )\nint_set = TypedSet( (1, 2, 3), i_type=int )\n\n#\u00a0Same operations and methods as the built-in equivalent\nint_list.append( 4 )\nint_list[2] = 42\nprint( int_list ) #\u00a0-> List[int]:[1, 2, 42, 4]\n\nint_set.add( 4 )\nint_set.update({ 5, 6 })\nprint( int_set ) # -> Set[int]:{1, 2, 3, 4, 5, 6}\n```\n\n- *Trying to insert an incompatible item will fail with `TypeRestrictionError`.*\n- *Type-checked operations expecting an iterable, but called with something else, will fail with `IterableExpectedError`.*\n- *Exceptions that are usually raised for a given operation (such as `TypeError`) can still be raised by the underlying built-in class.*\n\n\n\n### Non-mutating operations: Light *vs* Complete versions\n\nOperations that return a new instance and don't directly affect the current instance are handled differently between the 'light' and 'complete' versions of typed iterables:\n\n- **light versions:** all non-mutating operations are handled by the base built-in iterable (*except `copy()` which is overridden to return a new instance of the current typed iterable class*).\n- **complete versions:** non-mutating operations that return a new instance of the same class are overridden to return a new instance of the current typed iterable (for example, `list` addition returns a new `list`, so `TypedList` addition returns a new `TypedList`)\n\n```PYTHON\n# Importing both 'complete' and 'light' versions of typed list\nfrom typediter import TypedList_lt, TypedList\n\n# Creating instances\nlight_str_list = TypedList_lt( ('A', 'B', 'C'), i_type=str )\ncomplete_str_list = TypedList( ('A', 'B', 'C'), i_type=str )\n\n#\u00a0Operation handled by the light version:\n#\u00a0(Not type-restricted, returns a new built-in list)\nlight_result = light_str_list + [ 1, 2, 3 ]\ntype( light_result ) #\u00a0-> list\n\n#\u00a0Operation handled by the complete version:\n#\u00a0(Type-restricted, returns a new typed iterable)\ncomplete_result = complete_str_list + [ 'D', 'E', 'F' ]\ntype( complete_result ) # -> TypedList\n\ncomplete_result = complete_str_list + [ 1, 2, 3 ] # -> Fails with TypeRestrictionError\n```\n**for both versions:**\n- *Type-checked operations expecting an iterable, but called with something else, will fail with `IterableExpectedError`.*\n- *Exceptions that are usually raised for a given operation (such as `TypeError`) can still be raised by the underlying built-in class.*\n\n**for the complete version:**\n- *Trying to insert an incompatible item in the resulting instance will fail with `TypeRestrictionError`.*\n- *Order matters in operations using operators ( + - ^ | ...), the first object has priority to handle the operation, if the 'complete' typed iterable is not first, the operation will be handled by the other object and type safety isn't enforced, for example: `[1,2,3]+complete_str_list` will return a built-in list and will not fail.*\n- *Operations are type-restricted only if the operation is about to introduce an incompatible item in the result, operations that cannot introduce an item of the wrong type in the result aren't checked at all (like `set` `difference()` method).*\n\n\n\n\n## Utility Functions\n\nAll utility functions can be imported from `typediter.utils`\n\n```PYTHON\nfrom typediter.utils import get_converter_func\n```\n\n\n### `get_converter_func( typed_iterable_cls, *, i_type )`\n\nReturns a function converting an iterable to an instance of the given typed iterable class, restricted to the specified type (`i_type`).\n\n**Remark:** if we create a converter for something else than a typed iterable class, or with an invalid `i_type`, it will only fail when trying to convert a value, not when creating the converter.\n\n```PYTHON\nfrom typediter import TypedList\nfrom typediter.utils import get_converter_func\n\n#\u00a0Getting a function converting an iterable to a TypedList[str]\nto_str_list = get_converter_func( TypedList, i_type=str )\n\n#\u00a0Converting an iterable to a typed list\nstr_list = to_str_list( ['A', 'B', 'C'] )\n\ntype( str_list ) # -> TypedList\n```\n\n- *The converter getter function is only meant to be used with typed iterable classes.*\n- *If the iterable we are trying to convert, contains items that are not instances of `i_type`, the conversion will fail with `TypeRestrictionError`.*\n- *If the value being converted is not an iterable, the conversion will fail with `IterableExpectedError`.*\n- *If `i_type` is not an instance of `type`, the conversion will fail with an `InvalidTypeRestrictionError`.*\n- *When converting to `set`/`frozenset` based classes, if `i_type` is not a hashable type, the conversion will fail with an `InvalidTypeRestrictionError`.*\n\n\n\n### `get_typesafe_tuple_converter_func( i_type )`\n\nReturns a function converting an iterable to a built-in `tuple`, restricted to the specified type (`i_type`).\n\n**Remark:** if we create a converter with an invalid `i_type`, it will only fail when trying to convert a value, not when creating the converter.\n\n```PYTHON\nfrom typediter.utils import get_typesafe_tuple_converter_func\n\n#\u00a0Getting the converter functions\nto_str_builtin_tuple = get_typesafe_tuple_converter_func( str )\n\n#\u00a0Converting iterables to type-safe tuple\nstr_builtin_tuple = to_str_builtin_tuple( ['A', 'B', 'C'] )\n\ntype( str_builtin_tuple ) #\u00a0-> tuple\n```\n\n- *If the iterable we are trying to convert, contains items that are not instances of `i_type`, the conversion will fail with `TypeRestrictionError`.*\n- *If the value being converted is not an iterable, the conversion will fail with `IterableExpectedError`.*\n- *If `i_type` is not an instance of `type`, the conversion will fail with an `InvalidTypeRestrictionError`.*\n\n\n\n### `get_typesafe_frozenset_converter_func( i_type )`\n\nReturns a function converting an iterable to a built-in `frozenset`, restricted to the specified type (`i_type`).\n\n**Remark:** if we create a converter with an invalid `i_type`, it will only fail when trying to convert a value, not when creating the converter.\n\n```PYTHON\nfrom typediter.utils import get_typesafe_frozenset_converter_func\n\n#\u00a0Getting the converter functions\nto_str_builtin_frozenset = get_typesafe_frozenset_converter_func( str )\n\n#\u00a0Converting iterables to type-safe frozenset\nstr_builtin_frozenset = to_str_builtin_frozenset( ['A', 'B', 'C'] )\n\ntype( str_builtin_frozenset ) #\u00a0-> frozenset\n```\n\n- *If the iterable we are trying to convert, contains items that are not instances of `i_type`, the conversion will fail with `TypeRestrictionError`.*\n- *If the value being converted is not an iterable, the conversion will fail with `IterableExpectedError`.*\n- *If `i_type` is not an instance of `type` or if it's not a hashable type, the conversion will fail with an `InvalidTypeRestrictionError`.*\n\n\n\n### `filter_items( items, *, i_type )`\n\nFunction taking an iterable and a type, and returning a tuple containing only the items that are instances of that type.\n\n```PYTHON\nfrom typediter.utils import filter_items\n\nfiltered_items = filter_items( [1, 'A', 2, 'B'], i_type=int )\n\nprint( filtered_items ) # -> ( 1, 2 )\n```\n\n\n\n### `is_typediter_instance( obj )`\n\nFunction returning True if the given argument is an instance of a typed iterable\n\n```PYTHON\nfrom typediter import TypedList, TypedTuple\nfrom typediter.utils import is_typediter_instance\n\n#\u00a0Creating typed iterable instances\nstr_list = TypedList( ('A', 'B', 'C'), i_type=str )\nstr_tuple = TypedTuple( ('A', 'B', 'C'), i_type=str )\n\nis_typediter_instance( str_list ) # -> True\nis_typediter_instance( str_tuple ) # -> True\n\nis_typediter_instance( TypedList ) #\u00a0-> False\nis_typediter_instance( ['A', 'B', 'C'] ) #\u00a0-> False\n```\n\n\n\n### `is_typediter_subclass( cls )`\n\nFunction returning True if the given argument is a typed iterable class\n\n```PYTHON\nfrom typediter import TypedList, TypedTuple\nfrom typediter.utils import is_typediter_subclass\n\nis_typediter_subclass( TypedList ) # -> True\nis_typediter_subclass( TypedTuple ) # -> True\n\nis_typediter_subclass( list ) #\u00a0-> False\n```\n\n\n\n\n## Custom Exceptions\n\nAll exceptions can be imported from `typediter.exceptions`.\n\n```PYTHON\nfrom typediter.exceptions import TypeRestrictionError\n```\n\n\n\n### `TypeRestrictionError`\nInherits from `Exception`\n\nException raised to prevent operations from breaking type restriction.\n\n\n\n### `OperationError` \nInherits from `Exception`\n\nBase exception for errors related to mishandled type-checked operations.\n\n\n\n### `InvalidTypeRestrictionError` \nInherits from `OperationError`\n\nException raised if the type restriction (`i_type`) is invalid.\n\nEither because it's not a type, \nor because the type restriction is applied to a `set`/`frozenset` based class\nand the provided `i_type` is not hashable.\n\n\n\n### `IterableExpectedError` \nInherits from `OperationError`\n\nException raised when a type-checked operation expecting an iterable instance receives something else.\n\n\n\n\n## Type hinting utils\n\nSome utility types are made available for type hinting and can be imported from `typediter.types`\n\n```PYTHON\nfrom typediter.types import TypedIterable_T\n\nfoo: TypedIterable_T = ...\nbar: TypedIterable_T[str] = ...\n```\n\n### `TypedIterable_T`\n\nAny instance of a typed iterable class:\n- `TypedList_lt` / `TypedList`\n- `TypedTuple_lt` / `TypedTuple`\n- `TypedSet_lt` / `TypedSet`\n- `TypedFrozenset_lt` / `TypedFrozenset`\n\n\n\n### `MutableTypedIterable_T`\n\nAn instance of a mutable typed iterable class:\n- `TypedList_lt` / `TypedList`\n- `TypedSet_lt` / `TypedSet`\n\n\n\n### `FrozenTypedIterable_T`\n\nAn instance of an immutable typed iterable class:\n- `TypedTuple_lt` / `TypedTuple`\n- `TypedFrozenset_lt` / `TypedFrozenset`\n\n\n\n## Tests\n\nThis package was tested with python **3.11.2**, **3.11.9** and **3.12.5**, on Debian 12.\n\nIt won't work with any version below **3.11**.\n\n### Running Tests\n\n- Download the repo\n- `cd` to the root package directory\n- run following command\n\n```SHELL\npython -m unittest tests\n```\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2024 Didier Martin  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  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.",
    "summary": "Type-safe versions of Python's builtin iterables",
    "version": "1.0.0",
    "project_urls": {
        "Changelog": "https://github.com/Nebulaevo/typediter/blob/main/CHANGELOG.md",
        "Homepage": "https://github.com/Nebulaevo/typediter",
        "Issues": "https://github.com/Nebulaevo/typediter/issues"
    },
    "split_keywords": [
        "type safe",
        " type-safe",
        " type-hints",
        " type-checking",
        " typed",
        " iterable",
        " iterables",
        " list",
        " tuple",
        " set",
        " frozenset"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "80ace5e1feb2ae054c3c99569ae6ebce75a3de9555efec0697ed2fcb5e061b9c",
                "md5": "0b8d0b41ff9abdfd9756da7ed60a4dc8",
                "sha256": "af1c90c4ba35741ff64ca6ae6b7e78debdcd5286d1f151ed805046d5bde25f30"
            },
            "downloads": -1,
            "filename": "typediter-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0b8d0b41ff9abdfd9756da7ed60a4dc8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 29966,
            "upload_time": "2024-08-16T17:42:47",
            "upload_time_iso_8601": "2024-08-16T17:42:47.154582Z",
            "url": "https://files.pythonhosted.org/packages/80/ac/e5e1feb2ae054c3c99569ae6ebce75a3de9555efec0697ed2fcb5e061b9c/typediter-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "27eb903d89045a638821ffd2c245f2d082c02e4e0adfdd931a733dfc6d28c872",
                "md5": "5e20161946e27f1a275c52b8be808e26",
                "sha256": "875379310739ece15cf4c9c5fa5c456ec55bcd23aaf5467bc34650dc64f8c6df"
            },
            "downloads": -1,
            "filename": "typediter-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "5e20161946e27f1a275c52b8be808e26",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 21304,
            "upload_time": "2024-08-16T17:42:48",
            "upload_time_iso_8601": "2024-08-16T17:42:48.263520Z",
            "url": "https://files.pythonhosted.org/packages/27/eb/903d89045a638821ffd2c245f2d082c02e4e0adfdd931a733dfc6d28c872/typediter-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-16 17:42:48",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Nebulaevo",
    "github_project": "typediter",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "typediter"
}
        
Elapsed time: 0.33433s