Control: tags 1025111 + patch Dear maintainer,
I've prepared an NMU for python-omegaconf (versioned as 2.2.2-2.1). The diff is attached to this message. Regards. SR
diff -Nru python-omegaconf-2.2.2/debian/changelog python-omegaconf-2.2.2/debian/changelog --- python-omegaconf-2.2.2/debian/changelog 2022-10-26 06:24:04.000000000 -0400 +++ python-omegaconf-2.2.2/debian/changelog 2022-12-25 12:42:17.000000000 -0400 @@ -1,3 +1,10 @@ +python-omegaconf (2.2.2-2.1) unstable; urgency=medium + + * Non-maintainer upload. + * Patch: Support Python 3.11. (Closes: #1025111) + + -- Stefano Rivera <stefa...@debian.org> Sun, 25 Dec 2022 12:42:17 -0400 + python-omegaconf (2.2.2-2) unstable; urgency=medium * Fixed VCS URLs (Closes: #1016890). diff -Nru python-omegaconf-2.2.2/debian/patches/python-3.11.patch python-omegaconf-2.2.2/debian/patches/python-3.11.patch --- python-omegaconf-2.2.2/debian/patches/python-3.11.patch 1969-12-31 20:00:00.000000000 -0400 +++ python-omegaconf-2.2.2/debian/patches/python-3.11.patch 2022-12-25 12:41:57.000000000 -0400 @@ -0,0 +1,1184 @@ +Description: + This PR updates OmegaConf's tests and metadata for compatibility with python3.11. + . + There are no changes to the omegaconf source code. + . + The changes to the test are motivated by python3.11 dataclasses dropping + support for mutable default arguments. This means dataclasses with mutable + default arguments must use default_factory. + . + I've updated the dataclasses in the test suite to use default_factory, and + I've added a file tests/structured_conf/dataclasses_pre_311.py that contains + old-style dataclasses that do not use default_factory for mutable dataclass + defaults. This pre_311 file is run only when python version < 3.10. + . + Commits: + tests/structured_config module fixture: use pytest.param + test dataclass with mutable default: skip if python>=3.11 + tests/structured_conf: default_factory for mutable dataclass args + python3.11: add news fragment & update metadata + python3.11: update docs + +Author: Jasha <8935917+jash...@users.noreply.github.com> +Origin: upstream, https://github.com/omry/omegaconf/pull/1032 +Bug-Debian: https://bugs.debian.org/1025111 + +--- a/tests/structured_conf/test_structured_basic.py ++++ b/tests/structured_conf/test_structured_basic.py +@@ -1,8 +1,9 @@ + import re ++import sys + from importlib import import_module + from typing import Any, Optional + +-from pytest import fixture, mark, raises ++from pytest import fixture, mark, param, raises + + from omegaconf import ( + DictConfig, +@@ -20,10 +21,17 @@ + + @fixture( + params=[ +- "tests.structured_conf.data.dataclasses", +- "tests.structured_conf.data.attr_classes", ++ param("tests.structured_conf.data.dataclasses", id="dataclasses"), ++ param( ++ "tests.structured_conf.data.dataclasses_pre_311", ++ id="dataclasses_pre_311", ++ marks=mark.skipif( ++ sys.version_info >= (3, 11), ++ reason="python >= 3.11 does not support mutable default dataclass arguments", ++ ), ++ ), ++ param("tests.structured_conf.data.attr_classes", id="attr_classes"), + ], +- ids=["dataclasses", "attr_classes"], + ) + def module(request: Any) -> Any: + return import_module(request.param) +--- a/tests/structured_conf/test_structured_config.py ++++ b/tests/structured_conf/test_structured_config.py +@@ -29,10 +29,17 @@ + + @fixture( + params=[ +- "tests.structured_conf.data.dataclasses", +- "tests.structured_conf.data.attr_classes", ++ param("tests.structured_conf.data.dataclasses", id="dataclasses"), ++ param( ++ "tests.structured_conf.data.dataclasses_pre_311", ++ id="dataclasses_pre_311", ++ marks=mark.skipif( ++ sys.version_info >= (3, 11), ++ reason="python >= 3.11 does not support mutable default dataclass arguments", ++ ), ++ ), ++ param("tests.structured_conf.data.attr_classes", id="attr_classes"), + ], +- ids=["dataclasses", "attr_classes"], + ) + def module(request: Any) -> Any: + return import_module(request.param) +--- /dev/null ++++ b/tests/structured_conf/data/dataclasses_pre_311.py +@@ -0,0 +1,879 @@ ++import dataclasses ++import sys ++from dataclasses import dataclass, field ++from pathlib import Path ++from typing import Any, Dict, List, Optional, Tuple, Union ++ ++from pytest import importorskip ++ ++from omegaconf import II, MISSING, SI ++from tests import Color, Enum1 ++ ++if sys.version_info >= (3, 8): # pragma: no cover ++ from typing import TypedDict ++ ++# skip test if dataclasses are not available ++importorskip("dataclasses") ++ ++ ++class NotStructuredConfig: ++ name: str = "Bond" ++ age: int = 7 ++ ++ def __eq__(self, other: Any) -> Any: ++ if isinstance(other, type(self)): ++ return self.name == other.name and self.age == other.age ++ return False ++ ++ ++if sys.version_info >= (3, 8): # pragma: no cover ++ ++ class TypedDictSubclass(TypedDict): ++ foo: str ++ ++ ++@dataclass ++class StructuredWithInvalidField: ++ bar: NotStructuredConfig = NotStructuredConfig() ++ ++ ++@dataclass ++class User: ++ name: str = MISSING ++ age: int = MISSING ++ ++ ++@dataclass ++class UserList: ++ list: List[User] = MISSING ++ ++ ++@dataclass ++class UserDict: ++ dict: Dict[str, User] = MISSING ++ ++ ++@dataclass ++class UserWithDefaultName(User): ++ name: str = "bob" ++ ++ ++@dataclass ++class MissingUserField: ++ user: User = MISSING ++ ++ ++@dataclass ++class MissingUserWithDefaultNameField: ++ user: UserWithDefaultName = MISSING ++ ++ ++@dataclass ++class OptionalUser: ++ user: Optional[User] = None ++ ++ ++@dataclass ++class InterpolationToUser: ++ user: User = User("Bond", 7) ++ admin: User = II("user") ++ ++ ++@dataclass ++class AnyTypeConfig: ++ with_default: Any = "Can get any type at runtime" ++ null_default: Any = None ++ # Access to this prior to assigning a value to it will result in ++ # a MissingMandatoryValue exception. ++ # Equivalent to "???" in YAML files ++ mandatory_missing: Any = MISSING ++ ++ # interpolation, will inherit the type and value of `with_default' ++ interpolation: Any = II("with_default") ++ ++ # specific types assigned ++ int_default: Any = 12 ++ float_default: Any = 10.0 ++ str_default: Any = "foobar" ++ bool_default: Any = True ++ enum_default: Any = Color.BLUE ++ ++ # test mixing with variable with a specific type annotation ++ typed_int_default: int = 10 ++ ++ ++@dataclass ++class BoolConfig: ++ # with default value ++ with_default: bool = True ++ ++ # default is None ++ null_default: Optional[bool] = None ++ ++ # explicit no default ++ mandatory_missing: bool = MISSING ++ ++ # interpolation, will inherit the type and value of `with_default' ++ interpolation: bool = II("with_default") ++ ++ ++@dataclass ++class IntegersConfig: ++ # with default value ++ with_default: int = 10 ++ ++ # default is None ++ null_default: Optional[int] = None ++ ++ # explicit no default ++ mandatory_missing: int = MISSING ++ ++ # interpolation, will inherit the type and value of `with_default' ++ interpolation: int = II("with_default") ++ ++ ++@dataclass ++class StringConfig: ++ # with default value ++ with_default: str = "foo" ++ ++ # default is None ++ null_default: Optional[str] = None ++ ++ # explicit no default ++ mandatory_missing: str = MISSING ++ ++ # interpolation, will inherit the type and value of `with_default' ++ interpolation: str = II("with_default") ++ ++ ++@dataclass ++class FloatConfig: ++ # with default value ++ with_default: float = 0.10 ++ ++ # default is None ++ null_default: Optional[float] = None ++ ++ # explicit no default ++ mandatory_missing: float = MISSING ++ ++ # interpolation, will inherit the type and value of `with_default' ++ interpolation: float = II("with_default") ++ ++ ++@dataclass ++class BytesConfig: ++ # with default value ++ with_default: bytes = b"binary" ++ ++ # default is None ++ null_default: Optional[bytes] = None ++ ++ # explicit no default ++ mandatory_missing: bytes = MISSING ++ ++ # interpolation, will inherit the type and value of `with_default' ++ interpolation: bytes = II("with_default") ++ ++ ++@dataclass ++class PathConfig: ++ # with default value ++ with_default: Path = Path("hello.txt") ++ ++ # default is None ++ null_default: Optional[Path] = None ++ ++ # explicit no default ++ mandatory_missing: Path = MISSING ++ ++ # interpolation, will inherit the type and value of `with_default' ++ interpolation: Path = II("with_default") ++ ++ ++@dataclass ++class EnumConfig: ++ # with default value ++ with_default: Color = Color.BLUE ++ ++ # default is None ++ null_default: Optional[Color] = None ++ ++ # explicit no default ++ mandatory_missing: Color = MISSING ++ ++ # interpolation, will inherit the type and value of `with_default' ++ interpolation: Color = II("with_default") ++ ++ ++@dataclass ++class ConfigWithList: ++ list1: List[int] = field(default_factory=lambda: [1, 2, 3]) ++ list2: Tuple[int, int, int] = field(default_factory=lambda: (1, 2, 3)) ++ missing: List[int] = MISSING ++ ++ ++@dataclass ++class ConfigWithDict: ++ dict1: Dict[str, Any] = field(default_factory=lambda: {"foo": "bar"}) ++ missing: Dict[str, Any] = MISSING ++ ++ ++@dataclass ++class ConfigWithDict2: ++ dict1: Dict[str, int] = field(default_factory=lambda: {"foo": 2}) ++ ++ ++@dataclass ++class Nested: ++ # with default value ++ with_default: int = 10 ++ ++ # default is None ++ null_default: Optional[int] = None ++ ++ # explicit no default ++ mandatory_missing: int = MISSING ++ ++ # Note that since relative interpolations are not yet supported, ++ # Nested configs and interpolations does not play too well together ++ interpolation: int = II("value_at_root") ++ ++ ++@dataclass ++class NestedSubclass(Nested): ++ additional: int = 20 ++ ++ ++@dataclass ++class NestedConfig: ++ default_value: Nested ++ ++ # with default value ++ user_provided_default: Nested = Nested(with_default=42) ++ ++ value_at_root: int = 1000 ++ ++ ++@dataclass ++class NestedWithAny: ++ var: Any = Nested() ++ ++ ++@dataclass ++class NoDefaultValue: ++ no_default: Any ++ ++ ++@dataclass ++class Interpolation: ++ x: int = 100 ++ y: int = 200 ++ # The real type of y is int, cast the interpolation string ++ # to help static type checkers to see this truth ++ z1: int = II("x") ++ z2: str = SI("${x}_${y}") ++ ++ ++@dataclass ++class RelativeInterpolation: ++ x: int = 100 ++ y: int = 200 ++ z1: int = II(".x") ++ z2: str = SI("${.x}_${.y}") ++ ++ ++@dataclass ++class BoolOptional: ++ with_default: Optional[bool] = True ++ as_none: Optional[bool] = None ++ not_optional: bool = True ++ ++ ++@dataclass ++class IntegerOptional: ++ with_default: Optional[int] = 1 ++ as_none: Optional[int] = None ++ not_optional: int = 1 ++ ++ ++@dataclass ++class FloatOptional: ++ with_default: Optional[float] = 1.0 ++ as_none: Optional[float] = None ++ not_optional: float = 1 ++ ++ ++@dataclass ++class StringOptional: ++ with_default: Optional[str] = "foo" ++ as_none: Optional[str] = None ++ not_optional: str = "foo" ++ ++ ++@dataclass ++class ListOptional: ++ with_default: Optional[List[int]] = field(default_factory=lambda: [1, 2, 3]) ++ as_none: Optional[List[int]] = None ++ not_optional: List[int] = field(default_factory=lambda: [1, 2, 3]) ++ ++ ++@dataclass ++class TupleOptional: ++ with_default: Optional[Tuple[int, int, int]] = field( ++ default_factory=lambda: (1, 2, 3) ++ ) ++ as_none: Optional[Tuple[int, int, int]] = None ++ not_optional: Tuple[int, int, int] = field(default_factory=lambda: (1, 2, 3)) ++ ++ ++@dataclass ++class EnumOptional: ++ with_default: Optional[Color] = Color.BLUE ++ as_none: Optional[Color] = None ++ not_optional: Color = Color.BLUE ++ ++ ++@dataclass ++class DictOptional: ++ with_default: Optional[Dict[str, int]] = field(default_factory=lambda: {"a": 10}) ++ as_none: Optional[Dict[str, int]] = None ++ not_optional: Dict[str, int] = field(default_factory=lambda: {"a": 10}) ++ ++ ++@dataclass ++class RecursiveDict: ++ d: Dict[str, "RecursiveDict"] = MISSING ++ ++ ++@dataclass ++class StructuredOptional: ++ with_default: Optional[Nested] = Nested() ++ as_none: Optional[Nested] = None ++ not_optional: Nested = Nested() ++ ++ ++@dataclass(frozen=True) ++class FrozenClass: ++ user: User = User(name="Bart", age=10) ++ x: int = 10 ++ list: List[int] = field(default_factory=lambda: [1, 2, 3]) ++ ++ ++@dataclass ++class ContainsFrozen: ++ x: int = 10 ++ frozen: FrozenClass = FrozenClass() ++ ++ ++@dataclass ++class WithListField: ++ list: List[int] = field(default_factory=lambda: [1, 2, 3]) ++ ++ ++@dataclass ++class WithDictField: ++ dict: Dict[str, int] = field(default_factory=lambda: {"foo": 10, "bar": 20}) ++ ++ ++if sys.version_info >= (3, 8): # pragma: no cover ++ ++ @dataclass ++ class WithTypedDictField: ++ dict: TypedDictSubclass ++ ++ ++@dataclass ++class ErrorDictObjectKey: ++ # invalid dict key, must be str ++ dict: Dict[object, str] = field( ++ default_factory=lambda: {object(): "foo", object(): "bar"} ++ ) ++ ++ ++class RegularClass: ++ pass ++ ++ ++@dataclass ++class ErrorDictUnsupportedValue: ++ # invalid dict value type, not one of the supported types ++ dict: Dict[str, RegularClass] = field(default_factory=dict) ++ ++ ++@dataclass ++class ErrorListUnsupportedValue: ++ # invalid dict value type, not one of the supported types ++ dict: List[RegularClass] = field(default_factory=list) ++ ++ ++@dataclass ++class ErrorListUnsupportedStructuredConfig: ++ # Nesting of structured configs in Dict and List is not currently supported ++ list: List[User] = field(default_factory=list) ++ ++ ++@dataclass ++class ListExamples: ++ any: List[Any] = field(default_factory=lambda: [1, "foo"]) ++ ints: List[int] = field(default_factory=lambda: [1, 2]) ++ strings: List[str] = field(default_factory=lambda: ["foo", "bar"]) ++ booleans: List[bool] = field(default_factory=lambda: [True, False]) ++ colors: List[Color] = field(default_factory=lambda: [Color.RED, Color.GREEN]) ++ ++ ++@dataclass ++class TupleExamples: ++ any: Tuple[Any, Any] = field(default_factory=lambda: (1, "foo")) ++ ints: Tuple[int, int] = field(default_factory=lambda: (1, 2)) ++ strings: Tuple[str, str] = field(default_factory=lambda: ("foo", "bar")) ++ booleans: Tuple[bool, bool] = field(default_factory=lambda: (True, False)) ++ colors: Tuple[Color, Color] = field( ++ default_factory=lambda: (Color.RED, Color.GREEN) ++ ) ++ ++ ++@dataclass ++class DictExamples: ++ any: Dict[str, Any] = field(default_factory=lambda: {"a": 1, "b": "foo"}) ++ ints: Dict[str, int] = field(default_factory=lambda: {"a": 10, "b": 20}) ++ strings: Dict[str, str] = field(default_factory=lambda: {"a": "foo", "b": "bar"}) ++ booleans: Dict[str, bool] = field(default_factory=lambda: {"a": True, "b": False}) ++ colors: Dict[str, Color] = field( ++ default_factory=lambda: { ++ "red": Color.RED, ++ "green": Color.GREEN, ++ "blue": Color.BLUE, ++ } ++ ) ++ int_keys: Dict[int, str] = field(default_factory=lambda: {1: "one", 2: "two"}) ++ float_keys: Dict[float, str] = field( ++ default_factory=lambda: {1.1: "one", 2.2: "two"} ++ ) ++ bool_keys: Dict[bool, str] = field(default_factory=lambda: {True: "T", False: "F"}) ++ enum_key: Dict[Color, str] = field( ++ default_factory=lambda: {Color.RED: "red", Color.GREEN: "green"} ++ ) ++ ++ ++@dataclass ++class DictOfObjects: ++ users: Dict[str, User] = field( ++ default_factory=lambda: {"joe": User(name="Joe", age=18)} ++ ) ++ ++ ++@dataclass ++class DictOfObjectsMissing: ++ users: Dict[str, User] = field(default_factory=lambda: {"moe": MISSING}) ++ ++ ++@dataclass ++class ListOfObjects: ++ users: List[User] = field(default_factory=lambda: [User(name="Joe", age=18)]) ++ ++ ++@dataclass ++class ListOfObjectsMissing: ++ users: List[User] = field(default_factory=lambda: [MISSING]) ++ ++ ++class DictSubclass: ++ @dataclass ++ class Str2Str(Dict[str, str]): ++ pass ++ ++ @dataclass ++ class Str2Int(Dict[str, int]): ++ pass ++ ++ @dataclass ++ class Int2Str(Dict[int, str]): ++ pass ++ ++ @dataclass ++ class Float2Str(Dict[float, str]): ++ pass ++ ++ @dataclass ++ class Bool2Str(Dict[bool, str]): ++ pass ++ ++ @dataclass ++ class Color2Str(Dict[Color, str]): ++ pass ++ ++ @dataclass ++ class Color2Color(Dict[Color, Color]): ++ pass ++ ++ @dataclass ++ class Str2User(Dict[str, User]): ++ pass ++ ++ @dataclass ++ class Str2StrWithField(Dict[str, str]): ++ foo: str = "bar" ++ ++ @dataclass ++ class Str2IntWithStrField(Dict[str, int]): ++ foo: int = 1 ++ ++ @dataclass ++ class Str2UserWithField(Dict[str, User]): ++ foo: User = User("Bond", 7) ++ ++ class Error: ++ @dataclass ++ class User2Str(Dict[User, str]): ++ pass ++ ++ ++@dataclass ++class Plugin: ++ name: str = MISSING ++ params: Any = MISSING ++ ++ ++@dataclass ++class ConcretePlugin(Plugin): ++ name: str = "foobar_plugin" ++ ++ @dataclass ++ class FoobarParams: ++ foo: int = 10 ++ ++ params: FoobarParams = FoobarParams() ++ ++ ++@dataclass ++class PluginWithAdditionalField(Plugin): ++ name: str = "foobar2_plugin" ++ additional: int = 10 ++ ++ ++# Does not extend Plugin, cannot be assigned or merged ++@dataclass ++class FaultyPlugin: ++ name: str = "faulty_plugin" ++ ++ ++@dataclass ++class PluginHolder: ++ none: Optional[Plugin] = None ++ missing: Plugin = MISSING ++ plugin: Plugin = Plugin() ++ plugin2: Plugin = ConcretePlugin() ++ ++ ++@dataclass ++class LinkedList: ++ next: Optional["LinkedList"] = None ++ value: Any = MISSING ++ ++ ++@dataclass ++class RecursiveList: ++ d: List["RecursiveList"] = MISSING ++ ++ ++class MissingTest: ++ @dataclass ++ class Missing1: ++ head: LinkedList = MISSING ++ ++ @dataclass ++ class Missing2: ++ head: LinkedList = LinkedList(next=MISSING, value=1) ++ ++ ++@dataclass ++class NestedWithNone: ++ plugin: Optional[Plugin] = None ++ ++ ++@dataclass ++class UnionError: ++ x: Union[int, List[str]] = 10 ++ ++ ++@dataclass ++class WithNativeMISSING: ++ num: int = dataclasses.MISSING # type: ignore ++ ++ ++@dataclass ++class MissingStructuredConfigField: ++ plugin: Plugin = MISSING ++ ++ ++@dataclass ++class ListClass: ++ list: List[int] = field(default_factory=lambda: []) ++ tuple: Tuple[int, int] = field(default_factory=lambda: (1, 2)) ++ ++ ++@dataclass ++class UntypedList: ++ list: List = field(default_factory=lambda: [1, 2]) # type: ignore ++ opt_list: Optional[List] = None # type: ignore ++ ++ ++@dataclass ++class UntypedDict: ++ dict: Dict = field(default_factory=lambda: {"foo": "var"}) # type: ignore ++ opt_dict: Optional[Dict] = None # type: ignore ++ ++ ++class StructuredSubclass: ++ @dataclass ++ class ParentInts: ++ int1: int ++ int2: int ++ int3: int = dataclasses.MISSING # type: ignore ++ int4: int = MISSING ++ ++ @dataclass ++ class ChildInts(ParentInts): ++ int2: int = 5 ++ int3: int = 10 ++ int4: int = 15 ++ ++ @dataclass ++ class ParentContainers: ++ list1: List[int] = MISSING ++ list2: List[int] = field(default_factory=lambda: [5, 6]) ++ dict: Dict[str, Any] = MISSING ++ ++ @dataclass ++ class ChildContainers(ParentContainers): ++ list1: List[int] = field(default_factory=lambda: [1, 2, 3]) ++ dict: Dict[str, Any] = field(default_factory=lambda: {"a": 5, "b": 6}) ++ ++ @dataclass ++ class ParentNoDefaultFactory: ++ no_default_to_list: Any ++ int_to_list: Any = 1 ++ ++ @dataclass ++ class ChildWithDefaultFactory(ParentNoDefaultFactory): ++ no_default_to_list: Any = field(default_factory=lambda: ["hi"]) ++ int_to_list: Any = field(default_factory=lambda: ["hi"]) ++ ++ ++@dataclass ++class HasInitFalseFields: ++ post_initialized: str = field(init=False) ++ without_default: str = field(init=False) ++ with_default: str = field(init=False, default="default") ++ ++ def __post_init__(self) -> None: ++ self.post_initialized = "set_by_post_init" ++ ++ ++class NestedContainers: ++ @dataclass ++ class ListOfLists: ++ lls: List[List[str]] ++ llx: List[List[User]] ++ llla: List[List[List[Any]]] ++ lloli: List[List[Optional[List[int]]]] ++ lls_default: List[List[str]] = field( ++ default_factory=lambda: [[], ["abc", "def", 123, MISSING], MISSING] # type: ignore ++ ) ++ lolx_default: List[Optional[List[User]]] = field( ++ default_factory=lambda: [ ++ [], ++ [User(), User(age=7, name="Bond"), MISSING], ++ MISSING, ++ ] ++ ) ++ ++ @dataclass ++ class DictOfDicts: ++ dsdsi: Dict[str, Dict[str, int]] ++ dsdbi: Dict[str, Dict[bool, int]] ++ dsdsx: Dict[str, Dict[str, User]] ++ odsdsi_default: Optional[Dict[str, Dict[str, int]]] = field( ++ default_factory=lambda: { ++ "dsi1": {}, ++ "dsi2": {"s1": 1, "s2": "123", "s3": MISSING}, ++ "dsi3": MISSING, ++ } ++ ) ++ dsdsx_default: Dict[str, Dict[str, User]] = field( ++ default_factory=lambda: { ++ "dsx1": {}, ++ "dsx2": { ++ "s1": User(), ++ "s2": User(age=7, name="Bond"), ++ "s3": MISSING, ++ }, ++ "dsx3": MISSING, ++ } ++ ) ++ ++ @dataclass ++ class ListsAndDicts: ++ lldsi: List[List[Dict[str, int]]] ++ ldaos: List[Dict[Any, Optional[str]]] ++ dedsle: Dict[Color, Dict[str, List[Enum1]]] ++ dsolx: Dict[str, Optional[List[User]]] ++ oldfox: Optional[List[Dict[float, Optional[User]]]] ++ dedsle_default: Dict[Color, Dict[str, List[Enum1]]] = field( ++ default_factory=lambda: { ++ Color.RED: {"a": [Enum1.FOO, Enum1.BAR]}, ++ Color.GREEN: {"b": []}, ++ Color.BLUE: {}, ++ } ++ ) ++ ++ @dataclass ++ class WithDefault: ++ dsolx_default: Dict[str, Optional[List[User]]] = field( ++ default_factory=lambda: {"lx": [User()], "n": None} ++ ) ++ ++ ++class UnionsOfPrimitveTypes: ++ @dataclass ++ class Simple: ++ uis: Union[int, str] ++ ubc: Union[bool, Color] ++ uxf: Union[bytes, float] ++ ouis: Optional[Union[int, str]] ++ uois: Union[Optional[int], str] ++ uisn: Union[int, str, None] ++ uisN: Union[int, str, type(None)] # type: ignore ++ ++ @dataclass ++ class WithDefaults: ++ uis: Union[int, str] = "abc" ++ ubc1: Union[bool, Color] = True ++ ubc2: Union[bool, Color] = Color.RED ++ uxf: Union[bytes, float] = 1.2 ++ ouis: Optional[Union[int, str]] = None ++ uisn: Union[int, str, None] = 123 ++ uisN: Union[int, str, type(None)] = "abc" # type: ignore ++ ++ @dataclass ++ class WithExplicitMissing: ++ uis_missing: Union[int, str] = MISSING ++ ++ @dataclass ++ class WithBadDefaults1: ++ uis: Union[int, str] = None # type: ignore ++ ++ @dataclass ++ class WithBadDefaults2: ++ ubc: Union[bool, Color] = "abc" # type: ignore ++ ++ @dataclass ++ class WithBadDefaults3: ++ uxf: Union[bytes, float] = True ++ ++ @dataclass ++ class WithBadDefaults4: ++ oufb: Optional[Union[float, bool]] = Color.RED # type: ignore ++ ++ @dataclass ++ class ContainersOfUnions: ++ lubc: List[Union[bool, Color]] ++ dsubf: Dict[str, Union[bool, float]] ++ dsoubf: Dict[str, Optional[Union[bool, float]]] ++ lubc_with_default: List[Union[bool, Color]] = field( ++ default_factory=lambda: [True, Color.RED] ++ ) ++ dsubf_with_default: Dict[str, Union[bool, float]] = field( ++ default_factory=lambda: {"abc": True, "xyz": 1.2} ++ ) ++ ++ @dataclass ++ class InterpolationFromUnion: ++ ubi: Union[bool, int] ++ oubi: Optional[Union[bool, int]] ++ an_int: int = 123 ++ a_string: str = "abc" ++ missing: int = MISSING ++ none: Optional[int] = None ++ ubi_with_default: Union[bool, int] = II("an_int") ++ oubi_with_default: Optional[Union[bool, int]] = II("none") ++ ++ @dataclass ++ class InterpolationToUnion: ++ a_float: float = II("ufs") ++ bad_int_interp: bool = II("ufs") ++ ufs: Union[float, str] = 10.1 ++ ++ @dataclass ++ class BadInterpolationFromUnion: ++ a_float: float = 10.1 ++ ubi: Union[bool, int] = II("a_float") ++ ++ if sys.version_info >= (3, 10): ++ ++ @dataclass ++ class SupportPEP604: ++ """https://peps.python.org/pep-0604/""" ++ ++ uis: int | str ++ ouis: Optional[int | str] ++ uisn: int | str | None = None ++ uis_with_default: int | str = 123 ++ ++ ++if sys.version_info >= (3, 9): ++ ++ @dataclass ++ class SupportPEP585: ++ """ ++ PEP 585 – Type Hinting Generics In Standard Collections ++ https://peps.python.org/pep-0585/ ++ ++ This means lower-case dict/list/tuple annotations ++ can be used instad of uppercase Dict/List/Tuple. ++ """ ++ ++ dict_: dict[int, str] = field(default_factory=lambda: {123: "abc"}) ++ list_: list[int] = field(default_factory=lambda: [123]) ++ tuple_: tuple[int] = (123,) ++ dict_no_subscript: dict = field(default_factory=lambda: {123: "abc"}) ++ list_no_subscript: list = field(default_factory=lambda: [123]) ++ tuple_no_subscript: tuple = (123,) ++ ++ ++@dataclass ++class HasForwardRef: ++ @dataclass ++ class CA: ++ x: int = 3 ++ ++ @dataclass ++ class CB: ++ sub: "HasForwardRef.CA" ++ ++ a: CA ++ b: CB ++ ++ ++@dataclass ++class HasBadAnnotation1: ++ data: object ++ ++ ++@dataclass ++class HasBadAnnotation2: ++ data: object() # type: ignore ++ ++ ++@dataclass ++class HasIgnoreMetadataRequired: ++ ignore: int = field(metadata={"omegaconf_ignore": True}) ++ no_ignore: int = field(metadata={"omegaconf_ignore": False}) ++ ++ ++@dataclass ++class HasIgnoreMetadataWithDefault: ++ ignore: int = field(default=1, metadata={"omegaconf_ignore": True}) ++ no_ignore: int = field(default=2, metadata={"omegaconf_ignore": False}) +--- a/tests/__init__.py ++++ b/tests/__init__.py +@@ -101,7 +101,7 @@ + class FoobarParams: + foo: int = 10 + +- params: FoobarParams = FoobarParams() ++ params: FoobarParams = field(default_factory=FoobarParams) + + + @dataclass +@@ -110,7 +110,7 @@ + class BazParams: + baz: str = "${..name}" + +- subcfg: BazParams = BazParams() ++ subcfg: BazParams = field(default_factory=BazParams) + name: str = MISSING + + +--- a/tests/examples/test_dataclass_example.py ++++ b/tests/examples/test_dataclass_example.py +@@ -161,7 +161,9 @@ + admin: User = User # type: ignore + + # You can also specify different defaults for nested classes +- manager: User = User(name="manager", height=Height.TALL) ++ manager: User = field( ++ default_factory=lambda: User(name="manager", height=Height.TALL) ++ ) + + + def test_nesting() -> None: +@@ -343,7 +345,7 @@ + @dataclass + class Config: + num: int = 10 +- user: User = User(name=MISSING, height=MISSING) ++ user: User = field(default_factory=lambda: User(name=MISSING, height=MISSING)) + domains: Dict[str, Domain] = field(default_factory=dict) + + yaml = """ +@@ -385,8 +387,8 @@ + + @dataclass + class MyConfig: +- server: Server = Server() +- log: Log = Log() ++ server: Server = field(default_factory=Server) ++ log: Log = field(default_factory=Log) + users: List[str] = field(default_factory=list) + numbers: List[int] = field(default_factory=list) + +--- a/tests/structured_conf/data/dataclasses.py ++++ b/tests/structured_conf/data/dataclasses.py +@@ -34,7 +34,7 @@ + + @dataclass + class StructuredWithInvalidField: +- bar: NotStructuredConfig = NotStructuredConfig() ++ bar: NotStructuredConfig = field(default_factory=NotStructuredConfig) + + + @dataclass +@@ -75,7 +75,7 @@ + + @dataclass + class InterpolationToUser: +- user: User = User("Bond", 7) ++ user: User = field(default_factory=lambda: User("Bond", 7)) + admin: User = II("user") + + +@@ -251,14 +251,16 @@ + default_value: Nested + + # with default value +- user_provided_default: Nested = Nested(with_default=42) ++ user_provided_default: Nested = field( ++ default_factory=lambda: Nested(with_default=42) ++ ) + + value_at_root: int = 1000 + + + @dataclass + class NestedWithAny: +- var: Any = Nested() ++ var: Any = field(default_factory=Nested) + + + @dataclass +@@ -349,14 +351,14 @@ + + @dataclass + class StructuredOptional: +- with_default: Optional[Nested] = Nested() ++ with_default: Optional[Nested] = field(default_factory=Nested) + as_none: Optional[Nested] = None +- not_optional: Nested = Nested() ++ not_optional: Nested = field(default_factory=Nested) + + + @dataclass(frozen=True) + class FrozenClass: +- user: User = User(name="Bart", age=10) ++ user: User = field(default_factory=lambda: User(name="Bart", age=10)) + x: int = 10 + list: List[int] = field(default_factory=lambda: [1, 2, 3]) + +@@ -522,7 +524,7 @@ + + @dataclass + class Str2UserWithField(Dict[str, User]): +- foo: User = User("Bond", 7) ++ foo: User = field(default_factory=lambda: User("Bond", 7)) + + class Error: + @dataclass +@@ -544,7 +546,7 @@ + class FoobarParams: + foo: int = 10 + +- params: FoobarParams = FoobarParams() ++ params: FoobarParams = field(default_factory=FoobarParams) + + + @dataclass +@@ -563,8 +565,8 @@ + class PluginHolder: + none: Optional[Plugin] = None + missing: Plugin = MISSING +- plugin: Plugin = Plugin() +- plugin2: Plugin = ConcretePlugin() ++ plugin: Plugin = field(default_factory=Plugin) ++ plugin2: Plugin = field(default_factory=ConcretePlugin) + + + @dataclass +@@ -585,7 +587,9 @@ + + @dataclass + class Missing2: +- head: LinkedList = LinkedList(next=MISSING, value=1) ++ head: LinkedList = field( ++ default_factory=lambda: LinkedList(next=MISSING, value=1) ++ ) + + + @dataclass +--- a/tests/test_utils.py ++++ b/tests/test_utils.py +@@ -297,7 +297,7 @@ + + @dataclass + class _TestDataclassIllegalValue: +- x: Any = IllegalType() ++ x: Any = field(default_factory=IllegalType) + + + @attr.s(auto_attribs=True) +--- a/.circleci/config.yml ++++ b/.circleci/config.yml +@@ -38,4 +38,4 @@ + - test_linux: + matrix: + parameters: +- py_version: ["3.6", "3.7", "3.8", "3.9", "3.10"] ++ py_version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] +--- /dev/null ++++ b/news/feature.1023 +@@ -0,0 +1 @@ ++Support python3.11 +--- a/noxfile.py ++++ b/noxfile.py +@@ -3,7 +3,7 @@ + + import nox + +-DEFAULT_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10"] ++DEFAULT_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] + + PYTHON_VERSIONS = os.environ.get( + "NOX_PYTHON_VERSIONS", ",".join(DEFAULT_PYTHON_VERSIONS) +--- a/setup.py ++++ b/setup.py +@@ -64,6 +64,7 @@ + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", ++ "Programming Language :: Python :: 3.11", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + ], +--- a/docs/source/structured_config.rst ++++ b/docs/source/structured_config.rst +@@ -200,10 +200,10 @@ + ... class Group: + ... name: str = MISSING + ... # data classes can be nested +- ... admin: User = User() ++ ... admin: User = field(default_factory=User) + ... + ... # You can also specify different defaults for nested classes +- ... manager: User = User(name="manager", height=Height.TALL) ++ ... manager: User = field(default_factory=lambda: User(name="manager", height=Height.TALL)) + + >>> conf: Group = OmegaConf.structured(Group) + >>> print(OmegaConf.to_yaml(conf)) +@@ -580,8 +580,8 @@ + + >>> @dataclass + ... class MyConfig: +- ... server: Server = Server() +- ... log: Log = Log() ++ ... server: Server = field(default_factory=Server) ++ ... log: Log = field(default_factory=Log) + ... users: List[int] = field(default_factory=list) + + diff -Nru python-omegaconf-2.2.2/debian/patches/series python-omegaconf-2.2.2/debian/patches/series --- python-omegaconf-2.2.2/debian/patches/series 1969-12-31 20:00:00.000000000 -0400 +++ python-omegaconf-2.2.2/debian/patches/series 2022-12-25 12:39:24.000000000 -0400 @@ -0,0 +1 @@ +python-3.11.patch