Skip to content

Commit b091bfc

Browse files
authored
fix: preserve hyperlinks with hyphens (googleapis#1140)
The default behaviour of textwrap.wrap is to break text on hyphens. This PR sets the break_on_hyphens parameter of textwrap.wrap to False in order to preserve hyperlinks with hyphens. Fixes googleapis#1131
1 parent fe57eb2 commit b091bfc

File tree

10 files changed

+29
-20
lines changed

10 files changed

+29
-20
lines changed

gapic/utils/lines.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,12 @@ def wrap(text: str, width: int, *, offset: int = None, indent: int = 0) -> str:
7878
# Break off the first line of the string to address non-zero offsets.
7979
first = text.split('\n')[0] + '\n'
8080
if len(first) > width - offset:
81+
# Ensure `break_on_hyphens` is set to `False` when using
82+
# `textwrap.wrap` to avoid breaking hyperlinks with hyphens.
8183
initial = textwrap.wrap(first,
8284
break_long_words=False,
8385
width=width - offset,
86+
break_on_hyphens=False,
8487
)
8588
# Strip the first \n from the text so it is not misidentified as an
8689
# intentionally short line below.
@@ -107,11 +110,14 @@ def wrap(text: str, width: int, *, offset: int = None, indent: int = 0) -> str:
107110
# Wrap the remainder of the string at the desired width.
108111
return '{first}{text}'.format(
109112
first=first,
113+
# Ensure `break_on_hyphens` is set to `False` when using
114+
# `textwrap.fill` to avoid breaking hyperlinks with hyphens.
110115
text='\n'.join([textwrap.fill(
111116
break_long_words=False,
112117
initial_indent=' ' * indent,
113118
subsequent_indent=' ' * indent,
114119
text=token,
115120
width=width,
121+
break_on_hyphens=False,
116122
) for token in tokens]),
117123
).rstrip('\n')

tests/integration/goldens/credentials/google/iam/credentials_v1/services/iam_credentials/async_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ class IAMCredentialsAsyncClient:
4848
4949
Service account credentials are used to temporarily assume the
5050
identity of the service account. Supported credential types
51-
include OAuth 2.0 access tokens, OpenID Connect ID tokens, self-
52-
signed JSON Web Tokens (JWTs), and more.
51+
include OAuth 2.0 access tokens, OpenID Connect ID tokens,
52+
self-signed JSON Web Tokens (JWTs), and more.
5353
"""
5454

5555
_client: IAMCredentialsClient

tests/integration/goldens/credentials/google/iam/credentials_v1/services/iam_credentials/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ class IAMCredentialsClient(metaclass=IAMCredentialsClientMeta):
8383
8484
Service account credentials are used to temporarily assume the
8585
identity of the service account. Supported credential types
86-
include OAuth 2.0 access tokens, OpenID Connect ID tokens, self-
87-
signed JSON Web Tokens (JWTs), and more.
86+
include OAuth 2.0 access tokens, OpenID Connect ID tokens,
87+
self-signed JSON Web Tokens (JWTs), and more.
8888
"""
8989

9090
@staticmethod

tests/integration/goldens/credentials/google/iam/credentials_v1/services/iam_credentials/transports/grpc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class IAMCredentialsGrpcTransport(IAMCredentialsTransport):
3939
4040
Service account credentials are used to temporarily assume the
4141
identity of the service account. Supported credential types
42-
include OAuth 2.0 access tokens, OpenID Connect ID tokens, self-
43-
signed JSON Web Tokens (JWTs), and more.
42+
include OAuth 2.0 access tokens, OpenID Connect ID tokens,
43+
self-signed JSON Web Tokens (JWTs), and more.
4444
4545
This class defines the same methods as the primary client, so the
4646
primary client can load the underlying transport implementation

tests/integration/goldens/credentials/google/iam/credentials_v1/services/iam_credentials/transports/grpc_asyncio.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class IAMCredentialsGrpcAsyncIOTransport(IAMCredentialsTransport):
4040
4141
Service account credentials are used to temporarily assume the
4242
identity of the service account. Supported credential types
43-
include OAuth 2.0 access tokens, OpenID Connect ID tokens, self-
44-
signed JSON Web Tokens (JWTs), and more.
43+
include OAuth 2.0 access tokens, OpenID Connect ID tokens,
44+
self-signed JSON Web Tokens (JWTs), and more.
4545
4646
This class defines the same methods as the primary client, so the
4747
primary client can load the underlying transport implementation

tests/integration/goldens/logging/google/cloud/logging_v2/services/config_service_v2/async_client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,8 +2418,8 @@ def sample_get_cmek_settings():
24182418
The request object. The parameters to
24192419
[GetCmekSettings][google.logging.v2.ConfigServiceV2.GetCmekSettings].
24202420
See [Enabling CMEK for Logs
2421-
Router](https://cloud.google.com/logging/docs/routing/managed-
2422-
encryption) for more information.
2421+
Router](https://cloud.google.com/logging/docs/routing/managed-encryption)
2422+
for more information.
24232423
retry (google.api_core.retry.Retry): Designation of what errors, if any,
24242424
should be retried.
24252425
timeout (float): The timeout for this request.
@@ -2520,8 +2520,8 @@ def sample_update_cmek_settings():
25202520
The request object. The parameters to
25212521
[UpdateCmekSettings][google.logging.v2.ConfigServiceV2.UpdateCmekSettings].
25222522
See [Enabling CMEK for Logs
2523-
Router](https://cloud.google.com/logging/docs/routing/managed-
2524-
encryption) for more information.
2523+
Router](https://cloud.google.com/logging/docs/routing/managed-encryption)
2524+
for more information.
25252525
retry (google.api_core.retry.Retry): Designation of what errors, if any,
25262526
should be retried.
25272527
timeout (float): The timeout for this request.

tests/integration/goldens/logging/google/cloud/logging_v2/services/config_service_v2/client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2616,8 +2616,8 @@ def sample_get_cmek_settings():
26162616
The request object. The parameters to
26172617
[GetCmekSettings][google.logging.v2.ConfigServiceV2.GetCmekSettings].
26182618
See [Enabling CMEK for Logs
2619-
Router](https://cloud.google.com/logging/docs/routing/managed-
2620-
encryption) for more information.
2619+
Router](https://cloud.google.com/logging/docs/routing/managed-encryption)
2620+
for more information.
26212621
retry (google.api_core.retry.Retry): Designation of what errors, if any,
26222622
should be retried.
26232623
timeout (float): The timeout for this request.
@@ -2720,8 +2720,8 @@ def sample_update_cmek_settings():
27202720
The request object. The parameters to
27212721
[UpdateCmekSettings][google.logging.v2.ConfigServiceV2.UpdateCmekSettings].
27222722
See [Enabling CMEK for Logs
2723-
Router](https://cloud.google.com/logging/docs/routing/managed-
2724-
encryption) for more information.
2723+
Router](https://cloud.google.com/logging/docs/routing/managed-encryption)
2724+
for more information.
27252725
retry (google.api_core.retry.Retry): Designation of what errors, if any,
27262726
should be retried.
27272727
timeout (float): The timeout for this request.

tests/integration/goldens/logging/google/cloud/logging_v2/types/logging_config.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ class LogView(proto.Message):
144144
name (str):
145145
The resource name of the view.
146146
For example
147-
"projects/my-project-id/locations/my-
148-
location/buckets/my-bucket-id/views/my-view
147+
"projects/my-project-id/locations/my-location/buckets/my-bucket-id/views/my-view
149148
description (str):
150149
Describes this view.
151150
create_time (google.protobuf.timestamp_pb2.Timestamp):

tests/integration/goldens/redis/google/cloud/redis_v1/types/cloud_redis.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ class Instance(proto.Message):
9595
addresses that are reserved for this instance.
9696
If not provided, the service will choose an
9797
unused /29 block, for example, 10.0.0.0/29 or
98-
192.168.0.0/29. Ranges must be unique and non-
99-
overlapping with existing subnets in an
98+
192.168.0.0/29. Ranges must be unique and
99+
non-overlapping with existing subnets in an
100100
authorized network.
101101
host (str):
102102
Output only. Hostname or IP address of the

tests/unit/utils/test_lines.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,7 @@ def test_wrap_indent_short():
8787

8888
def test_wrap_short_line_preserved():
8989
assert lines.wrap('foo\nbar\nbaz', width=80) == 'foo\nbar\nbaz'
90+
91+
92+
def test_wrap_does_not_break_hyphenated_word():
93+
assert lines.wrap('do-not-break', width=5) == 'do-not-break'

0 commit comments

Comments
 (0)