lebrice / SimpleParsing

Simple, Elegant, Typed Argument Parsing with argparse
MIT License
386 stars 47 forks source link

[Feature Request] Support for Python 3.11 #186

Closed zhiruiluo closed 1 year ago

zhiruiluo commented 1 year ago

Feature requested

Is your feature request related to a problem? Please describe. Add support for Python 3.11. Python 3.11.1 is released at Dec. 6 2022. ref: [https://www.python.org/downloads/release/python-3111/]()

Python 3.11 support graph for the 360 most popular Python packages! [https://pyreadiness.org/3.11/]()

Highlight:

Motivation

Python 3.11 is fast! And we enjoy speedup :blush:!

Known issue

Error Example:

from dataclasses import dataclass

@dataclass
class A():
    arg_str: str = 'test'
    arg_int: int = 1
    arg_float: float = 0.5

@dataclass
class B():
    a: A = A()

def test_dataclass():
    B()

output:

ERROR test/python311/test_dataclass.py - ValueError: mutable default <class 'test.python311.test_dataclass.A'> for field a is not allowed: use default_factory

Passed Example:

from dataclasses import dataclass

@dataclass(eq=True,frozen=True)
class A():
    arg_str: str = 'test'
    arg_int: int = 1
    arg_float: float = 0.5

@dataclass
class B():
    a: A = A()

def test_dataclass():
    B()

Describe the solution you'd like

Describe alternatives you've considered

Additional context

zhiruiluo commented 1 year ago

Possible solution

We can pass dataclasses to the default_factory argument of field.

from dataclasses import dataclass, field

@dataclass()
class A():
    arg_str: str = 'test'
    arg_int: int = 1
    arg_float: float = 0.5

@dataclass
class B():
    # using lambda to initialize a user specified dataclass object
    a: A = field(default_factory=lambda: A(arg_str='hi'))

@dataclass
class C():
    # or pass a dataclass class direct to default_factory 
    a: A = field(default_factory=A)

def test_dataclass():
    B()
    C()
lebrice commented 1 year ago

This makes total sense. Will look into this as soon as I can. Thanks @zhiruiluo ! :)