6
6
import zlib
7
7
from typing import IO , TYPE_CHECKING , Callable
8
8
9
+ from sphinx .locale import __
9
10
from sphinx .util import logging
10
11
11
12
BUFSIZE = 16 * 1024
@@ -86,19 +87,23 @@ def load(
86
87
reader = InventoryFileReader (stream )
87
88
line = reader .readline ().rstrip ()
88
89
if line == '# Sphinx inventory version 1' :
89
- return cls .load_v1 (reader , uri , joinfunc )
90
+ invdata , ambiguities = cls .load_v1 (reader , uri , joinfunc )
90
91
elif line == '# Sphinx inventory version 2' :
91
- return cls .load_v2 (reader , uri , joinfunc )
92
+ invdata , ambiguities = cls .load_v2 (reader , uri , joinfunc )
92
93
else :
93
94
raise ValueError ('invalid inventory header: %s' % line )
95
+ for ambiguity in ambiguities :
96
+ logger .warning (__ ("inventory <%s> contains multiple definitions for %s" ),
97
+ uri , ambiguity , type = 'intersphinx' , subtype = 'external' )
98
+ return invdata
94
99
95
100
@classmethod
96
101
def load_v1 (
97
102
cls : type [InventoryFile ],
98
103
stream : InventoryFileReader ,
99
104
uri : str ,
100
105
join : Callable [[str , str ], str ],
101
- ) -> Inventory :
106
+ ) -> tuple [ Inventory , set ] :
102
107
invdata : Inventory = {}
103
108
projname = stream .readline ().rstrip ()[11 :]
104
109
version = stream .readline ().rstrip ()[11 :]
@@ -113,18 +118,20 @@ def load_v1(
113
118
type = 'py:' + type
114
119
location += '#' + name
115
120
invdata .setdefault (type , {})[name ] = (projname , version , location , '-' )
116
- return invdata
121
+ return invdata , frozenset ()
117
122
118
123
@classmethod
119
124
def load_v2 (
120
125
cls : type [InventoryFile ],
121
126
stream : InventoryFileReader ,
122
127
uri : str ,
123
128
join : Callable [[str , str ], str ],
124
- ) -> Inventory :
129
+ ) -> tuple [ Inventory , set ] :
125
130
invdata : Inventory = {}
126
131
projname = stream .readline ().rstrip ()[11 :]
127
132
version = stream .readline ().rstrip ()[11 :]
133
+ potential_ambiguities = set ()
134
+ actual_ambiguities = set ()
128
135
line = stream .readline ()
129
136
if 'zlib' not in line :
130
137
raise ValueError ('invalid inventory header (not compressed): %s' % line )
@@ -147,12 +154,20 @@ def load_v2(
147
154
# for Python modules, and the first
148
155
# one is correct
149
156
continue
157
+ if type in {'std:label' , 'std:term' }:
158
+ # Some types require case insensitive matches:
159
+ # * 'term': https://github.com/sphinx-doc/sphinx/issues/9291
160
+ # * 'label': https://github.com/sphinx-doc/sphinx/issues/12008
161
+ if name .lower () in potential_ambiguities :
162
+ actual_ambiguities .add (f"{ type } :{ name } " )
163
+ else :
164
+ potential_ambiguities .add (name .lower ())
150
165
if location .endswith ('$' ):
151
166
location = location [:- 1 ] + name
152
167
location = join (uri , location )
153
168
inv_item : InventoryItem = projname , version , location , dispname
154
169
invdata .setdefault (type , {})[name ] = inv_item
155
- return invdata
170
+ return invdata , actual_ambiguities
156
171
157
172
@classmethod
158
173
def dump (
0 commit comments