nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: rrrene/credo
Pull request #618 (2018-12-30 18:32:13)

Bang sigil option
modifies the 'no variable rebinding' to allow for a bang sigil, if the ":allow_bang" option is set.


Patch:
diff --git a/lib/credo/check/refactor/variable_rebinding.ex b/lib/credo/check/refactor/variable_rebinding.ex
index 33bfe638..c9a1d94c 100644
--- a/lib/credo/check/refactor/variable_rebinding.ex
+++ b/lib/credo/check/refactor/variable_rebinding.ex
@@ -28,6 +28,15 @@ defmodule Credo.Check.Refactor.VariableRebinding do
         verified_time
       end
 
+  In some rare cases you might really want to rebind a variable.  This can be
+  enabled "opt-in" on a per-variable basis by setting the :allow_bang option
+  to true and adding a bang suffix sigil to your variable.
+
+      def uses_mutating_parameters(params!) do
+        params! = do_a_thing(params!)
+        params! = do_another_thing(params!)
+        params! = do_yet_another_thing(params!)
+      end
   """
   @explanation [check: @checkdoc]
 
@@ -40,13 +49,14 @@ defmodule Credo.Check.Refactor.VariableRebinding do
     Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta))
   end
 
-  def traverse([do: {:__block__, _, ast}], issues, issue_meta) do
+  def traverse([do: {:__block__, _, ast}], issues, {_, _, opt} = issue_meta) do
     variables =
       ast
       |> Enum.map(&find_assignments/1)
       |> List.flatten()
       |> Enum.filter(&(&1 != nil))
       |> Enum.filter(&only_variables/1)
+      |> Enum.reject(&bang_sigil(&1, opt[:allow_bang]))
 
     duplicates =
       variables
@@ -142,4 +152,11 @@ defmodule Credo.Check.Refactor.VariableRebinding do
     |> String.starts_with?("_")
     |> Kernel.not()
   end
+
+  defp bang_sigil({name, _}, allowed) do
+    allowed &&
+      name
+      |> Atom.to_string()
+      |> String.ends_with?("!")
+  end
 end


Test patch:
diff --git a/test/credo/check/refactor/variable_rebinding_test.exs b/test/credo/check/refactor/variable_rebinding_test.exs
index d0c33625..a35d010e 100644
--- a/test/credo/check/refactor/variable_rebinding_test.exs
+++ b/test/credo/check/refactor/variable_rebinding_test.exs
@@ -36,6 +36,19 @@ defmodule Credo.Check.Refactor.VariableRebindingTest do
     |> refute_issues(@described_check)
   end
 
+  test "rebinding opt-in bang sigils is allowed" do
+    """
+    defmodule CredoSampleModule do
+      def some_function(parameter1, parameter2) do
+        a! = 1
+        a! = 2
+      end
+    end
+    """
+    |> to_source_file
+    |> refute_issues(@described_check, allow_bang: true)
+  end
+
   #
   # cases raising issues
   #
@@ -121,4 +134,17 @@ defmodule Credo.Check.Refactor.VariableRebindingTest do
     |> to_source_file
     |> assert_issue(@described_check)
   end
+
+  test "rebinding bang sigils is forbidden without the :allow_bang option" do
+    """
+    defmodule CredoSampleModule do
+      def some_function(parameter1, parameter2) do
+        a! = 1
+        a! = 2
+      end
+    end
+    """
+    |> to_source_file
+    |> assert_issue(@described_check)
+  end
 end
Repository: rrrene/credo
Pull request #622 (2019-01-09 17:04:23)

Fix StringSigils to not crash with strings containing non-UTF8 characters
Currently credo is crashing for the following code:

```elixir
@bad_data %{
  "key" => "\xFF"
}
```
```
** (EXIT from #PID<0.91.0>) an exception was raised:
    ** (FunctionClauseError) no function clause matching in Credo.Check.Readability.StringSigils.too_many_quotes?/3
        lib/credo/check/readability/string_sigils.ex:114: Credo.Check.Readability.StringSigils.too_many_quotes?(<<255>>, 0, 3)
        lib/credo/check/readability/string_sigils.ex:96: Credo.Check.Readability.StringSigils.issues_for_string_literal/5
        lib/credo/check/readability/string_sigils.ex:63: Credo.Check.Readability.StringSigils.traverse/4
        (elixir) lib/macro.ex:282: anonymous fn/4 in Macro.do_traverse_args/4
        (elixir) lib/enum.ex:1418: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
        (elixir) lib/macro.ex:248: Macro.do_traverse/4
        (elixir) lib/enum.ex:1418: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
        (elixir) lib/enum.ex:1418: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
```


Patch:
diff --git a/lib/credo/check/readability/string_sigils.ex b/lib/credo/check/readability/string_sigils.ex
index 075b398b..41e59b4c 100644
--- a/lib/credo/check/readability/string_sigils.ex
+++ b/lib/credo/check/readability/string_sigils.ex
@@ -128,6 +128,10 @@ defmodule Credo.Check.Readability.StringSigils do
     too_many_quotes?(rest, count, limit)
   end
 
+  defp too_many_quotes?(<<_::binary>>, _count, _limit) do
+    false
+  end
+
   defp issue_for(issue_meta, line_no, trigger, maximum_allowed_quotes) do
     format_issue(
       issue_meta,


Test patch:
diff --git a/test/credo/check/readability/string_sigils_test.exs b/test/credo/check/readability/string_sigils_test.exs
index 83b68c9b..30896b97 100644
--- a/test/credo/check/readability/string_sigils_test.exs
+++ b/test/credo/check/readability/string_sigils_test.exs
@@ -98,6 +98,16 @@ defmodule Credo.Check.Readability.StringSigilsTest do
     |> refute_issues(@described_check)
   end
 
+  test "does NOT crash if string contains non utf8 characters" do
+    snippet = ~S(defmodule CredoTest do
+      @module_var "\xFF"
+    end)
+
+    snippet
+    |> to_source_file
+    |> refute_issues(@described_check)
+  end
+
   #
   # cases raising issues
   #
Repository: rrrene/credo
Pull request #692 (2019-08-20 07:45:24)

Fix spec check
If a callback fun was marked with `@impl BehaviourMod`, `Credo.Check.Readability.Specs` check treated that fun as public.


Patch:
diff --git a/lib/credo/check/readability/specs.ex b/lib/credo/check/readability/specs.ex
index e3297949..56d9b5da 100644
--- a/lib/credo/check/readability/specs.ex
+++ b/lib/credo/check/readability/specs.ex
@@ -44,7 +44,7 @@ defmodule Credo.Check.Readability.Specs do
     {ast, [{name, length(args)} | specs]}
   end
 
-  defp find_specs({:impl, _, [true]} = ast, specs) do
+  defp find_specs({:impl, _, [impl]} = ast, specs) when impl != false do
     {ast, [:impl | specs]}
   end
 


Test patch:
diff --git a/test/credo/check/readability/specs_test.exs b/test/credo/check/readability/specs_test.exs
index 80d1caf3..a34306bf 100644
--- a/test/credo/check/readability/specs_test.exs
+++ b/test/credo/check/readability/specs_test.exs
@@ -101,4 +101,26 @@ defmodule Credo.Check.Readability.SpecsTest do
     |> to_source_file()
     |> refute_issues(@described_check)
   end
+
+  test "it should NOT report functions with `@impl SomeMod`" do
+    """
+    defmodule CredoTypespecTest do
+      @impl SomeMod
+      def foo(a), do: a
+    end
+    """
+    |> to_source_file()
+    |> refute_issues(@described_check)
+  end
+
+  test "it should report functions with `@impl false`" do
+    """
+    defmodule CredoTypespecTest do
+      @impl false
+      def foo(a), do: a
+    end
+    """
+    |> to_source_file()
+    |> assert_issue(@described_check)
+  end
 end
Repository: rrrene/credo
Pull request #693 (2019-08-20 13:38:13)

Fix name parsing bug in Credo.Check.Consistency.UnusedVariableNames
There was a bug in my `unused_variable_name?/1` helper function. I fixed it 😄 


Patch:
diff --git a/lib/credo/check/consistency/unused_variable_names/collector.ex b/lib/credo/check/consistency/unused_variable_names/collector.ex
index 42b3598a..f7b317ec 100644
--- a/lib/credo/check/consistency/unused_variable_names/collector.ex
+++ b/lib/credo/check/consistency/unused_variable_names/collector.ex
@@ -40,7 +40,7 @@ defmodule Credo.Check.Consistency.UnusedVariableNames.Collector do
 
   defp unused_variable_name?({:_, _, _}), do: true
 
-  defp unused_variable_name?({name, _, _}),
+  defp unused_variable_name?({name, _, _}) when is_atom(name),
     do: String.starts_with?(Atom.to_string(name), "_")
 
   defp unused_variable_name?(_), do: false


Test patch:
diff --git a/test/credo/check/consistency/unused_variable_names_test.exs b/test/credo/check/consistency/unused_variable_names_test.exs
index 1e94e578..a85f66cb 100644
--- a/test/credo/check/consistency/unused_variable_names_test.exs
+++ b/test/credo/check/consistency/unused_variable_names_test.exs
@@ -9,6 +9,7 @@ defmodule Credo.Check.Consistency.UnusedVariableNamesTest do
       defmodule Credo.SampleOne do
         defmodule Foo do
           def bar(_, %{foo: foo} = _, _) do
+            version = Mix.Project.config()[:version]
           end
         end
       end
Repository: rrrene/credo
Pull request #714 (2019-11-07 10:54:17)

Make Credo.Check.Readability.MultiAlias check work with submodule expansion
The `Credo.Check.Readability.MultiAlias` check was raising an error when trying to parse this code because of the `Bar.Baz` part.

```elixir
alias Foo.{Bar.Baz, Quux}
```

I fixed it and added a test.


Patch:
diff --git a/lib/credo/check/readability/multi_alias.ex b/lib/credo/check/readability/multi_alias.ex
index d38ffa25..b4e8e927 100644
--- a/lib/credo/check/readability/multi_alias.ex
+++ b/lib/credo/check/readability/multi_alias.ex
@@ -36,7 +36,9 @@ defmodule Credo.Check.Readability.MultiAlias do
          issues,
          issue_meta
        ) do
-    {:__aliases__, _, [module | []]} = multi_alias
+    {:__aliases__, _, module} = multi_alias
+    module = Enum.join(module, ".")
+
     new_issue = issue_for(issue_meta, Keyword.get(opts, :line), base_alias, module)
 
     {ast, [new_issue | issues]}


Test patch:
diff --git a/test/credo/check/readability/multi_alias_test.exs b/test/credo/check/readability/multi_alias_test.exs
index a3510474..8011cda2 100644
--- a/test/credo/check/readability/multi_alias_test.exs
+++ b/test/credo/check/readability/multi_alias_test.exs
@@ -41,4 +41,16 @@ defmodule Credo.Check.Readability.MultiAliasTest do
     |> to_source_file
     |> assert_issue(@described_check)
   end
+
+  test "it should report a violation for multiple nested expansions" do
+    """
+    defmodule CredoSampleModule do
+      alias App.{Module1.Submodule1, Module2}
+    end
+    """
+    |> to_source_file
+    |> assert_issue(@described_check, fn issue ->
+      assert issue.trigger == "Module1.Submodule1"
+    end)
+  end
 end
Repository: rrrene/credo
Pull request #773 (2020-04-23 20:05:38)

Check for `===` as well as `==` in empty enum check
At the moment, credo warns on 
```elixir
length(some_list) == 0
```

After this change, it will also warn on
```elixir
length(some_list) === 0
```


Patch:
diff --git a/lib/credo/check/warning/expensive_empty_enum_check.ex b/lib/credo/check/warning/expensive_empty_enum_check.ex
index d84fc192..146bb9b5 100644
--- a/lib/credo/check/warning/expensive_empty_enum_check.ex
+++ b/lib/credo/check/warning/expensive_empty_enum_check.ex
@@ -37,10 +37,12 @@ defmodule Credo.Check.Warning.ExpensiveEmptyEnumCheck do
     {@length_pattern, 0},
     {0, @length_pattern}
   ]
+  @operators [:==, :===]
 
-  for {lhs, rhs} <- @comparisons do
+  for {lhs, rhs} <- @comparisons,
+      operator <- @operators do
     defp traverse(
-           {:==, meta, [unquote(lhs), unquote(rhs)]} = ast,
+           {unquote(operator), meta, [unquote(lhs), unquote(rhs)]} = ast,
            issues,
            issue_meta
          ) do


Test patch:
diff --git a/test/credo/check/warning/expensive_empty_enum_check_test.exs b/test/credo/check/warning/expensive_empty_enum_check_test.exs
index d81a4931..d91bcd9f 100644
--- a/test/credo/check/warning/expensive_empty_enum_check_test.exs
+++ b/test/credo/check/warning/expensive_empty_enum_check_test.exs
@@ -138,4 +138,21 @@ defmodule Credo.Check.Warning.ExpensiveEmptyEnumCheckTest do
     |> run_check(@described_check)
     |> assert_issue()
   end
+
+  test "it should report when checking if length is 0 with triple-equals" do
+    """
+    defmodule CredoSampleModule do
+      def some_function(some_list) do
+        if length(some_list) === 0 do
+          "empty"
+        else
+          "not empty"
+        end
+      end
+    end
+    """
+    |> to_source_file
+    |> run_check(@described_check)
+    |> assert_issue()
+  end
 end
Repository: rrrene/credo
Pull request #783 (2020-06-19 12:53:14)

Properly handle lack of parens in spec check
Fixes a bug in `Credo.Check.Readability.Specs`, where a parensless definition (i.e. `def foo do ... end`) was not accounted for.


Patch:
diff --git a/lib/credo/check/readability/specs.ex b/lib/credo/check/readability/specs.ex
index a2e3b81d..be15b5ea 100644
--- a/lib/credo/check/readability/specs.ex
+++ b/lib/credo/check/readability/specs.ex
@@ -44,7 +44,8 @@ defmodule Credo.Check.Readability.Specs do
   end
 
   defp find_specs({:spec, _, [{_, _, [{name, _, args} | _]}]} = ast, specs)
-       when is_list(args) do
+       when is_list(args) or is_nil(args) do
+    args = with nil <- args, do: []
     {ast, [{name, length(args)} | specs]}
   end
 
@@ -84,7 +85,9 @@ defmodule Credo.Check.Readability.Specs do
          specs,
          issue_meta
        )
-       when is_list(args) do
+       when is_list(args) or is_nil(args) do
+    args = with nil <- args, do: []
+
     if {name, length(args)} in specs do
       {ast, issues}
     else


Test patch:
diff --git a/test/credo/check/readability/specs_test.exs b/test/credo/check/readability/specs_test.exs
index c6be2b67..f853701b 100644
--- a/test/credo/check/readability/specs_test.exs
+++ b/test/credo/check/readability/specs_test.exs
@@ -133,4 +133,27 @@ defmodule Credo.Check.Readability.SpecsTest do
     |> run_check(@described_check)
     |> assert_issue()
   end
+
+  test "it should report function with arity zero and no parentheses" do
+    """
+    defmodule CredoTypespecTest do
+      def foo, do: :ok
+    end
+    """
+    |> to_source_file()
+    |> run_check(@described_check)
+    |> assert_issue()
+  end
+
+  test "it should NOT report function with arity zero and a spec with no parentheses" do
+    """
+    defmodule CredoTypespecTest do
+      @spec foo :: :ok
+      def foo, do: :ok
+    end
+    """
+    |> to_source_file()
+    |> run_check(@described_check)
+    |> refute_issues()
+  end
 end
Repository: rrrene/credo
Pull request #1119 (2024-03-16 07:05:53)

chore: remove repetitive words


Patch:
diff --git a/lib/credo/execution.ex b/lib/credo/execution.ex
index c8d3e18f..3e9750f9 100644
--- a/lib/credo/execution.ex
+++ b/lib/credo/execution.ex
@@ -119,7 +119,7 @@ defmodule Credo.Execution do
   alias Credo.Execution.ExecutionSourceFiles
   alias Credo.Execution.ExecutionTiming
 
-  @doc "Builds an Execution struct for the the given `argv`."
+  @doc "Builds an Execution struct for the given `argv`."
   def build(argv \\ []) when is_list(argv) do
     max_concurrent_check_runs = System.schedulers_online()
 


Test patch:
diff --git a/test/credo/priority_test.exs b/test/credo/priority_test.exs
index bf93eb09..be51d6bf 100644
--- a/test/credo/priority_test.exs
+++ b/test/credo/priority_test.exs
@@ -83,7 +83,7 @@ defmodule Credo.PriorityTest do
     assert expected == Priority.scope_priorities(source_file)
   end
 
-  test "it should not crash if @def_ops attributes provided and and should return correct scope_priorities" do
+  test "it should not crash if @def_ops attributes provided and should return correct scope_priorities" do
     source_file =
       """
       defmodule Credo.Sample.Module do
Repository: rrrene/credo
Pull request #1149 (2024-09-01 02:57:04)

Change to not warn on calls to IO.inspect/3
It seems unlikely that an inspect call with a specific file handler passed in would be from a debugging session, so it makes sense to exclude these calls.

Thoughts?


Patch:
diff --git a/lib/credo/check/warning/io_inspect.ex b/lib/credo/check/warning/io_inspect.ex
index 73c83455..bc5d9194 100644
--- a/lib/credo/check/warning/io_inspect.ex
+++ b/lib/credo/check/warning/io_inspect.ex
@@ -16,23 +16,24 @@ defmodule Credo.Check.Warning.IoInspect do
   @impl true
   def run(%SourceFile{} = source_file, params) do
     issue_meta = IssueMeta.for(source_file, params)
-
     Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta))
   end
 
   defp traverse(
-         {{:., _, [{:__aliases__, meta, [:"Elixir", :IO]}, :inspect]}, _, _arguments} = ast,
+         {{:., _, [{:__aliases__, meta, [:"Elixir", :IO]}, :inspect]}, _, args} = ast,
          issues,
          issue_meta
-       ) do
+       )
+       when length(args) < 3 do
     {ast, issues_for_call(meta, "Elixir.IO.inspect", issues, issue_meta)}
   end
 
   defp traverse(
-         {{:., _, [{:__aliases__, meta, [:IO]}, :inspect]}, _meta, _arguments} = ast,
+         {{:., _, [{:__aliases__, meta, [:IO]}, :inspect]}, _, args} = ast,
          issues,
          issue_meta
-       ) do
+       )
+       when length(args) < 3 do
     {ast, issues_for_call(meta, "IO.inspect", issues, issue_meta)}
   end
 


Test patch:
diff --git a/test/credo/check/warning/io_inspect_test.exs b/test/credo/check/warning/io_inspect_test.exs
index cabf2a57..902903a4 100644
--- a/test/credo/check/warning/io_inspect_test.exs
+++ b/test/credo/check/warning/io_inspect_test.exs
@@ -20,6 +20,19 @@ defmodule Credo.Check.Warning.IoInspectTest do
     |> refute_issues()
   end
 
+  test "it should NOT report Inspect/3" do
+    """
+    defmodule CredoSampleModule do
+      def some_function(parameter1) do
+        IO.inspect(:stderr, parameter1, [])
+      end
+    end
+    """
+    |> to_source_file
+    |> run_check(@described_check)
+    |> refute_issues()
+  end
+
   #
   # cases raising issues
   #
Repository: rrrene/credo
Pull request #1157 (2024-11-01 13:21:51)

Add ** operator
This stops e.g. the following code from showing a readability warning:

```
defmodule CredoTest do
  @moduledoc """
  An example of the snakecase test failing
  """
  def a ** b do
    nil
  end
end
```


Patch:
diff --git a/lib/credo/check/readability/function_names.ex b/lib/credo/check/readability/function_names.ex
index f0e59474..c2b4253d 100644
--- a/lib/credo/check/readability/function_names.ex
+++ b/lib/credo/check/readability/function_names.ex
@@ -35,7 +35,7 @@ defmodule Credo.Check.Readability.FunctionNames do
   @all_sigil_atoms Enum.map(@all_sigil_chars, &:"sigil_#{&1}")
 
   # all non-special-form operators
-  @all_nonspecial_operators ~W(! && ++ -- .. <> =~ @ |> || != !== * + - / < <= == === > >= ||| &&& <<< >>> <<~ ~>> <~ ~> <~> <|> ^^^ ~~~ +++ ---)a
+  @all_nonspecial_operators ~W(! && ++ -- .. <> =~ @ |> || != !== * + - / ** < <= == === > >= ||| &&& <<< >>> <<~ ~>> <~ ~> <~> <|> ^^^ ~~~ +++ ---)a
 
   @doc false
   @impl true


Test patch:
diff --git a/test/credo/check/readability/function_names_test.exs b/test/credo/check/readability/function_names_test.exs
index f1800485..c7ec57df 100644
--- a/test/credo/check/readability/function_names_test.exs
+++ b/test/credo/check/readability/function_names_test.exs
@@ -152,6 +152,10 @@ defmodule Credo.Check.Readability.FunctionNamesTest do
     def left --- right do
       # ++ code
     end
+
+    def left ** right do
+      # ...
+    end
     """
     |> to_source_file
     |> run_check(@described_check)
Repository: rrrene/credo
Pull request #1185 (2025-03-18 13:51:29)

Fix false positive for NestedFunctionCalls
Added a guard for all typespec attributes, closes: #1170


Patch:
diff --git a/lib/credo/check/readability/nested_function_calls.ex b/lib/credo/check/readability/nested_function_calls.ex
index 9336b99e..a57b9f60 100644
--- a/lib/credo/check/readability/nested_function_calls.ex
+++ b/lib/credo/check/readability/nested_function_calls.ex
@@ -68,8 +68,9 @@ defmodule Credo.Check.Readability.NestedFunctionCalls do
     {nil, acc}
   end
 
-  # We don't look into @type attributes
-  defp traverse({:@, _, [{:type, _, _args}]}, acc, _issue) do
+  # We don't look into typespec attributes
+  defp traverse({:@, _, [{attr_name, _, _args}]}, acc, _issue)
+    when attr_name in ~w[callback macrocallback opaque spec type typep]a do
     {nil, acc}
   end
 


Test patch:
diff --git a/test/credo/check/readability/nested_function_calls_test.exs b/test/credo/check/readability/nested_function_calls_test.exs
index a55e4783..8b4d4673 100644
--- a/test/credo/check/readability/nested_function_calls_test.exs
+++ b/test/credo/check/readability/nested_function_calls_test.exs
@@ -10,10 +10,12 @@ defmodule Credo.Check.Readability.NestedFunctionCallsTest do
   test "it should NOT report code with no nested function calls" do
     """
     defmodule CredoSampleModule do
+      @callback callback_name :: Keyword.t(Some.remote(some_arg))
+      @macrocallback macrocallback_name :: Keyword.t(Some.remote(some_arg))
+      @spec spec_name :: Keyword.t(Some.remote(some_arg))
+      @opaque opaque_name :: Keyword.t(Some.remote(some_arg))
       @type type_name :: Keyword.t(Some.remote(some_arg))
-      def some_code(_foo) do
-        Enum.shuffle([1,2,3])
-      end
+      @typep typep_name :: Keyword.t(Some.remote(some_arg))
     end
     """
     |> to_source_file()
Repository: beam-telemetry/telemetry_metrics_statsd
Pull request #29 (2020-04-09 17:57:13)

Allowing prefix to be an atom
Hello and thank you for this library! My colleague and I ran into this today so I spun up a quick PR to keep it from happening to someone else. 🎉 

arkgil: Hi Jason, thank you for the PR! Is there a reason why you couldn't use a string prefix? Just trying to understand the use case here. Thanks!
jasondew: @arkgil sure thing! Nope, no reason to not use a string but we initially went with an atom and it  took us a minute to figure out what was failing and why. It's definitely not a big deal, but I thought that it might be worth it to add to keep other folks from stumbling on it.
arkgil: I agree, it doesn't hurt to have it. Thanks!

Patch:
diff --git a/lib/telemetry_metrics_statsd.ex b/lib/telemetry_metrics_statsd.ex
index 5ec8ed3..aca8ec1 100644
--- a/lib/telemetry_metrics_statsd.ex
+++ b/lib/telemetry_metrics_statsd.ex
@@ -231,7 +231,7 @@ defmodule TelemetryMetricsStatsd do
   alias Telemetry.Metrics
   alias TelemetryMetricsStatsd.{EventHandler, UDP}
 
-  @type prefix :: String.t() | nil
+  @type prefix :: String.t() | atom() | nil
   @type host :: String.t() | :inet.ip_address()
   @type option ::
           {:port, :inet.port_number()}
diff --git a/lib/telemetry_metrics_statsd/formatter.ex b/lib/telemetry_metrics_statsd/formatter.ex
index d72ee9c..c48df01 100644
--- a/lib/telemetry_metrics_statsd/formatter.ex
+++ b/lib/telemetry_metrics_statsd/formatter.ex
@@ -26,7 +26,7 @@ defmodule TelemetryMetricsStatsd.Formatter do
   end
 
   def format(formatter, metric, prefix, measurement, tags) do
-    [prefix, ?., formatter.format(metric, measurement, tags)]
+    [to_string(prefix), ?., formatter.format(metric, measurement, tags)]
     |> :erlang.iolist_to_binary()
   end
 end


Test patch:
diff --git a/test/telemetry_metrics_statsd/formatter_test.exs b/test/telemetry_metrics_statsd/formatter_test.exs
index fbc611b..267ad4e 100644
--- a/test/telemetry_metrics_statsd/formatter_test.exs
+++ b/test/telemetry_metrics_statsd/formatter_test.exs
@@ -14,6 +14,9 @@ defmodule TelemetryMetricsStatsd.FormatterTest do
 
     assert Formatter.format(Datadog, metric, "api", 1, resource: "users", method: "GET") ==
              "api.http.duration:1|c|#resource:users,method:GET"
+
+    assert Formatter.format(Datadog, metric, :api, 1, resource: "users", method: "GET") ==
+             "api.http.duration:1|c|#resource:users,method:GET"
   end
 
   test "formats the measurement using provided formatter implementation without prefix" do