We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
WPS114 Found underscored name pattern failes on cornercase
# Bug report

<!--
Hi, thanks for submitting a bug. We appreciate that.

But, we will need some information about what's wrong to help you.
-->

## What's wrong
```python
# Correct:
star_wars_episode2 = 'awesome!'

# Incorrect
star_wars_2episode = "also awesome"
```
```
test.py
     1:   1 WPS114 Found underscored name pattern: star_wars_2episode [wemake-python-styleguide]
  star_wars_2episode = ""
  ^
```
<!-- Describe what is not working. Please, attach a traceback. -->

## How is that should be
Checker should ignore numbers concatenated with strings.


There was a question [here](https://github.com/wemake-services/wemake-python-styleguide/issues/205#issuecomment-427339146) but with no answer

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `wemake_python_styleguide/logic/naming/logical.py`
Content:
```
1 import re
2 from typing import Iterable
3 
4 from typing_extensions import Final
5 
6 from wemake_python_styleguide.logic.naming import access
7 
8 # Used to specify a pattern which checks variables and modules for underscored
9 # numbers in their names:
10 _UNDERSCORED_NUMBER_PATTERN: Final = re.compile(r'.+\D\_\d+(\D|$)')
11 
12 
13 def is_wrong_name(name: str, to_check: Iterable[str]) -> bool:
14     """
15     Checks that name is not prohibited by explicitly listing it's name.
16 
17     >>> is_wrong_name('wrong', ['wrong'])
18     True
19 
20     >>> is_wrong_name('correct', ['wrong'])
21     False
22 
23     >>> is_wrong_name('_wrong', ['wrong'])
24     True
25 
26     >>> is_wrong_name('wrong_', ['wrong'])
27     True
28 
29     >>> is_wrong_name('wrong__', ['wrong'])
30     False
31 
32     >>> is_wrong_name('__wrong', ['wrong'])
33     False
34 
35     """
36     for name_to_check in to_check:
37         choices_to_check = {
38             name_to_check,
39             '_{0}'.format(name_to_check),
40             '{0}_'.format(name_to_check),
41         }
42         if name in choices_to_check:
43             return True
44     return False
45 
46 
47 def is_upper_case_name(name: str) -> bool:
48     """
49     Checks that attribute name has no upper-case letters.
50 
51     >>> is_upper_case_name('camelCase')
52     True
53 
54     >>> is_upper_case_name('UPPER_CASE')
55     True
56 
57     >>> is_upper_case_name('camel_Case')
58     True
59 
60     >>> is_upper_case_name('snake_case')
61     False
62 
63     >>> is_upper_case_name('snake')
64     False
65 
66     >>> is_upper_case_name('snake111')
67     False
68 
69     >>> is_upper_case_name('__variable_v2')
70     False
71 
72     """
73     return any(character.isupper() for character in name)
74 
75 
76 def is_too_short_name(
77     name: str,
78     min_length: int,
79     *,
80     trim: bool = True,
81 ) -> bool:
82     """
83     Checks for too short names.
84 
85     >>> is_too_short_name('test', min_length=2)
86     False
87 
88     >>> is_too_short_name('o', min_length=2)
89     True
90 
91     >>> is_too_short_name('_', min_length=2)
92     False
93 
94     >>> is_too_short_name('_', min_length=1)
95     False
96 
97     >>> is_too_short_name('z1', min_length=2)
98     False
99 
100     >>> is_too_short_name('z', min_length=1)
101     False
102 
103     >>> is_too_short_name('_z', min_length=2, trim=True)
104     True
105 
106     >>> is_too_short_name('z_', min_length=2, trim=True)
107     True
108 
109     >>> is_too_short_name('z_', min_length=2, trim=False)
110     False
111 
112     >>> is_too_short_name('__z', min_length=2, trim=True)
113     True
114 
115     >>> is_too_short_name('xy', min_length=2, trim=True)
116     False
117 
118     """
119     if access.is_unused(name):
120         return False
121 
122     if trim:
123         name = name.strip('_')
124 
125     return len(name) < min_length
126 
127 
128 def is_too_long_name(
129     name: str,
130     max_length: int,
131 ) -> bool:
132     """
133     Checks for too long names.
134 
135     >>> is_too_long_name('test', max_length=4)
136     False
137 
138     >>> is_too_long_name('_', max_length=4)
139     False
140 
141     >>> is_too_long_name('test', max_length=3)
142     True
143 
144     >>> is_too_long_name('this_is_twentynine_characters', max_length=29)
145     False
146 
147     """
148     return len(name) > max_length
149 
150 
151 def does_contain_underscored_number(name: str) -> bool:
152     """
153     Checks for names with underscored number.
154 
155     >>> does_contain_underscored_number('star_wars_episode2')
156     False
157 
158     >>> does_contain_underscored_number('come2_me')
159     False
160 
161     >>> does_contain_underscored_number('_')
162     False
163 
164     >>> does_contain_underscored_number('z1')
165     False
166 
167     >>> does_contain_underscored_number('iso123_456')
168     False
169 
170     >>> does_contain_underscored_number('star_wars_episode_2')
171     True
172 
173     >>> does_contain_underscored_number('come_2_me')
174     True
175 
176     >>> does_contain_underscored_number('come_44_me')
177     True
178 
179     >>> does_contain_underscored_number('iso_123_456')
180     True
181 
182     """
183     return _UNDERSCORED_NUMBER_PATTERN.match(name) is not None
184 
185 
186 def does_contain_consecutive_underscores(name: str) -> bool:
187     """
188     Checks if name contains consecutive underscores in middle of name.
189 
190     >>> does_contain_consecutive_underscores('name')
191     False
192 
193     >>> does_contain_consecutive_underscores('__magic__')
194     False
195 
196     >>> does_contain_consecutive_underscores('__private')
197     False
198 
199     >>> does_contain_consecutive_underscores('name')
200     False
201 
202     >>> does_contain_consecutive_underscores('some__value')
203     True
204 
205     >>> does_contain_consecutive_underscores('__some__value__')
206     True
207 
208     >>> does_contain_consecutive_underscores('__private__value')
209     True
210 
211     >>> does_contain_consecutive_underscores('some_value__')
212     True
213 
214     """
215     if access.is_magic(name) or access.is_private(name):
216         return '__' in name.strip('_')
217     return '__' in name
218 
219 
220 def does_contain_unicode(name: str) -> bool:
221     """
222     Check if name contains unicode characters.
223 
224     >>> does_contain_unicode('hello_world1')
225     False
226 
227     >>> does_contain_unicode('')
228     False
229 
230     >>> does_contain_unicode('привет_мир1')
231     True
232 
233     >>> does_contain_unicode('russian_техт')
234     True
235 
236     """
237     try:
238         name.encode('ascii')
239     except UnicodeEncodeError:
240         return True
241     else:
242         return False
243
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/wemake_python_styleguide/logic/naming/logical.py b/wemake_python_styleguide/logic/naming/logical.py
--- a/wemake_python_styleguide/logic/naming/logical.py
+++ b/wemake_python_styleguide/logic/naming/logical.py
@@ -7,7 +7,7 @@
 
 # Used to specify a pattern which checks variables and modules for underscored
 # numbers in their names:
-_UNDERSCORED_NUMBER_PATTERN: Final = re.compile(r'.+\D\_\d+(\D|$)')
+_UNDERSCORED_NUMBER_PATTERN: Final = re.compile(r'.+\D\_\d+($|[^a-zA-Z0-9])')
 
 
 def is_wrong_name(name: str, to_check: Iterable[str]) -> bool:
@@ -167,6 +167,9 @@
     >>> does_contain_underscored_number('iso123_456')
     False
 
+    >>> does_contain_underscored_number('contract_1c')
+    False
+
     >>> does_contain_underscored_number('star_wars_episode_2')
     True

{"golden_diff": "diff --git a/wemake_python_styleguide/logic/naming/logical.py b/wemake_python_styleguide/logic/naming/logical.py\n--- a/wemake_python_styleguide/logic/naming/logical.py\n+++ b/wemake_python_styleguide/logic/naming/logical.py\n@@ -7,7 +7,7 @@\n \n # Used to specify a pattern which checks variables and modules for underscored\n # numbers in their names:\n-_UNDERSCORED_NUMBER_PATTERN: Final = re.compile(r'.+\\D\\_\\d+(\\D|$)')\n+_UNDERSCORED_NUMBER_PATTERN: Final = re.compile(r'.+\\D\\_\\d+($|[^a-zA-Z0-9])')\n \n \n def is_wrong_name(name: str, to_check: Iterable[str]) -> bool:\n@@ -167,6 +167,9 @@\n     >>> does_contain_underscored_number('iso123_456')\n     False\n \n+    >>> does_contain_underscored_number('contract_1c')\n+    False\n+\n     >>> does_contain_underscored_number('star_wars_episode_2')\n     True\n", "issue": "WPS114 Found underscored name pattern failes on cornercase\n# Bug report\r\n\r\n<!--\r\nHi, thanks for submitting a bug. We appreciate that.\r\n\r\nBut, we will need some information about what's wrong to help you.\r\n-->\r\n\r\n## What's wrong\r\n```python\r\n# Correct:\r\nstar_wars_episode2 = 'awesome!'\r\n\r\n# Incorrect\r\nstar_wars_2episode = \"also awesome\"\r\n```\r\n```\r\ntest.py\r\n     1:   1 WPS114 Found underscored name pattern: star_wars_2episode [wemake-python-styleguide]\r\n  star_wars_2episode = \"\"\r\n  ^\r\n```\r\n<!-- Describe what is not working. Please, attach a traceback. -->\r\n\r\n## How is that should be\r\nChecker should ignore numbers concatenated with strings.\r\n\r\n\r\nThere was a question [here](https://github.com/wemake-services/wemake-python-styleguide/issues/205#issuecomment-427339146) but with no answer\n", "before_files": [{"content": "import re\nfrom typing import Iterable\n\nfrom typing_extensions import Final\n\nfrom wemake_python_styleguide.logic.naming import access\n\n# Used to specify a pattern which checks variables and modules for underscored\n# numbers in their names:\n_UNDERSCORED_NUMBER_PATTERN: Final = re.compile(r'.+\\D\\_\\d+(\\D|$)')\n\n\ndef is_wrong_name(name: str, to_check: Iterable[str]) -> bool:\n    \"\"\"\n    Checks that name is not prohibited by explicitly listing it's name.\n\n    >>> is_wrong_name('wrong', ['wrong'])\n    True\n\n    >>> is_wrong_name('correct', ['wrong'])\n    False\n\n    >>> is_wrong_name('_wrong', ['wrong'])\n    True\n\n    >>> is_wrong_name('wrong_', ['wrong'])\n    True\n\n    >>> is_wrong_name('wrong__', ['wrong'])\n    False\n\n    >>> is_wrong_name('__wrong', ['wrong'])\n    False\n\n    \"\"\"\n    for name_to_check in to_check:\n        choices_to_check = {\n            name_to_check,\n            '_{0}'.format(name_to_check),\n            '{0}_'.format(name_to_check),\n        }\n        if name in choices_to_check:\n            return True\n    return False\n\n\ndef is_upper_case_name(name: str) -> bool:\n    \"\"\"\n    Checks that attribute name has no upper-case letters.\n\n    >>> is_upper_case_name('camelCase')\n    True\n\n    >>> is_upper_case_name('UPPER_CASE')\n    True\n\n    >>> is_upper_case_name('camel_Case')\n    True\n\n    >>> is_upper_case_name('snake_case')\n    False\n\n    >>> is_upper_case_name('snake')\n    False\n\n    >>> is_upper_case_name('snake111')\n    False\n\n    >>> is_upper_case_name('__variable_v2')\n    False\n\n    \"\"\"\n    return any(character.isupper() for character in name)\n\n\ndef is_too_short_name(\n    name: str,\n    min_length: int,\n    *,\n    trim: bool = True,\n) -> bool:\n    \"\"\"\n    Checks for too short names.\n\n    >>> is_too_short_name('test', min_length=2)\n    False\n\n    >>> is_too_short_name('o', min_length=2)\n    True\n\n    >>> is_too_short_name('_', min_length=2)\n    False\n\n    >>> is_too_short_name('_', min_length=1)\n    False\n\n    >>> is_too_short_name('z1', min_length=2)\n    False\n\n    >>> is_too_short_name('z', min_length=1)\n    False\n\n    >>> is_too_short_name('_z', min_length=2, trim=True)\n    True\n\n    >>> is_too_short_name('z_', min_length=2, trim=True)\n    True\n\n    >>> is_too_short_name('z_', min_length=2, trim=False)\n    False\n\n    >>> is_too_short_name('__z', min_length=2, trim=True)\n    True\n\n    >>> is_too_short_name('xy', min_length=2, trim=True)\n    False\n\n    \"\"\"\n    if access.is_unused(name):\n        return False\n\n    if trim:\n        name = name.strip('_')\n\n    return len(name) < min_length\n\n\ndef is_too_long_name(\n    name: str,\n    max_length: int,\n) -> bool:\n    \"\"\"\n    Checks for too long names.\n\n    >>> is_too_long_name('test', max_length=4)\n    False\n\n    >>> is_too_long_name('_', max_length=4)\n    False\n\n    >>> is_too_long_name('test', max_length=3)\n    True\n\n    >>> is_too_long_name('this_is_twentynine_characters', max_length=29)\n    False\n\n    \"\"\"\n    return len(name) > max_length\n\n\ndef does_contain_underscored_number(name: str) -> bool:\n    \"\"\"\n    Checks for names with underscored number.\n\n    >>> does_contain_underscored_number('star_wars_episode2')\n    False\n\n    >>> does_contain_underscored_number('come2_me')\n    False\n\n    >>> does_contain_underscored_number('_')\n    False\n\n    >>> does_contain_underscored_number('z1')\n    False\n\n    >>> does_contain_underscored_number('iso123_456')\n    False\n\n    >>> does_contain_underscored_number('star_wars_episode_2')\n    True\n\n    >>> does_contain_underscored_number('come_2_me')\n    True\n\n    >>> does_contain_underscored_number('come_44_me')\n    True\n\n    >>> does_contain_underscored_number('iso_123_456')\n    True\n\n    \"\"\"\n    return _UNDERSCORED_NUMBER_PATTERN.match(name) is not None\n\n\ndef does_contain_consecutive_underscores(name: str) -> bool:\n    \"\"\"\n    Checks if name contains consecutive underscores in middle of name.\n\n    >>> does_contain_consecutive_underscores('name')\n    False\n\n    >>> does_contain_consecutive_underscores('__magic__')\n    False\n\n    >>> does_contain_consecutive_underscores('__private')\n    False\n\n    >>> does_contain_consecutive_underscores('name')\n    False\n\n    >>> does_contain_consecutive_underscores('some__value')\n    True\n\n    >>> does_contain_consecutive_underscores('__some__value__')\n    True\n\n    >>> does_contain_consecutive_underscores('__private__value')\n    True\n\n    >>> does_contain_consecutive_underscores('some_value__')\n    True\n\n    \"\"\"\n    if access.is_magic(name) or access.is_private(name):\n        return '__' in name.strip('_')\n    return '__' in name\n\n\ndef does_contain_unicode(name: str) -> bool:\n    \"\"\"\n    Check if name contains unicode characters.\n\n    >>> does_contain_unicode('hello_world1')\n    False\n\n    >>> does_contain_unicode('')\n    False\n\n    >>> does_contain_unicode('\u043f\u0440\u0438\u0432\u0435\u0442_\u043c\u0438\u04401')\n    True\n\n    >>> does_contain_unicode('russian_\u0442\u0435\u0445\u0442')\n    True\n\n    \"\"\"\n    try:\n        name.encode('ascii')\n    except UnicodeEncodeError:\n        return True\n    else:\n        return False\n", "path": "wemake_python_styleguide/logic/naming/logical.py"}], "after_files": [{"content": "import re\nfrom typing import Iterable\n\nfrom typing_extensions import Final\n\nfrom wemake_python_styleguide.logic.naming import access\n\n# Used to specify a pattern which checks variables and modules for underscored\n# numbers in their names:\n_UNDERSCORED_NUMBER_PATTERN: Final = re.compile(r'.+\\D\\_\\d+($|[^a-zA-Z0-9])')\n\n\ndef is_wrong_name(name: str, to_check: Iterable[str]) -> bool:\n    \"\"\"\n    Checks that name is not prohibited by explicitly listing it's name.\n\n    >>> is_wrong_name('wrong', ['wrong'])\n    True\n\n    >>> is_wrong_name('correct', ['wrong'])\n    False\n\n    >>> is_wrong_name('_wrong', ['wrong'])\n    True\n\n    >>> is_wrong_name('wrong_', ['wrong'])\n    True\n\n    >>> is_wrong_name('wrong__', ['wrong'])\n    False\n\n    >>> is_wrong_name('__wrong', ['wrong'])\n    False\n\n    \"\"\"\n    for name_to_check in to_check:\n        choices_to_check = {\n            name_to_check,\n            '_{0}'.format(name_to_check),\n            '{0}_'.format(name_to_check),\n        }\n        if name in choices_to_check:\n            return True\n    return False\n\n\ndef is_upper_case_name(name: str) -> bool:\n    \"\"\"\n    Checks that attribute name has no upper-case letters.\n\n    >>> is_upper_case_name('camelCase')\n    True\n\n    >>> is_upper_case_name('UPPER_CASE')\n    True\n\n    >>> is_upper_case_name('camel_Case')\n    True\n\n    >>> is_upper_case_name('snake_case')\n    False\n\n    >>> is_upper_case_name('snake')\n    False\n\n    >>> is_upper_case_name('snake111')\n    False\n\n    >>> is_upper_case_name('__variable_v2')\n    False\n\n    \"\"\"\n    return any(character.isupper() for character in name)\n\n\ndef is_too_short_name(\n    name: str,\n    min_length: int,\n    *,\n    trim: bool = True,\n) -> bool:\n    \"\"\"\n    Checks for too short names.\n\n    >>> is_too_short_name('test', min_length=2)\n    False\n\n    >>> is_too_short_name('o', min_length=2)\n    True\n\n    >>> is_too_short_name('_', min_length=2)\n    False\n\n    >>> is_too_short_name('_', min_length=1)\n    False\n\n    >>> is_too_short_name('z1', min_length=2)\n    False\n\n    >>> is_too_short_name('z', min_length=1)\n    False\n\n    >>> is_too_short_name('_z', min_length=2, trim=True)\n    True\n\n    >>> is_too_short_name('z_', min_length=2, trim=True)\n    True\n\n    >>> is_too_short_name('z_', min_length=2, trim=False)\n    False\n\n    >>> is_too_short_name('__z', min_length=2, trim=True)\n    True\n\n    >>> is_too_short_name('xy', min_length=2, trim=True)\n    False\n\n    \"\"\"\n    if access.is_unused(name):\n        return False\n\n    if trim:\n        name = name.strip('_')\n\n    return len(name) < min_length\n\n\ndef is_too_long_name(\n    name: str,\n    max_length: int,\n) -> bool:\n    \"\"\"\n    Checks for too long names.\n\n    >>> is_too_long_name('test', max_length=4)\n    False\n\n    >>> is_too_long_name('_', max_length=4)\n    False\n\n    >>> is_too_long_name('test', max_length=3)\n    True\n\n    >>> is_too_long_name('this_is_twentynine_characters', max_length=29)\n    False\n\n    \"\"\"\n    return len(name) > max_length\n\n\ndef does_contain_underscored_number(name: str) -> bool:\n    \"\"\"\n    Checks for names with underscored number.\n\n    >>> does_contain_underscored_number('star_wars_episode2')\n    False\n\n    >>> does_contain_underscored_number('come2_me')\n    False\n\n    >>> does_contain_underscored_number('_')\n    False\n\n    >>> does_contain_underscored_number('z1')\n    False\n\n    >>> does_contain_underscored_number('iso123_456')\n    False\n\n    >>> does_contain_underscored_number('contract_1c')\n    False\n\n    >>> does_contain_underscored_number('star_wars_episode_2')\n    True\n\n    >>> does_contain_underscored_number('come_2_me')\n    True\n\n    >>> does_contain_underscored_number('come_44_me')\n    True\n\n    >>> does_contain_underscored_number('iso_123_456')\n    True\n\n    \"\"\"\n    return _UNDERSCORED_NUMBER_PATTERN.match(name) is not None\n\n\ndef does_contain_consecutive_underscores(name: str) -> bool:\n    \"\"\"\n    Checks if name contains consecutive underscores in middle of name.\n\n    >>> does_contain_consecutive_underscores('name')\n    False\n\n    >>> does_contain_consecutive_underscores('__magic__')\n    False\n\n    >>> does_contain_consecutive_underscores('__private')\n    False\n\n    >>> does_contain_consecutive_underscores('name')\n    False\n\n    >>> does_contain_consecutive_underscores('some__value')\n    True\n\n    >>> does_contain_consecutive_underscores('__some__value__')\n    True\n\n    >>> does_contain_consecutive_underscores('__private__value')\n    True\n\n    >>> does_contain_consecutive_underscores('some_value__')\n    True\n\n    \"\"\"\n    if access.is_magic(name) or access.is_private(name):\n        return '__' in name.strip('_')\n    return '__' in name\n\n\ndef does_contain_unicode(name: str) -> bool:\n    \"\"\"\n    Check if name contains unicode characters.\n\n    >>> does_contain_unicode('hello_world1')\n    False\n\n    >>> does_contain_unicode('')\n    False\n\n    >>> does_contain_unicode('\u043f\u0440\u0438\u0432\u0435\u0442_\u043c\u0438\u04401')\n    True\n\n    >>> does_contain_unicode('russian_\u0442\u0435\u0445\u0442')\n    True\n\n    \"\"\"\n    try:\n        name.encode('ascii')\n    except UnicodeEncodeError:\n        return True\n    else:\n        return False\n", "path": "wemake_python_styleguide/logic/naming/logical.py"}]}