Skip to content
This repository has been archived by the owner on Jun 14, 2021. It is now read-only.

Commit

Permalink
Merge PAUSED branch 'feature/#151/represent-local-env' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
benoit-dubreuil committed May 1, 2021
2 parents 96f8cc3 + 7ce69f4 commit dfcbc82
Show file tree
Hide file tree
Showing 44 changed files with 657 additions and 66 deletions.
30 changes: 19 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# Override of :
### Python ###
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
pythonenv*

# Project specific
!/conf/script/src/
!/conf/script/src/*
!/conf/script/src/**/*

# Created by https://www.toptal.com/developers/gitignore/api/git,vim,c++,meson,macos,linux,batch,emacs,eclipse,windows,netbeans,clion+all,notepadpp,powershell,intellij+all,visualstudio,visualstudiocode,python,pycharm+all
# Edit at https://www.toptal.com/developers/gitignore?templates=git,vim,c++,meson,macos,linux,batch,emacs,eclipse,windows,netbeans,clion+all,notepadpp,powershell,intellij+all,visualstudio,visualstudiocode,python,pycharm+all

Expand Down Expand Up @@ -566,16 +583,6 @@ celerybeat.pid
# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
pythonenv*

# Spyder project settings
.spyderproject
.spyproject
Expand Down Expand Up @@ -1004,4 +1011,5 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/

# End of https://www.toptal.com/developers/gitignore/api/git,vim,c++,meson,macos,linux,batch,emacs,eclipse,windows,netbeans,clion+all,notepadpp,powershell,intellij+all,visualstudio,visualstudiocode,python,pycharm+all
# End of https://www.toptal.com/developers/gitignore/api/git,vim,c++,meson,macos,linux,batch,emacs,eclipse,windows,netbeans,clion+all,notepadpp,powershell,intellij+all,visualstudio,visualstudiocode,python,pycharm+all

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def cli_clean_build_dir():
"folder, where the build system organizes into subfolders specific builds.")
add_optional_path_arg(arg_parser, ROOT_DIR_ARG, path_arg_help="The project's root directory")

root_dir: AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
root_dir: TUnion_AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
arg_parser.parse_args()

def cli_cmd():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def cli_create_build_dir():
description=f"Creates the project's '{colorama.Fore.LIGHTBLACK_EX}{BUILD_DIR_NAME}{colorama.Style.RESET_ALL}' folder.")
add_optional_path_arg(arg_parser, ROOT_DIR_ARG, path_arg_help="The project's root directory")

root_dir: AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
root_dir: TUnion_AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
arg_parser.parse_args()

def cli_cmd():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def cli_create_targets_build_dirs_structure():
path_arg=BUILD_DIR_ARG,
path_arg_help=f"The project's {BUILD_DIR_NAME} directory")

build_dir: AnyPath = parse_optional_path_arg(arg_parser, BUILD_DIR_ARG)
build_dir: TUnion_AnyPath = parse_optional_path_arg(arg_parser, BUILD_DIR_ARG)
arg_parser.parse_args()

def cli_cmd():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def cli_find_build_dir():
description=f"Finds the project's '{colorama.Fore.LIGHTBLACK_EX}{BUILD_DIR_NAME}{colorama.Style.RESET_ALL}' folder.")
add_optional_path_arg(arg_parser, ROOT_DIR_ARG, path_arg_help="The project's root directory")

root_dir: AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
root_dir: TUnion_AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
arg_parser.parse_args()

def cli_cmd():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def cli_find_conf_dir():
description=f"Finds the project's '{colorama.Fore.LIGHTBLACK_EX}{CONF_DIR_NAME}{colorama.Style.RESET_ALL}' folder.")
add_optional_path_arg(arg_parser, ROOT_DIR_ARG, path_arg_help="The project's root directory")

root_dir: AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
root_dir: TUnion_AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
arg_parser.parse_args()

def cli_cmd():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ def colorize_label(label: str) -> str:
return colorama.Fore.CYAN + label + colorama.Style.RESET_ALL


def colorize_path(path_info: PathLike) -> str:
def colorize_path(path_info: TUnion_PathLike) -> str:
return colorama.Fore.LIGHTBLACK_EX + str(path_info) + colorama.Style.RESET_ALL
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javaproperties

from build_system.build_target import *
from ext.utils.string import *
from file_structure import *
from ..cli import *

Expand Down
2 changes: 1 addition & 1 deletion conf/script/src/build_system/cmd/setup/pub/cli_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def cli_setup_build_system():
'folder and setup specific build system builds inside.')
add_optional_path_arg(arg_parser, ROOT_DIR_ARG, path_arg_help="The project's root directory")

root_dir: AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
root_dir: TUnion_AnyPath = parse_optional_path_arg(arg_parser, ROOT_DIR_ARG)
arg_parser.parse_args()

def cli_cmd():
Expand Down
8 changes: 4 additions & 4 deletions conf/script/src/cli/arg_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


def add_optional_path_arg(arg_parser: argparse.ArgumentParser, path_arg: CLIArg = CLIArg.create_default_path_arg(),
path_arg_default_value: AnyPath = None, path_arg_help: Optional[AnyStr] = None):
path_arg_default_value: TUnion_AnyPath = None, path_arg_help: Optional[AnyStr] = None):
arg_parser.add_argument(path_arg.prefixed_name, type=Path, nargs=argparse.OPTIONAL, const=path_arg_default_value, default=path_arg_default_value, help=path_arg_help)


Expand All @@ -21,17 +21,17 @@ def _assure_no_unknown_parsed_args(arg_parser: argparse.ArgumentParser, unknown_
error.raise_or_exit_cli(arg_parser, print_usage=True)


def _assure_nonempty_parsed_path(arg_parser: argparse.ArgumentParser, path_arg_name: str, parsed_path: AnyPath):
def _assure_nonempty_parsed_path(arg_parser: argparse.ArgumentParser, path_arg_name: str, parsed_path: TUnion_AnyPath):
if str(parsed_path) == str():
error = EmptyParsedArgError(path_arg_name)
error.raise_or_exit_cli(arg_parser, print_usage=True)


def parse_optional_path_arg(arg_parser: argparse.ArgumentParser, path_arg: CLIArg = CLIArg.create_default_path_arg()) -> AnyPath:
def parse_optional_path_arg(arg_parser: argparse.ArgumentParser, path_arg: CLIArg = CLIArg.create_default_path_arg()) -> TUnion_AnyPath:
parsed_args, unknown_parsed_args = arg_parser.parse_known_args([path_arg.prefixed_name])

_assure_no_unknown_parsed_args(arg_parser, unknown_parsed_args)
parsed_path: AnyPath = getattr(parsed_args, path_arg.name) if path_arg.name in parsed_args else None
parsed_path: TUnion_AnyPath = getattr(parsed_args, path_arg.name) if path_arg.name in parsed_args else None
_assure_nonempty_parsed_path(arg_parser, path_arg.name, parsed_path)

return parsed_path
1 change: 1 addition & 0 deletions conf/script/src/ext/meta_prog/encapsulation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .clear_args_kwargs import *
from .export import *
from .no_export import *
12 changes: 12 additions & 0 deletions conf/script/src/ext/meta_prog/encapsulation/clear_args_kwargs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
__all__ = ['ClearArgsKwargs']

from typing import Any


class ClearArgsKwargs:

def __init__(self, *args, **kwargs) -> None:
super().__init__()

def __new__(cls, *args, **kwargs) -> Any:
return super().__new__(cls)
3 changes: 3 additions & 0 deletions conf/script/src/ext/meta_prog/generics/cls_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

class GenericClassMixin(GenericsDataMixin):

def __new__(cls, *args, **kwargs):
return super().__new__(cls, *args, **kwargs)

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

Expand Down
37 changes: 27 additions & 10 deletions conf/script/src/ext/meta_prog/generics/cls_proxy.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,45 @@
__all__ = ['GenericClassProxy']

import itertools
from typing import TypeVar
from typing import Any, TypeVar

from .cls_wrapper import *
from .cls_wrapper_data import *
from .data import *
from ..encapsulation import *
from .proxy_verifier_mixin import *


# TODO : functools -> wraps ?
class GenericClassProxy(GenericsDataMixin,
GenericClassWrapperMixin):
class GenericClassProxy(ProxyGenericsVerifierMixin,
GenericsDataMixin,
GenericClassWrapperMixin,
ClearArgsKwargs):

def __init__(self,
generic_cls: TAlias_generic_cls,
*args,
generics: tuple[type] = tuple(),
**kwargs) -> None:
generics_by_type_vars = self.__create_generics_by_type_vars(generic_cls=generic_cls, generics=generics)
super().__init__(*args, generic_cls=generic_cls, generics_by_type_vars=generics_by_type_vars, **kwargs)
def __new__(cls,
generic_cls: TAlias_generic_cls,
*args,
generics: tuple[type] = tuple(),
**kwargs):
generics_by_type_vars = cls.__create_generics_by_type_vars(generic_cls=generic_cls, generics=generics)
return super().__new__(cls, *args, generic_cls=generic_cls, generics_by_type_vars=generics_by_type_vars, **kwargs)

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

def __call__(self, *args, **kwargs):
return self.wrapped_generic_cls(*args, generics_by_type_vars=self.generics_by_type_vars, **kwargs)

def __getattribute__(self, name: str) -> Any:
attr: Any

try:
attr = super().__getattribute__(name)
except AttributeError:
attr = getattr(self.wrapped_generic_cls, name)

return attr

@classmethod
def __create_generics_by_type_vars(cls,
generic_cls: TAlias_generic_cls,
Expand Down
21 changes: 12 additions & 9 deletions conf/script/src/ext/meta_prog/generics/cls_proxy_injector.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,23 @@
class GenericClassProxyInjectorMixin(GenericClassMixin):
__TAlias_Generics_Subscript_Op = Optional[Union[tuple, type]]

def __init__(self,
*args,
generics_by_type_vars: TAlias_Generics_By_TypeVars = None,
**kwargs) -> None:
def __new__(cls,
*args,
generics_by_type_vars: TAlias_Generics_By_TypeVars = None,
**kwargs):
if generics_by_type_vars is None:
generic_cls = type(self)
generics = tuple()
generic_cls = cls
generics: tuple[type] = tuple()
cls_proxy = GenericClassProxy(generic_cls=generic_cls, generics=generics)

generics_by_type_vars = cls_proxy.generics_by_type_vars

super().__init__(*args, generics_by_type_vars=generics_by_type_vars, **kwargs)
return super().__new__(cls, *args, generics_by_type_vars=generics_by_type_vars, **kwargs)

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

@classmethod
def __class_getitem__(cls, item: __TAlias_Generics_Subscript_Op):
generics = item if isinstance(item, tuple) else (item,)
def __class_getitem__(cls, key: __TAlias_Generics_Subscript_Op):
generics = key if isinstance(key, tuple) else (key,)
return GenericClassProxy(generic_cls=cls, generics=generics)
3 changes: 3 additions & 0 deletions conf/script/src/ext/meta_prog/generics/cls_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
# TODO : functools -> wraps ?
class GenericClassWrapperMixin(GenericClassWrapperDataMixin):

def __new__(cls, *args, **kwargs):
return super().__new__(cls, *args, **kwargs)

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

Expand Down
13 changes: 9 additions & 4 deletions conf/script/src/ext/meta_prog/generics/cls_wrapper_data.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
__all__ = ['TAlias_generic_cls',
'GenericClassWrapperDataMixin']

from typing import Final, Generic
from typing import Generic

TAlias_generic_cls = type[Generic]


class GenericClassWrapperDataMixin:
wrapped_generic_cls: Final[TAlias_generic_cls]
wrapped_generic_cls: TAlias_generic_cls

def __init__(self, generic_cls: TAlias_generic_cls, *args, **kwargs) -> None:
self.wrapped_generic_cls = generic_cls
def __new__(cls, generic_cls: TAlias_generic_cls, *args, **kwargs):
instance = super().__new__(cls, *args, **kwargs)
instance.wrapped_generic_cls = generic_cls

return instance

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
18 changes: 12 additions & 6 deletions conf/script/src/ext/meta_prog/generics/data.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
__all__ = ['TAlias_Generics_By_TypeVars',
'GenericsDataMixin']

from typing import Final, Optional, TypeVar
from typing import Optional, TypeVar

TAlias_Generics_By_TypeVars = dict[TypeVar, Optional[type]]


class GenericsDataMixin:
generics_by_type_vars: Final[TAlias_Generics_By_TypeVars]
generics_by_type_vars: TAlias_Generics_By_TypeVars

def __init__(self, *args,
generics_by_type_vars: TAlias_Generics_By_TypeVars = None,
**kwargs) -> None:
self.generics_by_type_vars = generics_by_type_vars if generics_by_type_vars is not None else {}
def __new__(cls,
*args,
generics_by_type_vars: TAlias_Generics_By_TypeVars = None,
**kwargs):
instance = super().__new__(cls, *args, **kwargs)
instance.generics_by_type_vars = generics_by_type_vars if generics_by_type_vars is not None else {}

return instance

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
32 changes: 32 additions & 0 deletions conf/script/src/ext/meta_prog/generics/proxy_verifier_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
__all__ = ['ProxyGenericsVerifierMixin']

from typing import TypeVar

from .cls_wrapper_data import *
from .data import *


class ProxyGenericsVerifierMixin(GenericsDataMixin, GenericClassWrapperDataMixin):

def __new__(cls, *args, **kwargs):
instance: cls = super().__new__(cls, *args, **kwargs)
instance._verify_generics()

return instance

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

def _verify_generics(self) -> None:
generic_type_vars: tuple[TypeVar] = self.__get_cls_generic_type_vars(self.wrapped_generic_cls)

if len(self.generics_by_type_vars) != len(generic_type_vars):
raise TypeError(f'Wrong number of generic types for {type(self.wrapped_generic_cls)}.')

# TODO : Change me for checking if it matches the actual TypeVars, i.e. if the bound and the constraints are respected.
if tuple(self.generics_by_type_vars.keys()) != generic_type_vars:
raise TypeError(f'Supplied generic types do not match the class\'s generic type vars requirements.')

@staticmethod
def __get_cls_generic_type_vars(cls: TAlias_generic_cls) -> tuple[TypeVar]:
return cls.__parameters__
5 changes: 5 additions & 0 deletions conf/script/src/ext/meta_prog/introspection/caller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
__all__ = ['get_nth_caller',
'get_caller',
'get_caller_func_name',
'is_frame_main',
'is_caller_main']

Expand Down Expand Up @@ -29,6 +30,10 @@ def get_caller() -> FrameType:
return get_nth_caller(n=_CALLER_MIN_N + 1)


def get_caller_func_name() -> str:
return get_caller().f_code.co_name


def is_frame_main(frame: FrameType) -> bool:
frame_script_name = frame.f_locals[Macro.NAME]
return frame_script_name == Macro.MAIN
Expand Down
1 change: 1 addition & 0 deletions conf/script/src/ext/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .path import *
from .string import *
Loading

0 comments on commit dfcbc82

Please sign in to comment.