from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ... import User
def some_func(user: 'User') -> 'User':
...
class Service1(BaseService[ServicePayload, None]):
payload_class = ServicePayload
payload: ServicePayload
def do_something(self) -> None:
print(self.payload.some_string) # например
class Service2(BaseService[None, ServiceParams]):
params_class = ServiceParams
params: ServiceParams
def do_something(self) -> None:
print(self.params.some_int) # например
class Service3(BaseService[ServicePayload, ServiceParams]):
payload_class = ServicePayload
payload: ServicePayload
params_class = ServiceParams
params: ServiceParams
def do_something(self) -> None:
print(self.payload.some_string) # например
print(self.params.some_int) # например
educational_grant = float(input("Введите месячную стипендию: ")) # месячная стипуха
expenses = float(input("Введите месячный расход: ")) # расходы в месяц
i = 0
delta = 0
while i < 9:
delta += educational_grant - (expenses + (expenses) * 0.03 * i) # на первой итерации при i = 0, повышения цен аффектит значение
i += 1
if delta < 0:
print(f'нужно просить {-delta} на учебный год')
else:
print('денег просить не надо, может еще и останется')
import abc
from typing import ClassVar, Type, Dict, Generic, TypeVar
from pydantic import BaseModel
T = TypeVar('T', bound=BaseModel)
class Abstract(abc.ABC, Generic[T]):
context_class: ClassVar[Type[T]]
error: ClassVar[Type[Exception]]
def __init__(self, data: Dict) -> None:
self.context = self.context_class(**data)
@abc.abstractmethod
def process(self) -> None:
pass
class Context(BaseModel):
email: str
class Concrete(Abstract[Context]):
context_class = Context
def process(self) -> None:
print(self.context.email)
name: Release
on:
push:
branches:
- master
jobs:
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
name: Release
runs-on: ubuntu-latest
steps:
- name: Getting code
uses: actions/checkout@master
- name: Getting Python
uses: actions/setup-python@master
- name: Cache pip
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('poetry.lock') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Getting Poetry
uses: dschep/install-poetry-action@v1.3
- name: Getting PostgreSQL
uses: harmon758/postgresql-action@v1
with:
postgresql db: 'test_db'
postgresql user: 'postgres'
postgresql password: 'postgres'
- name: Installing dependencies
run: poetry install
- name: Running tests
run: make coverage_run
- name: Running coverage check
run: make coverage_cmd_report
- name: Running codestyle checks
run: make check_black
- name: Running types checks
run: make check_mypy
- name: Generate coverage report
run: make coverage_xml_report
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
- name: Getting package version
id: get_version
run: echo "::set-output name=version::$(poetry version)"
- name: Getting package clear version
id: get_clear_version
run: echo "::set-output name=clear_version::$(poetry version | cut -d ' ' -f 2)"
- name: Make release and publish
run: make release USERNAME=${{ secrets.PYPI_USERNAME }} TOKEN=${{ secrets.PYPI_TOKEN }}
- name: Get asset name
id: get_asset_name
run: echo "::set-output name=assert_name::$(ls dist | grep gz)"
- name: Create Release
id: create_release
uses: actions/create-release@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.get_clear_version.outputs.clear_version }}
release_name: ${{ steps.get_version.outputs.version }}
draft: false
prerelease: false
- name: Upload Release assets
id: upload_gz
uses: actions/upload-release-asset@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: dist/${{ steps.get_asset_name.outputs.assert_name }}
asset_name: ${{ steps.get_asset_name.outputs.assert_name }}
asset_content_type: application/tar+gzip
Как организовать проект таким образом чтобы при разработке модулей для него не требовался сам проект?
Модуль для своей работы дёргает контроллеры из основного проекта.
class ForeignObjFormSet:
def get_form_kwargs(self, index):
kwargs = super(ForeignObjFormSet, self).get_form_kwargs(index)
kwargs['obj'] = self.form_kwargs['obj'][index]
return kwargs
# Во вьюхе
def view(request):
target_objects = Obj.objects.filter(foreign_obj__isnull=True)
FormSet = formset_factory(forms.ForeignObjForm, formset=ForeignObjFormSet, extra=target_objects.count())
form_set = FormSet(form_kwargs={'obj': list(target_objects)})
# ...
MEDIA_URL = '/media/' #например
MEDIA_ROOT = '/srv/files/media' #например
class ModelClass(models.Model):
<поле> = models.ImageField(upload_to=rename_image, blank=True, verbose_name='...')
def rename_image(instance, filename):
image_name = md5(str(time.time()).encode()).hexdigest()
image_type = filename.split('.')[-1]
return 'imgs/{}.{}'.format(image_name, image_type)