3838
3939
4040class File :
41+ _lines_of_code : int
42+ _character_count : int
43+
4144 """Represents a single file within a mystb.in paste.
4245
4346 Attributes
@@ -46,44 +49,42 @@ class File:
4649 The file's name.
4750 content: :class:`str`
4851 The file's contents.
49- lines_of_code: Optional[:class:`int`]
50- The lines of code within the file.
51- character_count: Optional[:class:`int`]
52- The character count of the file.
53-
54-
55- .. note::
56- The ``lines_of_code`` and ``character_count`` come from the API and should not be provided by the user.
5752 """
5853
5954 __slots__ = (
6055 "filename" ,
6156 "content" ,
62- "lines_of_code " ,
63- "character_count " ,
57+ "_lines_of_code " ,
58+ "_character_count " ,
6459 )
6560
6661 def __init__ (
6762 self ,
6863 * ,
6964 filename : str ,
7065 content : str ,
71- lines_of_code : Optional [int ] = None ,
72- character_count : Optional [int ] = None ,
7366 ) -> None :
7467 self .filename : str = filename
7568 self .content : str = content
76- self .lines_of_code : int = lines_of_code or content .count ("\n " )
77- self .character_count : int = character_count or len (content )
69+
70+ @property
71+ def lines_of_code (self ) -> int :
72+ return self ._lines_of_code
73+
74+ @property
75+ def character_count (self ) -> int :
76+ return self ._character_count
7877
7978 @classmethod
8079 def _from_data (cls , payload : FileResponse , / ) -> Self :
81- return cls (
80+ self = cls (
8281 content = payload ["content" ],
8382 filename = payload ["filename" ],
84- lines_of_code = payload ["loc" ],
85- character_count = payload ["charcount" ],
8683 )
84+ self ._lines_of_code = payload ["loc" ]
85+ self ._character_count = payload ["charcount" ]
86+
87+ return self
8788
8889 def _to_dict (self ) -> dict [str , Any ]:
8990 ret : dict [str , Any ] = {"content" : self .content , "filename" : self .filename }
@@ -92,6 +93,10 @@ def _to_dict(self) -> dict[str, Any]:
9293
9394
9495class Paste :
96+ _last_edited : Optional [datetime .datetime ]
97+ _expires : Optional [datetime .datetime ]
98+ _views : Optional [int ]
99+
95100 """Represents a Paste object from mystb.in.
96101
97102 Attributes
@@ -100,47 +105,31 @@ class Paste:
100105 The ID of this paste.
101106 created_at: :class:`datetime.datetime`
102107 When this paste was created in UTC.
103- expires: Optional[:class:`datetime.datetime`]
104- When this paste expires, if at all.
105- last_edited: Optional[:class:`datetime.datetime`]
106- When this paste was last edited, if at all.
107108 files: list[:class:`mystbin.File`]
108109 The list of files within this Paste.
109- views: Optional[:class:`int`]
110- How many views this paste has had, if any.
111-
112-
113- .. note::
114- The ``last_edited``, ``expires`` and ``views`` attributes come from the API and are not user provided.
115110 """
116111
117112 __slots__ = (
118113 "id" ,
119114 "author_id" ,
120115 "created_at" ,
121- "expires" ,
122116 "files" ,
123117 "notice" ,
124- "views" ,
125- "last_edited" ,
118+ "_expires" ,
119+ "_views" ,
120+ "_last_edited" ,
126121 )
127122
128123 def __init__ (
129124 self ,
130125 * ,
131126 id : str ,
132127 created_at : str ,
133- expires : Optional [str ] = None ,
134- last_edited : Optional [str ] = None ,
135128 files : list [File ],
136- views : Optional [int ] = None ,
137129 ) -> None :
138130 self .id : str = id
139131 self .created_at : datetime .datetime = datetime .datetime .fromisoformat (created_at )
140- self .expires : Optional [datetime .datetime ] = datetime .datetime .fromisoformat (expires ) if expires else None
141- self .last_edited : Optional [datetime .datetime ] = datetime .datetime .fromisoformat (last_edited ) if last_edited else None
142132 self .files : list [File ] = files
143- self .views : Optional [int ] = views
144133
145134 def __str__ (self ) -> str :
146135 return self .url
@@ -152,14 +141,37 @@ def __repr__(self) -> str:
152141 def url (self ) -> str :
153142 return f"https://mystb.in/{ self .id } "
154143
144+ @property
145+ def last_edited (self ) -> Optional [datetime .datetime ]:
146+ return self ._last_edited
147+
148+ @property
149+ def expires (self ) -> Optional [datetime .datetime ]:
150+ return self ._expires
151+
152+ @property
153+ def views (self ) -> Optional [int ]:
154+ return self ._views
155+
155156 @classmethod
156157 def _from_data (cls , payload : PasteResponse , / ) -> Self :
157158 files = [File ._from_data (data ) for data in payload ["files" ]]
158- return cls (
159+ self = cls (
159160 id = payload ["id" ],
160161 created_at = payload ["created_at" ],
161- expires = payload ["expires" ],
162162 files = files ,
163- views = payload .get ("views" ),
164- last_edited = payload .get ("last_edited" ),
165163 )
164+ self ._views = payload .get ("views" )
165+ last_edited = payload .get ("last_edited" )
166+ if last_edited :
167+ self ._last_edited = datetime .datetime .fromisoformat (last_edited )
168+ else :
169+ self ._last_edited = None
170+
171+ expires = payload .get ("expires" )
172+ if expires :
173+ self ._expires = datetime .datetime .fromisoformat (expires )
174+ else :
175+ self ._expires = None
176+
177+ return self
0 commit comments