Skip to content

Commit 9ab77de

Browse files
committed
Change MerginProject constructor to force one instance per project
1 parent 843133c commit 9ab77de

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

mergin/merginproject.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import os
55
import re
66
import shutil
7-
import uuid
87
import tempfile
8+
import uuid
9+
import weakref
910
from datetime import datetime
1011
from dateutil.tz import tzlocal
1112

@@ -41,7 +42,30 @@ class MerginProject:
4142
Linked to existing local directory, with project metadata (mergin.json) and backups located in .mergin directory.
4243
"""
4344

45+
# To make sure we don't have multiple instances for a single project that
46+
# then have out-of-date information, we keep this map of absolute project
47+
# directory paths to instances.
48+
# The dictionary is a WeakValueDictionary so we don't cause memory leaks
49+
# (when the instance is GC'd, the entry is deleted).
50+
project_cache: weakref.WeakValueDictionary[str, "MerginProject"] = weakref.WeakValueDictionary()
51+
52+
def __new__(cls, directory):
53+
directory = os.path.abspath(directory)
54+
if instance := cls.project_cache.get(directory):
55+
return instance
56+
57+
instance = super().__new__(cls)
58+
cls.project_cache[directory] = instance
59+
return instance
60+
4461
def __init__(self, directory):
62+
# __init__ still gets called after __new__, even if it returns a
63+
# pre-existing object. Work around this by checking whether we've been
64+
# initialised.
65+
if hasattr(self, "_initialised"):
66+
return
67+
self._initialised = True
68+
4569
self.dir = os.path.abspath(directory)
4670
if not os.path.exists(self.dir):
4771
raise InvalidProject("Project directory does not exist")

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="mergin-client",
8-
version="0.11.0",
8+
version="0.12.0",
99
url="https://github.com/MerginMaps/python-api-client",
1010
license="MIT",
1111
author="Lutra Consulting Ltd.",

0 commit comments

Comments
 (0)