Skip to content

Commit

Permalink
Clean up import-related noqa directives
Browse files Browse the repository at this point in the history
  • Loading branch information
mesozoic committed Nov 29, 2024
1 parent fe40c62 commit 6bbad32
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 56 deletions.
22 changes: 10 additions & 12 deletions pyairtable/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
from typing_extensions import TypeAlias

from pyairtable.api import retrying
from pyairtable.api.base import Base
from pyairtable.api.enterprise import Enterprise
from pyairtable.api.params import options_to_json_and_params, options_to_params
from pyairtable.api.table import Table
from pyairtable.api.types import UserAndScopesDict, assert_typed_dict
from pyairtable.api.workspace import Workspace
from pyairtable.models.schema import Bases
Expand Down Expand Up @@ -44,7 +46,7 @@ class Api:
MAX_URL_LENGTH = 16000

# Cached metadata to reduce API calls
_bases: Optional[Dict[str, "pyairtable.api.base.Base"]] = None
_bases: Optional[Dict[str, "Base"]] = None

endpoint_url: Url
session: Session
Expand Down Expand Up @@ -126,7 +128,7 @@ def base(
*,
validate: bool = False,
force: bool = False,
) -> "pyairtable.api.base.Base":
) -> "Base":
"""
Return a new :class:`Base` instance that uses this instance of :class:`Api`.
Expand All @@ -141,7 +143,7 @@ def base(
if validate:
info = self._base_info(force=force).base(base_id)
return self._base_from_info(info)
return pyairtable.api.base.Base(self, base_id)
return Base(self, base_id)

@cache_unless_forced
def _base_info(self) -> Bases:
Expand All @@ -158,15 +160,15 @@ def _base_info(self) -> Bases:
}
return Bases.from_api(data, self)

def _base_from_info(self, base_info: Bases.Info) -> "pyairtable.api.base.Base":
return pyairtable.api.base.Base(
def _base_from_info(self, base_info: Bases.Info) -> "Base":
return Base(
self,
base_info.id,
name=base_info.name,
permission_level=base_info.permission_level,
)

def bases(self, *, force: bool = False) -> List["pyairtable.api.base.Base"]:
def bases(self, *, force: bool = False) -> List["Base"]:
"""
Retrieve the base's schema and return a list of :class:`Base` instances.
Expand All @@ -189,7 +191,7 @@ def create_base(
workspace_id: str,
name: str,
tables: Sequence[Dict[str, Any]],
) -> "pyairtable.api.base.Base":
) -> "Base":
"""
Create a base in the given workspace.
Expand All @@ -210,7 +212,7 @@ def table(
*,
validate: bool = False,
force: bool = False,
) -> "pyairtable.api.table.Table":
) -> "Table":
"""
Build a new :class:`Table` instance that uses this instance of :class:`Api`.
Expand Down Expand Up @@ -407,7 +409,3 @@ def enterprise(self, enterprise_account_id: str) -> Enterprise:
Build an object representing an enterprise account.
"""
return Enterprise(self, enterprise_account_id)


import pyairtable.api.base # noqa
import pyairtable.api.table # noqa
15 changes: 10 additions & 5 deletions pyairtable/api/base.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import warnings
from functools import cached_property
from typing import Any, Dict, List, Optional, Sequence, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union

import pyairtable.api.api
import pyairtable.api.table
from pyairtable.models.schema import BaseCollaborators, BaseSchema, BaseShares
from pyairtable.models.webhook import (
Expand All @@ -13,6 +12,9 @@
)
from pyairtable.utils import Url, UrlBuilder, cache_unless_forced, enterprise_only

if TYPE_CHECKING:
from pyairtable.api.api import Api


class Base:
"""
Expand All @@ -25,7 +27,7 @@ class Base:
"""

#: The connection to the Airtable API.
api: "pyairtable.api.api.Api"
api: "Api"

#: The base ID, in the format ``appXXXXXXXXXXXXXX``
id: str
Expand Down Expand Up @@ -67,7 +69,7 @@ def interface(self, interface_id: str) -> Url:

def __init__(
self,
api: Union["pyairtable.api.api.Api", str],
api: Union["Api", str],
base_id: str,
*,
name: Optional[str] = None,
Expand Down Expand Up @@ -99,7 +101,10 @@ def __init__(
category=DeprecationWarning,
stacklevel=2,
)
api = pyairtable.api.api.Api(api)

from pyairtable import Api

api = Api(api)

self.api = api
self.id = base_id
Expand Down
22 changes: 15 additions & 7 deletions pyairtable/api/enterprise.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
from datetime import date, datetime
from functools import cached_property, partialmethod
from typing import Any, Dict, Iterable, Iterator, List, Literal, Optional, Union
from typing import (
TYPE_CHECKING,
Any,
Dict,
Iterable,
Iterator,
List,
Literal,
Optional,
Union,
)

import pydantic
from typing_extensions import Self
Expand All @@ -17,6 +27,9 @@
enterprise_only,
)

if TYPE_CHECKING:
from pyairtable.api.api import Api


@enterprise_only
class Enterprise:
Expand Down Expand Up @@ -85,7 +98,7 @@ def remove_user(self, user_id: str) -> Url:

urls = cached_property(_urls)

def __init__(self, api: "pyairtable.api.api.Api", workspace_id: str):
def __init__(self, api: "Api", workspace_id: str):
self.api = api
self.id = workspace_id
self._info: Optional[EnterpriseInfo] = None
Expand Down Expand Up @@ -612,8 +625,3 @@ class MoveWorkspacesResponse(AirtableModel):


rebuild_models(vars())


# These are at the bottom of the module to avoid circular imports
import pyairtable.api.api # noqa
import pyairtable.api.base # noqa
37 changes: 23 additions & 14 deletions pyairtable/api/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,19 @@
import warnings
from functools import cached_property
from pathlib import Path
from typing import Any, Dict, Iterable, Iterator, List, Optional, Union, overload
from typing import (
TYPE_CHECKING,
Any,
Dict,
Iterable,
Iterator,
List,
Optional,
Union,
overload,
)

import pyairtable.models
from pyairtable.api.retrying import Retry
from pyairtable.api.types import (
FieldName,
RecordDeletedDict,
Expand All @@ -25,6 +34,11 @@
from pyairtable.models.schema import FieldSchema, TableSchema, parse_field_schema
from pyairtable.utils import Url, UrlBuilder, is_table_id

if TYPE_CHECKING:
from pyairtable.api.api import Api, TimeoutTuple
from pyairtable.api.base import Base
from pyairtable.api.retrying import Retry


class Table:
"""
Expand All @@ -37,7 +51,7 @@ class Table:
"""

#: The base that this table belongs to.
base: "pyairtable.api.base.Base"
base: "Base"

#: Can be either the table name or the table ID (``tblXXXXXXXXXXXXXX``).
name: str
Expand Down Expand Up @@ -82,31 +96,31 @@ def __init__(
base_id: str,
table_name: str,
*,
timeout: Optional["pyairtable.api.api.TimeoutTuple"] = None,
retry_strategy: Optional[Retry] = None,
timeout: Optional["TimeoutTuple"] = None,
retry_strategy: Optional["Retry"] = None,
endpoint_url: str = "https://api.airtable.com",
): ...

@overload
def __init__(
self,
api_key: None,
base_id: "pyairtable.api.base.Base",
base_id: "Base",
table_name: str,
): ...

@overload
def __init__(
self,
api_key: None,
base_id: "pyairtable.api.base.Base",
base_id: "Base",
table_name: TableSchema,
): ...

def __init__(
self,
api_key: Union[None, str],
base_id: Union["pyairtable.api.base.Base", str],
base_id: Union["Base", str],
table_name: Union[str, TableSchema],
**kwargs: Any,
):
Expand Down Expand Up @@ -210,7 +224,7 @@ def id_or_name(self, quoted: bool = True) -> str:
return value

@property
def api(self) -> "pyairtable.api.api.Api":
def api(self) -> "Api":
"""
The API connection used by the table's :class:`~pyairtable.Base`.
"""
Expand Down Expand Up @@ -801,8 +815,3 @@ def upload_attachment(
}
response = self.api.post(url, json=payload)
return assert_typed_dict(UploadAttachmentResultDict, response)


# These are at the bottom of the module to avoid circular imports
import pyairtable.api.api # noqa
import pyairtable.api.base # noqa
19 changes: 9 additions & 10 deletions pyairtable/api/workspace.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from functools import cached_property
from typing import Any, Dict, List, Optional, Sequence, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union

from pyairtable.models.schema import WorkspaceCollaborators
from pyairtable.utils import Url, UrlBuilder, cache_unless_forced, enterprise_only

if TYPE_CHECKING:
from pyairtable.api.api import Api
from pyairtable.api.base import Base


class Workspace:
"""
Expand Down Expand Up @@ -33,15 +37,15 @@ class _urls(UrlBuilder):

urls = cached_property(_urls)

def __init__(self, api: "pyairtable.api.api.Api", workspace_id: str):
def __init__(self, api: "Api", workspace_id: str):
self.api = api
self.id = workspace_id

def create_base(
self,
name: str,
tables: Sequence[Dict[str, Any]],
) -> "pyairtable.api.base.Base":
) -> "Base":
"""
Create a base in the given workspace.
Expand Down Expand Up @@ -73,7 +77,7 @@ def collaborators(self) -> WorkspaceCollaborators:
return WorkspaceCollaborators.from_api(payload, self.api, context=self)

@enterprise_only
def bases(self) -> List["pyairtable.api.base.Base"]:
def bases(self) -> List["Base"]:
"""
Retrieve all bases within the workspace.
"""
Expand Down Expand Up @@ -103,7 +107,7 @@ def delete(self) -> None:
@enterprise_only
def move_base(
self,
base: Union[str, "pyairtable.api.base.Base"],
base: Union[str, "Base"],
target: Union[str, "Workspace"],
index: Optional[int] = None,
) -> None:
Expand All @@ -123,8 +127,3 @@ def move_base(
if index is not None:
payload["targetIndex"] = index
self.api.post(self.urls.move_base, json=payload)


# These are at the bottom of the module to avoid circular imports
import pyairtable.api.api # noqa
import pyairtable.api.base # noqa
10 changes: 3 additions & 7 deletions pyairtable/orm/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from typing_extensions import Self as SelfType
from typing_extensions import TypeAlias

from pyairtable import utils
from pyairtable import formulas, utils
from pyairtable.api.types import (
AITextDict,
AttachmentDict,
Expand All @@ -69,7 +69,7 @@
from pyairtable.orm.lists import AttachmentsList, ChangeTrackingList

if TYPE_CHECKING:
from pyairtable.orm import Model # noqa
from pyairtable.orm import Model


_ClassInfo: TypeAlias = Union[type, Tuple["_ClassInfo", ...]]
Expand Down Expand Up @@ -610,7 +610,7 @@ def __init__(
lazy: If ``True``, this field will return empty objects with only IDs;
call :meth:`~pyairtable.orm.Model.fetch` to retrieve values.
"""
from pyairtable.orm import Model # noqa, avoid circular import
from pyairtable.orm import Model

if not (
model is _LinkFieldOptions.LinkSelf
Expand Down Expand Up @@ -1588,7 +1588,3 @@ class CreatedTimeField(RequiredDatetimeField):
"UrlField",
]
# [[[end]]] (checksum: 87b0a100c9e30523d9aab8cc935c7960)


# Delayed import to avoid circular dependency
from pyairtable import formulas # noqa
2 changes: 1 addition & 1 deletion tests/test_api_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest

from pyairtable import Api, Base, Table # noqa
from pyairtable import Api, Base, Table


@pytest.fixture
Expand Down

0 comments on commit 6bbad32

Please sign in to comment.