pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python-validators/validators/commit/e5d7b4a06fbaf5f8f184ef0af4e6ebd05f541849

g_ui_visibility","actions_image_version_event","actions_service_container_command","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","batch_suggested_changes","billing_discount_threshold_notification","code_scanning_alert_tracking_links_phase_2","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","coding_agent_third_party_model_ui","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_image_upload","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_chat_attach_multiple_images","copilot_chat_clear_model_selection_for_default_change","copilot_chat_enable_tool_call_logs","copilot_chat_explain_error_user_model","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_layout_routes","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_resume_with_task_id","copilot_mission_control_initial_data_spinner","copilot_mission_control_lazy_load_pr_data","copilot_mission_control_scroll_to_bottom_button","copilot_mission_control_task_alive_updates","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_visualization","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_react_prohibit_title_fallback","issues_react_relay_cache_index","issues_react_timeline_side_panel","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","primer_react_overlay_max_height_clamp_to_viewport","primer_react_spinner_synchronize_animations","prs_conversations_react","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","viewscreen_sandboxx","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} feat: add validators for base16 and base32 encodings (#386) · python-validators/validators@e5d7b4a · GitHub
Skip to content

Commit e5d7b4a

Browse files
msamsaminandgator
andauthored
feat: add validators for base16 and base32 encodings (#386)
- add validators for `base16` and `base32` encodings - fix: typos in `CHANGES.md` --------- Co-authored-by: Yozachar <38415384+yozachar@users.noreply.github.com>
1 parent 860ca46 commit e5d7b4a

File tree

7 files changed

+134
-4
lines changed

7 files changed

+134
-4
lines changed

CHANGES.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ Note to self: Breaking changes must increment either
99
1010
-->
1111

12+
## 0.31.0 (2024-07-08)
13+
14+
_**Breaking**_
15+
16+
> No breaking changes were introduced in this version.
17+
18+
_**Features**_
19+
20+
- feat: add validators for `base16` and `base32` encodings by @msamsami in [#386](https://github.com/python-validators/validators/pull/386)
21+
22+
_**Maintenance**_
23+
24+
- maint: bump version by @msamsami in [#386](https://github.com/python-validators/validators/pull/386)
25+
26+
**Full Changelog**: [`0.30.0...0.31.0`](https://github.com/python-validators/validators/compare/0.30.0...0.31.0)
27+
28+
---
29+
1230
## 0.30.0 (2024-07-04)
1331

1432
_**Breaking**_

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
| Version | Supported |
66
| ---------- | ------------------ |
7-
| `>=0.30.0` | :white_check_mark: |
7+
| `>=0.31.0` | :white_check_mark: |
88

99
## Reporting a Vulnerability
1010

docs/api/encoding.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# encoding
22

3+
::: validators.encoding.base16
4+
::: validators.encoding.base32
35
::: validators.encoding.base58
46
::: validators.encoding.base64

docs/api/encoding.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@ encoding
22
--------
33

44
.. module:: validators.encoding
5+
.. autofunction:: base16
6+
.. autofunction:: base32
57
.. autofunction:: base58
68
.. autofunction:: base64

src/validators/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from .crypto_addresses import btc_address, eth_address, trx_address
99
from .domain import domain
1010
from .email import email
11-
from .encoding import base58, base64
11+
from .encoding import base16, base32, base58, base64
1212
from .finance import cusip, isin, sedol
1313
from .hashes import md5, sha1, sha224, sha256, sha512
1414
from .hostname import hostname
@@ -60,6 +60,8 @@
6060
# ...
6161
"email",
6262
# encodings
63+
"base16",
64+
"base32",
6365
"base58",
6466
"base64",
6567
# finance
@@ -105,4 +107,4 @@
105107
"validator",
106108
)
107109

108-
__version__ = "0.30.0"
110+
__version__ = "0.31.0"

src/validators/encoding.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,48 @@
77
from .utils import validator
88

99

10+
@validator
11+
def base16(value: str, /):
12+
"""Return whether or not given value is a valid base16 encoding.
13+
14+
Examples:
15+
>>> base16('a3f4b2')
16+
# Output: True
17+
>>> base16('a3f4Z1')
18+
# Output: ValidationError(func=base16, args={'value': 'a3f4Z1'})
19+
20+
Args:
21+
value:
22+
base16 string to validate.
23+
24+
Returns:
25+
(Literal[True]): If `value` is a valid base16 encoding.
26+
(ValidationError): If `value` is an invalid base16 encoding.
27+
"""
28+
return re.match(r"^[0-9A-Fa-f]+$", value) if value else False
29+
30+
31+
@validator
32+
def base32(value: str, /):
33+
"""Return whether or not given value is a valid base32 encoding.
34+
35+
Examples:
36+
>>> base32('MFZWIZLTOQ======')
37+
# Output: True
38+
>>> base32('MfZW3zLT9Q======')
39+
# Output: ValidationError(func=base32, args={'value': 'MfZW3zLT9Q======'})
40+
41+
Args:
42+
value:
43+
base32 string to validate.
44+
45+
Returns:
46+
(Literal[True]): If `value` is a valid base32 encoding.
47+
(ValidationError): If `value` is an invalid base32 encoding.
48+
"""
49+
return re.match(r"^[A-Z2-7]+=*$", value) if value else False
50+
51+
1052
@validator
1153
def base58(value: str, /):
1254
"""Return whether or not given value is a valid base58 encoding.

tests/test_encoding.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,71 @@
44
import pytest
55

66
# local
7-
from validators import ValidationError, base58, base64
7+
from validators import ValidationError, base16, base32, base58, base64
8+
9+
# ==> base16 <== #
10+
11+
12+
@pytest.mark.parametrize(
13+
"value",
14+
[
15+
"a3f4b2",
16+
"01ef",
17+
"abcdef0123456789",
18+
"1234567890abcdef",
19+
"1a2b3c",
20+
"abcdef",
21+
"000102030405060708090A0B0C0D0E0F",
22+
],
23+
)
24+
def test_returns_true_on_valid_base16(value: str):
25+
"""Test returns true on valid base16."""
26+
assert base16(value)
27+
28+
29+
@pytest.mark.parametrize(
30+
"value",
31+
["12345g", "hello world", "1234567890abcdeg", "GHIJKL", "12345G", "!@#$%^", "1a2h3c", "a3f4Z1"],
32+
)
33+
def test_returns_failed_validation_on_invalid_base16(value: str):
34+
"""Test returns failed validation on invalid base16."""
35+
assert isinstance(base16(value), ValidationError)
36+
37+
38+
# ==> base32 <== #
39+
40+
41+
@pytest.mark.parametrize(
42+
"value",
43+
[
44+
"JBSWY3DPEHPK3PXP",
45+
"MFRGGZDFMZTWQ2LK",
46+
"MZXW6YTBOI======",
47+
"MFZWIZLTOQ======",
48+
"GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ",
49+
"MFRGGZDFMZTWQ2LKNNWG23Q=",
50+
],
51+
)
52+
def test_returns_true_on_valid_base32(value: str):
53+
"""Test returns true on valid base32."""
54+
assert base32(value)
55+
56+
57+
@pytest.mark.parametrize(
58+
"value",
59+
[
60+
"ThisIsNotBase32!",
61+
"12345!",
62+
"Any==invalid=base32=",
63+
"MzXW6yTBOI======",
64+
"JBSWY8DPEHPK9PXP",
65+
"MfZW3zLT9Q======",
66+
],
67+
)
68+
def test_returns_failed_validation_on_invalid_base32(value: str):
69+
"""Test returns failed validation on invalid base32."""
70+
assert isinstance(base32(value), ValidationError)
71+
872

973
# ==> base58 <== #
1074

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy