or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build.mdcheck.mdconfiguration.mdcreate.mdfragments.mdindex.mdproject.mdvcs.md

project.mddocs/

0

# Project Utilities

1

2

Extract project metadata like version and name from packages for automatic changelog generation.

3

4

## Capabilities

5

6

### Version Detection

7

8

Get the version of a package from metadata or source code.

9

10

```python { .api }

11

def get_version(package_dir: str, package: str) -> str:

12

"""

13

Get the version of a package.

14

15

Try to extract the version from the distribution version metadata that matches

16

`package`, then fall back to looking for the package in `package_dir`.

17

18

Args:

19

package_dir: Directory containing the package source

20

package: Package name to get version for

21

22

Returns:

23

str: Package version string

24

25

Raises:

26

ImportError: If package cannot be imported

27

AttributeError: If version cannot be determined

28

"""

29

```

30

31

### Project Name Detection

32

33

Get the project name from package metadata.

34

35

```python { .api }

36

def get_project_name(package_dir: str, package: str) -> str:

37

"""

38

Get the project name from package metadata.

39

40

Args:

41

package_dir: Directory containing the package source

42

package: Package name to get project name for

43

44

Returns:

45

str: Project name from metadata

46

47

Raises:

48

ImportError: If package cannot be imported

49

AttributeError: If project name cannot be determined

50

"""

51

```

52

53

### Internal Utilities

54

55

Helper functions for package loading and metadata access.

56

57

```python { .api }

58

def _get_package(package_dir: str, package: str) -> ModuleType:

59

"""

60

Import a package from a specific directory.

61

62

First tries to import normally, then adds package_dir to sys.path

63

and tries again if the initial import fails.

64

65

Args:

66

package_dir: Directory to search for package

67

package: Package name to import

68

69

Returns:

70

ModuleType: Imported package module

71

72

Raises:

73

ImportError: If package cannot be imported from any location

74

"""

75

76

def _get_metadata_version(package: str) -> str | None:

77

"""

78

Try to get the version from package distribution metadata.

79

80

Args:

81

package: Package name to look up

82

83

Returns:

84

str | None: Version string if found, None otherwise

85

"""

86

```

87

88

## Usage Examples

89

90

### Basic Version Detection

91

92

```python

93

from towncrier._project import get_version, get_project_name

94

95

# Get version from installed package metadata first, then source

96

version = get_version(

97

package_dir="src",

98

package="myproject"

99

)

100

print(f"Version: {version}")

101

102

# Get project name

103

project_name = get_project_name(

104

package_dir="src",

105

package="myproject"

106

)

107

print(f"Project: {project_name}")

108

```

109

110

### Integration with Build Process

111

112

```python

113

from towncrier._project import get_version

114

from towncrier._settings import load_config_from_options

115

116

# Load config and get version if not specified

117

base_directory, config = load_config_from_options(None, None)

118

119

if not config.version and config.package:

120

# Auto-detect version from package

121

detected_version = get_version(

122

package_dir=os.path.join(base_directory, config.package_dir),

123

package=config.package

124

)

125

print(f"Detected version: {detected_version}")

126

```

127

128

### Package Import Handling

129

130

```python

131

from towncrier._project import _get_package

132

133

try:

134

# Import package from source directory

135

module = _get_package(

136

package_dir="/path/to/src",

137

package="mypackage"

138

)

139

140

# Access package attributes

141

if hasattr(module, '__version__'):

142

version = module.__version__

143

144

except ImportError as e:

145

print(f"Cannot import package: {e}")

146

```

147

148

## Version Resolution Strategy

149

150

The `get_version` function uses this resolution order:

151

152

1. **Distribution metadata**: Check installed package metadata using `importlib.metadata.version()`

153

2. **Package __version__**: Import package and check `__version__` attribute

154

3. **Package _version**: Import package and check `_version` attribute

155

4. **Package VERSION**: Import package and check `VERSION` attribute

156

5. **Package version**: Import package and check `version` attribute

157

158

## Project Name Resolution

159

160

The `get_project_name` function uses:

161

162

1. **Distribution metadata**: Check installed package metadata using `importlib.metadata.metadata()`

163

2. **Package __name__**: Fall back to package name itself

164

165

## Error Handling

166

167

Project utilities handle these error scenarios:

168

169

- **ImportError**: Package cannot be imported from any location

170

- **PackageNotFoundError**: Package not found in distribution metadata

171

- **AttributeError**: Required version/name attributes not found

172

- **ModuleNotFoundError**: Package module structure issues

173

- **Path errors**: Invalid package_dir or package paths

174

175

## Integration Points

176

177

These utilities are used by:

178

179

- **Build command**: Auto-detect project version when not specified in config

180

- **Configuration system**: Resolve package-based settings

181

- **Template rendering**: Provide project metadata to templates

182

- **CLI commands**: Display project information in help and output