Metadata-Version: 2.4
Name: listclasses
Version: 2.3.1
Summary: A simple yet powerful decorator to create custom sequence types
License: MIT
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: license
Dynamic: license-file
Dynamic: summary

# listclasses
A Python library providing a @listclass decorator that transforms standard classes into powerful, 
type-safe, and highly customizable custom sequence types

# Features:

- Type Safety: Enforce strict data types for sequence items
- Length Constraints: Define fixed-size or dynamic sequences
- Immutability: Easily create read-only (frozen) collections
- Rich API: Seamlessly integrates with built-in functions (`len()`, `repr()`, iteration, slicing)
- Copy Support: Native support for shallow and deep copying
- Pretty Printing: Built-in methods for clean text formatting out of the box
- Is Listclass Checking : Support for checking if an object or a class is a listclass
- Installation: Add the listclass decorator code directly to your project

```commandline
pip install listclasses
```

```python
from listclasses import listclass, is_listclass
```

# Basic Usage

```python
from listclasses import listclass

@listclass
class Inventory:
    pass

# Create an instance with initial items
items = Inventory("Sword", "Shield", "Potion")

print(items)          # Output: Inventory(Sword, Shield, Potion)
print(items[0])       # Output: Sword
print(len(items))     # Output: 3
```

# Advanced Configuration
The @listclass decorator accepts configuration parameters to restrict container behavior

## Enforcing Strict Types

```python
@listclass(type=int)
class IntegerList:
    pass

# Works perfectly
numbers = IntegerList(1, 2, 3)

# Raises TypeError: Incorrect type: expected: int got: str
numbers = IntegerList(1, "two", 3)
```

## Multi-Type Union Support

```python
@listclass(type=int | str)
class MixedList:
    pass

# Both integers and strings are valid
mixed = MixedList(1, "hello", 42, "world")

# Appending a float raises an error
# Raises TypeError: Incorrect type: expected: int | str got: float
mixed.append(3.14)
```

## Advanced types

```python
@listclass(type=list[int])
class ListOfListsOfInts:
    pass

# Works
mixed = ListOfListsOfInts([1, 2], [3, 4, 5])

# Appending a list of string raises an error
# Raises TypeError: Incorrect type: expected: list[int] got: list[str]
mixed.append(['6'])
```

## Setting Fixed Lengths

```python
@listclass(len=2)
class Coordinates:
    pass

# Works perfectly
point = Coordinates(10, 20)

# Raises ValueError: Too many items: expected: 2 got: 3
point = Coordinates(10, 20, 30)
```

## Creating Frozen (Immutable) Lists

```python
@listclass(frozen=True)
class ReadOnlyData:
    pass

data = ReadOnlyData("A", "B")

# Raises TypeError: 'ReadOnlyData' object does not support item assignment
data[0] = "Z"
```

## Built-in Formatting
listclasses comes with utility methods to print your items cleanly.

```python
@listclass
class TodoList:
    pass

todos = TodoList("Buy milk", "Clean room", "Code Python")

# Dotted list format
todos.print_dotted('-')
# Output:
# -  Buy milk
# -  Clean room
# -  Code Python

# Numbered list format
todos.print_numbered()
# Output:
# 1. Buy milk
# 2. Clean room
# 3. Code Python
```

## Random item selection

```python
@listclass
class TodoList:
    pass

tasks = TodoList('Clean the bathroom', 'Make the bed', 'Touch grass')
random_task = tasks.random()
```

# Checking for listclasses
listclasses comes with a function to check if an object or a class is a listclass. 

## Checking if a class is a listclass

```python
@listclass
class MyList:
    pass

class Car:
    pass

print(is_listclass(MyList))
# Output:
# True

print(is_listclass(Car))
# Output:
# False
```

## Checking if an object is a listclass

```python
from listclasses import listclass, is_listclass

@listclass
class MyList:
    pass

class Car:
    pass

todo = MyList()
volvo = Car()

print(is_listclass(todo))
# Output:
# True

print(is_listclass(volvo))
# Output:
# False
```

# Math and logic operations on listclasses

## Adding an item to a listclass

```python
@listclass
class Flowers:
    pass

flowers = Flowers('Rose', 'Tulip')

new_flowers = flowers + 'Lily'
print(new_flowers)
# Output:
# Flowers('Rose', 'Tulip', 'Lily')

newer_flowers = 'Poppy' + new_flowers # This adds 'Poppy' to the beggining of a listclass
print(newer_flowers)
# Output:
# Flowers('Poppy', 'Rose', 'Tulip', 'Lily')
```

You can also use += on listclasses.

## Adding to every item of a listclass
If a listclass has a fixed length adding to it will instead add to every of its elements.

```python
@listclass(len=3)
class Color:
    pass

red = Color(255, 0, 0)
green = Color(0, 255, 0)

yellow = red + green
print(yellow)
# Output:
# Color(255, 255, 0)
```

## Subtraction
Works the same as `remove()`

```python
@listclass
class Flowers:
    pass

flowers = Flowers('Rose', 'Tulip', 'Sunflower')

flowers_new = flowers - 'Rose'
print(flowers_new)
# Output:
# Flowers('Tulip', 'Sunflower')
```
You can also use -=,
if a listclass has a fixed length subtracting from it will instead subtract from every of its elements.

## Multiplication

```python
@listclass
class Coordinates:
    pass

xy =  Coordinates(20, 400)
print(xy * 5)
# Output:
# Coordinates(20, 400, 20, 400, 20, 400, 20, 400, 20, 400)
```
You can also use *=,
if a listclass has a fixed length multiplying it will instead multiply every of its elements.

## Division

```python
@listclass(len=3)
class Color:
    pass

green = Color(0, 255, 0)

dark_green = green / 2
print(dark_green)
# Output
# Color(0.0, 127.5, 0.0)
```
You can also use /=, //, //=, **, **=.

## And-ing two listclasses

```python
@listclass(type=bool)
class Attendance:
    pass

class1 = Attendance(True, False, True)
class2 = Attendance(True, True, False)

print(class1 and class2)
# Output
# Attendance(True, False, False)
```
You can also or and xor listclasses 

# API Reference

## Decorator Arguments
| Argument | Type | Default |                                           Description                                            |
|:--------:|:----:|:-------:|:------------------------------------------------------------------------------------------------:|
|   len    | int  |    0    |                     Expected length of the collection. 0 means dynamic size.                     |
|   type   | type |   any   | Restricts elements to a single or multiple explicit python types, any means all types are valid. |
|  frozen  | bool |  False  |                    If True, prevents item assignment and mutating operations.                    |

## Available Methods
Depending on configuration (frozen and len), instances support standard list operations:

- Access: `__getitem__`, `__iter__`, `__contains__`, `count()`, `index()`, `random()`
- Mutation (Dynamic only): `append()`, `pop()`, `clear()`, `insert()`, `__delitem__`
- Ordering (Mutable only): `sort()`, `reverse()`
- Math: `__add__`, `__sub__`, `__mul__`, `__truediv__` and more
- Logic: `__and__`, `__or__`, `__xor__`
