{"id":31029999,"url":"https://github.com/yusing/typing-ex","last_synced_at":"2025-09-13T22:57:39.886Z","repository":{"id":222830769,"uuid":"758482362","full_name":"yusing/typing-ex","owner":"yusing","description":null,"archived":false,"fork":false,"pushed_at":"2024-02-20T22:38:38.000Z","size":75,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-05-02T03:53:07.515Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yusing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-02-16T12:21:49.000Z","updated_at":"2024-03-19T07:38:19.000Z","dependencies_parsed_at":"2024-02-18T02:46:26.017Z","dependency_job_id":null,"html_url":"https://github.com/yusing/typing-ex","commit_stats":null,"previous_names":["yusing/typing-ex"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/yusing/typing-ex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusing%2Ftyping-ex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusing%2Ftyping-ex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusing%2Ftyping-ex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusing%2Ftyping-ex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yusing","download_url":"https://codeload.github.com/yusing/typing-ex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yusing%2Ftyping-ex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275038258,"owners_count":25394640,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-13T02:00:10.085Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-13T22:57:24.750Z","updated_at":"2025-09-13T22:57:39.879Z","avatar_url":"https://github.com/yusing.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# typing-ex\n\n## A python package for extended `typing` (python 3.8+)\n\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=coverage)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=ncloc)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=bugs)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=security_rating)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=yusing_typing-ex\u0026metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=yusing_typing-ex)\n\n## Notice\n\nEven with all tests passed, unexpected bugs might occur on edge cases\n\n## Project Overview\n\nI made this for fun, and also as a dependency for my other project [docker-playbook](https://github.com/yusing/docker-playbook) (working in progress).\n\nIf you found any bug, or have any suggestions, please let me know.\n\n## Target Audience\n\nPeople who want more strict type checking and less runtime errors / bugs.\n\n## Comparison\n\n[typeguard](https://github.com/agronholm/typeguard) provides runtime type checking for functions and class methods with `@typeguard` decorator. This project aims to enforce type annotation instead.\n\n[mypy](https://github.com/python/mypy) provides static type checking, a good companion for this project to provide both static and runtime type checking.\n\n## Installation\n\n`pip install typing-ex`\n\n## Modules/Classes\n\nAll Docs in [docs](docs/) (AI generated with small modification, may be incomplete)\n\n### TypedDefaultDict *[typed_defaultdict.py](typing_ex/typed_defaultdict.py)* [Documentation](docs/TypedDefaultDict.md)\n\n`TypedDefaultDict` combines features of `TypedDict` and `defaultdict` with type checking in `__init__`, `__setitem__`, `__setattr__` and `update()`, similar to `pydantic.BaseModel`.\n\nAttributes without type annotation or starting with underscore \"_\" will be treated as class variables\n\nGood for writing schema as a class for `JSON`/`YAML`/`XML`/etc. data which provides both static and runtime type checking.\n\n- `TypedDefaultDict.schema`: the schema dictionary: `MappingProxyType[str, NamedTuple[default: Any, type:TypeInfo]]`\n- `TypedDefaultDict.on_get_unknown_property`: called on getting unknown property\n- `TypedDefaultDict.on_set_unknown_property`: called on setting unknown property\n- `TypedDefaultDict.set`: set a property to a value without property check and type check\n- `@factorymethod(property_name: str)`: defines a factory method for property\n\n```python\nclass OtherClass:\n    def __self__(self, s_list: List[str]):\n        ...\n\nclass MyModel(TypedDefaultDict):\n    key1: str = \"default value\"\n    key2: Optional[int] \n    complex_key: SomeClass\n\n    @factorymethod(\"complex_key\")\n    def complex_key_factory(value: List[str]) -\u003e OtherClass:\n        return OtherClass(value)\n\nmy_dict = MyModel(key1=\"value1\", complex_key=[\"1\", \"2\", \"3\"])\n# or dict way\nmy_dict = MyModel({\n    \"key1\": \"value1\",\n    \"complex_key\": [\"1\", \"2\", \"3\"]\n})\nprint(my_dict[\"key1\"])  # Output: value1\nprint(my_dict.complex_key)  # Output: By definition of OtherClass\n```\n\n### TypeInfo *[type_info.py](typing_ex/type_info.py)* [Documentation](docs/TypeInfo.md)\n\n`TypeInfo` provides type information and run-time type checking, no more `isinstance`, `issubclass`, `is`, `==` mess.\n\nUseful when you want to check / assert variable type in runtime.\n\n`TypeInfo` provides type information and run-time type checking\n\n- `TypeInfo.get(t)`: alias of `TypeInfo[t]`\n- `TypeInfo.of(value)`: return a `TypeInfo` object that represents the type of `value`\n- `TypeInfo.check_union(t1, t2)`: check if union type t1 fulfill union type t2\n- `TypeInfo[t].type`: type\n- `TypeInfo[t].origin`: unsubscripted type\n- `TypeInfo[t].args`: type arguments\n- `TypeInfo[t].name`: name of type (including arguments)\n- `TypeInfo[t].check_value(value)`: check if value matches the type in type info\n- `TypeInfo[t].is_*`: check if type is _\n\n### EnumEx *[enum_ex.py](typing_ex/enum_ex.py)* [Documentation](docs/EnumEx.md)\n\n`EnumEx` is a `Enum` like class that support enum aliasing (keeping same value but different name). Useful if you want to output a different name but with same internal implementation.\n\n- `EnumEx.__iter__`: a generator of all non-alias enum instances.\n- `EnumEx.names`: a tuple of all enum names.\n- `EnumEx.values`: a tuple of all enum values.\n- `EnumEx.enums`: a tuple of all enum instances.\n- `EnumEx.value_type`: returns `__value_type__` if defined, int otherwise.\n\n- `EnumEx.X.value`: value of enum X\n- `EnumEx.X.name`: name of enum X (i.e. X)\n- `EnumEx.X_ALIAS.orig_name`: original name of enum X_ALIAS (i.e. X)\n- `EnumEx.X_ALIAS.origin`: origin enum of X_ALIAS (i.e. EnumEx.X)\n\n```python\nclass ActionEnum(EnumEx):\n    __value_type__ = int  # Optional: Specify value type (defaults to `int`)\n    STOP = 0\n    CREATE = 1\n    START = CREATE # Alias for CREATE\n    UPDATE = 2\n    RESTART = UPDATE # Alias for RESTART\nprint(Action.CREATE)  # Output: CREATE \nprint(Action.START)  # Output: START\nprint(Action.START.orig_name)  # Output: CREATE\nprint(MyEnum.START.value)  # Output: 1\n\nclass Action:\n    action :ActionEnum\n    def start(self): ...\n    def stop(self): ...\n    def restart(self): ...\n    def execute(self):\n        with ProgressBar() as progress:\n            progress.text = f\"{action.name.lower()}ing...\"\n            getattr(self, action.orig_name.lower())()\n            progress.text = \"Done\"\n```\n\n### Frozen *[frozen.py](typing_ex/frozen.py)*\n\nUseful when you want to lock data after processing, without static type checker complaining (i.e. when casting it to `tuple`)\n\n- `FrozenList`: Immutable `list`\n- `FrozenDict`: Immutable `dict`\n- `frozen_copy`: Create frozen copy of supported types (`Sequence`, `Set`, `Mapping`)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyusing%2Ftyping-ex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyusing%2Ftyping-ex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyusing%2Ftyping-ex/lists"}