Package: betterdataclass
betterdataclassis a Python library that enhances the functionality
of the existingdataclasssystem. It provides additional features
and improvements to make working with data classes even better.Features1. StrictDictionaryTheStrictDictionaryclass is a powerful data class that acts like a
dictionary, allowing you to store and access key-value pairs. It
enforces strict typing of the values based on the annotations of the
class attributes, ensuring data integrity and preventing type-related
bugs.2. StrictListTheStrictListclass is an enhanced version of the built-in list
class. It allows you to create lists with strict typing and restrictions
on the elements. You can define the allowed types or even customize
restrictions to ensure that only valid elements are added to the list.Authors@Asutosh RathInstallationYou can installbetterdataclassusing pip:pipinstallbetterdataclassRestrictionsAccepted typing TypesUnionOptionalFinalDictTupleSetListLiteralanything that ``typing.get_origin()`` 1 times leads to the
aforementioned types or the default generic typesCan’t produce JSON file out ofEnum, but it is accepted.Can’t add data members postclass defination, i.e. inruntime.Usage Example- StrictDictionaryLet’s see a simple example of usingbetterdataclassto create a
strict dictionary and list.Creating a ``StrictDictionary``frombetterdataclassimportStrictDictionaryclassPerson(StrictDictionary):name:strage:int# Create an instance of the strict dictionaryperson=Person(name='John',age=30)# Access the attributesprint(person.name)# Output: Johnprint(person.age)# Output: 30# Add new attribute with type checkingperson['address']='123 Main Street'# Print the strict dictionaryprint(person)# Output: {'name': 'John', 'age': 30, 'address': '123 Main Street'}Creating a ``StrictList``frombetterdataclassimportStrictListclassNumberList(StrictList):types=(int,float)# Create an instance of the strict listnumbers=NumberList([1,2,3.14])# Access the elementsprint(numbers[0])# Output: 1print(numbers[1])# Output: 2print(numbers[2])# Output: 3.14# Add new element with type checkingnumbers.append(4)# Print the strict listprint(numbers)# Output: [1, 2, 3.14, 4]More ``StrictDictionary`` complex ExampleThis will speed you up what are the edge capabilities of the library is.
1. ### Example 1 ```python from betterdataclass import StrictDictionary
from typing import List, Optionalclass Address(StrictDictionary):
    street: str
    city: str
    postal_code: str

class Person(StrictDictionary):
    name: str
    age: int
    addresses: List[Address]
    phone: Optional[str] = None

# Create an instance of the strict dictionary
person = Person(
    name='John',
    age=30,
    addresses=[
        Address(street='123 Main Street', city='New York', postal_code='10001'),
        Address(street='456 Elm Street', city='Los Angeles', postal_code='90001')
    ],
    phone='555-1234'
)

# Access the attributes
print(person.name)
print(person.age)
print(person.addresses)
print(person.phone)

# Add new attribute with type checking

# Print the strict dictionary
print(person)
```
~~``` person['email'] = 'john@example.com' ```~~
<br>*This won't work. I can't add new data members on the go. Hence the name StrictDictionary.*Example 2.frombetterdataclassimportStrictDictionaryfromtypingimportList,Dict,AnyclassAddress(StrictDictionary):street:strcity:strpostal_code:strclassContact(StrictDictionary):email:strphone:strclassPerson(StrictDictionary):name:strage:intaddresses:List[Address]contacts:Dict[str,Contact]metadata:Dict[str,Any]# Create an instance of the strict dictionaryperson=Person(name='John',age=30,addresses=[Address(street='123 Main Street',city='New York',postal_code='10001'),Address(street='456 Elm Street',city='Los Angeles',postal_code='90001')],contacts={'personal':Contact(email='john@example.com',phone='555-1234'),'work':Contact(email='john@work.com',phone='555-5678')},metadata={'employee_id':12345,'position':'Manager','active':True})# Access the attributesprint(person.name)print(person.age)print(person.addresses)print(person.contacts)print(person.metadata)# Access nested attributesprint(person.addresses[0].street)print(person.contacts['personal'].email)print(person.metadata['position'])Example 3.frombetterdataclassimportStrictDictionaryfromtypingimportDict,Union,OptionalclassAddress(StrictDictionary):street:strcity:strpostal_code:strclassContact(StrictDictionary):email:strphone:Union[str,int]classPerson(StrictDictionary):name:strage:intaddress:Optional[Address]contacts:Optional[Dict[str,Union[Contact,Dict[str,str]]]]# Create an empty instance of the strict dictionaryperson=Person()# Add data using key mapping and attribute settingperson['name']='John'person.name='John'person['age']=30person.age=30# Add nested data using key mappingperson['address']=Address(street='123 Main Street',city='New York',postal_code='10001')# Add nested data using attribute settingperson.address=Address(street='123 Main Street',city='New York',postal_code='10001')# Add multiple levels of nested data using key mappingperson['contacts']={'personal':Contact(email='john@example.com',phone='555-1234'),'work':{'email':'john@work.com','phone':12345}}# Add multiple levels of nested data using attribute settingperson.contacts={'personal':Contact(email='john@example.com',phone='555-1234'),'work':{'email':'john@work.com','phone':12345}}# Print the strict dictionaryprint(person)Usage Example- StrictListCreating a ``StrictList``frombetterdataclassimportStrictListclassNumberList(StrictList):types=(int,float)# Create an instance of the strict listnumbers=NumberList([1,2,3.14])# Access the elementsprint(numbers[0])# Output: 1print(numbers[1])# Output: 2print(numbers[2])# Output: 3.14# Add new element with type checkingnumbers.append(4)# Print the strict listprint(numbers)# Output: [1, 2, 3.14, 4]Validation usage ``StrictList`` examplefrombetterdataclassimportStrictListimportreclassEmailList(StrictList):defrestriction(self,value):email_regex=r'^[\w\.-]+@[\w\.-]+\.\w+$'ifnotre.match(email_regex,str(value)):returnFalsereturnTrue# Create an instance of the EmailListemails=EmailList()# Add email valuesemails.append('john@example.com')emails.append('jane@example.com')emails.append('invalid_email')# Throws error# Print the listprint(emails)Roadmap☐ Make Validation decorators☐ Make StrictDictionary comply with Enum☐ Make it work with other dataclassesThe Long and the short is I want generalise all the dataclass options
we got