示例#1
0
This module implements all errors and warnings for psef.

This module does not contain any error checking or handling.

SPDX-License-Identifier: AGPL-3.0-only
"""
import typing as t

import structlog
from flask import Response, g, request

from cg_json import jsonify

from .exceptions import APICodes, APIWarnings, APIException

HttpWarning = t.NewType('HttpWarning', str)  # pylint: disable=invalid-name

logger = structlog.get_logger()


def make_warning(warning_text: str, code: APIWarnings) -> HttpWarning:
    """Make a ``HttpWarning`` with the given warning and code.

    :param warning_text: The text that describes the warning.
    :param code: The warning code to associate with the warning.
    :returns: A warning with the given text and code.
    """
    return HttpWarning('{:03d} CodeGrade "{}"'.format(
        code.value,
        warning_text.replace('"', '\\"'),
    ))
示例#2
0
import typing as t
import typing_extensions as tx
import pytest
from magicalimport import import_symbol

_MyString = t.NewType("S", str)


class _Person:
    name: str


def atom(*, raw, underlying, is_optional=False, custom=None):
    return {
        "raw": raw,
        "underlying": underlying,
        "is_optional": is_optional,
        "custom": custom,
    }


def container(*,
              container,
              raw,
              is_optional=False,
              is_composite=False,
              raw_args=None,
              args=None):
    raw_args = raw_args or [atom(raw=x, underlying=x) for x in args]
    return {
        "raw": raw,
示例#3
0
import typing

from pandas import Series
from tqdm import tqdm

from .cpg_collector import CpGCollector

DataClass = typing.NewType("DataClass", typing.Any)


def find_pairs_(
    search_range: int, tqdm_disable: bool, cpg_per_chr: Series
) -> typing.List[DataClass]:
    collected_cpg = []

    for cpg in tqdm(cpg_per_chr.index, disable=tqdm_disable):
        collector = CpGCollector(
            chromosome_cpg_collection=cpg_per_chr,
            search_range=search_range,
            base_cpg_id=cpg,
        )
        collector.interval_size()
        collector.find_nearby_cpg()
        collected_cpg.append(collector)

    return collected_cpg
示例#4
0
文件: types.py 项目: yyolk/xpring-py
from dataclasses import dataclass
from enum import Enum
import typing as t

import typing_extensions as tex

# 16 bytes.
# The two key-derivation functions we have today both use 128-bit keys,
# but only by happy accident.
# We should not assume that seeds will always be 128 bits.
Seed = t.NewType('Seed', bytes)
# Base58 encoding (with prefix and checksum) of
# a seed and a choice of signing algorithm.
EncodedSeed = t.NewType('EncodedSeed', str)

# 32 bytes.
PrivateKey = t.NewType('PrivateKey', bytes)

# 33 bytes.
PublicKey = t.NewType('PublicKey', bytes)
# 20 bytes computed from a public key.
AccountId = t.NewType('AccountId', bytes)
# Base58 encoding (with prefix and checksum) of an account ID.
# https://xrpl.org/accounts.html#address-encoding
Address = t.NewType('Address', str)

Signature = t.NewType('Signature', bytes)

NonXrpAmount = tex.TypedDict('NonXrpAmount', {
    'value': str,
    'currency': str,
示例#5
0
    def __init__(self, inp: JSONObject):
        super(TestSkipEvent, self).__init__(inp)
        self.test = inp.pop("Test", None)
        self.elapsed = inp["Elapsed"]

        del inp["Elapsed"]
        check_empty(inp)


parse_callbacks = {
    "run": lambda x: TestRunEvent(x),
    "pause": lambda x: TestPauseEvent(x),
    "cont": lambda x: TestContinueEvent(x),
    "pass": lambda x: TestPassEvent(x),
    "fail": lambda x: TestFailEvent(x),
    "output": lambda x: TestOutputEvent(x),
    "skip": lambda x: TestSkipEvent(x),
}

TestEvent = typing.NewType(
    "TestEvent", typing.Union[TestRunEvent, TestPauseEvent, TestContinueEvent,
                              TestPassEvent, TestFailEvent, TestOutputEvent,
                              TestSkipEvent, ])


def parse_test_line(inp: JSONObject) -> typing.Optional[TestEvent]:
    cb = parse_callbacks.get(inp["Action"], None)
    if cb is None:
        return None
    return cb(inp)
示例#6
0
文件: mypyq.py 项目: Meithal/mypyq
import functools
import math
import time
import operator
import _huffman
import audioop

import explode

__version__ = "0.0.1"

listfile_name = b'(listfile)'
attributes_name = b'(attributes)'
signature_name = b'(signature)'

_HashType = typing.NewType('_HashType', int)
"Hashed version of a string, that MPQ can work with."
_FilePosition = typing.NewType('_FilePosition', int)
"An offset in the stream."
HashTableEntries = typing.NewType('HashTableEntries', int)
"A number that is a power of 2."
FilePath = typing.NewType('FilePath', bytes)
r"""
A full qualified path that is a valid windows path, for example `Foo\\Bar\\file.txt`.
Such a path is used as an entry key to extract a file from a MPQ.
For multi-OS compatibility, only backslashes have been observed as directory separators
and every implementation capitalizes the letters of the path to
allow unpacking on case insensitive file systems.
"""

示例#7
0
def RuleCondition(value: str,
                  *,
                  description: typing.Optional[str] = None) -> filter.Filter:
    try:
        return filter.Filter.parse(value, description)
    except filter.parser.pyparsing.ParseException as e:
        raise voluptuous.Invalid(
            message=f"Invalid condition '{value}'. {str(e)}",
            error_message=str(e))
    except filter.InvalidQuery as e:
        raise voluptuous.Invalid(
            message=f"Invalid condition '{value}'. {str(e)}",
            error_message=str(e))


RuleConditions = typing.NewType("RuleConditions", typing.List[filter.Filter])
RuleMissingConditions = typing.NewType("RuleMissingConditions",
                                       typing.List[filter.Filter])


async def get_branch_protection_conditions(
    ctxt: context.Context, ) -> typing.List[filter.Filter]:
    return [
        RuleCondition(
            f"check-success-or-neutral={check}",
            description="🛡 GitHub branch protection",
        ) for check in await ctxt.repository.get_branch_protection_checks(
            ctxt.pull["base"]["ref"])
    ]

示例#8
0
文件: base.py 项目: vinsonlee/meson
    EXTRAFRAMEWORK = 'extraframework'
    # Detect using the sysconfig module.
    SYSCONFIG = 'sysconfig'
    # Specify using a "program"-config style tool
    CONFIG_TOOL = 'config-tool'
    # For backwards compatibility
    SDLCONFIG = 'sdlconfig'
    CUPSCONFIG = 'cups-config'
    PCAPCONFIG = 'pcap-config'
    LIBWMFCONFIG = 'libwmf-config'
    QMAKE = 'qmake'
    # Misc
    DUB = 'dub'


DependencyTypeName = T.NewType('DependencyTypeName', str)


class Dependency(HoldableObject):

    @classmethod
    def _process_include_type_kw(cls, kwargs: T.Dict[str, T.Any]) -> str:
        if 'include_type' not in kwargs:
            return 'preserve'
        if not isinstance(kwargs['include_type'], str):
            raise DependencyException('The include_type kwarg must be a string type')
        if kwargs['include_type'] not in ['preserve', 'system', 'non-system']:
            raise DependencyException("include_type may only be one of ['preserve', 'system', 'non-system']")
        return kwargs['include_type']

    def __init__(self, type_name: DependencyTypeName, kwargs: T.Dict[str, T.Any]) -> None:
示例#9
0
T = t.TypeVar('T')
ZZ = t.TypeVar('ZZ')
T_CONTRA = t.TypeVar('T_CONTRA', contravariant=True)
Z = t.TypeVar('Z')
Y = t.TypeVar('Y')
U = t.TypeVar('U')
E = t.TypeVar('E', bound=enum.Enum)
DbSelf = t.TypeVar('DbSelf', bound='MyDb')
QuerySelf = t.TypeVar('QuerySelf', bound='MyNonOrderableQuery')
_T_BASE = t.TypeVar('_T_BASE', bound='Base')
_Y_BASE = t.TypeVar('_Y_BASE', bound='Base')
T_DB_COLUMN = t.TypeVar('T_DB_COLUMN', bound='DbColumn')
T_NUM = t.TypeVar('T_NUM', bound=t.Union[int, float])

Never = t.NewType('Never', object)


class MySession:  # pragma: no cover
    info: dict

    def bulk_save_objects(self, objs: t.Sequence['Base']) -> None:
        ...

    def execute(self, query: object) -> object:
        ...

    @t.overload
    def query(self, __x: 'ExistsColumn') -> '_MyExistsQuery':
        ...
示例#10
0
import math
import typing
import numpy as np

# Typing
Vector2D = typing.NewType("Vector2D", object)

class Vector2D:
    """A mathematical representation of a 2-dimensional vector

    This vector can be used in many ways and is integrated with other representations
    such as Line.
    
    """
    def __init__(self, x: int, y: int) -> None:
        self.x = x
        self.y = y
    

    @classmethod
    def fromTuple(cls, t: tuple):
        return cls(t[0], t[1])

    ### Normal Algebraic func
    def __add__(self, other: Vector2D) -> Vector2D:
        """Add two vectors together using the '+' operator

            ### Args:
                other: A vector.
        """
        if(type(other) == Vector2D):
示例#11
0
# systems  and/or  data to be  ensured and,  more generally,  to use and
# operate it in the same conditions as regards security.
#
# The fact that you  are presently reading this  means that you have had
# knowledge of the CeCILL-B license and that you accept its terms.
# ======================================================================

import logging
import random
import typing as ty
from copy import deepcopy
from math import exp

logger = logging.getLogger("hamap.optimisation.simulated_annealing")

StateType = ty.NewType("StateType", ty.Any)


def _accept_neighbour(neighbour_cost: float, current_cost: float,
                      temperature: float) -> bool:
    try:
        p = exp(-(neighbour_cost - current_cost) / temperature)
    except OverflowError:
        return True
    return p >= random.random()


def simulated_annealing(
    initial_state: StateType,
    cost_function: ty.Callable[[StateType], float],
    get_neighbour: ty.Callable[[StateType], StateType],
示例#12
0
# Adapted from https://gist.github.com/JeffPaine/3145490/revisions#diff-6c74585fc93fb54ed50f85e4166e2fb4

import getpass
import json
import typing
from pathlib import Path

import requests

GitHubIdentity = typing.NewType('GitHubIdentity', str)


class Issue(typing.NamedTuple):
    id: int
    url: str
    assignees: typing.List[GitHubIdentity]
    title: str


def get_credentials() -> typing.Tuple[str, str]:
    config_file = Path(__file__).parent.parent / '.config.json'

    data: typing.Dict[str, str] = {}
    username = None
    password = None

    if config_file.exists():
        with config_file.open() as f:
            data = json.load(f)
            username = data['username']
            password = data.get('password')
示例#13
0
import re
import typing

from enum import Enum
from urllib.parse import unquote
from collections import namedtuple
from flask.sessions import SecureCookieSession

from .exceptions import Readonly

Cookie = typing.NewType('Cookie', str)
FormParam = typing.NewType("FormParam", str)
Session = typing.NewType("Session", SecureCookieSession)
DummyFlaskApp = namedtuple(
    "DummyFlaskApp",
    "session_cookie_name,secret_key,permanent_session_lifetime,config")


class File(object):
    mime_type_regex = re.compile(b"Content-Type: (\S*)")
    disposition_regex = re.compile(rb"Content-Disposition: form-data;"
                                   rb"(?: name=\"(?P<name>[^;]*?)\")?"
                                   rb"(?:; filename\*?=\"?"
                                   rb"(?:(?P<enc>[\w\-]+?)'"
                                   rb"(?P<lang>\w*)')?"
                                   rb"(?P<filename>[^\"]*)\"?)?")

    def __init__(self, stream, receive, boundary, name, filename, mimetype):
        self.mimetype = mimetype
        self.receive = receive
        self.filename = filename
示例#14
0
import abc
import asyncio
import http.client
import logging
import pathlib
import ssl
import time
import typing
import urllib.request  # TODO: Figure out how to get aiohttp

from magma.common.service import MagmaService
from magma.common.service_registry import ServiceRegistry
from magma.magmad.upgrade.upgrader import Upgrader
from prometheus_client import Gauge

VersionT = typing.NewType("VersionT", str)
ImageNameT = typing.NewType("ImageNameT", str)

# TODO - Add gauges for upgrade actions and failure

UpgraderGauges = typing.NamedTuple(
    'UpgraderGauges',
    [
        ('time_taken', Gauge),
        ('error', Gauge),
        ('downloaded', Gauge),
        ('prepared', Gauge),
        ('canary', Gauge),
        ('stable', Gauge),
        ('idle', Gauge),
    ]
示例#15
0
import datetime
import hashlib
import hmac
import os
import socket
import ssl
import typing

import aredis

from mergify_engine import config

_PROCESS_IDENTIFIER = os.environ.get("DYNO") or socket.gethostname()

# NOTE(sileht): I wonder with mypy thing aredis.StrictRedis is Any...
RedisCache = typing.NewType("RedisCache", aredis.StrictRedis)  # type: ignore
RedisStream = typing.NewType("RedisStream", aredis.StrictRedis)  # type: ignore


def redis_from_url(url: str, **options: typing.Any) -> aredis.StrictRedis:
    ssl_scheme = "rediss://"
    if config.REDIS_SSL_VERIFY_MODE_CERT_NONE and url.startswith(ssl_scheme):
        final_url = f"redis://{url[len(ssl_scheme):]}"
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        options["ssl_context"] = ctx
    else:
        final_url = url
    return aredis.StrictRedis.from_url(final_url, **options)
示例#16
0
import re
import typing

from enum import Enum
from urllib.parse import unquote
from collections import namedtuple
from flask.sessions import SecureCookieSession

from toolkit import cache_classproperty
from toolkit.settings import SettingsLoader, Settings

from .exceptions import Readonly

Cookie = typing.NewType('Cookie', str)
FormParam = typing.NewType("FormParam", str)
Session = typing.NewType("Session", SecureCookieSession)
MultiPartForm = typing.NewType("MultiPartForm", dict)
UrlEncodeForm = typing.NewType("UrlEncodeForm", dict)
DummyFlaskApp = namedtuple(
    "DummyFlaskApp",
    "session_cookie_name,secret_key,permanent_session_lifetime,config")


class File(object):
    mime_type_regex = re.compile(rb"Content-Type: (\S*)")
    content_length_regex = re.compile(rb"Content-Length: (\d*)")
    disposition_regex = re.compile(
        rb'Content-Disposition: form-data(?:; name\*?=\"?(?:(?P<name_enc>[\w\-]+?)\'(?P<name_lang>\w*)\')?(?P<name>[^\";]*)\"?)?.*?(?:; filename\*?=\"?(?:(?P<enc>[\w\-]+?)\'(?P<lang>\w*)\')?(?P<filename>[^\"]*?)\"?)?(?:$|\r\n)'
    )

    def __init__(self, stream, receive, boundary, name, filename, mimetype,
示例#17
0
import typing as t

from datetime import datetime
from sqlalchemy.sql import func
from sqlalchemy.orm import Session

from app.db.session import SessionLocal
from app import crud, models

db = SessionLocal()
CalcType = t.NewType('Calculation Type', str)


def get_claim_bill(_db: Session = db,
                   *,
                   start: datetime = None,
                   end: datetime = None,
                   store_internal_id: int = None,
                   owner_id: int = None,
                   kind: models.ClaimKind = None,
                   calculation: CalcType = "avg"):
    """ WE USE THIS FUNCTION TO CREATE A CLAIM QUERY WITH OPTIONAL PARAMETER
        AND CALCULATE BY SQLALCHEMY.SQL.FUNC
    """
    query = crud.claim.get_query(_db)
    if start and end:
        query = query.filter(models.Claim.created_at.between(start, end))
    if store_internal_id:
        query = query.filter(
            models.Claim.store_internal_id == store_internal_id)
    if owner_id:
示例#18
0
import dataclasses as dc
from hashlib import sha256
from pathlib import Path
import typing as ty

File = ty.NewType("File", Path)
Directory = ty.NewType("Directory", Path)


@dc.dataclass
class SpecInfo:
    name: str
    fields: ty.List[ty.Tuple] = dc.field(default_factory=list)
    bases: ty.Tuple[dc.dataclass] = dc.field(default_factory=tuple)


@dc.dataclass(order=True)
class BaseSpec:
    """The base dataclass specs for all inputs and outputs"""
    @property
    def hash(self):
        """Compute a basic hash for any given set of fields"""
        return sha256(str(self).encode()).hexdigest()


@dc.dataclass
class Runtime:
    rss_peak_gb: ty.Optional[float] = None
    vms_peak_gb: ty.Optional[float] = None
    cpu_peak_percent: ty.Optional[float] = None
示例#19
0
import functools

from .expressions import *

__all__ = [
    "ExpressionReference",
    "NormalizedExpression",
    "NormalizedExpressions",
    "Parent",
    "Children",
    "hash_value",
    "Hash",
    "ID",
]

ID = typing.NewType("ID", int)
Hash = typing.NewType("Hash", int)


@dataclasses.dataclass(frozen=True)
class Parent:
    hash: Hash
    key: typing.Union[str, int]


@functools.singledispatch
def hash_value(value: object) -> int:
    """
    Computes some hash for a value that should be stable. Either use the built in hash, or if we cannot
    (like the object is mutable) then use the id.
示例#20
0
"Python is a protocol orientated lang; every top-level function has a corresponding dunder method implemented;"

import sqlite3
import typing
Path = typing.NewType('T', str)
Cursor = typing.NewType('Cursor', sqlite3.Cursor)


class TemporaryTable:
    def __init__(self, cur: Cursor):
        self._cur = cur

    def __enter__(self, *args):
        print('__enter__ : ', args)
        self._cur.execute('CREATE TABLE points(x int, y int);')

    def __exit__(self, *args):
        print('__exit__ : ', args)
        self._cur.execute('DROP TABLE points;')


def dml(db: Path) -> None:
    with sqlite3.connect(db) as conn:
        cur = conn.cursor()

        with TemporaryTable(cur):
            cur.execute('INSERT INTO points(x, y) VALUES(1, 1);')
            cur.execute('INSERT INTO points(x, y) VALUES(1, 2);')
            cur.execute('INSERT INTO points(x, y) VALUES(2, 1);')
            cur.execute('INSERT INTO points(x, y) VALUES(2, 2);')
示例#21
0
import argparse
import collections
import logging
import os
import pathlib
import re
import shutil
import sqlite3
import sys
import tempfile
import typing

__version__ = "0.5.0"

FileID = typing.NewType("FileID", int)
FileID.__doc__ = """\
The numeric identifier of a source file in the coverage database."""
ContextID = typing.NewType("ContextID", int)
ContextID.__doc__ = """\
The numeric identifier of an execution context in the coverage database."""
SourceModule = typing.NewType("SourceModule", str)
SourceModule.__doc__ = """The import path of a Python module."""
TestModule = typing.NewType("TestModule", str)
TestModule.__doc__ = """The import path of a Python module containing tests."""

MODULE_RE = re.compile(r"tests\.((?:\w+\.)*)test_(\w+)")

Rows = typing.List[typing.Tuple[int]]

logger = logging.getLogger(__name__)
示例#22
0
import typing as t

# see: https://swagger.io/docs/specification/data-models/data-types/
number = float
double = t.NewType("double", number)
float = t.NewType("float", number)

integer = int
int32 = t.NewType("int32", int)
int64 = t.NewType("int64", int)

string = str
date = t.NewType("date", str)
date_time = t.NewType("date_time", str)
password = t.NewType("password", str)

byte = bytes
binary = t.NewType("binary", byte)
email = t.NewType("email", str)
uuid = t.NewType("uuid", str)
uri = t.NewType("uri", str)
hostname = t.NewType("hostname", str)
ipv4 = t.NewType("ipv4", str)
ipv6 = t.NewType("ipv6", str)
示例#23
0
else:
    vcr_errors_CannotOverwriteExistingCassetteException: Exception = (  # type: ignore
        vcr.errors.CannotOverwriteExistingCassetteException
    )


LOG = daiquiri.getLogger(__name__)


MAX_RETRIES: int = 3
WORKER_PROCESSING_DELAY: float = 30
STREAM_ATTEMPTS_LOGGING_THRESHOLD: int = 20


StreamNameType = typing.NewType("StreamNameType", str)


class IgnoredException(Exception):
    pass


@dataclasses.dataclass
class PullRetry(Exception):
    attempts: int


class MaxPullRetry(PullRetry):
    pass

示例#24
0
import json
import typing
from urllib.parse import urlparse

from apistar import types

Method = typing.NewType('Method', str)
Scheme = typing.NewType('Scheme', str)
Host = typing.NewType('Host', str)
Port = typing.NewType('Port', int)
Path = typing.NewType('Path', str)
QueryString = typing.NewType('QueryString', str)
QueryParam = typing.NewType('QueryParam', str)
Header = typing.NewType('Header', str)
Body = typing.NewType('Body', bytes)
PathParams = typing.NewType('PathParams', dict)
PathParam = typing.NewType('PathParam', str)
RequestData = typing.TypeVar('RequestData')


class URL(str):
    """
    A string that also supports accessing the parsed URL components.
    eg. `url.components.query`
    """
    @property
    def components(self):
        if not hasattr(self, '_components'):
            self._components = urlparse(self)
        return self._components
示例#25
0
import os
import typing

from ..constants import DATA_HOME_DEFAULT_DIRNAME, DATA_HOME_ENV_VAR_NAME, DATA_HOME_SUB_DIRNAME

DataDirname = typing.NewType("DataDirname", str)


def data_dirname() -> DataDirname:
    base_data_dir_name = os.getenv(DATA_HOME_ENV_VAR_NAME, os.path.expanduser(DATA_HOME_DEFAULT_DIRNAME))

    return DataDirname(os.path.join(base_data_dir_name, DATA_HOME_SUB_DIRNAME))
示例#26
0
from collections import Counter
from dataclasses import dataclass
from decimal import Decimal
import typing

ProductName = typing.NewType('ProductName', str)
SlotCode = typing.NewType('SlotCode', str)
Assortment = typing.Dict[ProductName, 'Product']
Coins = typing.Counter[Decimal]
Menu = typing.Dict[ProductName, typing.Tuple[SlotCode, Decimal]]
Prod2Slot = typing.Dict[ProductName, typing.Tuple['slots', 'slot_depth']]


class MachineOverloadedException(Exception):
    pass


@dataclass
class Product:
    name: ProductName
    quantity: int
    price: Decimal


class Machine:
    def __init__(self, slots: int, slot_depth: int) -> None:
        self.slots = slots
        self.slot_depth = slot_depth
        pass

    def load_products(self, assortment: Assortment) -> None:
示例#27
0
# Copyright © 2020 Mergify SAS
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import typing

GitHubLogin = typing.NewType("GitHubLogin", str)


class GitHubInstallationAccessToken(typing.TypedDict):
    # https://developer.github.com/v3/apps/#response-7
    token: str
    expires_at: str


GitHubAccountType = typing.Literal["User", "Organization", "Bot"]
GitHubAccountIdType = typing.NewType("GitHubAccountIdType", int)


class GitHubAccount(typing.TypedDict):
    login: GitHubLogin
    id: GitHubAccountIdType
示例#28
0
def test_can_register_NewType():
    Name = typing.NewType("Name", str)
    st.register_type_strategy(Name, st.just("Eric Idle"))
    assert st.from_type(Name).example() == "Eric Idle"
示例#29
0
    return Callable[list(args), None]

# Static cache of all Python QJIT objects that have been created.
# There seems to be a bug when a Python interpreter tried to create a new QJIT
# *after* a previous QJIT is destroyed.
# Note: this could only occur when QJIT kernels were declared in local scopes.
# i.e. multiple kernels all declared in global scope don't have this issue.
# Hence, to be safe, we cache all the QJIT objects ever created until QCOR module is unloaded.
QJIT_OBJ_CACHE = []
@atexit.register
def clear_qjit_cache():
    QJIT_OBJ_CACHE = []

PauliOperator = xacc.quantum.PauliOperator
FermionOperator = xacc.quantum.FermionOperator 
FLOAT_REF = typing.NewType('value', float)
INT_REF = typing.NewType('value', int)

typing_to_simple_map = {'<class \'_pyqcor.qreg\'>': 'qreg',
                            '<class \'_pyqcor.qubit\'>': 'qubit',
                            '<class \'float\'>': 'float', 'typing.List[float]': 'List[float]',
                            '<class \'int\'>': 'int', 'typing.List[int]': 'List[int]',
                            '<class \'_pyxacc.quantum.PauliOperator\'>': 'PauliOperator',
                            '<class \'_pyxacc.quantum.FermionOperator\'>': 'FermionOperator',
                            'typing.List[typing.Tuple[int, int]]': 'List[Tuple[int,int]]',
                            'typing.List[_pyxacc.quantum.PauliOperator]': 'List[PauliOperator]',
                            'typing.List[_pyxacc.quantum.FermionOperator]': 'List[FermionOperator]'}

# Need to add a few extra header paths 
# for the clang code-gen mechanism. Mac OS X will 
# need QCOR_EXTRA_HEADERS, all will need the 
"""

import functools as ft
import itertools as it
import typing as t
import pydantic as pyd
from pathlib import Path
import re
import subprocess as sub
import pkg_resources
import shutil

EXTENDED_PKG_SPEC_REGEX = re.compile(r'^\s*(?P<package_name>[\w\-_.]+)\s*@\s*(?P<package_url>\S+)\s*$')
REGULAR_PKG_SPEC_REGEX = re.compile(r'^\s*(?P<package_name>[\w\-_.]+)==(?P<package_version>\S+)\s*$')

NonBlankStr = t.NewType('NonBlankStr', pyd.constr(strip_whitespace=True, min_length=1))


class HashableMixin:
    def __hash__(self) -> int:
        return hash(
            (type(self),) + tuple(getattr(self, f) for f in self.__fields__.keys())
        )


class Package(HashableMixin, pyd.BaseModel):
    name: NonBlankStr
    pkg_spec: NonBlankStr


class DownloadedPackage(Package):