Skip to content
Closed
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
40 changes: 40 additions & 0 deletions docs_sphinx/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,43 @@ def __getattr__(cls, name):

# Configure linking to github
extlinks = {"issue": ("https://github.com/brian-team/brian2/issues/%s", "# %s")}
# Dictionary to cache module members for O(1) lookups
_module_member_cache = {}

def skip_case_collisions(app, what, name, obj, skip, options):
"""
Optimized O(1) hook to prevent Windows case-insensitive file collisions
Uses a cache to check if a lowercase member (e.g., 'device') shares a name
with any other case variation (e.g., 'Device', 'DEVICE','DeVice') in the same module
"""
# Skip this check on non-Windows platforms where case sensitivity is not an issue
if sys.platform != "win32":
return skip
if skip:
return True

if name.islower():
mod_name = getattr(obj, '__module__', None)
if mod_name and mod_name in sys.modules:
# If we haven't scanned this module yet, scan it ONCE and cache it so it takes O(1) time for future lookups.
if mod_name not in _module_member_cache:
parent_mod = sys.modules[mod_name]
lower_map = {}
for member in dir(parent_mod):
lower_name = member.lower()
if lower_name not in lower_map:
lower_map[lower_name] = set()
lower_map[lower_name].add(member)

# Save the map to our global cache
_module_member_cache[mod_name] = lower_map

# Now, do an instant O(1) lookup in our cache.
# If the set for 'device' has more than 1 item (e.g., {'device', 'Device'}) it skips
if len(_module_member_cache[mod_name].get(name, set())) > 1:
return True

return skip

def setup(app):
app.connect('autodoc-skip-member', skip_case_collisions)
Loading