Skip to content

Commit

Permalink
🐛 Bug: fix cache and cycle ref issue (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
yanyongyu authored Jan 6, 2024
1 parent 8a381cb commit 469afbb
Show file tree
Hide file tree
Showing 41 changed files with 466 additions and 50 deletions.
12 changes: 11 additions & 1 deletion codegen/templates/rest/__init__.py.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""{{ header() }}"""

from weakref import ref
from typing import TYPE_CHECKING
from functools import cached_property

Expand All @@ -14,7 +15,16 @@ if TYPE_CHECKING:

class RestNamespace:
def __init__(self, github: "GitHubCore"):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> "GitHubCore":
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this namespace after the client has been collected."
)

{% for tag in tags %}
@cached_property
Expand Down
12 changes: 11 additions & 1 deletion codegen/templates/rest/client.py.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand Down Expand Up @@ -56,7 +57,16 @@ class {{ pascal_case(tag) }}Client:
_REST_API_VERSION = "{{ rest_api_version }}"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

{% for endpoint in endpoints %}
{% if endpoint.request_body and endpoint.request_body.allowed_models %}
Expand Down
24 changes: 18 additions & 6 deletions codegen/templates/versions/rest.py.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""{{ header() }}"""

import importlib
from weakref import WeakKeyDictionary, ref
from typing import TYPE_CHECKING, Any, Dict, Literal, overload

from . import VERSIONS, LATEST_VERSION, VERSION_TYPE
Expand All @@ -22,7 +23,7 @@ else:
_VersionProxy = object

class RestVersionSwitcher(_VersionProxy):
_cached_namespaces: Dict[VERSION_TYPE, Any] = {}
_cached_namespaces: "WeakKeyDictionary[GitHubCore, Dict[VERSION_TYPE, Any]]" = WeakKeyDictionary()

if not TYPE_CHECKING:
def __getattr__(self, name: str) -> Any:
Expand All @@ -34,7 +35,16 @@ class RestVersionSwitcher(_VersionProxy):
return getattr(namespace, name)

def __init__(self, github: "GitHubCore"):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> "GitHubCore":
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use the namespace after the client has been collected."
)

{% for version, module in versions.items() %}
@overload
Expand All @@ -47,9 +57,11 @@ class RestVersionSwitcher(_VersionProxy):
...

def __call__(self, version: VERSION_TYPE = LATEST_VERSION) -> Any:
if version in self._cached_namespaces:
return self._cached_namespaces[version]
g = self._github
cache = self._cached_namespaces.setdefault(g, {})
if version in cache:
return cache[version]
module = importlib.import_module(f".{VERSIONS[version]}.rest", __package__)
namespace = module.RestNamespace(self._github)
self._cached_namespaces[version] = namespace
namespace = module.RestNamespace(g)
cache[version] = namespace
return namespace
26 changes: 20 additions & 6 deletions githubkit/versions/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"""

import importlib
from weakref import WeakKeyDictionary, ref
from typing import TYPE_CHECKING, Any, Dict, Literal, overload

from . import VERSIONS, VERSION_TYPE, LATEST_VERSION
Expand All @@ -27,7 +28,9 @@ class _VersionProxy(V20221128RestNamespace):


class RestVersionSwitcher(_VersionProxy):
_cached_namespaces: Dict[VERSION_TYPE, Any] = {}
_cached_namespaces: "WeakKeyDictionary[GitHubCore, Dict[VERSION_TYPE, Any]]" = (
WeakKeyDictionary()
)

if not TYPE_CHECKING:

Expand All @@ -40,7 +43,16 @@ def __getattr__(self, name: str) -> Any:
return getattr(namespace, name)

def __init__(self, github: "GitHubCore"):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> "GitHubCore":
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use the namespace after the client has been collected."
)

@overload
def __call__(self, version: Literal["2022-11-28"]) -> "V20221128RestNamespace":
Expand All @@ -51,9 +63,11 @@ def __call__(self) -> "V20221128RestNamespace":
...

def __call__(self, version: VERSION_TYPE = LATEST_VERSION) -> Any:
if version in self._cached_namespaces:
return self._cached_namespaces[version]
g = self._github
cache = self._cached_namespaces.setdefault(g, {})
if version in cache:
return cache[version]
module = importlib.import_module(f".{VERSIONS[version]}.rest", __package__)
namespace = module.RestNamespace(self._github)
self._cached_namespaces[version] = namespace
namespace = module.RestNamespace(g)
cache[version] = namespace
return namespace
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
See https://github.com/github/rest-api-description for more information.
"""

from weakref import ref
from typing import TYPE_CHECKING
from functools import cached_property

Expand Down Expand Up @@ -52,7 +53,16 @@

class RestNamespace:
def __init__(self, github: "GitHubCore"):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> "GitHubCore":
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this namespace after the client has been collected."
)

@cached_property
def meta(self) -> "MetaClient":
Expand Down
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand Down Expand Up @@ -121,7 +122,16 @@ class ActionsClient:
_REST_API_VERSION = "2022-11-28"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

def get_actions_cache_usage_for_org(
self,
Expand Down
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand Down Expand Up @@ -54,7 +55,16 @@ class ActivityClient:
_REST_API_VERSION = "2022-11-28"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

def list_public_events(
self,
Expand Down
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand Down Expand Up @@ -62,7 +63,16 @@ class AppsClient:
_REST_API_VERSION = "2022-11-28"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

def get_authenticated(
self,
Expand Down
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand All @@ -30,7 +31,16 @@ class BillingClient:
_REST_API_VERSION = "2022-11-28"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

def get_github_actions_billing_org(
self,
Expand Down
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand Down Expand Up @@ -57,7 +58,16 @@ class ChecksClient:
_REST_API_VERSION = "2022-11-28"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

@overload
def create(
Expand Down
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/classroom.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand Down Expand Up @@ -41,7 +42,16 @@ class ClassroomClient:
_REST_API_VERSION = "2022-11-28"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

def get_an_assignment(
self,
Expand Down
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/code_scanning.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand Down Expand Up @@ -52,7 +53,16 @@ class CodeScanningClient:
_REST_API_VERSION = "2022-11-28"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

def list_alerts_for_org(
self,
Expand Down
12 changes: 11 additions & 1 deletion githubkit/versions/v2022_11_28/rest/codes_of_conduct.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

from weakref import ref
from typing_extensions import Annotated
from typing import TYPE_CHECKING, Dict, Literal, Optional, overload

Expand All @@ -32,7 +33,16 @@ class CodesOfConductClient:
_REST_API_VERSION = "2022-11-28"

def __init__(self, github: GitHubCore):
self._github = github
self._github_ref = ref(github)

@property
def _github(self) -> GitHubCore:
if g := self._github_ref():
return g
raise RuntimeError(
"GitHub client has already been collected. "
"Do not use this client after the client has been collected."
)

def get_all_codes_of_conduct(
self,
Expand Down
Loading

0 comments on commit 469afbb

Please sign in to comment.