{"id":13501542,"url":"https://github.com/csparpa/fluentcheck","last_synced_at":"2025-12-28T10:23:07.736Z","repository":{"id":32472049,"uuid":"94079806","full_name":"csparpa/fluentcheck","owner":"csparpa","description":"Fluent assertions for Python","archived":false,"fork":false,"pushed_at":"2022-04-23T13:52:12.000Z","size":108,"stargazers_count":84,"open_issues_count":5,"forks_count":8,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-10-31T20:40:16.362Z","etag":null,"topics":["assertion-framework","assertion-library","assertions","check","fluent","fluent-assertions","fluent-interface","python","testing"],"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/csparpa.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":"2017-06-12T09:40:01.000Z","updated_at":"2024-04-26T19:03:32.000Z","dependencies_parsed_at":"2022-08-07T17:31:22.031Z","dependency_job_id":null,"html_url":"https://github.com/csparpa/fluentcheck","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csparpa%2Ffluentcheck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csparpa%2Ffluentcheck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csparpa%2Ffluentcheck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csparpa%2Ffluentcheck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csparpa","download_url":"https://codeload.github.com/csparpa/fluentcheck/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246167006,"owners_count":20734377,"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":["assertion-framework","assertion-library","assertions","check","fluent","fluent-assertions","fluent-interface","python","testing"],"created_at":"2024-07-31T22:01:41.069Z","updated_at":"2025-12-28T10:23:02.697Z","avatar_url":"https://github.com/csparpa.png","language":"Python","readme":"# Fluentcheck\n_Fluent assertion framework for Python_\n\nBored of using `assert` multiple times to check types, intervals, etc. on data passed as input to your Python functions?\nThis generates a lot of boilerplate code.\n\n__fluentcheck__ helps you reducing the lines of code providing a human-friendly and fluent way to make assertions.\n\nInstead of:\n\n```python\ndef my_function(n, obj):\n    assert n is not None\n    assert isinstance(n, float)\n    assert 0. \u003c n \u003c 1.\n    assert obj is not None\n    assert isinstance(obj, MyCustomType)\n```\n\nyou just streamline the assertions (\"checks\") you want to make, in a fluent way:\n\n```python\nfrom fluentcheck import Check\n\ndef my_function(n, obj):\n    Check(n).is_not_None().is_float().is_between(0., 1.)\n    Check(obj).is_not_None().is_subtype_of(MyCustomType)\n```\n\nYou can even use the alternate `Is` syntax:\n\n```python\nfrom fluentcheck import Is\n\ndef my_function(n, obj):\n    Is(n).not_none.float.between(0, 1)\n    Is(obj).not_none.subtype_of(MyCustomType)\n```\n\n__Fluentcheck__ can also be used as an _assertion framework in tests_.\n\n\n## Installation\n```shell\npip install fluentcheck\n```\nor \n\n```shell\npython setup.py install\n```\n\nOnly _Python 3_ is supported (because you DID update your code to Python3, didn't you?)\n\n\n## Usage\n\n### Check API\n\nSimply instantiate the `Check` wrapper around the Python value you want to\ncheck out, then fluently append assertions like this:\n\n```python\nfrom fluentcheck import Check\n\nCheck(my_value).assertion1().assertion2().assertion3() # and so on\n```\n\n### Is API\n\nSimply instantiate the `Is` wrapper around the Python value you want to\ncheck out, then fluently append assertions like this:\n\n```python\nfrom fluentcheck import Is\n\nIs(my_value).assertion1.assertion2_with_params(a, b).assertion3 # and so on\n```\n\n### When an assertion fails\n\nWhat if an assertion fails? A `CheckError` is raised: just catch it!\n\nPlease notice: if the order of assertions _matters_ to your overall goal, _then take care of it_!\n\n\n### Linters and Is API\n\nYou may run into warnings for code such as this when using the `Is` API:\n\n```python\nn = .4\nIs(n).not_none.float.non_negative\n\n# WARNING: Statement seems to have no effect ...\n```\n\nWhile not required for assertions to work, you can always \"call\" the last assertion to make linters happy: \n\n\n```python\nn = .4\nIs(n).not_none.float.non_negative()\n\n# Happy, calling non_negative() has no effect but the linter warnings are gone.\n```\n\n## What can I actually check with it?\nTo date, here's a list of assertions you can make:\n\n### Check API\n\n```python\n# Check(value).X where X is one of:\n\n# Numbers\nis_none()\nis_not_none()\nis_number()\nis_not_number()\nis_integer()\nis_not_integer()\nis_long()\nis_not_long()\nis_float()\nis_not_float()\nis_real()\nis_not_real()\nis_complex()\nis_not_complex()\nis_positive()\nis_not_positive()\nis_negative()\nis_not_negative()\nis_zero()\nis_not_zero()\nis_at_least(lower)\nis_at_most(upper)\nis_between(lower, upper)\nis_not_between(lower, upper)\n\n# Sequences\nis_empty()\nis_not_empty()\nis_iterable()\nis_not_iterable()\nis_couple()\nis_triplet()\nis_nuple(dimension)\nhas_dimensionality(dimensionality)\n\n# Tuples\nis_tuple()\n\n# Lists\nis_list()\n\n# Strings\nis_string()\nis_not_string()\ncontains_numbers()\nnot_contains_numbers()\ncontains_numbers_only()\ncontains_chars()\nnot_contains_chars()\ncontains_chars_only()\ncontains_spaces()\nnot_contains_spaces()\ncontains_char(_char)\nnot_contains_char(_char)\nis_shorter_than(n_chars)\nis_longer_than(n_chars)\nhas_length(n_chars)\nhas_not_length(n_chars)\nis_lowercase()\nis_not_lowercase()\nis_uppercase()\nis_not_uppercase()\nis_camelcase()\nis_not_camelcase()\nis_snakecase()\nis_not_snakecase()\nis_unicode()\nis_not_unicode()\nis_json()\nis_not_json()\nis_yaml()\nis_not_yaml()\nis_xml()\nis_not_xml()\nmatches(regex)\nnot_matches(regex)\n\n# Booleans\nis_boolean()\nis_not_boolean()\nis_true()\nis_not_true()\nis_truthy()\nis_not_truthy()\nis_false()\nis_not_false()\nis_falsy()\nis_not_falsy()\nhas_same_truth_of(val)\nhas_opposite_truth_of(val)\n\n# Dictionaries\nis_dict()\nis_not_dict()\nhas_keys(*args)\nhas_not_keys(*args)\n\n# Sets\nis_set()\nis_not_set()\nis_subset_of(_set)\nis_not_subset_of(_set)\nis_superset_of(_set)\nis_not_superset_of(_set)\nintersects(_set)\nnot_intersects(_set)\n\n# Functions\nis_runnable()\nis_not_runnable()\n\n# Modules\nis_module()\nis_not_module()\n\n# Type hierarchy\nis_subtype_of(_type)\nis_not_subtype_of(_type)\n\n# Custom types\nis_of_type(_type)\nis_not_of_type(_type)\n\n# Geographic coords\nis_latitude()\nis_longitude()\nis_azimuth()\nis_geopoint()\n\n# UUIDs\nis_uuid1()\nis_not_uuid1()\nis_uuid4()\nis_not_uuid4()\n\n```\n\n### Is API\n\n```python\n# Is(value).X where X is one of:\n\n# Numbers\nnone\nnot_none\nnumber\nnot_number\ninteger\nnot_integer\nfloat\nnot_float\nreal\nnot_real\ncomplex\nnot_complex\npositive\nnot_positive\nnegative\nnot_negative\nzero\nnot_zero\nat_least(lower)\nat_most(upper)\nbetween(lower, upper)\nnot_between(lower, upper)\n\n# Sequences\nempty\nnot_empty\niterable\nnot_iterable\nhas_dimensionality(dimensionality)\n\n# Tuples\ntuple\n\n# Lists\nlist\n\n# Strings\nstring\nnot_string\ncontains_numbers\nnot_contains_numbers\nonly_numbers\ncontains_chars\nnot_contains_chars\nonly_chars\ncontains_spaces\nnot_contains_spaces\ncontains_char(_char)\nnot_contains_char(_char)\nshorter_than(n_chars)\nlonger_than(n_chars)\nlength(n_chars)\nnot_length(n_chars)\n\njson\nnot_json\nmatches(regex)\nnot_matches(regex)\n\n# Booleans\nboolean\nnot_boolean\ntrue\nnot_true\ntruthy\nnot_truthy\nfalse\nnot_false\nfalsy\nnot_falsy\nhas_same_truth_of(val)\nhas_opposite_truth_of(val)\n\n# Dictionaries\ndict\nnot_dict\nhas_keys(*args)\nhas_not_keys(*args)\n\n# Sets\nset\nnot_set\nsubset_of(_set)\nnot_subset_of(_set)\nsuperset_of(_set)\nnot_superset_of(_set)\nintersects(_set)\nnot_intersects(_set)\n\n# Type hierarchy\nsubtype_of(_type)\nnot_subtype_of(_type)\n\n# UUIDs\nis_uuid1()\nis_not_uuid1()\nis_uuid4()\nis_not_uuid4()\n\n```\n\n\n## Coming soon\n\nThe following checks will be added in the upcoming versions:\n\n```python\n# Dates\nis_date()\nis_not_date()\nis_datetime()\nis_not_datetime()\nis_before(_datetime)\nis_not_before(_datetime)\nis_after(_datetime)\nis_not_after(_datetime)\nis_today()\nis_not_today()\nis_yesterday()\nis_not_yesterday()\nis_tomorrow()\nis_not_tomorrow()\nis_weekend()\nis_not_weekend()\nis_this_month()\nis_not_this_month()\nis_previous_month()\nis_not_previous_month()\nis_next_month()\nis_not_next_month()\nis_this_year()\nis_not_this_year()\nis_last_year()\nis_not_last_year()\nis_next_year()\nis_not_next_year()\nis_leap_year()\nis_not_leap_year()\nis_this_century()\nis_not_this_century()\nis_before(date)\nis_not_before(date)\nis_after(date)\nis_not_after(date)\nis_between_dates(lower, upper)\nis_not_between_dates(lower, upper)\nis_timezone_aware()\nis_not_timezone_aware()\nhas_timezone(tz)\nhas_not_timezone(tz)\n\n# Geographic coords\nis_plus_code()  # https://plus.codes/\nis_not_plus_code()\n\n# Check against a custom rule (lambda)\nconforms_to(func)\nnot_conforms_to(func)\n\n# Sequences\nis_sorted(rule=func)\nis_not_sorted(rule=func)\nis_subsequence_of(subseq)\nis_not_subsequence_of(subseq)\nhas_duplicates()\nhas_not_duplicates()\n\n# Objects\ncontains(element)\nnot_contains(element)\nhas_attribute(_attr)\nhas_not_attribute(_attr)\n\n\n```\n\n## License\nMIT license\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsparpa%2Ffluentcheck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsparpa%2Ffluentcheck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsparpa%2Ffluentcheck/lists"}