Skip to content

Fixes #24348: Strip URL scheme from hostPort to prevent ValueError#27191

Open
RajdeepKushwaha5 wants to merge 9 commits intoopen-metadata:mainfrom
RajdeepKushwaha5:fix/hostport-url-scheme-valueerror-24348
Open

Fixes #24348: Strip URL scheme from hostPort to prevent ValueError#27191
RajdeepKushwaha5 wants to merge 9 commits intoopen-metadata:mainfrom
RajdeepKushwaha5:fix/hostport-url-scheme-valueerror-24348

Conversation

@RajdeepKushwaha5
Copy link
Copy Markdown
Contributor

@RajdeepKushwaha5 RajdeepKushwaha5 commented Apr 9, 2026

Describe your changes:

Fixes #24348

When users enter a full URL like http://localhost:3306 or https://mydb.example.com:5432 in the hostPort connection field instead of just localhost:3306, the ingestion framework crashes with an unhelpful ValueError: invalid literal for int() with base 10.

Root cause: Code throughout the ingestion framework calls hostPort.split(":") expecting at most 2 parts (host:port), but a URL like http://localhost:3306 splits into 3 parts (["http", "//localhost", "3306"]), causing either unpacking errors or int("//localhost") failures.

Fix: Centralised hostPort sanitisation in BaseModel.model_post_init() (custom_pydantic.py), the base class for every generated Pydantic model. When any *Connection class is constructed with a hostPort containing ://, the scheme prefix is automatically stripped before any connector code ever accesses it.

This covers all 38+ connectors in a single place — no per-connector patches needed, and future connectors are automatically protected.

Changes (4 files):

  • custom_pydantic.py — Added hostPort sanitisation to model_post_init() (~15 lines)
  • db_utils.py — Added clean_host_port() utility and updated get_host_from_host_port() to use it (defence-in-depth)
  • test_db_utils.py — Unit tests for clean_host_port() (15+ assertions) and extended get_host_from_host_port() tests
  • test_build_connection_url.py — Integration tests for MySQL and Postgres with scheme-prefixed hostPort

How I tested:

  • Verified locally: CassandraConnection(hostPort='http://localhost:9042')hostPort becomes 'localhost:9042'
  • Clean hostPort values pass through unchanged ✓
  • Warning logged when scheme is detected ✓
  • All 24 helper cases pass; non-numeric ports (http://localhost:abc, jdbc:postgresql://host:abc/db, jdbc:postgresql://[::1]:abc) raise ValueError
  • make py_format_check (Black) clean ✓
  • All existing tests continue to pass ✓

Type of change:

  • Bug fix
  • Improvement
  • New feature
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • I have commented on my code, particularly in hard-to-understand areas.
  • I have added a test that covers the exact scenario we are fixing. For complex issues, comment the issue number in the test for future reference.

@RajdeepKushwaha5 RajdeepKushwaha5 requested a review from a team as a code owner April 9, 2026 05:43
Copilot AI review requested due to automatic review settings April 9, 2026 05:43
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prevents ingestion crashes when users mistakenly enter a full URL (e.g. http://localhost:3306) in hostPort by introducing a shared sanitization helper and applying it before hostPort parsing/URL construction, along with added test coverage.

Changes:

  • Added clean_host_port() utility to strip URL schemes (and trailing slashes) before parsing hostPort.
  • Updated multiple connectors and shared builders to call clean_host_port() before splitting/using hostPort.
  • Added/extended unit tests to cover scheme-prefixed hostPort inputs and connection URL generation.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
ingestion/src/metadata/utils/db_utils.py Adds clean_host_port() and uses it in get_host_from_host_port() to sanitize scheme-prefixed inputs.
ingestion/src/metadata/ingestion/connections/builders.py Applies clean_host_port() when generating DB URLs and when splitting host/port for IAM token generation.
ingestion/src/metadata/ingestion/source/database/cassandra/connection.py Uses clean_host_port() before splitting Cassandra hostPort.
ingestion/src/metadata/ingestion/source/database/db2/connection.py Uses clean_host_port() for DB2 host extraction and port parsing.
ingestion/src/metadata/ingestion/source/database/databricks/client.py Uses clean_host_port() to derive the Databricks workspace base host.
ingestion/src/metadata/ingestion/source/database/databricks/auth.py Uses clean_host_port() when building Databricks SDK host for auth flows.
ingestion/src/metadata/ingestion/source/database/redshift/connection.py Uses clean_host_port() when deriving host for IAM flow type detection.
ingestion/tests/unit/test_db_utils.py Adds tests for clean_host_port() and scheme-prefixed get_host_from_host_port() inputs.
ingestion/tests/unit/test_build_connection_url.py Adds integration-style tests ensuring MySQL/Postgres URL building works with scheme-prefixed hostPort.

Comment thread ingestion/src/metadata/utils/db_utils.py Outdated
Comment thread ingestion/src/metadata/ingestion/connections/builders.py
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

Copilot AI review requested due to automatic review settings April 9, 2026 07:55
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Comment thread ingestion/src/metadata/ingestion/connections/builders.py
Comment thread ingestion/src/metadata/utils/db_utils.py Outdated
Comment thread ingestion/src/metadata/utils/db_utils.py Outdated
@github-actions
Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

Copilot AI review requested due to automatic review settings April 11, 2026 20:00
@RajdeepKushwaha5 RajdeepKushwaha5 force-pushed the fix/hostport-url-scheme-valueerror-24348 branch from 8cec367 to fcfd026 Compare April 11, 2026 20:00
@github-actions
Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

Comment thread ingestion/src/metadata/ingestion/source/database/cassandra/connection.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread ingestion/src/metadata/utils/db_utils.py Outdated
Comment thread ingestion/src/metadata/utils/db_utils.py Outdated
@RajdeepKushwaha5 RajdeepKushwaha5 force-pushed the fix/hostport-url-scheme-valueerror-24348 branch from fcfd026 to 0b955fb Compare April 11, 2026 20:15
@github-actions
Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

Copilot AI review requested due to automatic review settings April 11, 2026 23:17
@RajdeepKushwaha5 RajdeepKushwaha5 force-pushed the fix/hostport-url-scheme-valueerror-24348 branch from 0b955fb to 6a779c3 Compare April 11, 2026 23:17
@github-actions
Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

ingestion/src/metadata/ingestion/source/database/db2/connection.py:90

  • In _get_ibmi_connection_args(), port_str = host_port.split(":")[1] is fragile: it will fail for bracketed IPv6 ([::1]:50000) and will also misbehave if clean_host_port() ever returns an unbracketed IPv6 host (e.g. from http://[::1]:50000). Prefer splitting from the right once (e.g. rsplit(':', 1)) and/or explicitly handling [...]:port to reliably extract the port.
    args = get_connection_args_common(connection)
    host_port = clean_host_port(connection.hostPort)
    if ":" in host_port:
        port_str = host_port.split(":")[1]
        try:
            args["port"] = int(port_str)

Comment thread ingestion/src/metadata/utils/db_utils.py Outdated
Comment thread ingestion/src/metadata/utils/db_utils.py Outdated
Comment thread ingestion/src/metadata/utils/db_utils.py Outdated
@RajdeepKushwaha5
Copy link
Copy Markdown
Contributor Author

ping @harshach

url = f"{connection.scheme.value}://"
url += f"{quote_plus(username)}:{quote_plus(password)}@"
url += connection.hostPort
url += clean_host_port(connection.hostPort)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens to other connectors? why are we making changes only to few connectors that to in a connection.py?

@RajdeepKushwaha5 RajdeepKushwaha5 force-pushed the fix/hostport-url-scheme-valueerror-24348 branch from 6a779c3 to 8ed98aa Compare April 12, 2026 04:05
@github-actions
Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@RajdeepKushwaha5
Copy link
Copy Markdown
Contributor Author

RajdeepKushwaha5 commented Apr 12, 2026

@harshach thanks for the feedback, you're absolutely right. Patching individual connector files was the wrong approach.

I've reworked this completely. The fix is now centralised in BaseModel.model_post_init() (custom_pydantic.py), which is the base class for every generated Pydantic model. When any *Connection class is constructed with a hostPort that contains ://, the scheme is automatically stripped before any connector code ever sees it.

What changed:

  • Removed all 6 per-connector patches (builders.py, cassandra, databricks, db2, redshift)
  • Added ~15 lines to model_post_init() in custom_pydantic.py — this covers all 38+ connectors automatically
  • Kept clean_host_port() in db_utils.py as a public utility (also used by get_host_from_host_port() as defence-in-depth)
  • Tests unchanged — they verify the end-to-end behaviour

The diff is now 4 files, 145 additions, 6 deletions (down from 9 files).

Verified locally: CassandraConnection(hostPort='http://localhost:9042')hostPort becomes 'localhost:9042'

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment on lines 168 to 170
return (
<SelectContext.Provider value={{ size }}>
<SelectContext.Provider value={{ fontSize, size }}>
<AriaComboBox menuTrigger="focus" {...otherProps}>
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title/description focus on ingestion hostPort sanitization and claim 4 ingestion files changed, but this PR also includes UI changes in openmetadata-ui-core-components (e.g., adding/passing fontSize through SelectContext). Please either update the PR description to account for these UI changes or split them into a separate PR to keep the scope aligned with the stated issue fix.

Copilot uses AI. Check for mistakes.
…Autocomplete

Unblocks CI on this PR. main is currently failing tsc --noEmit with TS2741 because open-metadata#27379 made fontSize a required field on SelectContext but only updated select.tsx. combobox.tsx and autocomplete.tsx also provide that context and were missed, cascading into all py-tests and Playwright failures on every open PR.

Mirrors the fix in PR open-metadata#27435.
The broad 'except Exception' in model_post_init() was swallowing the

intentional ValueError that clean_host_port raises for invalid ports

(e.g. 'http://localhost:abc'), leaving a malformed hostPort on the

connection object and turning a clear user error into an obscure

downstream failure.

The local import of clean_host_port is from a sibling module that

always exists, so the try/except was unnecessary defence. Removed it

so pydantic surfaces validation errors where they belong.
…r import

The model_post_init hook added in the previous commit imported
`clean_host_port` from `metadata.utils.db_utils` at runtime. That
module has a heavy dependency graph (OpenMetadata client, LineageParser,
generated schemas), so every *Connection class construction would drag
it in and cause circular-import failures during integration test
bootstrap.

The file docstring explicitly requires BaseModel to be 'self-sufficient
with only pydantic at import time', so the hostPort sanitisation is now
handled by a stdlib-only helper (_strip_hostport_scheme) colocated with
BaseModel. `clean_host_port` remains the public API in db_utils and
delegates to the same helper, preserving behaviour for all existing
callers and unit tests.
Copilot AI review requested due to automatic review settings April 17, 2026 02:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.


# HTTP prefix is stripped
self.assertEqual(clean_host_port("http://localhost:3306"), "localhost:3306")
self.assertEqual(clean_host_port("http://example.com:8080"), "example.com:8080")
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New assertions in this test exceed Black's default formatting width and will cause make py_format_check (black --check) to fail. Please run make py_format (or manually wrap these calls) so Black can reformat them consistently.

Suggested change
self.assertEqual(clean_host_port("http://example.com:8080"), "example.com:8080")
self.assertEqual(
clean_host_port("http://example.com:8080"), "example.com:8080"
)

Copilot uses AI. Check for mistakes.
get_lineage_by_query,
get_lineage_via_table_entity,
)
from metadata.ingestion.models.custom_pydantic import _strip_hostport_scheme
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

db_utils.py is importing _strip_hostport_scheme (a private underscored helper) from custom_pydantic.py. Since this is now used cross-module, consider making it a public helper (e.g., strip_hostport_scheme) or relocating the implementation to db_utils.py to avoid a fragile dependency on a private symbol.

Copilot uses AI. Check for mistakes.
Comment on lines 138 to +142
export const ComboBox = ({
placeholder = 'Search',
shortcut = true,
size = 'sm',
fontSize = 'md',
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says this change is limited to 4 ingestion files, but this PR also modifies UI core components (openmetadata-ui-core-components/...). Please either update the PR description to reflect the UI changes (and why they are needed for this fix) or split the UI changes into a separate PR to keep the scope focused.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment on lines +46 to +48
Raises ValueError if the scheme carries a non-numeric port so the user
gets a clear error instead of a silently broken hostPort.
"""
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _strip_hostport_scheme docstring says it “Raises ValueError if the scheme carries a non-numeric port”, but the JDBC-style not hostname fallback returns the stripped tail without port validation. Please either validate the port in that branch as well, or clarify the docstring to match the behavior.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

for sep in ("/", "?", "#"):
tail = tail.split(sep, 1)[0]
if "@" in tail:
tail = tail.rsplit("@", 1)[-1]
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the not hostname fallback branch, the function returns the stripped tail without validating the port component. For inputs like jdbc:postgresql://host:abc/db, this will return host:abc and the original int(port) failure can still happen later, which undermines the goal of producing a clearer error for non-numeric ports (and also makes the docstring claim about raising on non-numeric ports incomplete). Consider parsing tail for a host:port pattern and raising a ValueError when the port is present but non-numeric.

Suggested change
tail = tail.rsplit("@", 1)[-1]
tail = tail.rsplit("@", 1)[-1]
fallback_port = None
if tail.startswith("["):
closing_bracket = tail.find("]")
if closing_bracket != -1 and len(tail) > closing_bracket + 1:
if tail[closing_bracket + 1] == ":":
fallback_port = tail[closing_bracket + 2 :]
elif ":" in tail:
_, fallback_port = tail.rsplit(":", 1)
if fallback_port and not fallback_port.isdigit():
raise ValueError(
f"Invalid hostPort '{safe_label}'. Expected format is "
"'hostname[:port]' (e.g. 'localhost:3306')."
)

Copilot uses AI. Check for mistakes.
Comment on lines +95 to 98
Post-init hook for Connection classes:
- Sanitises ``hostPort`` by stripping accidental URL scheme prefixes.
- Converts raw ``dict`` values into ``FilterPattern`` objects.
"""
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description includes an auto-generated “Summary by Gitar” referencing UI changes (e.g., fontSize in AutocompleteBase/ComboBox), but this PR’s diff only modifies ingestion framework Python files. Please update/remove that summary to avoid a mismatch between the PR description and the actual changes being reviewed.

Copilot uses AI. Check for mistakes.
- Renames _strip_hostport_scheme to public strip_hostport_scheme so cross-module imports (db_utils.py) no longer depend on a private symbol; private alias kept for back-compat.

- Validates the port in the JDBC-style fallback branch so inputs like 'jdbc:postgresql://host:abc/db' raise ValueError with a clear message, matching the docstring contract instead of silently passing a broken hostPort downstream.

- Extends test_clean_host_port with the new fallback raise cases.
@gitar-bot
Copy link
Copy Markdown

gitar-bot Bot commented Apr 20, 2026

Code Review ✅ Approved 5 resolved / 5 findings

Refactors hostPort parsing logic to handle IPv6 brackets and missing ports correctly, resolving crashes in Cassandra, JDBC, and model initialization. The implementation now safely strips URL schemes and preserves credentials without relying on overly broad error handling.

✅ 5 resolved
Edge Case: Cassandra split(":") crashes when hostPort has no port

📄 ingestion/src/metadata/ingestion/source/database/cassandra/connection.py:75 📄 ingestion/src/metadata/ingestion/connections/builders.py:158-163 📄 ingestion/src/metadata/utils/db_utils.py:76
clean_host_port() can return just a hostname without a colon (e.g., "localhost") when no port is present — see db_utils.py:76. At cassandra/connection.py:75, the tuple unpacking host, port = clean_host_port(...).split(":") will raise ValueError: not enough values to unpack in that case.

This is the same class of crash the PR aims to fix. The builders.py change at line 158-162 correctly handles this by checking ":" not in cleaned before splitting, and the Databricks client uses *_ to absorb extra parts. The Cassandra path should follow the same defensive pattern.

Edge Case: JDBC fallback path preserves userinfo credentials in output

📄 ingestion/src/metadata/utils/db_utils.py:82-88
The JDBC-style URL fallback (lines 81-88) uses simple string splitting (rsplit("://", 1)[-1]) which does not strip the userinfo portion of the authority. For an input like jdbc:postgresql://user:pass@host:5432/db, the function returns user:pass@host:5432 instead of host:5432.

While JDBC URLs with embedded credentials in the hostPort field are unlikely in practice, this is a defense-in-depth path that should handle the case correctly.

Edge Case: Unguarded clean_host_port in model_post_init can crash model construction

📄 ingestion/src/metadata/ingestion/models/custom_pydantic.py:55-60
The clean_host_port() call in model_post_init (line 60) is not wrapped in a try/except, unlike the FilterPattern logic below it (line 62+). If a user provides an unusual hostPort value that causes clean_host_port to raise (e.g. http://localhost:abc raises ValueError), Pydantic model construction will fail entirely.

While failing fast on clearly invalid input is reasonable, this is inconsistent with the defensive pattern already established in the same method for FilterPattern. An unexpected edge-case input could prevent model instantiation when the existing connector code might still have handled it (or produced a more contextual error).

Edge Case: clean_host_port drops IPv6 brackets, breaking downstream splits

📄 ingestion/src/metadata/utils/db_utils.py:92
For a scheme-prefixed IPv6 hostPort like http://[::1]:3306, urlparse(...).hostname returns ::1 (without brackets), so clean_host_port returns ::1:3306. Downstream code that does split(":")[0] (e.g. get_host_from_host_port) would then extract an empty string instead of the IPv6 address.

This is a pre-existing limitation of the split(":") approach, but the new code could avoid making it worse by re-adding brackets when an IPv6 hostname is detected.

Edge Case: Broad except swallows intentional ValueError for invalid ports

📄 ingestion/src/metadata/ingestion/models/custom_pydantic.py:58-66 📄 ingestion/src/metadata/utils/db_utils.py:75-79
In model_post_init, the except Exception block (line 62) catches all exceptions from clean_host_port, including the intentional ValueError it raises when the port is genuinely invalid (e.g. http://localhost:abc). The handler only logs a warning and leaves the malformed hostPort value in place. This means downstream connector code will still crash with the same unhelpful ValueError: invalid literal for int() that this PR aims to fix.

For truly invalid input, the user should get a clear error at construction time rather than a confusing one later in the pipeline.

Options

Display: compact → Showing less information.

Comment with these commands to change:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ValueError: invalid literal for int() with base 10

4 participants