emcd-projects 1.15rc0__py3-none-any.whl → 1.17__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: emcd-projects
3
- Version: 1.15rc0
3
+ Version: 1.17
4
4
  Summary: Project management utilities.
5
5
  Project-URL: Homepage, https://github.com/emcd/python-project-common
6
6
  Project-URL: Documentation, https://emcd.github.io/python-project-common
@@ -0,0 +1,27 @@
1
+ emcdproj/data/.gitignore,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ emcdproj/data/copier/answers-default.yaml,sha256=dgdxDTcZZpHjg3-uZyDALzJ0Gc7GBcSSvQ7L_OmebWM,150
3
+ emcdproj/data/copier/answers-maximum.yaml,sha256=aVAiQZgltQYZWf3wYGzw6-Syp2iZr7yjOauqd2lhYfQ,392
4
+ emcdproj/data/templates/coverage.svg.jinja,sha256=UWJE9I1QVoo31DB4PAcf_sYFs1oOViDbnCmhzuoVuq8,1479
5
+ emcdproj/data/templates/website.html.jinja,sha256=V958XUcGdNmvSl_RalRvPRIZ5uUcpaXgycddOLN6rfA,1513
6
+ emcdproj/README.rst,sha256=ThJlTJWDLurnGuhCXlQDRuSYexDJrAUnHIPiTGaAmww,4495
7
+ emcdproj/__init__.py,sha256=UK1t3kKXvsMKGS1ObotJh5JNPjfISHGNNzP16BPl8zY,1582
8
+ emcdproj/__main__.py,sha256=KkTeK75rYgF2yVf2HpTs-L2V1jru3j7ohDSgGXWFXjQ,1409
9
+ emcdproj/cli.py,sha256=WNAF0pmAbdxtmuCcyTBkuG1CQnWixpkDSXNuQ4KwXDE,4414
10
+ emcdproj/exceptions.py,sha256=Y9n5pGh1-hMkKtOYherAjUw19af4-uWDNzUZjiqiU00,2641
11
+ emcdproj/filesystem.py,sha256=YgcX5Q52r2hTYU-7_VoW2inMC4NBTzqSTINB9eNT9Hw,1708
12
+ emcdproj/interfaces.py,sha256=PvNZb4G0EhXbK_yaAOhqcgp0uNR30FCRUf4Qn0e03M8,3185
13
+ emcdproj/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ emcdproj/template.py,sha256=S_SAlrVtEco2c2eO0QNdy-Gffn_hk8zVFFT1GzqXcuc,4823
15
+ emcdproj/website.py,sha256=YfIGPp2WzoL0E9nQLJgbfU6yVbipns-I7F6alkSowb0,10657
16
+ emcdproj/__/__init__.py,sha256=oGdDy7STF7jZlrxKzgvdbqw5-tR-RRWqurizIazVvvg,1598
17
+ emcdproj/__/application.py,sha256=6uF2yTIlAsLWKadus7a7mPvr7q3pagplPrDAA1EUwlw,2316
18
+ emcdproj/__/distribution.py,sha256=9TCSm8oJtIot-MPR8Ypt72gMaUh77WXtkpuxggb6tGQ,3972
19
+ emcdproj/__/imports.py,sha256=P4r8oEkrKGQ0NuA4uTTbM-ZYUJp3QgvjuqJELdlSJH0,2340
20
+ emcdproj/__/preparation.py,sha256=rNbA8VvrspanbP_0O4GjmwaqgzgPf0SdY7WadcINJZE,3824
21
+ emcdproj/__/state.py,sha256=inChROB1WcJ_b9kZ6VfQZr-dLj56-MxWoMHrvB-yXu4,3596
22
+ emcdproj/_typedecls/__builtins__.pyi,sha256=VhJfnYgggXihUzomBHtA1xEKzG7XqEHkSjhl0Ro6qgg,153
23
+ emcd_projects-1.17.dist-info/METADATA,sha256=w1weDAbKQglWr1Hf4Xls8QVY0dzS3DxhSgyoL0j8NL8,6085
24
+ emcd_projects-1.17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
25
+ emcd_projects-1.17.dist-info/entry_points.txt,sha256=22Pc1xg3OboNBxpTnDM3gLYXo8QuY2E0SOv1djo0fdc,43
26
+ emcd_projects-1.17.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
27
+ emcd_projects-1.17.dist-info/RECORD,,
emcdproj/__/imports.py CHANGED
@@ -20,20 +20,22 @@
20
20
 
21
21
  ''' Common imports and type aliases used throughout the package. '''
22
22
 
23
- # pylint: disable=unused-import
24
23
  # ruff: noqa: F401
25
24
 
26
25
 
27
26
  from __future__ import annotations
28
27
 
29
- import abc
30
- import collections.abc as cabc
31
- import contextlib as ctxl
32
- import json
33
- import math
34
- import os
35
- import shutil
36
- import types
28
+ import abc
29
+ import collections.abc as cabc
30
+ import contextlib as ctxl
31
+ import enum
32
+ import io
33
+ import json
34
+ import math
35
+ import os
36
+ import shutil
37
+ import sys
38
+ import types
37
39
 
38
40
  from pathlib import Path
39
41
 
@@ -30,9 +30,10 @@ from . import distribution as _distribution
30
30
  from . import state as _state
31
31
 
32
32
 
33
- async def prepare( # pylint: disable=too-many-arguments,too-many-locals
33
+ async def prepare(
34
34
  exits: __.ctxl.AsyncExitStack,
35
- application: _application.Information = _application.Information( ),
35
+ application: _application.Information = (
36
+ _application.Information( ) ), # noqa: B008
36
37
  # configedits: _dictedits.Edits = ( ),
37
38
  # configfile: __.Absential[ __.Path ] = __.absent,
38
39
  # environment: bool = False,
@@ -66,7 +67,7 @@ async def prepare( # pylint: disable=too-many-arguments,too-many-locals
66
67
  exits = exits )
67
68
  # if environment: await _environment.update( auxdata )
68
69
  # _inscribe_preparation_report( auxdata )
69
- return auxdata
70
+ return auxdata # noqa: RET504
70
71
 
71
72
 
72
73
  # def _inscribe_preparation_report( auxdata: _state.Globals ):
emcdproj/__init__.py CHANGED
@@ -27,7 +27,7 @@ from . import exceptions
27
27
  # --- END: Injected by Copier ---
28
28
 
29
29
 
30
- __version__ = '1.15rc0'
30
+ __version__ = '1.17'
31
31
 
32
32
 
33
33
  def main( ):
emcdproj/cli.py CHANGED
@@ -25,6 +25,7 @@ from __future__ import annotations
25
25
 
26
26
  from . import __
27
27
  from . import interfaces as _interfaces
28
+ from . import template as _template
28
29
  from . import website as _website
29
30
 
30
31
 
@@ -34,8 +35,10 @@ class VersionCommand(
34
35
  ):
35
36
  ''' Prints version information. '''
36
37
 
37
- async def __call__( self, auxdata: __.Globals ) -> None:
38
- from . import __version__ # pylint: disable=cyclic-import
38
+ async def __call__(
39
+ self, auxdata: __.Globals, display: _interfaces.ConsoleDisplay
40
+ ) -> None:
41
+ from . import __version__
39
42
  print( f"{__package__} {__version__}" )
40
43
  raise SystemExit( 0 )
41
44
 
@@ -48,8 +51,12 @@ class Cli(
48
51
 
49
52
  application: __.ApplicationInformation
50
53
  # configfile: __.typx.Optional[ str ] = None
51
- # display: ConsoleDisplay
54
+ display: _interfaces.ConsoleDisplay
52
55
  command: __.typx.Union[
56
+ __.typx.Annotated[
57
+ _template.CommandDispatcher,
58
+ __.tyro.conf.subcommand( 'template', prefix_name = False ),
59
+ ],
53
60
  __.typx.Annotated[
54
61
  _website.CommandDispatcher,
55
62
  __.tyro.conf.subcommand( 'website', prefix_name = False ),
@@ -66,8 +73,8 @@ class Cli(
66
73
  async with __.ctxl.AsyncExitStack( ) as exits:
67
74
  auxdata = await _prepare( exits = exits, **nomargs )
68
75
  ictr( 0 )( self.command )
69
- await self.command( auxdata = auxdata )
70
- # await self.command( auxdata = auxdata, display = self.display )
76
+ # await self.command( auxdata = auxdata )
77
+ await self.command( auxdata = auxdata, display = self.display )
71
78
 
72
79
  def prepare_invocation_args(
73
80
  self,
@@ -107,9 +114,8 @@ async def _prepare(
107
114
  import ictruck
108
115
  # TODO: Finetune Icecream truck installation from CLI arguments.
109
116
  ictruck.install( trace_levels = 9 )
110
- auxdata = await __.prepare(
117
+ return await __.prepare(
111
118
  application = application,
112
119
  # configedits = configedits,
113
120
  # environment = environment,
114
121
  exits = exits )
115
- return auxdata
@@ -0,0 +1,4 @@
1
+ project_name: python-test-defaults
2
+ distribution_name: emcdproj-defaults
3
+ package_name: defaults
4
+ description: 'All configuration options are defaults.'
@@ -0,0 +1,14 @@
1
+ project_name: python-test-maximum
2
+ distribution_name: emcdproj-maximum
3
+ package_name: maximum
4
+ description: 'All configuration options set.'
5
+ enable_rust_extension: true
6
+ include_data_resources: true
7
+ enable_property_tests: true
8
+ enable_publication: true
9
+ enable_cli: true
10
+ enable_executables: true
11
+ inject_foundations: true
12
+ inject_exceptions: true
13
+ inject_immutables: true
14
+ inject_docstring_utils: true
emcdproj/interfaces.py CHANGED
@@ -26,7 +26,47 @@ from __future__ import annotations
26
26
  from . import __
27
27
 
28
28
 
29
- class CliCommand( # pylint: disable=invalid-metaclass
29
+ class DisplayStreams( __.enum.Enum ): # TODO: Python 3.11: StrEnum
30
+ # TODO: Protected class attributes.
31
+ ''' Stream upon which to place output. '''
32
+
33
+ Stderr = 'stderr'
34
+ Stdout = 'stdout'
35
+
36
+
37
+ class ConsoleDisplay(
38
+ metaclass = __.ImmutableDataclass,
39
+ ):
40
+ silence: __.typx.Annotated[
41
+ bool,
42
+ __.tyro.conf.arg(
43
+ aliases = ( '--quiet', '--silent', ), prefix_name = False ),
44
+ ] = False
45
+ file: __.typx.Annotated[
46
+ __.typx.Optional[ __.Path ],
47
+ __.tyro.conf.arg(
48
+ name = 'console-capture-file', prefix_name = False ),
49
+ ] = None
50
+ stream: __.typx.Annotated[
51
+ DisplayStreams,
52
+ __.tyro.conf.arg( name = 'console-stream', prefix_name = False ),
53
+ ] = DisplayStreams.Stderr
54
+
55
+ async def provide_stream( self ) -> __.io.TextIOWrapper:
56
+ ''' Provides output stream for display. '''
57
+ # TODO: register file stream as a process-lifetime exit
58
+ if self.file: return open( self.file, 'w' )
59
+ # TODO: async context manager for async file streams
60
+ # TODO: return async stream - need async printers
61
+ # TODO: handle non-TextIOWrapper streams
62
+ match self.stream:
63
+ case DisplayStreams.Stdout:
64
+ return __.sys.stdout # pyright: ignore[reportReturnType]
65
+ case DisplayStreams.Stderr:
66
+ return __.sys.stderr # pyright: ignore[reportReturnType]
67
+
68
+
69
+ class CliCommand(
30
70
  __.typx.Protocol,
31
71
  metaclass = __.ImmutableProtocolDataclass,
32
72
  decorators = ( __.typx.runtime_checkable, ),
@@ -34,7 +74,9 @@ class CliCommand( # pylint: disable=invalid-metaclass
34
74
  ''' CLI command. '''
35
75
 
36
76
  @__.abc.abstractmethod
37
- async def __call__( self, auxdata: __.Globals ) -> None:
77
+ async def __call__(
78
+ self, auxdata: __.Globals, display: ConsoleDisplay
79
+ ) -> None:
38
80
  ''' Executes command with global state. '''
39
81
  raise NotImplementedError
40
82
 
emcdproj/template.py ADDED
@@ -0,0 +1,127 @@
1
+ # vim: set filetype=python fileencoding=utf-8:
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #============================================================================#
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); #
7
+ # you may not use this file except in compliance with the License. #
8
+ # You may obtain a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ # #
18
+ #============================================================================#
19
+
20
+
21
+ ''' Copier template maintenance and validation. '''
22
+
23
+
24
+ from __future__ import annotations
25
+
26
+ import subprocess as _subprocess
27
+ import tempfile as _tempfile
28
+
29
+ from . import __
30
+ from . import interfaces as _interfaces
31
+
32
+
33
+ class CommandDispatcher(
34
+ _interfaces.CliCommand, decorators = ( __.standard_tyro_class, ),
35
+ ):
36
+ ''' Dispatches commands for static website maintenance. '''
37
+
38
+ command: __.typx.Union[
39
+ __.typx.Annotated[
40
+ SurveyCommand,
41
+ __.tyro.conf.subcommand( 'survey', prefix_name = False ),
42
+ ],
43
+ __.typx.Annotated[
44
+ ValidateCommand,
45
+ __.tyro.conf.subcommand( 'validate', prefix_name = False ),
46
+ ],
47
+ ]
48
+
49
+ async def __call__(
50
+ self, auxdata: __.Globals, display: _interfaces.ConsoleDisplay
51
+ ) -> None:
52
+ ictr( 1 )( self.command )
53
+ await self.command( auxdata = auxdata, display = display )
54
+
55
+
56
+ class SurveyCommand(
57
+ _interfaces.CliCommand, decorators = ( __.standard_tyro_class, ),
58
+ ):
59
+ ''' Surveys available configuration variants. '''
60
+
61
+ async def __call__(
62
+ self, auxdata: __.Globals, display: _interfaces.ConsoleDisplay
63
+ ) -> None:
64
+ stream = await display.provide_stream( )
65
+ for variant in survey_variants( auxdata ):
66
+ print( variant, file = stream )
67
+
68
+
69
+ class ValidateCommand(
70
+ _interfaces.CliCommand, decorators = ( __.standard_tyro_class, ),
71
+ ):
72
+ ''' Validates template against configuration variant. '''
73
+
74
+ variant: __.typx.Annotated[
75
+ str,
76
+ __.typx.Doc( ''' Configuration variant to validate. ''' ),
77
+ __.tyro.conf.Positional,
78
+ ]
79
+
80
+ async def __call__(
81
+ self, auxdata: __.Globals, display: _interfaces.ConsoleDisplay
82
+ ) -> None:
83
+ ''' Copies new project from template for configuration variant. '''
84
+ # TODO: Validate variant argument.
85
+ validate_variant( auxdata, self.variant )
86
+
87
+
88
+ def copy_template( answers_file: __.Path, projectdir: __.Path ) -> None:
89
+ ''' Copies template to target directory using answers. '''
90
+ _subprocess.run( # noqa: S603
91
+ ( 'copier', 'copy', '--data-file', str( answers_file ),
92
+ '--defaults', '--overwrite', '--vcs-ref', 'HEAD',
93
+ '.', str( projectdir ) ),
94
+ cwd = __.Path( ), check = True )
95
+
96
+
97
+ def survey_variants( auxdata: __.Globals ) -> __.cabc.Sequence[ str ]:
98
+ ''' Surveys available configuration variants. '''
99
+ location = auxdata.distribution.provide_data_location( 'copier' )
100
+ return tuple(
101
+ fsent.stem.lstrip( 'answers-' )
102
+ for fsent in location.glob( 'answers-*.yaml' )
103
+ if fsent.is_file( ) )
104
+
105
+
106
+ def validate_variant( auxdata: __.Globals, variant: str ) -> None:
107
+ ''' Validates configuration variant. '''
108
+ answers_file = (
109
+ auxdata.distribution.provide_data_location(
110
+ 'copier', f"answers-{variant}.yaml" ) )
111
+ if not answers_file.is_file( ):
112
+ # TODO: Raise error.
113
+ return
114
+ with _tempfile.TemporaryDirectory( ) as tmpdir:
115
+ projectdir = __.Path( tmpdir ) / variant
116
+ copy_template( answers_file, projectdir )
117
+ validate_variant_project( projectdir )
118
+
119
+
120
+ def validate_variant_project( projectdir: __.Path ) -> None:
121
+ ''' Validates standard project as generated from template. '''
122
+ for command in (
123
+ ( 'hatch', '--env', 'develop', 'run',
124
+ 'python', '-m', 'pip', 'install',
125
+ '--upgrade', 'pip', 'build' ),
126
+ ( 'hatch', '--env', 'develop', 'run', 'make-all' ),
127
+ ): _subprocess.run( command, cwd = str( projectdir ), check = True ) # noqa: S603
emcdproj/website.py CHANGED
@@ -33,8 +33,7 @@ from . import interfaces as _interfaces
33
33
 
34
34
 
35
35
  class CommandDispatcher(
36
- _interfaces.CliCommand,
37
- decorators = ( __.standard_tyro_class, ),
36
+ _interfaces.CliCommand, decorators = ( __.standard_tyro_class, ),
38
37
  ):
39
38
  ''' Dispatches commands for static website maintenance. '''
40
39
 
@@ -49,25 +48,27 @@ class CommandDispatcher(
49
48
  ],
50
49
  ]
51
50
 
52
- async def __call__( self, auxdata: __.Globals ) -> None:
51
+ async def __call__(
52
+ self, auxdata: __.Globals, display: _interfaces.ConsoleDisplay
53
+ ) -> None:
53
54
  ictr( 1 )( self.command )
54
- await self.command( auxdata = auxdata )
55
+ await self.command( auxdata = auxdata, display = display )
55
56
 
56
57
 
57
58
  class SurveyCommand(
58
- _interfaces.CliCommand,
59
- decorators = ( __.standard_tyro_class, ),
59
+ _interfaces.CliCommand, decorators = ( __.standard_tyro_class, ),
60
60
  ):
61
61
  ''' Surveys release versions published in static website. '''
62
62
 
63
- async def __call__( self, auxdata: __.Globals ) -> None:
63
+ async def __call__(
64
+ self, auxdata: __.Globals, display: _interfaces.ConsoleDisplay
65
+ ) -> None:
64
66
  # TODO: Implement.
65
67
  pass
66
68
 
67
69
 
68
70
  class UpdateCommand(
69
- _interfaces.CliCommand,
70
- decorators = ( __.standard_tyro_class, ),
71
+ _interfaces.CliCommand, decorators = ( __.standard_tyro_class, ),
71
72
  ):
72
73
  ''' Updates static website for particular release version. '''
73
74
 
@@ -77,7 +78,9 @@ class UpdateCommand(
77
78
  __.tyro.conf.Positional,
78
79
  ]
79
80
 
80
- async def __call__( self, auxdata: __.Globals ) -> None:
81
+ async def __call__(
82
+ self, auxdata: __.Globals, display: _interfaces.ConsoleDisplay
83
+ ) -> None:
81
84
  update( auxdata, self.version )
82
85
 
83
86
 
@@ -146,7 +149,7 @@ def update(
146
149
  locations.website.mkdir( exist_ok = True, parents = True )
147
150
  if locations.archive.is_file( ):
148
151
  with tarfile_open( locations.archive, 'r:xz' ) as archive:
149
- archive.extractall( path = locations.website )
152
+ archive.extractall( path = locations.website ) # noqa: S202
150
153
  available_species = _update_available_species( locations, version )
151
154
  j2context = _jinja2.Environment(
152
155
  loader = _jinja2.FileSystemLoader( locations.templates ),
@@ -157,7 +160,7 @@ def update(
157
160
  _update_coverage_badge( locations, j2context )
158
161
  ( locations.website / '.nojekyll' ).touch( )
159
162
  from .filesystem import chdir
160
- with chdir( locations.website ):
163
+ with chdir( locations.website ): # noqa: SIM117
161
164
  with tarfile_open( locations.archive, 'w:xz' ) as archive:
162
165
  archive.add( '.' )
163
166
 
@@ -195,7 +198,7 @@ def _update_available_species(
195
198
  return tuple( available_species )
196
199
 
197
200
 
198
- def _update_coverage_badge( # pylint: disable=too-many-locals
201
+ def _update_coverage_badge(
199
202
  locations: Locations, j2context: _jinja2.Environment
200
203
  ) -> None:
201
204
  ''' Updates coverage badge SVG.
@@ -207,11 +210,9 @@ def _update_coverage_badge( # pylint: disable=too-many-locals
207
210
  - green: >= 80%
208
211
  '''
209
212
  coverage = _extract_coverage( locations )
210
- # pylint: disable=magic-value-comparison
211
213
  color = (
212
- 'red' if coverage < 50 else (
213
- 'yellow' if coverage < 80 else 'green' ) )
214
- # pylint: enable=magic-value-comparison
214
+ 'red' if coverage < 50 else ( # noqa: PLR2004
215
+ 'yellow' if coverage < 80 else 'green' ) ) # noqa: PLR2004
215
216
  label_text = 'coverage'
216
217
  value_text = f"{coverage}%"
217
218
  label_width = len( label_text ) * 6 + 10
@@ -1,24 +0,0 @@
1
- emcdproj/data/.gitignore,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- emcdproj/data/templates/coverage.svg.jinja,sha256=UWJE9I1QVoo31DB4PAcf_sYFs1oOViDbnCmhzuoVuq8,1479
3
- emcdproj/data/templates/website.html.jinja,sha256=V958XUcGdNmvSl_RalRvPRIZ5uUcpaXgycddOLN6rfA,1513
4
- emcdproj/README.rst,sha256=ThJlTJWDLurnGuhCXlQDRuSYexDJrAUnHIPiTGaAmww,4495
5
- emcdproj/__init__.py,sha256=5iNawyfbFxQHwJ11Iv5ae73xcsh1BX-0IMK46SEK3OA,1585
6
- emcdproj/__main__.py,sha256=KkTeK75rYgF2yVf2HpTs-L2V1jru3j7ohDSgGXWFXjQ,1409
7
- emcdproj/cli.py,sha256=6IEdWtJY4LORb5bUfW0cJDEHFxNSJ867ycs7FLZDz74,4222
8
- emcdproj/exceptions.py,sha256=Y9n5pGh1-hMkKtOYherAjUw19af4-uWDNzUZjiqiU00,2641
9
- emcdproj/filesystem.py,sha256=YgcX5Q52r2hTYU-7_VoW2inMC4NBTzqSTINB9eNT9Hw,1708
10
- emcdproj/interfaces.py,sha256=G7o4XgJB0Ad1UpnYbK3vcnZD7ydszKKhikvW60BiFNo,1771
11
- emcdproj/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- emcdproj/website.py,sha256=Pqd_BOuGybDEJC19SjhramB_KHZd0j-4fQs1trajWxM,10566
13
- emcdproj/__/__init__.py,sha256=oGdDy7STF7jZlrxKzgvdbqw5-tR-RRWqurizIazVvvg,1598
14
- emcdproj/__/application.py,sha256=6uF2yTIlAsLWKadus7a7mPvr7q3pagplPrDAA1EUwlw,2316
15
- emcdproj/__/distribution.py,sha256=9TCSm8oJtIot-MPR8Ypt72gMaUh77WXtkpuxggb6tGQ,3972
16
- emcdproj/__/imports.py,sha256=WYkzM0Af4LlI6WzrX3wN1Jt4MxnPoZbbMY2PuZWwYJA,2141
17
- emcdproj/__/preparation.py,sha256=5GGqf4RVkc8P_fvcT11CUFvU1zTLGjpj7QE2DBRa28w,3837
18
- emcdproj/__/state.py,sha256=inChROB1WcJ_b9kZ6VfQZr-dLj56-MxWoMHrvB-yXu4,3596
19
- emcdproj/_typedecls/__builtins__.pyi,sha256=VhJfnYgggXihUzomBHtA1xEKzG7XqEHkSjhl0Ro6qgg,153
20
- emcd_projects-1.15rc0.dist-info/METADATA,sha256=nbVVPBehRkheTUbwf5Lexk8d5Y_tvRtm8w1zR3lVJGY,6088
21
- emcd_projects-1.15rc0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
22
- emcd_projects-1.15rc0.dist-info/entry_points.txt,sha256=22Pc1xg3OboNBxpTnDM3gLYXo8QuY2E0SOv1djo0fdc,43
23
- emcd_projects-1.15rc0.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
24
- emcd_projects-1.15rc0.dist-info/RECORD,,