Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .tool_version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.16.4
1.17.0
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG OPENGREP_VERSION=v1.16.4
ARG OPENGREP_VERSION=v1.17.0
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

CI/README build examples pass --build-arg TOOL_VERSION=$(cat .tool_version), but this Dockerfile only defines/uses OPENGREP_VERSION. As a result, the build arg has no effect and .tool_version can drift from the opengrep binary version. Consider renaming the ARG to TOOL_VERSION (or updating CI/docs to pass OPENGREP_VERSION) and wiring it through consistently.

Copilot uses AI. Check for mistakes.

# Build codacy-opengrep wrapper
FROM golang:1.23-alpine3.21 AS builder
Expand Down
106 changes: 106 additions & 0 deletions docs/codacy-rules-i18n.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -432,3 +432,109 @@ rules:
impact: MEDIUM
confidence: LOW
likelihood: HIGH

- id: codacy.python.i18n.no-hardcoded-print-concat
severity: WARNING
languages:
- python
pattern-either:
- pattern: print("..." + ...)
- pattern: print(... + "...")
message: >-
Avoid hardcoded or concatenated strings in print. Use an i18n translation function (e.g., _("key")) with .format() or f-strings.
metadata:
category: codestyle
subcategory: i18n
description: Flags hardcoded string literals concatenated in print calls to enforce localization
technology:
- python
impact: MEDIUM
confidence: LOW
likelihood: HIGH

- id: codacy.python.i18n.no-hardcoded-strftime
severity: WARNING
languages:
- python
pattern: $X.strftime("...")
message: >-
Avoid hardcoded date format strings in strftime. Use locale.nl_langinfo(locale.D_FMT) or similar locale-aware formatting.
metadata:
category: codestyle
subcategory: i18n
description: Flags hardcoded date format strings passed to strftime to enforce locale-aware date formatting
technology:
- python
impact: MEDIUM
confidence: HIGH
likelihood: HIGH

- id: codacy.python.i18n.no-hardcoded-number-format
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚪ LOW RISK

Suggestion: The rationale for flagging hardcoded number formatting is that decimal separators (period vs. comma) are locale-dependent. Using :.Nf forces a period, which is incorrect for many locales. Consider adding this context to the rule description to help users understand the i18n impact.

severity: WARNING
languages:
- python
pattern-regex: ":\\.[0-9]+f"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

The global regex :\.[0-9]+f is too generic and will flag matches in comments, documentation, or technical strings (like other regexes). Update the rule codacy.python.i18n.no-hardcoded-number-format to use structural Semgrep patterns for f-strings and .format() calls instead of a global pattern-regex.

message: >-
Avoid using :.Nf format specifiers for user-visible number formatting. Use locale.currency() or locale.format_string() for locale-aware formatting.
metadata:
category: codestyle
subcategory: i18n
description: Flags :.Nf format specifiers in f-strings used for user-visible numbers instead of locale-aware formatting
technology:
- python
impact: MEDIUM
confidence: LOW
likelihood: HIGH

- id: codacy.cpp.i18n.no-hardcoded-cout
severity: WARNING
languages:
- cpp
pattern: std::cout << "$MSG"
message: >-
Avoid hardcoded strings in std::cout. Use a localization function or resource bundle for user-facing output.
metadata:
category: codestyle
subcategory: i18n
description: Flags hardcoded string literals streamed directly to std::cout to enforce localization
technology:
- cpp
impact: MEDIUM
confidence: LOW
likelihood: HIGH

- id: codacy.cpp.i18n.no-hardcoded-strftime
severity: WARNING
languages:
- cpp
pattern-either:
- pattern: std::strftime($BUF, $SIZE, "$FMT", $TIME);
- pattern: strftime($BUF, $SIZE, "$FMT", $TIME);
message: >-
Avoid hardcoded date format strings in strftime. Use locale-aware date formatting (e.g., std::put_time with a locale-imbued stream).
metadata:
category: codestyle
subcategory: i18n
description: Flags hardcoded date format strings passed to strftime to enforce locale-aware date formatting
technology:
- cpp
impact: MEDIUM
confidence: HIGH
likelihood: HIGH

- id: codacy.cpp.i18n.no-hardcoded-number-format
severity: WARNING
languages:
- cpp
pattern: std::setprecision($N)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

Suggestion: This rule will flag technical formatting that doesn't require localization (e.g., logging or data serialization). Narrow the codacy.cpp.i18n.no-hardcoded-number-format rule to only flag std::setprecision when it's part of a stream expression involving std::cout or similar user-facing streams.

message: >-
Avoid using std::setprecision for user-visible number formatting. Imbue the stream with a locale and use std::use_facet<std::numpunct> for locale-aware output.
metadata:
category: codestyle
subcategory: i18n
description: Flags std::setprecision used for user-visible number formatting instead of locale-aware alternatives
technology:
- cpp
impact: MEDIUM
confidence: LOW
likelihood: HIGH
6 changes: 6 additions & 0 deletions docs/multiple-tests/i18n/patterns.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@
<module name="codacy.js.i18n.no-hardcoded-throw-error" />
<module name="codacy.java.i18n.no-hardcoded-map-put" />
<module name="codacy.java.i18n.no-hardcoded-map-of" />
<module name="codacy.python.i18n.no-hardcoded-print-concat" />
<module name="codacy.python.i18n.no-hardcoded-strftime" />
<module name="codacy.python.i18n.no-hardcoded-number-format" />
<module name="codacy.cpp.i18n.no-hardcoded-cout" />
<module name="codacy.cpp.i18n.no-hardcoded-strftime" />
<module name="codacy.cpp.i18n.no-hardcoded-number-format" />
</module>
52 changes: 52 additions & 0 deletions docs/multiple-tests/i18n/results.xml
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,56 @@
message="Avoid hardcoded strings in Map.put(). Use ResourceBundle.getString() or a localization key for user-facing messages."
severity="warning" />
</file>
<file name="Order.cpp">
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="25"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="31"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="34"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-number-format" line="40"
message="Avoid using std::setprecision for user-visible number formatting."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="44"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="52"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="57"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-strftime" line="64"
message="Avoid hardcoded date format strings in strftime."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="65"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="73"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
<error source="codacy.cpp.i18n.no-hardcoded-cout" line="74"
message="Avoid hardcoded strings in std::cout."
severity="warning" />
</file>
<file name="Sample.py">
<error source="codacy.python.i18n.no-hardcoded-print-concat" line="35"
message="Avoid hardcoded or concatenated strings in print."
severity="warning" />
<error source="codacy.python.i18n.no-hardcoded-strftime" line="48"
message="Avoid hardcoded date format strings in strftime."
severity="warning" />
<error source="codacy.python.i18n.no-hardcoded-number-format" line="48"
message="Avoid using :.Nf format specifiers for user-visible number formatting."
severity="warning" />
<error source="codacy.python.i18n.no-hardcoded-print-concat" line="61"
message="Avoid hardcoded or concatenated strings in print."
severity="warning" />
<error source="codacy.python.i18n.no-hardcoded-print-concat" line="62"
message="Avoid hardcoded or concatenated strings in print."
severity="warning" />
</file>
</checkstyle>
83 changes: 83 additions & 0 deletions docs/multiple-tests/i18n/src/Sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import datetime
import locale
import gettext

# Set up gettext (only English & French, but French translations missing some keys)
locales = {
"en": gettext.translation("messages", localedir="locales", languages=["en"], fallback=True),
"fr": gettext.translation("messages", localedir="locales", languages=["fr"], fallback=True),
}

current_locale = "en"
_ = locales[current_locale].gettext

orders = [
{"id": 1, "customer": "Alice", "amount": 1234.56, "date": datetime.date.today()},
{"id": 2, "customer": "Bob", "amount": 98765.43, "date": datetime.date.today()},
]


def switch_language(lang):
global _, current_locale
if lang in locales:
current_locale = lang
_ = locales[lang].gettext
else:
print(f"Language {lang} not supported, falling back to English")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

Suggestion: This fallback error message is hardcoded and won't be translated, which is inconsistent with the i18n practices being established. Since the new 'no-hardcoded-print-concat' rule only flags concatenation, this f-string is missed. Use a translation wrapper: print(_("Language {lang} not supported").format(lang=lang)).

current_locale = "en"
_ = locales["en"].gettext


def add_order(customer, amount):
today = datetime.date.today()

# ❌ BAD: Hardcoded English + concatenation
print("Order for " + customer + " created on " + str(today))

# ✅ GOOD: Proper i18n message
print(_("Order for {customer} created on {date}").format(customer=customer, date=today))

orders.append({"id": len(orders) + 1, "customer": customer, "amount": amount, "date": today})


def list_orders():
print(_("Order List"))
print("------------")
for o in orders:
# ❌ BAD: Hardcoded date format
print(f"{o['customer']} | {o['date'].strftime('%m/%d/%Y')} | ${o['amount']:.2f}")

# ✅ GOOD: Locale-aware formatting
locale.setlocale(locale.LC_ALL, current_locale)
formatted_date = o['date'].strftime(locale.nl_langinfo(locale.D_FMT))
formatted_amount = locale.currency(o['amount'], grouping=True)
Comment on lines +49 to +53
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

locale.setlocale(locale.LC_ALL, current_locale) is passed values like "en"/"fr", which are not valid locale identifiers on many systems (commonly raises locale.Error: unsupported locale setting). Consider mapping language codes to concrete locales (e.g., "en_US.UTF-8", "fr_FR.UTF-8") and setting the locale once when switching languages (with a safe fallback) rather than inside the per-order loop.

Copilot uses AI. Check for mistakes.
print(f"{o['customer']} | {formatted_date} | {formatted_amount}")


def summary():
total = sum(o["amount"] for o in orders)

# ❌ BAD: Hardcoded string
print("Total Orders: " + str(len(orders)))
print("Total Revenue: $" + str(total))

# ✅ GOOD: Localized message
print(_("Total Orders: {count}").format(count=len(orders)))
print(_("Total Revenue: {revenue}").format(revenue=locale.currency(total, grouping=True)))
Comment on lines +64 to +66
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

summary() calls locale.currency(total, grouping=True) without ensuring a usable locale has been set. If the process locale is the default "C" locale (or if list_orders() hasn’t run yet / setlocale fails), this can raise ValueError: Currency formatting is not possible using the 'C' locale. Set the locale before currency formatting (or handle failures) to keep this sample runnable.

Copilot uses AI. Check for mistakes.


if __name__ == "__main__":
print(_("Welcome to Order Management System"))

list_orders()

add_order("Charlie", 555.75)

print("\nAfter Adding Order:")
list_orders()

summary()

print("\nSwitching to French (missing translations -> fallback):")
switch_language("fr")
list_orders()