{"id":19146264,"url":"https://github.com/01walid/py-dz-phone-number","last_synced_at":"2025-05-07T02:03:53.205Z","repository":{"id":65603006,"uuid":"272228750","full_name":"01walid/py-dz-phone-number","owner":"01walid","description":"Algerian phone numbers as a value object implementation in Python","archived":false,"fork":false,"pushed_at":"2020-06-16T13:45:13.000Z","size":20,"stargazers_count":29,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-07T02:03:48.395Z","etag":null,"topics":["algeria","dz","landline","mobile","phone","regex","telephone-numbers","value-object"],"latest_commit_sha":null,"homepage":"","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/01walid.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}},"created_at":"2020-06-14T15:23:50.000Z","updated_at":"2024-12-18T21:05:05.000Z","dependencies_parsed_at":"2023-01-31T10:25:11.580Z","dependency_job_id":null,"html_url":"https://github.com/01walid/py-dz-phone-number","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01walid%2Fpy-dz-phone-number","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01walid%2Fpy-dz-phone-number/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01walid%2Fpy-dz-phone-number/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01walid%2Fpy-dz-phone-number/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/01walid","download_url":"https://codeload.github.com/01walid/py-dz-phone-number/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252798852,"owners_count":21805886,"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","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":["algeria","dz","landline","mobile","phone","regex","telephone-numbers","value-object"],"created_at":"2024-11-09T07:43:42.558Z","updated_at":"2025-05-07T02:03:53.171Z","avatar_url":"https://github.com/01walid.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Algerian phone numbers as a value object\n\n\nInspired from [the PHP implementation](https://github.com/cherifGsoul/php-algerian-mobile-phone-number) with some differences (see below).\n\n------------\n\nAlgerian phone numbers as a value object implementation in Python. This can be used in your domain models or be integrated with your favorite framework.\n\nWhat is value object?\n\u003e In computer science, a value object is a small object that represents a simple entity whose equality is not based on identity: i.e. two value objects are equal when they have the same value, not necessarily being the same object.\n\nRead more on [wikipedia](https://en.wikipedia.org/wiki/Value_object).\n\n## Installation:\n\n```\npip install dz-phone-numbers\n```\n\n## Usage:\n\n```python\nfrom dz_phone_number import DZPhoneNumber\n\ndz_phone_number = DZPhoneNumber(\"0599000000\") # or DZPhoneNumber.from_string(\"0599000000\")\ndz_phone_number.indicative # \u003cCountryCode.LOCAL: '0'\u003e\ndz_phone_number.operator_or_region # \u003cMobileOperator.OOREDOO: 5\u003e\ndz_phone_number.suffix # '99000000'\n\ndz_phone_number.is_mobile() # True\ndz_phone_number.is_landline() # a.k.a Fixe. False\ndz_phone_number.is_ooredoo() # True\ndz_phone_number.is_djezzy() # false\ndz_phone_number.is_annaba() # false\n\nDZPhoneNumber(\"038123456\").is_annaba() # True\n\n# repr:\n\u003cDZPhoneNumber:CountryCode.LOCAL - MobileOperator: OOREDOO - 99000000\u003e\n\n# str:\nstr(dz_phone_number) # 0599000000\n```\n\n### Equality\n\n```python\nDZPhoneNumber(\"0599000000\") == DZPhoneNumber(\"+213 599000000\") # True\nDZPhoneNumber(\"(0) 599000000\") == DZPhoneNumber(\"0 599-00-00-00\") # True\nDZPhoneNumber(\"(0) 599000000\") == DZPhoneNumber(\"(0) 699000000\"\") # False\n```\n\n### Correctness \n\n```Python\ntry:\n    DZPhoneNumber(\"09 12 34 56 78\")\nexcept ValueError: # ValueError can catch it\n    pass\n# Otherwise you can also expect `InvalidDZPhoneNumber` (an alias of ValueError).\n```\n### Immutability\n\nThe object can't be modified if you try to modify of its members, a `TypeError` will be raised:\n```python\ndz_phone_number.number = '038123456' # will raise TypeError.\n```\n\n# Understanding the regex \n03 main parts of the full number are categorized into three groups: indicative (Country Code), Operator or Region (e.g. Ooredoo or Annaba), and the rest of the dial number.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://res.cloudinary.com/walid/image/upload/v1592310084/regex-explain1_ggau8t.png\" /\u003e\n\u003c/p\u003e\n\nThe regex uses Python's [capturing group](https://docs.python.org/3/howto/regex.html#grouping) feature built in its regex engine. Where \"Country Code\", \"Operator or Region\" and the \"Number\" are put into numbered groups when matched.\n\nThe regex also uses a conditional statemet in the form of `(?(1)yes|no)` where `(1)` is the capturing group number. The following picture explain how it's working:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://res.cloudinary.com/walid/image/upload/v1592310151/regex-explain2_hmvwgp.png\" /\u003e\n\u003c/p\u003e\n\n## Differences from the PHP implementation (as of writing this):\n- This raises a `ValueError` (Python built-in) instead of the broad `Exception` `InvalidDZPhoneNumber` is an alias of `ValueError`.\n- A different version of regex with support for landline (a.k.a fixe) numbers.\n- Enums are used to both limit landline possible values, and make it extensible (e.g. very easy if, say, a new operator got into Algeria).\n- This uses Python regex \"capturing groups\" feature. Where \"Country Code\", \"Operator or Region\" and the \"Number\" are put in groups when matched.\n- pytest are used instead of any other spec or behavior testing.\n- Immutability is achieved through `__slots__` and overriding `__setattr__` and `__delattr__`. This was a bit more flexibile that `@dataclass(frozen=True)`.\n\n# Bonuses \n\nThis is a simple, self-contained problem. One of the reasons I wrote this is to serve as a python package example for the Algerian Python community where:\n- The code is [Black](https://github.com/psf/black)-formatted. \n- Type annotated code using Python type hints. Checked with [MyPy](http://mypy-lang.org/).\n- The project structure follows what's common for Python projects. See the [Hitchhiker guide](https://docs.python-guide.org/writing/structure/).\n- A simple `Makefile` within to show how to build this (with Python wheels support) and how to release a package to pypi. Just issue `make` to see the available commands.\n- Example `setup.py`\n- Testing with pytest.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F01walid%2Fpy-dz-phone-number","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F01walid%2Fpy-dz-phone-number","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F01walid%2Fpy-dz-phone-number/lists"}