textpy
Reads a python module and statically analyzes it. This works well with jupyter extensions in VS Code, and will have better performance when the module files are formatted with PEP-8.
Installation
$ pip install textpy
Requirements
lazyr
typing-extensions
black
colorama
htmlmaster
re_extensions
NOTE: pandas>=1.4.0 is recommended but not necessary.
Quick Start
To demonstrate the usage of this module, we put a file named myfile.py under ./examples/ (you can find it in the repository, or create a new file of your own):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from typing import Optional
class MyBook:
"""
A book that records a story.
Parameters
----------
story : str, optional
Story to record, by default None.
"""
def __init__(self, story: Optional[str] = None) -> None:
if story is None:
self.content = "This book is empty."
self.content = story
def print_my_book(book: MyBook) -> None:
"""
Print a book.
Parameters
----------
book : MyBook
A book.
"""
print(book.content)
Run the following codes to find all the occurrences of some pattern (for example, "MyBook") in myfile.py:
>>> import textpy as tx
>>> myfile = tx.module("./examples/myfile.py") # reads the python module
>>> myfile.findall("MyBook")
examples/myfile.py:7: 'class <MyBook>:'
examples/myfile.py:24: 'def print_my_book(book: <MyBook>) -> None:'
examples/myfile.py:30: ' book : <MyBook>'
If you are using a jupyter notebook, you can run a cell like this:
>>> myfile.findall("MyBook")
| source | match |
|---|---|
| myfile.MyBook:7 | class MyBook: |
| myfile.print_my_book():24 | def print_my_book(book: MyBook) -> None: |
| myfile.print_my_book():30 | book : MyBook |
In this case, the matched substrings are clickable, linking to where the patterns were found.
Usage
tx.module()
The previous demonstration introduced the core function tx.module(). The return value of tx.module() is a subinstance of the abstract class tx.TextTree, which supports various text manipulation methods:
>>> isinstance(myfile, tx.TextTree)
True
Sometimes, your python module may contain not just one file, but don't worry, since tx.module() provides support for complex file hierarchies. If the path points to a single file, the return type will be PyFile; otherwise, the return type will be PyDir - both of which are subclasses of tx.TextTree.
In conclusion, once you've got a python package, you can simply give the package dirpath to tx.module(), and do things like before:
>>> pkg_dir = "" # type any path here
>>> pattern = "" # type any regex pattern here
>>> res = tx.module(pkg_dir).findall(pattern)
tx.TextTree.findall()
As mentioned before, user can use .findall() to find all non-overlapping matches of some pattern in a python module.
>>> myfile.findall("optional")
examples/myfile.py:13: ' story : str, <optional>'
The object returned by .findall() has a _repr_mimebundle_() method to beautify the representation inside a jupyter notebook. However, you can compulsively disable this feature by setting display_params.use_mimebundle to False:
>>> from textpy import display_params
>>> display_params.use_mimebundle = False
In addition, the .findall() method has some optional parameters to customize the pattern, including whole_word=, case_sensitive=, and regex=.
>>> myfile.findall("mybook", case_sensitive=False, regex=False, whole_word=True)
examples/myfile.py:7: 'class <MyBook>:'
examples/myfile.py:24: 'def print_my_book(book: <MyBook>) -> None:'
examples/myfile.py:30: ' book : <MyBook>'
tx.TextTree.replace()
Use .replace() to find all non-overlapping matches of some pattern, and replace them with another string:
>>> replacer = myfile.replace("book", "magazine")
>>> replacer
examples/myfile.py:9: ' A <book/magazine> that records a story.'
examples/myfile.py:20: ' self.content = "This <book/magazine> is empty."'
examples/myfile.py:24: 'def print_my_<book/magazine>(<book/magazine>: MyBook) -> None:'
examples/myfile.py:26: ' Print a <book/magazine>.'
examples/myfile.py:30: ' <book/magazine> : MyBook'
examples/myfile.py:31: ' A <book/magazine>.'
examples/myfile.py:34: ' print(<book/magazine>.content)'
At this point, the replacement has not actually taken effect yet. Use .confirm() to confirm the changes and write them to the file(s):
>>> replacer.confirm()
{'successful': ['examples/myfile.py'], 'failed': []}
If you want to rollback the changes, run:
>>> replacer.rollback()
{'successful': ['examples/myfile.py'], 'failed': []}
tx.TextTree.delete()
Use .delete() to find all non-overlapping matches of some pattern, and delete them:
>>> deleter = myfile.delete("book")
>>> deleter
examples/myfile.py:9: ' A <book> that records a story.'
examples/myfile.py:20: ' self.content = "This <book> is empty."'
examples/myfile.py:24: 'def print_my_<book>(<book>: MyBook) -> None:'
examples/myfile.py:26: ' Print a <book>.'
examples/myfile.py:30: ' <book> : MyBook'
examples/myfile.py:31: ' A <book>.'
examples/myfile.py:34: ' print(<book>.content)'
>>> deleter.confirm()
{'successful': ['examples/myfile.py'], 'failed': []}
>>> deleter.rollback()
{'successful': ['examples/myfile.py'], 'failed': []}
See Also
Github repository
PyPI project
License
This project falls under the BSD 3-Clause License.
History
v0.2.4
- The first argument of
tx.module()is optional now, by default "".
v0.2.3
- Compatible with
htmlmaster==0.0.4.
v0.2.2
- Compatible with
htmlmaster==0.0.2.
v0.2.1
- New module-level functions
tx.file()andtx.fromstr(). - Removed the deprecated function
tx.textpy(). - Removed
utils.re_extensionsas a submodule, related utils are now directly import from the packagere_extensions. User can use an instance ofre_extensions.SmartPatternas the pattern forTextTree.findall(),TextTree.replace(), andTextTree.delete(). - After this version, the required Python version is updated to >=3.12.7. Download and install v0.1.32 if the user is under lower Python version (>=3.8.13).
v0.1.32
- Added
distinDEFAULT_IGNORED_PATHS.
v0.1.31
- Got ANSI escapes to work on Windows.
v0.1.30
- New optional paramter
include=fortx.module(). - Renamed
tx.PyTexttotx.TextTree; the namePyTextwill be deprecated.
v0.1.29
- Updated
PyText.check_format(), which now returns a boolean value instead of None. - Updated the
ignore=parameter fortx.module(), which now accepts a list of path-patterns. Paths matching any of these patterns will be ignored when searching for files.
v0.1.28
- Fixed issue: failed to display special characters in
*._repr_mimebundle_().
v0.1.27
- New gloabal parameters:
tree_style=,table_style=,use_mimebundle=, andskip_line_numbers=- find them undertx.display_params. - Defined
display_params.defaults()for users to get the default values of the parameters. - New subclass
PyPropertyinherited fromPyMethod. Class properties will be stored in instances ofPyPropertyinstead ofPyMethodin the future. - Updated the method
PyText.jumpto(): it now allows "/" as delimiters (in addition to "."); if a class or callable is defined more than once, jump to the last (previously first) place where it was defined. PyTexthas a_repr_mimebundle_()method now.- New property
PyText.imports. - Created a utility class
HTMLTableMakerin place ofStyler; this significantly reduces the running overhead of*._repr_mimebundle_().
v0.1.26
- Updated with the package
re_extensions:- bugfix for
rsplit(); - new string operation
quote_collapse().
- bugfix for
v0.1.25
- Updated
utils.re_extensions:- Important: we've decided to extract
utils.re_extensionsinto an independent package namedre_extensions(presently at v0.0.3), so any future updates should be looked up in https://github.com/Chitaoji/re-extensions instead; we will stay in sync with it, however; real_findall()now returns match objects instead of spans and groups;smart_sub()accepts a new optional parameter calledcount=;SmartPatternsupports [] to indicate a Unicode (str) or bytes pattern (like whatre.Patterndoes);- new regex operations
smart_split(),smart_findall(),line_findall(),smart_subn(), andsmart_fullmatch(); - created a namespace
Smartfor all the smart operations; - bugfixes for
rsplit(),lsplit(), andsmart_sub().
- Important: we've decided to extract
- Reduced the running cost of
PyText.findall()by taking advantage of the new regex operationline_findall().
v0.1.24
- New methods
PyText.is_file()andPyText.is_dir()to find out whether the instance represents a file / directory. - New method
PyText.check_format()for format checking. - Defined the comparison ordering methods
__eq__(),__gt__(), and__ge__()forPyText. They compares twoPyTextobject via their absolute paths. - Updated
utils.re_extensions:- new regex operations
smart_search(),smart_match(), andsmart_sub(); - new string operation
counted_strip(); - new utility classes
SmartPatternandSmartMatch. - new utility functions
find_right_bracket()andfind_left_bracket().
- new regex operations
v0.1.23
- New string operation
utils.re_extensions.word_wrap(). - Various improvements.
v0.1.22
- The module-level function
tx.textpy()is going to be deprecated to avoid conflicts with the package nametextpy. Please usetx.module()insead. - New methods
PyText.replace()andPyText.delete(). - New class
Replaceras the return type ofPyText.replace(), with public methods.confirm(),.rollback(), etc. - Added a dunder method
PyText.__truediv__()as an alternative toPyText.jumpto(). - New subclass
PyContentinherited fromPyText. APyContentobject stores a part of a file that is not storable by instances of other subclasses.
v0.1.21
- Improved behavior of clickables.
v0.1.20
- Fixed issue: incorrect file links in the output of
TextPy.findall();
v0.1.19
- Various improvements.
v0.1.18
- Updated LICENSE.
v0.1.17
- Refactored README.md.
v0.1.16
- Lazily imported pandas to reduce the time cost for importing.
v0.1.12
- New optional parameters for
TextPy.findall():whole_word=: whether to match whole words only;case_sensitive=: specifies case sensitivity.
v0.1.10
- New optional parameter
encoding=fortextpy().
v0.1.9
- Removed unnecessary dependencies.
v0.1.8
- Bugfix under Windows system.
v0.1.5
- Provided compatibility with pandas versions lower than 1.4.0.
- Updated
textpy():Pathobject is now acceptable as the positional argument;- new optional parameter
home=for specifying the home path.
- More flexible presentation of output from
TextPy.findall().
v0.1.4
- Fixed a display issue of README.md on PyPI.
v0.1.3
- Initial release.
Metadata
Release files for textpy 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| textpy-0.2.4.tar.gz | 25.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| textpy-0.2.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 53.0 kB
Release files / textpy-0.2.4.tar.gz
| Download URL | textpy-0.2.4.tar.gz |
|---|---|
| Size | 25.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c45c0952ca11f8f84124cada99124df776a3f8cd9d38df6a8596a180f86e2ecc
|
|
BLAKE2b-256 checksum How to use checksums |
1aca2364f017b7921d09e447fc6b7db3ea7166234801039eb16d4377214ccdd9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|
Release files / textpy-0.2.4-py3-none-any.whl
| Download URL | textpy-0.2.4-py3-none-any.whl |
|---|---|
| Size | 27.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ac3dcd5e5549ca0f4f138a3ae7f4d565c26f447750ab0597cc6f9d718347749d
|
|
BLAKE2b-256 checksum How to use checksums |
a1b7f2259a8fe01d23fb6becc11617d0533fcd36eecf74395800f2dc97319dc7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|