first commit

This commit is contained in:
Ayxan
2022-05-23 00:16:32 +04:00
commit d660f2a4ca
24786 changed files with 4428337 additions and 0 deletions

View File

@ -0,0 +1,18 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,125 @@
Metadata-Version: 2.1
Name: apipkg
Version: 2.0.0
Summary: apipkg: namespace control and lazy-import mechanism
Home-page: https://github.com/pytest-dev/apipkg
Author: holger krekel
Maintainer: Ronny Pfannschmidt
Maintainer-email: opensource@ronnypfannschmidt.de
License: MIT
Platform: unix
Platform: linux
Platform: osx
Platform: cygwin
Platform: win32
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Libraries
Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7
Description-Content-Type: text/x-rst
License-File: LICENSE
Welcome to apipkg !
-------------------
With apipkg you can control the exported namespace of a Python package and
greatly reduce the number of imports for your users.
It is a `small pure Python module`_ that works on CPython 2.7 and 3.4+,
Jython and PyPy. It cooperates well with Python's ``help()`` system,
custom importers (PEP302) and common command-line completion tools.
Usage is very simple: you can require 'apipkg' as a dependency or you
can copy paste the ~200 lines of code into your project.
Tutorial example
-------------------
Here is a simple ``mypkg`` package that specifies one namespace
and exports two objects imported from different modules::
# mypkg/__init__.py
import apipkg
apipkg.initpkg(__name__, {
'path': {
'Class1': "_mypkg.somemodule:Class1",
'clsattr': "_mypkg.othermodule:Class2.attr",
}
}
The package is initialized with a dictionary as namespace.
You need to create a ``_mypkg`` package with a ``somemodule.py``
and ``othermodule.py`` containing the respective classes.
The ``_mypkg`` is not special - it's a completely
regular Python package.
Namespace dictionaries contain ``name: value`` mappings
where the value may be another namespace dictionary or
a string specifying an import location. On accessing
an namespace attribute an import will be performed::
>>> import mypkg
>>> mypkg.path
<ApiModule 'mypkg.path'>
>>> mypkg.path.Class1 # '_mypkg.somemodule' gets imported now
<class _mypkg.somemodule.Class1 at 0xb7d428fc>
>>> mypkg.path.clsattr # '_mypkg.othermodule' gets imported now
4 # the value of _mypkg.othermodule.Class2.attr
The ``mypkg.path`` namespace and its two entries are
loaded when they are accessed. This means:
* lazy loading - only what is actually needed is ever loaded
* only the root "mypkg" ever needs to be imported to get
access to the complete functionality
* the underlying modules are also accessible, for example::
from mypkg.sub import Class1
Including apipkg in your package
--------------------------------------
If you don't want to add an ``apipkg`` dependency to your package you
can copy the `apipkg.py`_ file somewhere to your own package,
for example ``_mypkg/apipkg.py`` in the above example. You
then import the ``initpkg`` function from that new place and
are good to go.
.. _`small pure Python module`:
.. _`apipkg.py`: https://github.com/pytest-dev/apipkg/blob/master/src/apipkg/__init__.py
Feedback?
-----------------------
If you have questions you are welcome to
* join the **#pytest** channel on irc.libera.chat_
(using an IRC client, via webchat_, or via Matrix_).
* create an issue on the bugtracker_
.. _irc.libera.chat: ircs://irc.libera.chat:6697/#pytest
.. _webchat: https://web.libera.chat/#pytest
.. _matrix: https://matrix.to/#/%23pytest:libera.chat
.. _bugtracker: https://github.com/pytest-dev/apipkg/issues

View File

@ -0,0 +1,11 @@
apipkg-2.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
apipkg-2.0.0.dist-info/LICENSE,sha256=6J7tEHTTqUMZi6E5uAhE9bRFuGC7p0qK6twGEFZhZOo,1054
apipkg-2.0.0.dist-info/METADATA,sha256=GqNwkxraK5UTxObLVXTLc2UqktOPwZnKqdk2ThzHX0A,4292
apipkg-2.0.0.dist-info/RECORD,,
apipkg-2.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
apipkg-2.0.0.dist-info/WHEEL,sha256=WzZ8cwjh8l0jtULNjYq1Hpr-WCqCRgPr--TX4P5I1Wo,110
apipkg-2.0.0.dist-info/top_level.txt,sha256=3TGS6nmN7kjxhUK4LpPCB3QkQI34QYGrT0ZQGWajoZ8,7
apipkg/__init__.py,sha256=gpbD3O57S9f-LsO2e-XwI6IGISayicfnCq3B5y_8frg,6978
apipkg/__pycache__/__init__.cpython-39.pyc,,
apipkg/__pycache__/version.cpython-39.pyc,,
apipkg/version.py,sha256=bgZFg-f3UKhgE-z2w8RoFrwqRBzJBZkM4_jKFiYB9eU,142

View File

@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.37.0)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@ -0,0 +1,217 @@
"""
apipkg: control the exported namespace of a Python package.
see https://pypi.python.org/pypi/apipkg
(c) holger krekel, 2009 - MIT license
"""
import os
import sys
from types import ModuleType
from .version import version as __version__ # NOQA:F401
def _py_abspath(path):
"""
special version of abspath
that will leave paths from jython jars alone
"""
if path.startswith("__pyclasspath__"):
return path
else:
return os.path.abspath(path)
def distribution_version(name):
"""try to get the version of the named distribution,
returs None on failure"""
from pkg_resources import get_distribution, DistributionNotFound
try:
dist = get_distribution(name)
except DistributionNotFound:
pass
else:
return dist.version
def initpkg(pkgname, exportdefs, attr=None, eager=False):
""" initialize given package from the export definitions. """
attr = attr or {}
oldmod = sys.modules.get(pkgname)
d = {}
f = getattr(oldmod, "__file__", None)
if f:
f = _py_abspath(f)
d["__file__"] = f
if hasattr(oldmod, "__version__"):
d["__version__"] = oldmod.__version__
if hasattr(oldmod, "__loader__"):
d["__loader__"] = oldmod.__loader__
if hasattr(oldmod, "__path__"):
d["__path__"] = [_py_abspath(p) for p in oldmod.__path__]
if hasattr(oldmod, "__package__"):
d["__package__"] = oldmod.__package__
if "__doc__" not in exportdefs and getattr(oldmod, "__doc__", None):
d["__doc__"] = oldmod.__doc__
d["__spec__"] = getattr(oldmod, "__spec__", None)
d.update(attr)
if hasattr(oldmod, "__dict__"):
oldmod.__dict__.update(d)
mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d)
sys.modules[pkgname] = mod
# eagerload in bypthon to avoid their monkeypatching breaking packages
if "bpython" in sys.modules or eager:
for module in list(sys.modules.values()):
if isinstance(module, ApiModule):
module.__dict__
return mod
def importobj(modpath, attrname):
"""imports a module, then resolves the attrname on it"""
module = __import__(modpath, None, None, ["__doc__"])
if not attrname:
return module
retval = module
names = attrname.split(".")
for x in names:
retval = getattr(retval, x)
return retval
class ApiModule(ModuleType):
"""the magical lazy-loading module standing"""
def __docget(self):
try:
return self.__doc
except AttributeError:
if "__doc__" in self.__map__:
return self.__makeattr("__doc__")
def __docset(self, value):
self.__doc = value
__doc__ = property(__docget, __docset)
def __init__(self, name, importspec, implprefix=None, attr=None):
self.__name__ = name
self.__all__ = [x for x in importspec if x != "__onfirstaccess__"]
self.__map__ = {}
self.__implprefix__ = implprefix or name
if attr:
for name, val in attr.items():
# print "setting", self.__name__, name, val
setattr(self, name, val)
for name, importspec in importspec.items():
if isinstance(importspec, dict):
subname = "{}.{}".format(self.__name__, name)
apimod = ApiModule(subname, importspec, implprefix)
sys.modules[subname] = apimod
setattr(self, name, apimod)
else:
parts = importspec.split(":")
modpath = parts.pop(0)
attrname = parts and parts[0] or ""
if modpath[0] == ".":
modpath = implprefix + modpath
if not attrname:
subname = "{}.{}".format(self.__name__, name)
apimod = AliasModule(subname, modpath)
sys.modules[subname] = apimod
if "." not in name:
setattr(self, name, apimod)
else:
self.__map__[name] = (modpath, attrname)
def __repr__(self):
repr_list = []
if hasattr(self, "__version__"):
repr_list.append("version=" + repr(self.__version__))
if hasattr(self, "__file__"):
repr_list.append("from " + repr(self.__file__))
if repr_list:
return "<ApiModule {!r} {}>".format(self.__name__, " ".join(repr_list))
return "<ApiModule {!r}>".format(self.__name__)
def __makeattr(self, name):
"""lazily compute value for name or raise AttributeError if unknown."""
# print "makeattr", self.__name__, name
target = None
if "__onfirstaccess__" in self.__map__:
target = self.__map__.pop("__onfirstaccess__")
importobj(*target)()
try:
modpath, attrname = self.__map__[name]
except KeyError:
if target is not None and name != "__onfirstaccess__":
# retry, onfirstaccess might have set attrs
return getattr(self, name)
raise AttributeError(name)
else:
result = importobj(modpath, attrname)
setattr(self, name, result)
try:
del self.__map__[name]
except KeyError:
pass # in a recursive-import situation a double-del can happen
return result
__getattr__ = __makeattr
@property
def __dict__(self):
# force all the content of the module
# to be loaded when __dict__ is read
dictdescr = ModuleType.__dict__["__dict__"]
dict = dictdescr.__get__(self)
if dict is not None:
hasattr(self, "some")
for name in self.__all__:
try:
self.__makeattr(name)
except AttributeError:
pass
return dict
def AliasModule(modname, modpath, attrname=None):
mod = []
def getmod():
if not mod:
x = importobj(modpath, None)
if attrname is not None:
x = getattr(x, attrname)
mod.append(x)
return mod[0]
x = modpath + ("." + attrname if attrname else "")
repr_result = "<AliasModule {!r} for {!r}>".format(modname, x)
class AliasModule(ModuleType):
def __repr__(self):
return repr_result
def __getattribute__(self, name):
try:
return getattr(getmod(), name)
except ImportError:
if modpath == "pytest" and attrname is None:
# hack for pylibs py.test
return None
else:
raise
def __setattr__(self, name, value):
setattr(getmod(), name, value)
def __delattr__(self, name):
delattr(getmod(), name)
return AliasModule(str(modname))

View File

@ -0,0 +1,5 @@
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '2.0.0'
version_tuple = (2, 0, 0)

View File

@ -0,0 +1,19 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,78 @@
Metadata-Version: 2.1
Name: iniconfig
Version: 1.1.1
Summary: iniconfig: brain-dead simple config-ini parsing
Home-page: http://github.com/RonnyPfannschmidt/iniconfig
Author: Ronny Pfannschmidt, Holger Krekel
Author-email: opensource@ronnypfannschmidt.de, holger.krekel@gmail.com
License: MIT License
Platform: unix
Platform: linux
Platform: osx
Platform: cygwin
Platform: win32
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Utilities
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 3
iniconfig: brain-dead simple parsing of ini files
=======================================================
iniconfig is a small and simple INI-file parser module
having a unique set of features:
* tested against Python2.4 across to Python3.2, Jython, PyPy
* maintains order of sections and entries
* supports multi-line values with or without line-continuations
* supports "#" comments everywhere
* raises errors with proper line-numbers
* no bells and whistles like automatic substitutions
* iniconfig raises an Error if two sections have the same name.
If you encounter issues or have feature wishes please report them to:
http://github.com/RonnyPfannschmidt/iniconfig/issues
Basic Example
===================================
If you have an ini file like this::
# content of example.ini
[section1] # comment
name1=value1 # comment
name1b=value1,value2 # comment
[section2]
name2=
line1
line2
then you can do::
>>> import iniconfig
>>> ini = iniconfig.IniConfig("example.ini")
>>> ini['section1']['name1'] # raises KeyError if not exists
'value1'
>>> ini.get('section1', 'name1b', [], lambda x: x.split(","))
['value1', 'value2']
>>> ini.get('section1', 'notexist', [], lambda x: x.split(","))
[]
>>> [x.name for x in list(ini)]
['section1', 'section2']
>>> list(list(ini)[0].items())
[('name1', 'value1'), ('name1b', 'value1,value2')]
>>> 'section1' in ini
True
>>> 'inexistendsection' in ini
False

View File

@ -0,0 +1,11 @@
iniconfig-1.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
iniconfig-1.1.1.dist-info/LICENSE,sha256=KvaAw570k_uCgwNW0dPfGstaBgM8ui3sehniHKp3qGY,1061
iniconfig-1.1.1.dist-info/METADATA,sha256=_4-oFKpRXuZv5rzepScpXRwhq6DzqsgbnA5ZpgMUMcs,2405
iniconfig-1.1.1.dist-info/RECORD,,
iniconfig-1.1.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
iniconfig-1.1.1.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110
iniconfig-1.1.1.dist-info/top_level.txt,sha256=7KfM0fugdlToj9UW7enKXk2HYALQD8qHiyKtjhSzgN8,10
iniconfig/__init__.py,sha256=-pBe5AF_6aAwo1CxJQ8i_zJq6ejc6IxHta7qk2tNJhY,5208
iniconfig/__init__.pyi,sha256=-4KOctzq28ohRmTZsqlH6aylyFqsNKxYqtk1dteypi4,1205
iniconfig/__pycache__/__init__.cpython-39.pyc,,
iniconfig/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

View File

@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.35.1)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@ -0,0 +1,165 @@
""" brain-dead simple parser for ini-style files.
(C) Ronny Pfannschmidt, Holger Krekel -- MIT licensed
"""
__all__ = ['IniConfig', 'ParseError']
COMMENTCHARS = "#;"
class ParseError(Exception):
def __init__(self, path, lineno, msg):
Exception.__init__(self, path, lineno, msg)
self.path = path
self.lineno = lineno
self.msg = msg
def __str__(self):
return "%s:%s: %s" % (self.path, self.lineno+1, self.msg)
class SectionWrapper(object):
def __init__(self, config, name):
self.config = config
self.name = name
def lineof(self, name):
return self.config.lineof(self.name, name)
def get(self, key, default=None, convert=str):
return self.config.get(self.name, key,
convert=convert, default=default)
def __getitem__(self, key):
return self.config.sections[self.name][key]
def __iter__(self):
section = self.config.sections.get(self.name, [])
def lineof(key):
return self.config.lineof(self.name, key)
for name in sorted(section, key=lineof):
yield name
def items(self):
for name in self:
yield name, self[name]
class IniConfig(object):
def __init__(self, path, data=None):
self.path = str(path) # convenience
if data is None:
f = open(self.path)
try:
tokens = self._parse(iter(f))
finally:
f.close()
else:
tokens = self._parse(data.splitlines(True))
self._sources = {}
self.sections = {}
for lineno, section, name, value in tokens:
if section is None:
self._raise(lineno, 'no section header defined')
self._sources[section, name] = lineno
if name is None:
if section in self.sections:
self._raise(lineno, 'duplicate section %r' % (section, ))
self.sections[section] = {}
else:
if name in self.sections[section]:
self._raise(lineno, 'duplicate name %r' % (name, ))
self.sections[section][name] = value
def _raise(self, lineno, msg):
raise ParseError(self.path, lineno, msg)
def _parse(self, line_iter):
result = []
section = None
for lineno, line in enumerate(line_iter):
name, data = self._parseline(line, lineno)
# new value
if name is not None and data is not None:
result.append((lineno, section, name, data))
# new section
elif name is not None and data is None:
if not name:
self._raise(lineno, 'empty section name')
section = name
result.append((lineno, section, None, None))
# continuation
elif name is None and data is not None:
if not result:
self._raise(lineno, 'unexpected value continuation')
last = result.pop()
last_name, last_data = last[-2:]
if last_name is None:
self._raise(lineno, 'unexpected value continuation')
if last_data:
data = '%s\n%s' % (last_data, data)
result.append(last[:-1] + (data,))
return result
def _parseline(self, line, lineno):
# blank lines
if iscommentline(line):
line = ""
else:
line = line.rstrip()
if not line:
return None, None
# section
if line[0] == '[':
realline = line
for c in COMMENTCHARS:
line = line.split(c)[0].rstrip()
if line[-1] == "]":
return line[1:-1], None
return None, realline.strip()
# value
elif not line[0].isspace():
try:
name, value = line.split('=', 1)
if ":" in name:
raise ValueError()
except ValueError:
try:
name, value = line.split(":", 1)
except ValueError:
self._raise(lineno, 'unexpected line: %r' % line)
return name.strip(), value.strip()
# continuation
else:
return None, line.strip()
def lineof(self, section, name=None):
lineno = self._sources.get((section, name))
if lineno is not None:
return lineno + 1
def get(self, section, name, default=None, convert=str):
try:
return convert(self.sections[section][name])
except KeyError:
return default
def __getitem__(self, name):
if name not in self.sections:
raise KeyError(name)
return SectionWrapper(self, name)
def __iter__(self):
for name in sorted(self.sections, key=self.lineof):
yield SectionWrapper(self, name)
def __contains__(self, arg):
return arg in self.sections
def iscommentline(line):
c = line.lstrip()[:1]
return c in COMMENTCHARS

View File

@ -0,0 +1,31 @@
from typing import Callable, Iterator, Mapping, Optional, Tuple, TypeVar, Union
from typing_extensions import Final
_D = TypeVar('_D')
_T = TypeVar('_T')
class ParseError(Exception):
# Private __init__.
path: Final[str]
lineno: Final[int]
msg: Final[str]
class SectionWrapper:
# Private __init__.
config: Final[IniConfig]
name: Final[str]
def __getitem__(self, key: str) -> str: ...
def __iter__(self) -> Iterator[str]: ...
def get(self, key: str, default: _D = ..., convert: Callable[[str], _T] = ...) -> Union[_T, _D]: ...
def items(self) -> Iterator[Tuple[str, str]]: ...
def lineof(self, name: str) -> Optional[int]: ...
class IniConfig:
path: Final[str]
sections: Final[Mapping[str, Mapping[str, str]]]
def __init__(self, path: str, data: Optional[str] = None): ...
def __contains__(self, arg: str) -> bool: ...
def __getitem__(self, name: str) -> SectionWrapper: ...
def __iter__(self) -> Iterator[SectionWrapper]: ...
def get(self, section: str, name: str, default: _D = ..., convert: Callable[[str], _T] = ...) -> Union[_T, _D]: ...
def lineof(self, section: str, name: Optional[str] = ...) -> Optional[int]: ...