Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Josverl/micropython-stubber as stubs repository + Stubs module renovations. #304

Merged
merged 69 commits into from
Dec 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
0b061ee
feat(data): add micropython-stubs source
BradenM Nov 6, 2022
fac69b7
feat(deps): add attrs/pydantic
BradenM Nov 6, 2022
02b8cda
feat(stubs): add RepositoryInfo model.
BradenM Nov 13, 2022
94c3b82
feat(stubs): add StubRepositoryPackage model.
BradenM Nov 13, 2022
4fe89f8
feat(stubs): add StubPackage model.
BradenM Nov 13, 2022
df4b14f
feat(stubs): add StubsManifest model.
BradenM Nov 13, 2022
efe3f79
feat(stubs): add MicropyStubs package/manifest models.
BradenM Nov 13, 2022
9db0d05
feat(stubs): add Micropython stubs package/manifest models.
BradenM Nov 13, 2022
7574102
feat(stubs): add StubRepository for managing stub manifests.
BradenM Nov 13, 2022
63d187f
test(stubs): add unittests for stubs repositories.
BradenM Nov 13, 2022
1cebaf3
feat(stubs): add resolve package url abstract meth to stubs manifest
BradenM Nov 27, 2022
91e11e7
feat(stubs): micropy-stubs resolve package url impl, stub micropython…
BradenM Nov 27, 2022
77e1fde
feat(stubs): expose url via StubRepositoryPackage descriptor.
BradenM Nov 27, 2022
e26df51
feat(stubs): impl resolve package method in StubRepository.
BradenM Nov 27, 2022
90ac445
feat(main): drop in new StubRepository impl in place of StubRepo.
BradenM Nov 27, 2022
48b90e6
feat(stubs): add `display_name` field to stub repository.
BradenM Nov 27, 2022
10adb37
feat(data): add display names for current stub sources.
BradenM Nov 27, 2022
46507c3
test(stubs): update mock stub repositories.
BradenM Nov 27, 2022
cf36bca
fix(stubs): use `typing.Type` for sub py3.7 compat.
BradenM Nov 27, 2022
f00459f
feat(stubs): add method for resolving absolute stub package name from…
BradenM Nov 27, 2022
5d3045d
feat(stubs): expose name/version/absolute_name fields from stub repo …
BradenM Nov 27, 2022
2178dca
feat(stubs): check absolute name for stub resolve matching.
BradenM Nov 27, 2022
73c2893
fix(stubs): utilize absolute names in stub search results.
BradenM Nov 27, 2022
332f3a7
fix(main): StubRepository has faux immutability.
BradenM Nov 27, 2022
9c25a05
feat(stubs): enforce faux immutability in StubRepository.
BradenM Nov 27, 2022
29ffe29
feat(deps): add distlib.
BradenM Nov 28, 2022
be6c829
feat(utils): add utils.types, PathStr alias.
BradenM Nov 28, 2022
50d1535
feat(utils): add types to `ensure_existing_dir`
BradenM Nov 28, 2022
65f2102
feat(stubs): impl `resolve_package_url` for micropython-stubs repo.
BradenM Nov 28, 2022
e246c67
feat(stubs): add `resolve_package_(absolute,)_versioned_name` to mani…
BradenM Nov 28, 2022
3e1ddde
feat(stubs): rename `StubRepositoryPackage.repository` -> `manifest`.
BradenM Nov 28, 2022
c104f45
feat(stubs): expose `repo_name`,`versioned_name`,`absolute_versioned_…
BradenM Nov 28, 2022
24e3130
feat(stubs): utilize `StubRepositoryPackage.match_exact`
BradenM Nov 28, 2022
fb58cb3
feat(stubs): make `StubSource` proper abstract, add prepare abstractm…
BradenM Nov 28, 2022
43874e6
fix(main): add types to `MicroPy.stubs`
BradenM Nov 28, 2022
a042d0d
feat(stubs): implement dirty metadata adapter for dist-based stubs un…
BradenM Nov 28, 2022
9fd04a3
feat(cli): improve stub search output.
BradenM Nov 28, 2022
100f4df
feat(deps): add importlib_metadata as dep.
BradenM Dec 4, 2022
d12425f
fix(utils): use importlib metadata to check micropy version in utils.
BradenM Dec 4, 2022
28bf245
feat(utils): defer updating stale cache with `utils.get_cached_data`
BradenM Dec 4, 2022
8110aa9
feat(stubs): validate RepoInfo source, add method for fetching contents.
BradenM Dec 4, 2022
79d5a40
feat(stubs): make `StubRepositoryPackage` immutable, iterate matchers.
BradenM Dec 4, 2022
fd88c13
feat(stubs): make `StubsManifest` immutable.
BradenM Dec 4, 2022
140e947
refactor(stubs): update repository impls to retain immutability.
BradenM Dec 4, 2022
0f8464f
feat(stubs): make `StubPackage` immutable.
BradenM Dec 4, 2022
e76aca9
fix(stubs): remove mutating subclass hook from `StubsManifest`.
BradenM Dec 4, 2022
d51489a
feat(stubs): build progressive package indexes in `StubRepository`, u…
BradenM Dec 4, 2022
a946f98
feat(main): init `StubRepository` as attr.
BradenM Dec 4, 2022
54af9cb
fix(stubs): perform repo lookups prior to adding stub
BradenM Dec 4, 2022
931c274
refactor(stubs): remove old `StubRepo` class.
BradenM Dec 4, 2022
c7e1b74
feat(cli): format repo as title in stubs search output.
BradenM Dec 4, 2022
5e76373
test(utils): update mock target for update check test
BradenM Dec 4, 2022
03853ee
test(conf): move stubs repo fixtures to conf.
BradenM Dec 4, 2022
ef9e163
test(stubs): update remote stub source mock to decrease its scope.
BradenM Dec 4, 2022
8a9b550
test(stubs): remove old `StubRepo` tests.
BradenM Dec 4, 2022
981ee48
feat(utils): add SupportsLessThan protocol to types util.
BradenM Dec 11, 2022
d7a722d
feat(deps): add pytest-clarity+better-exceptions to dev deps.
BradenM Dec 11, 2022
60e4108
feat(stubs): accept generic package type in stub manifest
BradenM Dec 11, 2022
035df32
feat(stubs): make micropython stubs package sortable.
BradenM Dec 11, 2022
ed0cf99
feat(stubs): assume latest version by default, optionally show latest…
BradenM Dec 11, 2022
d65d146
refactor(stubs): utilize locator strategies over stub source factory …
BradenM Dec 11, 2022
054ee60
refactor(stubs): remove search remote from stub manager.
BradenM Dec 11, 2022
4341562
fix((stubs): accomodate for source not handling repo lookup anymore, …
BradenM Dec 11, 2022
ed4c870
feat(cli): add flag to show outdated stub packages in search + group …
BradenM Dec 11, 2022
2d5325e
test(stubs): expand stub repository unit tests.
BradenM Dec 11, 2022
2c68cdb
test(stubs): remove search test, update existing.
BradenM Dec 11, 2022
af8bcab
test(stubs): add locators unit tests, update.
BradenM Dec 11, 2022
59795bd
test: update minor issues with tests.
BradenM Dec 11, 2022
9aa583e
fix(utils): add annotations future in type utils.
BradenM Dec 11, 2022
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
8 changes: 5 additions & 3 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ babel==2.11.0 ; python_version >= "3.7" and python_version < "3.12"
bleak-sigspec==0.0.4 ; python_version >= "3.7" and python_version < "3.12"
bleak-winrt==1.2.0 ; python_version >= "3.7" and python_version < "3.12" and platform_system == "Windows"
bleak==0.19.4 ; python_version >= "3.7" and python_version < "3.12"
boltons==19.3.0 ; python_version >= "3.7" and python_version < "3.12"
boltons==21.0.0 ; python_version >= "3.7" and python_version < "3.12"
cachier==1.5.4 ; python_version >= "3.7" and python_version < "3.12"
certifi==2022.9.24 ; python_version >= "3.7" and python_version < "3.12"
charset-normalizer==2.1.1 ; python_version >= "3.7" and python_version < "3.12"
Expand All @@ -16,13 +16,14 @@ colorama==0.4.6 ; python_version >= "3.7" and python_version < "3.12" and sys_pl
commonmark==0.9.1 ; python_version >= "3.7" and python_version < "3.12"
dbus-fast==1.73.0 ; python_version >= "3.7" and python_version < "3.12" and platform_system == "Linux"
dill==0.3.6 ; python_version >= "3.7" and python_version < "3.12"
distlib==0.3.6 ; python_version >= "3.7" and python_version < "3.12"
docutils==0.17.1 ; python_version >= "3.7" and python_version < "3.12"
dpath==1.5.0 ; python_version >= "3.7" and python_version < "3.12"
gitdb==4.0.9 ; python_version >= "3.7" and python_version < "3.12"
gitpython==3.1.29 ; python_version >= "3.7" and python_version < "3.12"
idna==3.4 ; python_version >= "3.7" and python_version < "3.12"
imagesize==1.4.1 ; python_version >= "3.7" and python_version < "3.12"
importlib-metadata==5.0.0 ; python_version >= "3.7" and python_version < "3.10"
importlib-metadata==5.1.0 ; python_version >= "3.7" and python_version < "3.12"
jinja2==3.1.2 ; python_version >= "3.7" and python_version < "3.12"
jsonschema==3.2.0 ; python_version >= "3.7" and python_version < "3.12"
markupsafe==2.1.1 ; python_version >= "3.7" and python_version < "3.12"
Expand All @@ -33,6 +34,7 @@ packaging==21.3 ; python_version >= "3.7" and python_version < "3.12"
pathtools==0.1.2 ; python_version >= "3.7" and python_version < "3.12"
portalocker==2.6.0 ; python_version >= "3.7" and python_version < "3.12"
prompt-toolkit==3.0.32 ; python_version >= "3.7" and python_version < "3.12"
pydantic==1.10.2 ; python_version >= "3.7" and python_version < "3.12"
pygments==2.13.0 ; python_version >= "3.7" and python_version < "3.12"
pyobjc-core==8.5.1 ; python_version >= "3.7" and python_version < "3.12" and platform_system == "Darwin"
pyobjc-framework-cocoa==8.5.1 ; python_version >= "3.7" and python_version < "3.12" and platform_system == "Darwin"
Expand Down Expand Up @@ -75,4 +77,4 @@ upydevice==0.3.8 ; python_version >= "3.7" and python_version < "3.12"
urllib3==1.26.12 ; python_version >= "3.7" and python_version < "3.12"
watchdog==2.1.9 ; python_version >= "3.7" and python_version < "3.12"
wcwidth==0.2.5 ; python_version >= "3.7" and python_version < "3.12"
zipp==3.10.0 ; python_version >= "3.7" and python_version < "3.10"
zipp==3.10.0 ; python_version >= "3.7" and python_version < "3.12"
36 changes: 31 additions & 5 deletions micropy/cli.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/usr/bin/env python

"""MicropyCli Console Entrypoint."""
from __future__ import annotations

import sys
from contextlib import suppress
from pathlib import Path
from typing import TYPE_CHECKING

import click
import micropy.exceptions as exc
Expand All @@ -12,6 +16,9 @@
from micropy.project import Project, modules
from questionary import Choice

if TYPE_CHECKING:
pass

pass_mpy = click.make_pass_decorator(main.MicroPy, ensure=True)


Expand Down Expand Up @@ -187,7 +194,7 @@ def install(mpy, packages, dev=False, path=None):
@click.argument("stub_name", required=True)
@click.option("-f", "--force", is_flag=True, default=False, help="Overwrite Stub if it exists.")
@pass_mpy
def add(mpy, stub_name, force=False):
def add(mpy: main.MicroPy, stub_name, force=False):
"""Add Stubs from package or path.

\b
Expand All @@ -208,6 +215,8 @@ def add(mpy, stub_name, force=False):
mpy.stubs.verbose_log(True)
proj = mpy.project
mpy.log.title(f"Adding $[{stub_name}] to stubs")
with suppress(exc.StubNotFound):
stub_name = mpy.repo.resolve_package(stub_name)
try:
stub = mpy.stubs.add(stub_name, force=force)
except exc.StubNotFound:
Expand All @@ -224,15 +233,32 @@ def add(mpy, stub_name, force=False):

@stubs.command()
@click.argument("query", required=True)
@click.option(
"-s", "--show-outdated", is_flag=True, help="Include outdated versions in search results."
)
@pass_mpy
def search(mpy, query):
def search(mpy: main.MicroPy, query: str, show_outdated: bool = False):
"""Search available Stubs."""
mpy.log.title(f"Searching Stub Repositories...")
results = mpy.stubs.search_remote(query)
installed_stubs = map(str, mpy.stubs._loaded | mpy.stubs._firmware)
results = [
(r, r.name in installed_stubs)
for r in mpy.repo.search(query, include_versions=show_outdated)
]
results = sorted(results, key=lambda pkg: pkg[0].name)
if not any(results):
mpy.log.warn(f"No results found for: $[{query}].")
sys.exit(0)
mpy.log.title(f"Results for $[{query}]:")
max_name = max(len(n[0].repo_name) for n in results)
for pkg, installed in results:
name = f"{pkg} $B[(Installed)]" if installed else pkg
mpy.log.info(name)
pad = max_name - len(pkg.repo_name) + 2
pad = pad if (pad % 2 == 0) else pad + 1
spacer = "{:>{pad}}".format(f"::", pad=pad)
repo_logger = Log.add_logger(f"{pkg.repo_name} {spacer}", "bright_white")
name = "{:>{pad}}".format(f"{pkg.name} ($w[{pkg.version}])", pad=pad)
name = f"{name} $B[(Installed)]" if installed else name
repo_logger.info(name)


@stubs.command()
Expand Down
8 changes: 7 additions & 1 deletion micropy/data/sources.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
[
{
"name": "Micropy Stubs",
"display_name": "BradenM/micropy-stubs",
"name": "micropy-stubs",
"source": "https://raw.githubusercontent.com/BradenM/micropy-stubs/master/source.json"
},
{
"display_name": "Josverl/micropython-stubs",
"name": "micropython-stubs",
"source": "https://raw.githubusercontent.com/Josverl/micropython-stubs/main/publish/package_data.jsondb"
}
]
22 changes: 16 additions & 6 deletions micropy/main.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
"""Main Module."""

from __future__ import annotations

import tempfile
from pathlib import Path
from typing import Optional

from micropy import data, utils
from micropy.exceptions import PyDeviceError
from micropy.lib.stubber import process as stubber
from micropy.logger import Log
from micropy.project import Project, modules
from micropy.pyd import DevicePath, MessageHandlers, ProgressStreamConsumer, PyDevice
from micropy.stubs import StubManager, source
from micropy.stubs import RepositoryInfo, StubManager, StubRepository
from pydantic import parse_file_as


class MicroPy:
"""Handles App State Management."""

RUN_CHECKS = True
repo: StubRepository
_stubs: Optional[StubManager] = None

def __init__(self):
self.log = Log.get_logger("MicroPy")
self.verbose = True
self.log.debug("MicroPy Loaded")
repo_list = parse_file_as(list[RepositoryInfo], data.REPO_SOURCES)
self.repo = StubRepository()
for repo_info in repo_list:
self.repo = self.repo.add_repository(repo_info)
if not data.STUB_DIR.exists():
self.setup()

Expand All @@ -31,17 +41,17 @@ def setup(self):
data.FILES.mkdir(exist_ok=True)
data.STUB_DIR.mkdir()

@utils.lazy_property
def stubs(self):
@property
def stubs(self) -> StubManager:
"""Primary Stub Manager for MicroPy.

Returns:
StubManager: StubManager Instance

"""
repo_list = data.REPO_SOURCES.read_text()
repos = source.StubRepo.from_json(repo_list)
return StubManager(resource=data.STUB_DIR, repos=repos)
if not self._stubs:
self._stubs = StubManager(resource=data.STUB_DIR, repos=self.repo)
return self._stubs

@utils.lazy_property
def project(self):
Expand Down
20 changes: 19 additions & 1 deletion micropy/stubs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@
"""

from . import source
from .manifest import StubsManifest
from .package import AnyStubPackage, StubPackage
from .repo import StubRepository
from .repo_package import StubRepositoryPackage
from .repositories import MicropyStubPackage, MicropythonStubsManifest, MicropythonStubsPackage
from .repository_info import RepositoryInfo
from .stubs import StubManager

__all__ = ["StubManager", "source"]
__all__ = [
"StubManager",
"source",
"StubsManifest",
"StubPackage",
"AnyStubPackage",
"StubRepository",
"MicropyStubPackage",
"MicropythonStubsPackage",
"MicropythonStubsManifest",
"RepositoryInfo",
"StubRepositoryPackage",
]
35 changes: 35 additions & 0 deletions micropy/stubs/manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations

import abc
from typing import Generic

from micropy.stubs.package import AnyStubPackage, StubPackage
from micropy.stubs.repository_info import RepositoryInfo
from pydantic import Field
from pydantic.generics import GenericModel
from typing_extensions import Annotated


class StubsManifest(GenericModel, Generic[AnyStubPackage], abc.ABC):

class Config:
frozen = True

repository: RepositoryInfo
packages: Annotated[frozenset[AnyStubPackage], Field(repr=False)]

@abc.abstractmethod
def resolve_package_url(self, package: StubPackage) -> str:
"""Resolve package to a stub source."""

def resolve_package_absolute_name(self, package: StubPackage) -> str:
"""Resolve package absolute name."""
return "/".join([self.repository.name, package.name])

def resolve_package_versioned_name(self, package: StubPackage) -> str:
"""Resolve package versioned absolute name."""
return "-".join([package.name, package.version])

def resolve_package_absolute_versioned_name(self, package: StubPackage) -> str:
"""Resolve package versioned absolute name."""
return "-".join([self.resolve_package_absolute_name(package), package.version])
22 changes: 22 additions & 0 deletions micropy/stubs/package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from __future__ import annotations

from typing import TypeVar

from pydantic import BaseModel


class StubPackage(BaseModel):

class Config:
frozen = True
allow_population_by_field_name = True

name: str
version: str

@property
def package_name(self) -> str:
return self.name


AnyStubPackage = TypeVar("AnyStubPackage", bound=StubPackage)
Loading